ecModel YAML format#
This page defines the YAML format GECKO and geckopy use to save and load ecModels. It is reference material, not a task: both toolboxes read and write the same file, so there is no MATLAB-vs-Python distinction to draw here.
It is the cobrapy YAML format, plus a few GECKO keys#
There is no bespoke ecModel format. An ecModel is saved as exactly the YAML
that cobrapy writes (cobra.io.save_yaml_model), with a handful of
GECKO-specific top-level keys added alongside it for the data cobra does not
model: \(k_{cat}\) values, the enzyme list (molecular weight, sequence,
concentration), and the reaction-enzyme coupling matrix.
RAVEN handles the I/O on the MATLAB side and geckopy delegates to
raven-toolbox on the Python side; both call into cobrapy for the cobra-shaped
portion and parse the GECKO ec-rxns / ec-enzymes / gecko_light
sections into the ecModel's ec substructure (model.ec in MATLAB,
EcModel.ec in Python). Two consequences follow:
Any cobrapy-aware tool (Escher, Memote, plain cobrapy) loads the file and ignores the extra
ec-*keys, reading it as an ordinary conventional model.GECKO (MATLAB) and geckopy (Python) write and read the exact same format, so an ecModel built in one toolbox loads directly in the other with no translation step.
Design goals#
Identical to cobrapy. The cobra-shaped portion of the file is exactly what
cobra.io.model_to_dict/model_from_dictround-trips; there is no custom parser or schema for that part.Round-trippable between MATLAB and Python. RAVEN's
writeYAMLmodelandreadYAMLmodel, and raven-toolbox's equivalents, emit and accept the same format.Backward compatible. Both toolboxes also load the legacy MATLAB/RAVEN layout (see the last section below). Empty strings and NaN values can be omitted on write; a reader fills in the documented default on load.
Top-level structure#
The file is one YAML mapping. It holds the following keys:
Key |
Required? |
Owner |
What it holds |
|---|---|---|---|
|
yes |
cobra |
Model id |
|
optional |
cobra |
Human-readable name |
|
optional |
cobra |
cobra schema version (omit if unused) |
|
optional |
cobra |
Mapping of compartment id to name |
|
yes |
cobra |
List of metabolite entries (see below) |
|
yes |
cobra |
List of reaction entries (see below) |
|
yes |
cobra |
List of gene entries (see below) |
|
yes for an ecModel |
raven-toolbox / RAVEN |
Per-reaction ec data (see below) |
|
yes for an ecModel |
raven-toolbox / RAVEN |
Per-enzyme ec data (see below) |
|
optional |
raven-toolbox / RAVEN |
Boolean flag, defaults to |
|
optional |
raven-toolbox / RAVEN |
Free-form provenance: version, date, author, taxonomy, note |
A tool that understands only the cobra side (cobrapy, Escher, Memote, and
similar) ignores the GECKO-specific keys (ec-rxns, ec-enzymes,
gecko_light, metaData) without raising an error, so the same file loads
there as a plain cobra model, minus the enzyme-constraint layer.
Cobra-shaped section#
This part of the file is exactly the schema cobra.io.dict.model_to_dict
produces, with a few conventions:
compartmentsis a flat mapping ({c: cytosol, e: extracellular}), not a list.metabolites,reactions, andgenesare lists of plain mappings, one per entry.A reaction's
metabolitesfield is a flat mapping from metabolite id to stoichiometric coefficient.annotationis a mapping from key to a list of strings. A metabolite's SMILES string lives atannotation: {smiles: ["..."]}.
Example metabolite:
- id: s_0001
name: "(1->3)-beta-D-glucan"
compartment: ce
formula: C6H10O5
charge: 0
annotation:
bigg.metabolite: ["13BDglcn"]
chebi: ["CHEBI:37671"]
kegg.compound: ["C00965"]
metanetx.chemical: ["MNXM6492"]
sbo: ["SBO:0000247"]
smiles: ["C(C1C(C(C(C(O1)O)O)O)O)O"]
Example reaction:
- id: r_0001
name: "(R)-lactate:ferricytochrome-c 2-oxidoreductase"
metabolites:
s_0027: -1.0
s_0556: 1.0
lower_bound: 0
upper_bound: 1000
gene_reaction_rule: "(YDL174C and YML054C) or (YEL024W and YML054C)"
subsystem: "Oxidative phosphorylation"
annotation:
ec-code: ["1.1.2.4"]
kegg.reaction: ["R00196"]
ec-rxns: per-reaction ec data#
A list with one entry per catalyzed reaction. When the build pipeline splits
a reaction across isozymes (_EXP_<N> suffix) or into forward/reverse pairs
(_REV suffix), each variant gets its own entry here.
Field |
Type |
Required? |
Notes |
|---|---|---|---|
|
string |
yes |
Matches a model reaction id; may carry |
|
number |
yes |
Turnover number in s⁻¹; |
|
string |
optional |
Where the kcat came from ( |
|
string |
optional |
Free-form note; default |
|
string or list |
optional |
One EC code as a string, or a list when several apply; default |
|
mapping, enzyme id to stoichiometry |
yes |
Which enzymes catalyze this reaction, and the subunit count of each; every key must also appear in |
Example:
- id: r_0001_EXP_1
kcat: 1500.0
source: "brenda"
eccodes: ["1.1.2.4", "1.1.99.40"]
enzymes:
P00045: 1
P32891: 1
A reaction with no kcat assigned yet is written as kcat: 0, the sentinel
both toolboxes use for "unknown", so it round-trips back to 0 rather than
being inferred as an omission.
ec-enzymes: per-enzyme ec data#
A list with one entry per unique enzyme.
Field |
Type |
Required? |
Notes |
|---|---|---|---|
|
string |
yes |
Gene id; must match a |
|
string |
yes |
Enzyme id, usually a UniProt accession |
|
number |
optional |
Molecular weight in Da; write NaN as |
|
string |
optional |
Amino acid sequence; default |
|
number |
optional |
Measured concentration in mmol/gDW, from proteomics; write NaN as |
The standard pseudo-gene, added when a reaction lacks a real gene
association (see Applying kcat values), appears as
both genes: "standard" and enzymes: "standard".
Example:
- genes: "Q0045"
enzymes: "P00401"
mw: 58798.0
sequence: "MVQRWLYSTNAKDIAVLY..."
Sparse defaults#
To keep files compact, a writer can omit any field that takes its documented
default (empty string, NaN); a reader fills the default back in on load. The
exception is a numeric value meant to stay explicit rather than be inferred
as an omission: a mw or concs that is deliberately unknown is written as
.nan, and a kcat with no value assigned is written as 0, its own
sentinel (see the ec-rxns section above).
Legacy MATLAB / RAVEN format#
Older RAVEN/GECKO ecModels used a slightly different schema. Both GECKO and
geckopy load it: geckopy's loader normalizes it on read, and RAVEN's
readYAMLmodel auto-detects it. The schema differences are:
Aspect |
Legacy MATLAB / RAVEN |
Current (cobrapy + GECKO keys) |
|---|---|---|
|
top-level metabolite key |
under |
Annotation values |
scalar strings |
list of strings |
|
inside |
top-level |
|
reverse direction ( |
forward direction ( |
Outer |
present |
absent, cobra omits it |
|
inside |
inside |
The model id itself stays nested under metaData in both the legacy and
the current format; it is not a schema difference between them. Normalizing
a legacy file moves any per-metabolite smiles field into annotation;
cobra tolerates the scalar-vs-list difference in annotation values on read. A
reader also flips any usage_prot_* / prot_pool_exchange reaction still
using the reverse-direction bounds to the current forward convention,
warning once. A legacy file written as a bare --- sequence of single-key
maps (with no !!omap) is merged into one mapping by geckopy's reader. The
two layouts
hold the same information; both toolboxes' readers accept either one.
See also#
Proteomics integration, where
ec-enzymesconcentration values (concs) come from.Building an ecModel and Applying kcat values, where
ec-rxnsandec-enzymesare first populated.API reference, for the read/write functions themselves.