Build & edit ecModel (Python)#

geckopy objects in geckopy.ec_model.

Functions#

Function

Summary

add_protein_pool_exchange_reaction

Stage 12: add the single prot_pool_exchange reaction.

add_protein_pool_pseudometabolite

Stage 10: add the single prot_pool pseudometabolite.

add_protein_pseudometabolites

Stage 9: add prot_<enzyme> pseudometabolites to the model.

add_protein_usage_reactions

Stage 11: add usage_prot_<enzyme> reactions.

allocate_ec_and_coupling_light

Stages 6 + 8 (gecko-light layout): allocate ec.rxns and ec.rxn_enz_mat.

allocate_ec_for_catalyzed_reactions

Stage 6: allocate ec.rxns and per-reaction slots.

apply_complex_data

Update ec.rxn_enz_mat with subunit stoichiometries from ComplexPortal.

apply_custom_kcats

Apply user-curated kcats from a customKcats.tsv file.

apply_kcat_constraints

Translate ec.kcat values into stoichiometric coefficients.

build_rxn_enzyme_coupling

Stage 8: populate ec.rxn_enz_mat.

canonicalize_rxn_id

Map a split reaction id back to its conventional GEM id.

EcModel

A cobra model with enzyme-constraint data attached.

Enzyme

Stateless proxy for one enzyme in an EcModel.

EnzymeView

Lazy DictList-like view over EcModel enzymes.

fill_kcats_from_isozymes

Fill in missing kcats by combining known kcats across sibling isozymes.

get_reactions_from_enzyme

Return all reactions catalyzed by a given enzyme, as a DataFrame.

invert_backwards_only_reactions

Flip reactions that are constrained to only carry negative flux.

Kcats

Dict-like view of {reaction_id: kcat_per_s} for one enzyme.

make_ec_model

Build an enzyme-constrained model from a conventional GEM.

populate_enzyme_data

Stage 7: fill per-enzyme fields from UniProt (with optional KEGG fallback).

remove_pseudoreaction_gprs

Clear gene-protein-reaction rules from pseudoreactions.

set_kcat_for_reactions

Set kcat values for one or more reactions in ec.kcat.

set_prot_pool_size

Set the upper bound of prot_pool_exchange (the protein budget).

split_light_rxn_id

Split a gecko-light prefixed ec.rxn id into (isozyme_index, cobra_id).

Reference#

add_protein_pool_exchange_reaction#

add_protein_pool_exchange_reaction(model: 'EcModel')

Stage 12: add the single prot_pool_exchange reaction.

Stoichiometry: (nothing) -> prot_pool with bounds (0, 1000). Positive flux imports protein into the pool, mirroring how cobrapy writes ordinary exchange reactions for extracellular metabolites.

Parameters

model

An EcModel with stage 10 already run. Mutated in place.

add_protein_pool_pseudometabolite#

add_protein_pool_pseudometabolite(model: 'EcModel')

Stage 10: add the single prot_pool pseudometabolite.

Parameters

model

An EcModel with adapter set. Mutated in place.

add_protein_pseudometabolites#

add_protein_pseudometabolites(model: 'EcModel')

Stage 9: add prot_<enzyme> pseudometabolites to the model.

Adds one pseudometabolite per unique enzyme in model.ec.enzymes, in the compartment named by adapter.params.enzyme_comp. Enzymes that already have a prot_<enzyme> metabolite in the model are skipped (idempotent).

Parameters

model

An EcModel with ec.enzymes already populated (stage 7) and adapter set. Mutated in place.

Returns

list of str

Sorted IDs of the pseudometabolites actually added (excludes any that already existed).

add_protein_usage_reactions#

add_protein_usage_reactions(model: 'EcModel')

Stage 11: add usage_prot_<enzyme> reactions.

Each usage reaction has stoichiometry prot_pool -> prot_<enzyme> with bounds (0, 1000); positive flux represents enzyme production.

The GPR of each usage reaction is set to the single gene whose enzyme is the produced pseudometabolite, so that model.genes retains that gene even if no metabolic reaction references it anymore after upstream filtering.

Parameters

model

An EcModel with stage 9 already run. Mutated in place.

Returns

list of str

Sorted IDs of added usage reactions.

allocate_ec_and_coupling_light#

allocate_ec_and_coupling_light(model: 'EcModel')

Stages 6 + 8 (gecko-light layout): allocate ec.rxns and ec.rxn_enz_mat.

