Limit proteins (Python)#
geckopy objects in geckopy.limit_proteins.
Functions#
Function |
Summary |
|---|---|
Constrain the model's exchange fluxes from a |
|
Compute the f-factor for an ec model. |
|
Group the enzymes of multi-subunit reactions into complexes. |
|
The complexes of an ecModel and their shared subunits. |
|
Constrain |
|
Fill |
|
Information about which enzyme constraints were flexibilized. |
|
Iteratively relax enzyme concentration constraints until the |
|
Compute control coefficients for enzyme concentrations. |
|
Level molar abundances to one abundance per complex. |
|
Give every complex in |
|
What |
|
Relax enzyme caps by the least total amount that reaches |
|
Greedy relaxation of proteomics constraints until growth >= minimal_growth. |
|
Reference#
apply_flux_data_constraints#
apply_flux_data_constraints(model: 'EcModel', flux_data: 'FluxData', *, condition: int | str=0, max_min_growth: Literal['max', 'min']='max', loose_strict_flux: _LooseStrict='loose', bio_rxn: Optional[str]=None, c_source: Optional[str]=None)
Constrain the model's exchange fluxes from a FluxData measurement.
Sets the biomass reaction bounds to the measured growth rate and
each exchange reaction in flux_data.exch_rxn_ids to its
measured flux for the chosen condition. Also zeros out the
adapter's preferred carbon source so the data drives the choice.
Ported from GECKO MATLAB: src/geckomat/limit_proteins/constrainFluxData.m.
A +/-1000 measured flux means unconstrained, regardless of
loose_strict_flux:
-1000 -> lb=-1000, ub=0 (free uptake), +1000 ->
lb=0, ub=1000 (free excretion).
Parameters
modelEcModel with the exchange reactions referenced by
flux_dataalready in place. Mutated in place.flux_dataPre-loaded FluxData (typically from a future
load_flux_datautility).conditionEither the 0-indexed condition number, or the condition name (matched against
flux_data.conds).max_min_growth"max"setsbio_rxnupper bound to the measured growth rate (and lower bound to 0);"min"sets the lower bound (suitable when minimisingprot_pool_exchange).loose_strict_flux"loose"keeps one bound at 0 and the other at the measured value (allows zero flux). A numeric percentagepbrackets the measured value with hard bounds:lb = val * (1 - p/200),ub = val * (1 + p/200), swapped as needed to keeplb <= ubwhenvalis negative.p=10allows 10% total variance (i.e. +/-5%).bio_rxnBiomass reaction ID. Defaults to the adapter's configured biomass reaction (
model.adapter.params.bio_rxn) whenNone.c_sourceReaction ID of the preferred carbon-source uptake reaction; its bounds are set to
(0, 0)before applying the flux data so that the data alone determines the carbon source used. Defaults tomodel.adapter.params.c_source(or no blocking if there is no adapter) whenNone; pass""to skip blocking any reaction. Silently ignored if the reaction id is not found in the model.
Raises
ValueErrorIf
model.adapteris None,max_min_growth/loose_strict_fluxis invalid,condition(as string) is not influx_data.conds, or anyflux_data.exch_rxn_idsis missing from the model.IndexErrorIf
condition(as int) is out of range.
calculate_f_factor#
calculate_f_factor(model: 'EcModel', prot_data: 'ProtData', *, enzymes: Optional[list[str]]=None)
Compute the f-factor for an ec model.
The f-factor is the mass fraction of total cellular protein that is accounted for by enzymes in the model. It is computed as
f = sum(abundances of in-model enzymes) / sum(all abundances)
where abundances are read from a pre-loaded ProtData (typically
populated via load_pax_db).
For 2-D abundances (multiple proteomics samples), the
per-protein average is taken first via np.nanmean(axis=1).
Ported from GECKO MATLAB: src/geckomat/limit_proteins/calculateFfactor.m.
Parameters
modelEcModel; only used to default
enzymestomodel.ec.enzymes.prot_dataPre-loaded proteomics data (typically from
load_pax_db). There is no implicit fallback when proteomics data is unavailable -- callers without measurements should use a default value such asf = 0.5directly instead of calling this function.enzymesUniProt IDs counted as "in the model". Defaults to
model.ec.enzymes.
Returns
floatThe f-factor in [0, 1]. Returns 0.0 if the total proteome abundance is zero, or if none of the proteomics UniProt IDs match a model enzyme.
complex_families#
complex_families(model: 'EcModel', min_overlap: float=0.5, min_shared: int=2)
Group the enzymes of multi-subunit reactions into complexes.
Parameters
modelAn EcModel with
ec.rxn_enz_mat(copies per subunit).min_overlapTwo enzyme sets are one complex when they share at least this fraction of the larger set's subunits...
min_shared...and at least this many subunits.
ComplexFamilies#
The complexes of an ecModel and their shared subunits.
Attributes
complexesOne dict per complex,
{enzyme: copies}over every subunit that appears in any of its enzyme sets.ownerFor every subunit that belongs to a complex, the index of that complex in
complexes.sharedSubunits of a complex that belong to none: carriers and subunits shared between complexes.
constrain_enz_concs#
constrain_enz_concs(model: 'EcModel', *, remove_constraints: bool=False, restrict_to: list[str] | None=None)
Constrain usage_prot_<enzyme> reactions by model.ec.concs.
For each enzyme in model.ec.enzymes whose entry in
model.ec.concs is non-NaN, the corresponding
usage_prot_<enzyme> reaction's upper bound is set to that
concentration. Enzymes with NaN concentrations have their usage
reaction reset to the default upper_bound = 1000, drawing
freely from prot_pool. Only the reaction's upper bound is
changed; its stoichiometry (as set by
add_protein_usage_reactions) is left untouched.
Ported from GECKO MATLAB: src/geckomat/limit_proteins/constrainEnzConcs.m.
Parameters
modelEcModel with
model.ec.concspopulated (typically byfill_enz_concs) and the protein pool / usage reaction machinery already in place. Mutated in place.remove_constraintsWhen True, all usage reactions are reset to their default
upper_bound = 1000, regardless ofec.concs.ec.concsitself is left unchanged.restrict_toIf supplied, only the listed enzyme uniprot IDs are processed (others are left untouched). Useful for incremental updates from
Enzyme.concentrationsetters. Unknown IDs in the list are silently ignored. DefaultNone= process every enzyme inmodel.ec.enzymes.
Raises
ValueErrorIf the
prot_poolmetabolite is missing, or if anyusage_prot_<enzyme>reaction is missing for an enzyme inmodel.ec.enzymes(e.g. because the model is gecko-light, which has no usage reactions).
fill_enz_concs#
fill_enz_concs(model: 'EcModel', prot_data: 'ProtData', *, data_col: int=0)
Fill model.ec.concs from prot_data.abundances (mg/gDCW).
Resets model.ec.concs to all-NaN of length n_enzymes,
then writes each (uniprot_id, abundance) pair into the slot
matching model.ec.enzymes. UniProt IDs absent from
model.ec.enzymes are silently ignored. Enzymes absent from
prot_data keep their NaN.
For 2-D prot_data.abundances (multiple conditions /
samples), data_col selects which column to use.
Ported from GECKO MATLAB: src/geckomat/limit_proteins/fillEnzConcs.m.
Parameters
modelEcModel;
model.ec.concsis replaced in place.prot_dataPre-loaded proteomics data (e.g. from
load_pax_dbor a manual TSV reader). Abundances are expected in mg/gDCW.data_col0-indexed column of
prot_data.abundancesto read. Must be0for 1-D abundances.
Raises
IndexErrorIf
data_colis out of range for the supplied abundances.
FlexEnzResult#
Information about which enzyme constraints were flexibilized.
All arrays are sorted by ratio_incr descending. May contain a
final entry with uniprot_ids[-1] == "prot_pool" if the protein
pool exchange itself was relaxed.
Attributes
uniprot_idsUniProt IDs of the flexibilized enzymes (plus
"prot_pool"as a final entry when the protein pool itself was relaxed).old_concsUpper bound of each enzyme's usage reaction (or of
prot_pool_exchangefor the"prot_pool"entry) before relaxation.flex_concsUpper bound after relaxation.
ratio_incrflex_concs / old_concs;infwhereold_concsis 0.frequenceNumber of loop iterations in which each enzyme was picked as the most limiting one.
flexibilize_enz_concs#
flexibilize_enz_concs(model: 'EcModel', *, exp_growth: Optional[float]=None, fold_change: float=2.0, iter_per_enzyme: int=5, bio_rxn: Optional[str]=None, verbose: bool=True, per_complex: bool=False)
Iteratively relax enzyme concentration constraints until the
model reaches exp_growth.
Each iteration uses get_conc_control_coeffs to find the most
limiting enzyme, then multiplies its usage_prot_<enzyme>
upper bound by (1 + fold_change * iteration_count). If no
enzyme is limiting (all control coefficients zero), the function
tries relaxing prot_pool_exchange.
After the loop, a refinement pass solves min prot_pool_exchange
with bio_rxn constrained to a soft +/-0.25% band around
exp_growth (matching MATLAB's flexibilizeEnzConcs.m, which
uses RAVEN's setParam('var', bioRxn, expGrowth, 0.5) for the same
solve) to find the minimal usage that supports growth. Because
minimal protein-pool usage is non-decreasing in growth rate near the
optimum, the minimiser typically settles at the band's low edge --
growth ends up about 0.25% below exp_growth, not at it exactly.
For each flexibilized enzyme, if the actual usage at this minimum is
less than its original concentration, the original constraint is
restored (i.e. that enzyme is dropped from the result). This avoids
over-relaxing enzymes that the prior iterative pass increased more
than necessary.
Ported from GECKO MATLAB: src/geckomat/limit_proteins/flexibilizeEnzConcs.m.
Parameters
modelEcModel with
prot_pool_exchangeandusage_prot_*reactions installed andmodel.ec.concspopulated for at least some enzymes (typically byfill_enz_concsandconstrain_enz_concs). Mutated in place;ec.concsitself is left unchanged.exp_growthTarget growth rate. Defaults to
model.adapter.params.gr_exp.fold_changeControls how much the limiting enzyme's usage upper bound grows each time it is picked: on its
k-th pick, the bound is set tooriginal_conc * (1 + fold_change * k).iter_per_enzymeMaximum number of times the same enzyme may be picked before warning and breaking.
0means no limit.bio_rxnBiomass reaction id. Defaults to
params.bio_rxnfrom the adapter; pass it (withexp_growth) to run without an adapter.verboseWhether per-iteration progress is logged at INFO.
per_complexTreat every complex (see
complex_families) as one enzyme: rank enzymes and complexes by the growth gained per fold of raising all their caps together (a levelled complex binds on all subunits at once, so no single subunit shows a gain), raise every measured subunit of the picked complex by the same factor, count iterations per complex, and keep one factor per complex in the refinement pass, so that concentrations levelled bylevel_complex_concsstay levelled. Off by default.
Returns
FlexEnzResult
:
Raises
ValueErrorIf no enzyme has a measured concentration (nothing to flexibilize), or if
model.adapteris None andexp_growthis also None.
get_conc_control_coeffs#
get_conc_control_coeffs(model: 'EcModel', proteins: Optional[list[str]]=None, fold_change: float=2.0, limit: float=0.0)
Compute control coefficients for enzyme concentrations.
For each protein in proteins, the coefficient quantifies how
much the LP optimum (typically growth) increases per unit increase
in that enzyme's upper bound. Proteins whose usage flux is at most
limit times their upper bound are skipped (no sensitivity to
expect there).
The default path uses the prot_<id> metabolite shadow price
from a single LP solve — equivalent to the per-protein
finite-difference probe at the margin, but n times fewer LPs.
When the active solver is one that does not expose LP duals (notably
optlang's scipy backend), the function automatically falls back to
the per-protein finite-difference loop and logs once that it has
done so. The fold-change probe size is only used in that fallback.
Ported from GECKO MATLAB: src/geckomat/limit_proteins/getConcControlCoeffs.m.
Parameters
modelEcModel with a defined LP objective (typically a biomass reaction) and
usage_prot_<enzyme>reactions for every analysed protein.proteinsUniProt IDs to analyse. Defaults to
model.ec.enzymes.fold_changeProbe size for the finite-difference fallback (default 2.0). Ignored on the shadow-price path.
limitSkip proteins whose usage flux is at most
limittimes their upper bound. Default 0.0 includes any protein with non-zero flux.
Returns
enz_maskBoolean array of length
len(proteins); True where the protein was analysed.control_coeffsFloat array of length
len(proteins); 0.0 where the protein was either skipped or showed no sensitivity.
GreedyRelaxResult#
level_complex_abundances#
level_complex_abundances(model: 'EcModel', uniprot_ids: Sequence[str], abundances: Sequence[float], *, statistic: str='median', fill_missing: bool=True, families: Optional[ComplexFamilies]=None)
Level molar abundances to one abundance per complex.
Parameters
modelThe EcModel whose complexes are used.
uniprot_ids, abundancesMeasured molar abundances (any molar unit; per subunit, not per complex).
statistic"median"or"mean"over the measured, non-shared subunits' abundance divided by their copies.fill_missingGive unmeasured, non-shared subunits the complex's abundance.
familiesPrecomputed
complex_families(model).
Returns
ids, abundances, resultThe levelled data (unmeasured subunits appended when filled) and what changed.
level_complex_concs#
level_complex_concs(model: 'EcModel', *, statistic: str='median', fill_missing: bool=True)
Give every complex in model.ec.concs one abundance.
Run after fill_enz_concs and before constrain_enz_concs.
Concentrations (mg/gDCW) are converted to molar amounts with
ec.mw for the levelling and back afterwards. Mutates
model.ec.concs.
Parameters
modelEcModel with
ec.concsfilled.statistic"median"(default) or"mean".fill_missingGive unmeasured, non-shared subunits the complex's concentration.
LevelComplexResult#
What level_complex_concs changed.
Attributes
adjustedMeasured subunits whose concentration was replaced by the complex's.
addedUnmeasured subunits given the complex's concentration.
sharedSubunits left as measured because they belong to more than one complex.
skippedComplexes (as sorted subunit tuples) without any measured, non-shared subunit.
relax_enz_concs#
relax_enz_concs(model: 'EcModel', *, exp_growth: Optional[float]=None, bio_rxn: Optional[str]=None, per_complex: bool=False, weight: str='relative', pool_weight: float=1000.0, floor: float=1e-09)
Relax enzyme caps by the least total amount that reaches exp_growth.
Parameters
modelEcModel with
model.ec.concsfilled and the caps applied (fill_enz_concsandconstrain_enz_concs). The usage upper bounds (andprot_pool_exchange) are updated in place;ec.concsitself is left unchanged, as inflexibilize_enz_concs.exp_growthTarget growth rate. Defaults to
params.gr_exp.bio_rxnBiomass reaction id. Defaults to
params.bio_rxn.per_complexOne fold per complex (its measured, owned subunits; see
complex_families) instead of one per enzyme.weight"relative"minimises the summed fold increases, so an enzyme measured at almost nothing is not relaxed freely because its absolute cost is small;"absolute"minimises the mg/gDCW added.pool_weightPrice of one fold of the protein pool relative to one fold of an enzyme (or, with
weight="absolute", per mg).floorConcentration below which a measured value is treated as this floor when scaling its fold, so a zero measurement can still be relaxed (at a high relative price).
Returns
FlexEnzResultThe relaxed enzymes, as from
flexibilize_enz_concs(frequenceis 1 for every entry), with a"prot_pool"entry when the pool was raised.
Raises
ValueErrorIf no enzyme is measured, the weighting is unknown, or no relaxation reaches
exp_growth(the target is then not limited by protein).
relax_proteomics_greedy#
relax_proteomics_greedy(model: 'EcModel', *, minimal_growth: float, enzyme_set: Optional[set[str]]=None, max_iterations: int=100, default_upper_bound: float=1000.0)
Greedy relaxation of proteomics constraints until growth >= minimal_growth.
Parameters
modelEcModel with proteomics-constrained enzymes (some
usage_prot_<id>reactions have finite upper bounds fromconstrain_enz_concs).minimal_growthTarget objective value.
enzyme_setSubset of uniprot IDs eligible for relaxation.
None= all currently proteomics-constrained enzymes.max_iterationsSafety cap; raises
RuntimeErrorif exceeded without convergence.default_upper_boundValue to restore on a relaxed usage reaction. Matches the default set by
add_protein_usage_reactions.
Returns
GreedyRelaxResultrelaxedmaps uniprot to the original concentration (so the caller can restore if desired);tracerecords each step;final_growthis the objective value reached at the last iteration attempted;convergedis True ifffinal_growth >= minimal_growth.
Ported from the legacy geckopy package (Carrasco et al., 2023,
:
https://doi.org/10.1128/spectrum.01705-23),
:
geckopy/experimental/relaxation.py (relax_proteomics_greedy).
: