Proteome-constrained enzyme-constrained model analysis of overflow metabolism in Saccharomyces cerevisiae, across four carbon/nitrogen ratios and one high growth rate condition.
The analysis is built on the GECKO 4 ecYeastGEM and runs in Python through
geckopy and
raven-toolbox. The MATLAB
implementation that produced the published results, which used GECKO 2, is
kept in legacy_matlab/.
pip install -e ".[dev]"Python 3.11 or later. Gurobi (gurobipy with a licence) is the default solver for
the analysis and the tests. Another solver can be chosen with --solver, or with
the OVERFLOW_SOLVER environment variable, which also applies to the tests; an
unavailable solver is an error, not a silent switch.
| Path | Contents |
|---|---|
data/ |
Measured proteomics, fermentation rates, ribosome subunits, annotation |
models/ |
The GECKO 4 ecModel and the conventional GEM it derives from, see models/PROVENANCE.md |
src/overflow/ |
The analysis package |
tests/ |
Test suite |
results/ |
Output tables and figures |
legacy_matlab/ |
The GECKO 2 MATLAB implementation and its results |
data/fermentationData.txt holds, per condition, the total protein content,
the dilution rate and the measured exchange rates. data/abs_proteomics.txt
holds absolute protein abundances in mmol/gDW: three biological replicates
per condition, four for hGR.
from overflow import load_conditions
conditions = load_conditions()
conditions["CN4"].d_rate # 0.1
conditions["CN4"].byproduct_bounds() # undetected byproducts are blockedfrom overflow import build_adapter, load_model
model = load_model(build_adapter(conditions["CN4"]))build_adapter reads model_adapter.toml and layers the condition's measured
protein content and dilution rate on top.
python -m overflow.build # every condition
python -m overflow.build CN4 --solver glpk # instead of the default, GurobiEach condition gets models/ecModel_P_<cond>.yml and, in results/, the
enzymes whose measured abundance the model could not run on, the enzymes whose
caps had to be released, and the full flux distribution.
Options change what the models are asked to account for:
--fit-ratesholds CO2, oxygen and the byproducts within a tolerance of their measurements (--rate-tolerance, default 5%) and raises the measured abundances by the least that makes that feasible. Without it those rates are free, and the model disposes of surplus carbon through whichever exit is cheapest in protein rather than respiring it.--uptake-flexcaps glucose uptake at that multiple of the measured rate (default 1.05). CN4 needs 1.08: at its dilution rate the model needs 6.5% more glucose than was measured, even with protein unlimited.--objectivechooses what the finished model optimises: the smallest protein pool (protein, the default), or the smallest total flux at the dilution rate over every reaction (flux) or over the metabolic reactions only (metabolic-flux). The flux objectives need--fit-rates.--block RXN ...closes the named reactions before anything else is applied. The analysis blocksr_2129, the proton leak: it has no enzyme and no bound, so it is a free sink for oxygen. Fitting the measured oxygen with it open sent most of the respiration through it at high C/N (P/O 0.19 at CN75, against 1.1-1.2 with it closed), because the fit raises each cap only as far as the rates need and the built models can carry no maintenance ATP. Closed, the respiration is coupled and the maintenance shows up as non-growth ATP use.--scale-proteinrescales biomass to the measured protein content. Off by default: the model has no carbon to spare at the measured glucose uptake, and CN4 then falls short of its dilution rate.
python -m overflow.build_ribosomeWrites models/ecModel_P_<cond>_ribosome.yml. The protein pseudoreaction is
split so that protein comes out of a translation reaction catalysed by the
ribosomal subunits, at 10.5 amino acids per second per ribosome. The core is
the 48 subunits whose average abundance across all conditions reaches
1e-5 mmol/gDW.
python -m overflow.analyze_usageWrites, per enzyme and condition, how much of it the model uses and what fraction of what was available that is, plus the capacity usage of the annotated systems and the two figures over them.
python -m overflow.run_sampling --procs 16Samples the conventional model under the measured rates, with and without formate in the measured set, and writes the sampled means and standard deviations, the byproducts the model secretes when it is not told to, and the ATP and redox budget.
Sampling draws vertices by maximising small random objectives and then minimising
total flux at each, as the published analysis did; means over such draws are vertex
means rather than an average over the interior of the flux space. --no-min-flux
skips the second step, which lets the sampler wander into high-flux routes: the
pentose phosphate pathway then carries several times the published flux.
Conditions are independent, so they can be sampled as separate runs (for example one Slurm job each) and combined afterwards:
python -m overflow.run_sampling CN4 --procs 12 --results-dir runs/CN4 # one per condition
python -m overflow.run_sampling --merge runs/CN4 runs/CN22 runs/CN38 runs/CN75 runs/hGRThe loop-free screening that precedes sampling has a five-minute limit and retries with a new seed, because cobra's search for cyclic reactions occasionally runs for hours.
python -m overflow.compareWrites results/COMPARISON.md: predicted exchange rates, median capacity usage
per system and the sampled ATP and redox budget, this pipeline beside the MATLAB
one, read from legacy_matlab/results/.
The analysis is run with --fit-rates, implemented in overflow.build
(relax_to_measured_rates): it holds CO2, oxygen and the byproducts at their
measurements and raises the measured enzyme abundances by the least that makes
that feasible. Without it those rates are free, and on the earlier tutorial model
the enzyme-constrained solution disposed of surplus carbon through unmeasured
exits instead of respiring it, so the flux distribution did not describe the
measured physiology. --uptake-flex 1.08 gives CN4 the glucose it needs, and --block r_2129 closes the
proton leak (see the build options).
python -m overflow.build --fit-rates --rate-tolerance 0.08 --uptake-flex 1.08 --block r_2129
python -m overflow.build_ribosome
python -m overflow.analyze_usage
python -m overflow.run_sampling --procs 12
python -m overflow.compareEach step reads the models the previous one wrote, so --models-dir and
--results-dir keep a run self-contained.
pytest # everything except the full condition builds
pytest -m "not slow" # skip the tests that load a genome-scale model
pytest -m integration # build a condition end to end; minutesThe suite runs on the same solver as the analysis, Gurobi by default. Set
OVERFLOW_SOLVER=glpk to run it without a licence, as CI does.