Light models do not split isozyme reactions in the cobra layer (expand_model is skipped), so the per-isozyme bookkeeping moves into ec instead:

  • Each cobra reaction with N isozymes (i.e. len(gpr_to_dnf(rxn.gpr)) == N) produces N rows in ec.rxns. Row k carries the id "{k:03d}_{rxn.id}" (1-indexed, three-digit zero-padded counter).

  • Row k's slice of ec.rxn_enz_mat is 1.0 for each gene in that isozyme's AND-clause; other genes are 0.

ec.kcat is initialized to 0 ("no kcat assigned"), and ec.source / ec.notes / ec.eccodes to empty strings — same convention as allocate_ec_for_catalyzed_reactions.

Stage 7 (populate_enzyme_data) runs unchanged on light models, so ec.genes / ec.enzymes / ec.mw / ec.sequence must already be populated before this function builds the coupling matrix. Call order in make_ec_model for light: populate_enzyme_data first, then this function.

Parameters

model

An EcModel preprocessed through stage 4 (irreversibility), with stage 5 (expand_model) skipped and stage 7 already complete. Mutated in place.

Returns

list of str

The prefixed reaction IDs written into model.ec.rxns.

allocate_ec_for_catalyzed_reactions#

allocate_ec_for_catalyzed_reactions(model: 'EcModel')

Stage 6: allocate ec.rxns and per-reaction slots.

Applies only to full (non-light) ecModels; gecko-light uses allocate_ec_and_coupling_light instead.

Walks the model (which must already have been through stages 1-5) and selects every reaction that has at least one gene associated. Each selected reaction gets an entry in ec.rxns; ec.kcat is initialized to 0 (0 marks "no kcat assigned"), and ec.source/notes/eccodes to empty strings. The per-enzyme arrays (including ec.concs) are left untouched (stage 7 populates them).

Parameters

model

An EcModel, already preprocessed through stage 5. Mutated in place.

Returns

list of str

The reaction IDs written into ec.rxns, in model order.

apply_complex_data#

apply_complex_data(model: 'EcModel', *, path: Optional[Path]=None, complex_data: Optional[list[ComplexPortalEntry]]=None, apply: bool=True, min_match_to_propose: float=0.75)

Update ec.rxn_enz_mat with subunit stoichiometries from ComplexPortal.

For each catalyzed reaction in ec.rxns, look up its enzyme set in the ComplexPortal data. Three outcomes:

Exact match The model's enzyme set equals a complex's protein list, with no extras on either side. Apply the complex's stoichiometry.

Proposed (subset) Either: every model enzyme is in some complex, but the complex lists additional subunits not in the model (closest superset is reported). Or: min_match_to_propose (default 0.75) of model enzymes are in some complex, with extras or substitutions on the model side. Logged as WARNING; not applied.

No match Skipped silently.

Parameters

model

An EcModel produced by make_ec_model. Mutated in place.

path

Path to a ComplexPortal JSON file. If None and complex_data is also None, defaults to adapter.params.path / "data" / "ComplexPortal.json".

complex_data

Pre-loaded list of ComplexPortalEntry. Overrides path.

apply

If True (default), call apply_kcat_constraints afterward. Needed because changing rxn_enz_mat invalidates the existing kcat coefficients.

min_match_to_propose

Minimum fraction of model enzymes in a complex for it to be reported as a proposal. MATLAB hardcodes 0.75.

Raises

FileNotFoundError

If neither complex_data nor a valid path is provided.

apply_custom_kcats#

apply_custom_kcats(model: 'EcModel', path: Optional[Path]=None, *, apply: bool=True)

Apply user-curated kcats from a customKcats.tsv file.

Reads a tab-separated file with seven columns and one header line:

proteins | genes | gene_name | kcat | rxns | notes | stoicho

Each row is interpreted in one of three modes, determined by which of the proteins and rxns columns are populated:

Mode A (rxns only, proteins empty) Apply the kcat to every entry of ec.rxns whose ID, after stripping any _EXP_<n> suffix, equals one of the listed reaction IDs (comma-separated). Reverse direction is honored: "R2" matches R2_EXP_* but not R2_REV_*.

Mode B (proteins only, rxns empty) Candidate reactions are those catalyzed by any listed protein. For each candidate, the kcat is applied only if the candidate's enzyme set exactly matches the listed proteins (full match). Partial matches (>= 50% but < 100%) are logged for manual review.

Mode C (both populated) Same matching rule as Mode B, but candidates are restricted to reactions matching the listed reaction IDs (with the same _EXP_ stripping as Mode A).

Notes from the notes column are appended to ec.notes for each updated reaction (separated by , from any existing note). The ec.source is set to "custom". The stoicho column is parsed but not applied; a warning is logged if any row has non-trivial stoichiometry. The genes and gene_name columns are read but not used.

Rows that fail to resolve to any reaction, or whose enzyme match is only partial, are logged at WARNING level for manual review rather than raised as errors.

Parameters

model

An EcModel produced by make_ec_model. Mutated in place.

path

Path to the TSV. If None, defaults to adapter.params.path / "data" / "customKcats.tsv".

apply

If True (default), call apply_kcat_constraints after updating ec.kcat so the new values reflect in the S matrix.

Raises

FileNotFoundError

If the file does not exist.

ValueError

If the file has fewer than 7 tab-delimited columns in the header.

apply_kcat_constraints#

apply_kcat_constraints(model: 'EcModel', update_rxns: list[str] | None=None)

Translate ec.kcat values into stoichiometric coefficients.

For each reaction in ec.rxns with a valid kcat and at least one associated enzyme, writes a negative coefficient at S[prot_<enzyme>, rxn] of magnitude::

subunits * MW / (kcat * 3600)

where subunits is the corresponding entry of ec.rxn_enz_mat (1 for a single subunit, higher for multi-copy complexes), MW is the enzyme molecular weight from ec.mw (in Da), and the factor 3600 converts kcat from 1/s (its conventional unit and the unit used in ec.kcat) to 1/h so it aligns with cobrapy's mmol/gDW/h flux convention.

Entries with kcat == 0 or kcat == NaN are treated as "no kcat assigned"; their stoichiometric coefficients are set to 0 (i.e., the enzyme places no constraint on that reaction).

The function is idempotent: existing non-zero coefficients at S[prot_<enzyme>, rxn] are first cleared for the reactions being updated, then freshly written from current ec.kcat. Running it twice yields the same result as running it once. Setting a kcat back to NaN/0 and re-applying clears the previously written coefficient.

Parameters

model

An EcModel produced by make_ec_model, with at least some kcat values assigned to model.ec.kcat. Mutated in place.

update_rxns

Reaction IDs (from model.ec.rxns) to update. If None, updates all entries.

Raises

ValueError

If update_rxns contains IDs not present in ec.rxns.

Warns

UserWarning If every kcat to be applied is 0 or NaN. Old coefficients are still cleared in this case; nothing is written afterward.

build_rxn_enzyme_coupling#

build_rxn_enzyme_coupling(model: 'EcModel')

Stage 8: populate ec.rxn_enz_mat.

For each reaction ID in ec.rxns and each gene in ec.genes, writes 1.0 at (i, j) if the reaction's GPR contains that gene. After stage 5, every reaction has at most one AND-clause, so this is simply "which enzymes are subunits of the complex catalyzing this reaction."

Downstream functions (e.g. applyComplexData) may later overwrite these 1.0 entries with actual subunit stoichiometries.

Parameters

model

An EcModel with ec.rxns and ec.genes already populated (stages 6 and 7). Mutated in place.

canonicalize_rxn_id#

canonicalize_rxn_id(rxn_id: str)

Map a split reaction id back to its conventional GEM id.

Returns (base_id, is_reverse). Strips a trailing _EXP_<n> and then a trailing _REV (so _REV_EXP_<n> is handled too). Reaction ids that merely contain _REV elsewhere — e.g. a real id like R_REVERTASE — are left intact, unlike a blanket str.replace("_REV", "").

EcModel#

A cobra model with enzyme-constraint data attached.

Subclasses cobra.Model so anything you do with a regular cobra model still works. Adds two attributes:

Attributes

ec : EcData

The enzyme-constraint data: kcats, enzyme MW, sequence, proteomics concentrations, and the sparse matrix saying which enzymes catalyse which reactions. See geckopy.ec_model.ec_data.EcData.

adapter : ModelAdapter or None

The adapter the ecModel was built with (organism parameters, paths, etc.). None if the model was loaded from disk and no adapter was attached at load time.

enzymes : EnzymeView

Lazy view that lets you reach individual enzymes via model.enzymes.get_by_id("P00350"). Each call returns a live Enzyme proxy; reads and writes always go through the underlying ec data.

Enzyme#

Stateless proxy for one enzyme in an EcModel.

All reads and writes go through model.ec and the underlying cobra model. Do not cache instances; rebuild via model.enzymes.get_by_id(uniprot).

EnzymeView#

Lazy DictList-like view over EcModel enzymes.

Always reflects live state of model.ec.enzymes.

fill_kcats_from_isozymes#

fill_kcats_from_isozymes(model: 'EcModel', *, apply: bool=True, aggregate: Optional[str]=None)

Fill in missing kcats by combining known kcats across sibling isozymes.

Two reactions are siblings if their ec.rxns IDs are identical after stripping any _EXP_<n> suffix. The _REV suffix is NOT stripped: forward and reverse reactions share chemistry but can have different kcats, so they are kept distinct.

For each reaction with no kcat assigned (ec.kcat == 0), find its siblings whose kcat is set (> 0). If any exist, take their mean and assign it. Set ec.source to "isozymes" for the filled entries.

Reactions whose siblings all also lack a kcat stay at 0. Reactions with a single isozyme (no siblings beyond themselves) also stay at 0.

get_kcat_across_isozymes is a deprecated alias for this function.

Parameters

model

An EcModel produced by make_ec_model. Mutated in place. Must not be a gecko-light model.

apply

If True (default), call apply_kcat_constraints after updating ec.kcat so the new values reflect in the S matrix.

aggregate

How to combine sibling kcats: "mean" (matches MATLAB GECKO), "median" (more robust for log-distributed rate constants), or "max". None (default) reads model.adapter.params.kcat_aggregate_isozymes if an adapter is attached, falling back to "mean" otherwise.

Raises

NotImplementedError

If model.ec.gecko_light is True. Isozyme-averaging does not apply to the light formulation since it does not split reactions per isozyme.

get_reactions_from_enzyme#

get_reactions_from_enzyme(model: 'EcModel', protein_id: str)

Return all reactions catalyzed by a given enzyme, as a DataFrame.

Parameters

model

An EcModel with populated ec.enzymes and ec.rxn_enz_mat.

protein_id

UniProt accession (or whatever IDs are in ec.enzymes), matched case-insensitively (matching MATLAB's getReactionsFromEnzyme, which uses strcmpi).

Returns

pandas.DataFrame

One row per catalyzed reaction, with columns:

  • rxn_id: the reaction ID.

  • kcat: the kcat value (1/s) from ec.kcat (0 if unset).

  • name: the reaction name from the cobra model.

  • gpr: the gene-protein-reaction rule.

Empty DataFrame with the right columns if the enzyme catalyzes no reactions in the current model.

Raises

ValueError

If protein_id is not found in ec.enzymes (case-insensitive). A deliberate Python-API choice, not a parity gap to close: MATLAB's getReactionsFromEnzyme returns five empty outputs instead of raising on an unmatched proteinId. See raven-gecko-parity#70.

invert_backwards_only_reactions#

invert_backwards_only_reactions(model: 'cobra.Model')

Flip reactions that are constrained to only carry negative flux.

A reaction with lb < 0 and ub == 0 is physically identical to a forward-only reaction with inverted stoichiometry and bounds [0, -lb]. Rewriting it in that canonical form keeps downstream irreversibility handling simple.

Reactions with lb == 0 (already forward) or with both bounds negative or both positive are not touched.

Parameters

model

A cobra.Model, mutated in place.

Returns

list of str

Sorted IDs of reactions that were inverted.

Kcats#

Dict-like view of {reaction_id: kcat_per_s} for one enzyme.

Reads return model.ec.kcat[rxn_idx] for any reaction in which this enzyme participates (non-zero column in rxn_enz_mat).

Writes update model.ec.kcat for the cell, then call apply_kcat_constraints for that reaction. Raises ValueError if the target reaction has more than one enzyme: per-enzyme kcats are ambiguous in that case; the user must edit model.ec.kcat[idx] and call apply_kcat_constraints themselves.

make_ec_model#

make_ec_model(model: cobra.Model, adapter: 'ModelAdapter', *, gecko_light: bool=False, uniprot_db: Optional[UniprotDB]=None, kegg_db: 'Optional[KeggDB]'=None)

Build an enzyme-constrained model from a conventional GEM.

Runs the 12-stage GECKO pipeline end to end and returns the populated EcModel. The output has:

  • Reactions split per isozyme where applicable (_EXP_<N> suffix) and per direction for reversible ones (_REV).

  • One prot_<uniprot> pseudo-metabolite per enzyme.

  • One usage_prot_<uniprot> reaction per enzyme drawing from the shared protein pool.

  • A prot_pool pseudo-metabolite and a prot_pool_exchange reaction acting as the global protein budget.

  • A populated model.ec substructure (kcats, MW, sequences, coupling matrix).

The kcat values themselves are NOT filled in here — they stay at 0 (0 marks "no kcat assigned") until you populate them via the gather_kcats functions (BRENDA / DLKcat / custom files) and call apply_kcat_constraints, or set them manually via set_kcat_for_reactions.

Parameters

model

A conventional cobra.Model (the starting GEM). Left unchanged: the function operates on an internal copy, so the caller's model is never mutated (matching the MATLAB GECKO makeEcModel value semantics).

adapter

A loaded ModelAdapter. Carries organism parameters (taxonomy id, biomass reaction, sigma factor, ...) and the path to the UniProt cache.

gecko_light

Build a light ecModel instead of a full one. The light layout skips the isozyme split (cobra reactions stay singular), omits the per-enzyme prot_<id> pseudometabolites and usage_prot_<id> reactions, and keeps only the shared prot_pool. The per-isozyme bookkeeping moves into ec instead: each cobra reaction with N isozymes produces N rows in ec.rxns distinguished by a 3-digit counter prefix (e.g. 001_RXN1, 002_RXN1). Suitable for large GEMs (HumanGEM, Recon3D) where the full layout's LP size becomes impractical. See docs/gecko_light_status.md.

uniprot_db

Pre-loaded UniprotDB. If None, the function looks for adapter.params.path / "data" / "uniprot.tsv" and loads it automatically.

kegg_db

Pre-loaded KeggDB. Optional fallback source for protein information and EC numbers. When provided, stage 7 fills genes that UniProt missed (with ec.enzymes set to the UniProt accession carried in the KEGG row, or to the KEGG gene id when that accession is empty), and the EC-number lookup (fill_eccodes_from_database) consults KEGG when the UniProt result is empty or ends with -. If None, KEGG is not used.

Returns

EcModel

The built ecModel. model.ec.kcat is all 0; fill it in before solving.

Raises

FileNotFoundError

If uniprot_db is None and no uniprot.tsv is found under the adapter's data folder.

ValueError

Propagated from individual pipeline stages on inconsistencies (e.g. genes referenced in GPRs that don't exist in the model).

Genes referenced in the model's GPRs but not found in UniProt are :

left enzyme-unconstrained: they are reported as a single warning :

summary, and each affected reaction is annotated via :

```rxn.notes["geckopy_warning"]``.` :

populate_enzyme_data#

populate_enzyme_data(model: 'EcModel', uniprot_db: 'UniprotDB', *, kegg_db: 'KeggDB | None'=None)

Stage 7: fill per-enzyme fields from UniProt (with optional KEGG fallback).

For every gene in the model (sorted alphabetically for reproducibility), a lookup is performed:

  1. adapter.get_uniprot_compatible_genes transforms model gene IDs into a form that should match the UniProt "Gene Names" column.

  2. If an uniprotConversion.tsv is present, it instead transforms model gene IDs directly to UniProt IDs and matches on the "Entry" column.

Matched genes are added to ec.genes / ec.enzymes / ec.mw / ec.sequence (same length as ec.genes), and ec.concs is allocated as NaN of matching length. Unmatched genes are returned as a list.

When kegg_db is supplied, each gene UniProt could not match is looked up in the KEGG database via adapter.get_kegg_compatible_genes. KEGG hits feed ec.enzymes with the UniProt accession stored on the KEGG entry; if that is empty, the bare KEGG gene ID (KeggDB.kegg_genes) is used as a fallback identifier. The returned list then names only the genes that neither source could fill.

Reactions whose GPR references an unmatched gene get a warning note added to rxn.notes[geckopy_warning]. If such a reaction has at least one other matched gene, it will still be enzyme-constrained through that gene. If all its genes are unmatched it will be unconstrained.

Parameters

model

An EcModel. Must have adapter set. Mutated in place.

uniprot_db

Loaded UniProt database.

kegg_db

Optional pre-loaded KEGG database, consulted as a fallback for genes UniProt does not match. None (default) skips the KEGG lookup entirely.

Returns

list of str

Model gene IDs (pre-transformation) that did not match.

remove_pseudoreaction_gprs#

remove_pseudoreaction_gprs(model: 'cobra.Model', adapter: 'ModelAdapter')

Clear gene-protein-reaction rules from pseudoreactions.

A reaction is treated as a pseudoreaction if either:

  • its name contains the substring pseudoreaction (case-sensitive); or

  • its ID is listed in the first column of data/pseudoRxns.tsv inside the adapter's project folder, if that file exists.

Parameters

model

A cobra.Model that will be mutated in place: the gene reaction rule of each matched reaction is cleared (empty string). This automatically updates the reaction's .genes set via cobrapy's GPR handling.

adapter

Provides the project path used to locate the optional TSV.

Returns

list of str

Sorted IDs of reactions whose GPR was cleared. Intended for logging and test assertions.

set_kcat_for_reactions#

set_kcat_for_reactions(model: 'EcModel', rxn_ids: Sequence[str], kcat: Union[float, Sequence[float]], *, apply: bool=True)

Set kcat values for one or more reactions in ec.kcat.

Each ID in rxn_ids is interpreted as follows:

  • If the ID ends in _EXP_<n> (full layout) or starts with ###_ (gecko-light), only that exact reaction is matched.

  • Otherwise, the ID is treated as a base name and matches every ec.rxns entry whose ID, after stripping the layout-specific isozyme marker, equals the base name. So in a full model, "R2" matches R2, R2_EXP_1, R2_EXP_2; in a light model, "R2" matches 001_R2, 002_R2.

The kcat argument follows numpy-style broadcasting: a single float applies to every matched reaction; a sequence of length len(rxn_ids) gives one value per input ID (broadcast across that ID's own matches); a sequence of length equal to the total number of matched reactions gives one value per resolved match, in ec.rxns order.

That last form lets one un-suffixed rxn_id that expands to multiple isozymes take a list of per-isozyme values, matching MATLAB setKcatForReactions's positional semantics exactly: values are assigned to matches in whatever order they occur in ec.rxns, with no check that this is the order the caller intended. This is real but fragile as an API surface -- prefer passing the suffixed reaction IDs explicitly when the mapping matters, so intent doesn't depend on ec.rxns's row order.

ec.source is set to "setKcatForReactions" for every reaction changed by this call, matching MATLAB's ec.source label (its own docstring says 'from setKcatForReactions', but the actual assignment writes the bare function name).

Parameters

model

An EcModel with ec.rxns populated. Mutated in place.

rxn_ids

Reaction identifiers to update.

kcat

New kcat value(s) in 1/s. Scalar or sequence (see above).

apply

If True (default), call apply_kcat_constraints after updating ec.kcat / ec.source so the change is reflected in the S matrix immediately. If False, the caller must invoke apply_kcat_constraints themselves.

Returns

list of str

IDs of the reactions whose kcat was changed (the post-expansion set), in the order in which they were updated.

Raises

ValueError

If any rxn_id matches zero reactions, or if kcat has a length other than 1, len(rxn_ids), or the total number of resolved matches.

set_prot_pool_size#

set_prot_pool_size(model: 'EcModel', *, p_tot: float | None=None, f: float | None=None, sigma: float | None=None)

Set the upper bound of prot_pool_exchange (the protein budget).

Ported from GECKO MATLAB: src/geckomat/change_model/setProtPoolSize.m.

The protein pool exchange represents the cell's total enzyme supply. Its upper bound is what limits how much protein the model can deploy at once. The formula is:

bound = p_tot * f * sigma * 1000

where:

  • p_tot is the total cellular protein content (g/gDCW),

  • f is the fraction of that protein that's made up of enzymes in the model (g model-enzyme / g total-protein),

  • sigma is the average enzyme saturation factor (0-1) — how close enzymes run to their Vmax in vivo,

  • the 1000 converts units (ec.mw is in Da and fluxes are in mmol/gDW/h, so multiplying p_tot (g/gDW) by 1000 brings it to mg/gDW, matching the mg/mmol that Da represents).

When called with no arguments, the function reads p_tot, f, and sigma from the adapter. Any of the three can be overridden via keyword.

Parameters

model

An EcModel with prot_pool_exchange already added (stage 12).

p_tot, f, sigma

Override values. If None, read from model.adapter.params.

Returns

float

The bound that was set (for logging or assertions).

Raises

ValueError

If the model has no adapter and any argument is None, or if prot_pool_exchange is not in the model.

split_light_rxn_id#

split_light_rxn_id(prefixed_id: str)

Split a gecko-light prefixed ec.rxn id into (isozyme_index, cobra_id).

Light models prefix each ec.rxns entry with a fixed-width zero-padded counter (e.g. "001_RXN1" -> (1, "RXN1")). Helpers that need to look up the underlying cobra reaction use this to strip the prefix. Raises ValueError on an unprefixed id.