Skip to content

feat: GECKO and geckopy parity scenarios, ledger links and a stricter ledger audit - #141

Merged
edkerk merged 58 commits into
developfrom
parity/gecko-round-2
Oct 30, 2026
Merged

edkerk merged 58 commits into
developfrom
parity/gecko-round-2

Conversation

@edkerk

@edkerk edkerk commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Scenarios and ledger for the GECKO and geckopy pair, and a stricter ledger audit.

Scenarios. 48 scenarios of the gecko pair: 25 agree on both sides and 23 report the differences that remain, each described in its scenario.yml. They cover the ecTestGEM functions (proteomics and complex edge cases, EC lookups, the written ecModel file, enzyme usage, flexibilization, flux data, kcat sources and merging, the GECKO 3 upgrade, evotune, sensitivity tuning and sigma fitting) and built models of full size: the tutorial ecYeastGEM and ecYeastGEM 9.1.1 (load, analysis, flux variability, proteomics, tuning), the light Human-GEM ecModel (load, build, solving, subsetting, flux variability), eciYali5-GEM (load, upgrade, round trips) and the Yarrowia lipolytica build with BRENDA. ec_model_io_crossload needs the readYAMLmodel of RAVEN with CompMetEng/RAVEN#14. ec_model_full_yeastgem reads the tutorial's model_adapter.toml on both sides and also runs in the nightly and weekly jobs, which stage the BRENDA release with scripts/ci/stage_brenda.py.

Solvers. PARITY_MATLAB_SOLVER and PARITY_PYTHON_SOLVER replace the matlab_solver and python_solver inputs of the scenarios that declare them. The solver scenarios were run with Gurobi and GLPK on both sides and with scipy (HiGHS) in Python. What remains different between solvers is stated in the ledger notes and in the plan: LP vertex and dual choice, RAVEN's solver tolerance of 1e-9 against cobra's 1e-6, MATLAB with GLPK accepting an infeasible flux-data LP, and the accuracy of HiGHS on ill-scaled LPs in ec_fva.

Ledger. Every row of ledgers/gecko.yml that a scenario exercises links it, and the notes state the differences that remain. The geckopy functions that exist on develop carry their Python names.

Audit. A row may list differs:, checkpoint path prefixes of the differences its linked scenarios report. With strict_differs: true at the top of a ledger (set for gecko), every parity row linked to a scenario that differs must list them, a listed prefix that no result shows fails, and every group of differences must be covered by some row. Ledgers without the key keep the previous rule, so ledgers/raven.yml is audited as before.

Plan. docs/gecko-behaviour-parity-plan.md describes the scenarios and their statuses as they are now.

Companion changes, merged: CompMetEng/GECKO#13 and #14, CompMetEng/geckopy#70, CompMetEng/raven-toolbox#183 and CompMetEng/RAVEN#14. Open, and needed for the scenarios to agree as the ledger states: CompMetEng/GECKO#15, CompMetEng/geckopy#72 and CompMetEng/raven-toolbox#185.

Not checked: the scenarios on solvers Vera does not have (SCIP, CPLEX), ec_fva_ecyeastgem with GLPK in MATLAB (the MATLAB step exceeds an hour), ec_fva_light_humangem on scipy (HiGHS aborts), seeds 1 and 2 for the solver combinations other than Gurobi, and about 14 --- dashes in untouched lines of the plan.

edkerk added 30 commits October 25, 2026 16:18
…setKcatForReactions, getKcatAcrossIsozymes and applyCustomKcats on both sides
…plexes, nested gene rules, backward-only reactions, multi-metabolite sinks and reserved ids
…le, so both sides report the same targets

The enforced levels differ by the 0.999999 relaxation of solveLP(model,1), so the tolerance is 1e-5. The scenario text describes what is and is not compared.
… enzyme concentrations on edge inputs; protein_pool_ectestgem calls loadProtData with the filters on
…d; ec_model_io_ectestgem states how the two written files differ
…ting, BRENDA loading, fuzzy matching, merging and kcat selection on both sides
…model, getSubsetEcModel, addNewRxnsToEC with nested rules, and mapRxnsToConv and ecFVA on ids that contain _REV or _EXP_
…put, kcat source files and the standard-kcat fallback on both sides
…h sides and the downloaded BRENDA release; track geckopy develop

MATLAB builds the adapter with TomlAdapter on tutorials/full_ecModel and Python reads the same folder, so one TOML configures both sides. databases_dir names the brenda-2026.1-1 folder that fetchBrendaAsset downloads. Eight kcats (EC 1.1.1.101) differ because geckopy drops low-outlier BRENDA rows by default; the scenario states the cause.
…s, each side asserting its own behaviour

getReactionsFromEnzyme returns empty outputs and get_reactions_from_enzyme raises ValueError for an id that is not in ec.enzymes, a deliberate difference. Each side asserts that inside the scenario and reports the same empty result, so the scenario matches and fails if either side changes. The okp_kcat and kcat_chain comments state the behaviour of both sides as it is now.
…of both sides as it is now

model_edits_ectestgem matches at every checkpoint, with the unknown-enzyme case asserted on each side as a deliberate difference. okp_kcat_ectestgem and kcat_chain_ectestgem match; both sides carry the OKP- source prefix, aggregate the median criterion, and set source and note in applyCustomKcats.
…h their geckopy functions and add rows for the new geckopy exports

geckopy develop exports the ports of 17 rows that were queued, so they are parity rows now; resolveKcatAggregation is subsumed in kcats_from_brenda. Nine rows stay python-pending because their port is not exported through __all__. The notes of getSubsetEcModel, loadBRENDAdata and getPfbaEnzymes state what each side does today, including geckopy's outlier filter on BRENDA kcats.
…ts on ecTestGEM: GECKO 3 shapes in memory and through each side's YAML reader, projects dry and applied, a class adapter, the stock and an edge customKcats file
…nputs: grid and bisection, protein pool limits, ec.notes text, kcat ceiling, protToIgnore ids, source groups, flat objective and NaN points
…asurements: statistics per EC, the review with hand-built and loaded statistics, lowercase ECs, measurement folders with .tsv and .xz
…stimate and kcatsFromECTree on hand-written kcat source files: config variants, select and combine stages, EC-tree estimates and subsets
…ge inputs

enzyme_usage_edge_cases_ectestgem: an enzyme with an upper bound of 0 or without a usage reaction, usage tables without zero-usage enzymes and the report built from them, topAbsUsage below 1, tied bottleneck rankings, getPfbaEnzymes on a fraction of the optimum and with a missing objective, and control coefficients with a binding protein pool.

flexibilize_edge_cases_ectestgem: flexibilizeEnzConcs with a capped growth, a preset usage bound and an infeasible start; relaxProteomicsGreedy with tied enzymes and an empty candidate set; constrainEnzConcs with a prior lower bound and a negative concentration.

flux_data_edge_cases_ectestgem: loadFluxData and constrainFluxData with a ragged row, only the fixed columns, a nested-parentheses header, a missing file, an unknown condition, a missing exchange reaction and an invalid maxMinGrowth. All three differ from MATLAB where the sides disagree; the cases state the cause.
…d content of the written ecModel files as the scenarios show them
…the written ecModel files as the scenarios show them
…t, the stoichiometry by protein id, the kcat source of a kept row and lowercase EC codes agree on both sides
…pplyKcatConstraints: gene rules, partial complexes, id suffixes and isozymes without enzymes agree
… EC separators, zero-bound capacity and capped-growth cases agree
…o both sides give 0 for an enzyme whose bound does not bind while the pool binds
…ches wildcard level 4, reports the selected EC and keeps subsets as given, and applyCustomKcats skips blank kcats; ec_model_full_yeastgem agrees
…ctestgem: the default scan, the objective bounds and the tuning rules agree on both sides
…edian rows of kcat_chain and the ranked FSEOF targets; drop the unread max_*.txt fixtures
…that scenario reports; link the scenarios of the python-pending rows
…ce, coverage needs the group or deeper, partial runs and unreadable results are handled
…ints difference, and where the subsystem differences end
…d read the BRENDA release folder inside it, so a checkout without the downloaded release still passes the input check
…pecific code and with a gene without an EC number; findECInDB note states the clean-up of every gene set
…tems since RAVEN#14

The ec_lookup scenario gains a variant whose EC cell joins two codes with ';' and no space. The crossload scenario no longer differs on subsystem: its fixtures are regenerated for the current writers and the loadEcModel row drops its differs entry.
Base automatically changed from parity/round-2 to develop October 28, 2026 21:39
edkerk added 17 commits October 28, 2026 22:59
…cko scenarios; PARITY_MATLAB_SOLVER and PARITY_PYTHON_SOLVER override declared solvers

ec_model_full_yeastgem reads databases/brenda-2026.1-1 of the GECKO checkout on both sides, a folder no fresh checkout has. The install script of the gecko pair and the genome-scale workflow now run stage_brenda.py after installing geckopy. The two variables replace the matlab_solver and python_solver inputs of the scenarios that declare them, so a scenario can run on another solver. Comments of the genome-scale workflow, the scenario and the plan state that the scenario also runs in the nightly workflow.
…eastGEM, ecYeastGEM 9.1.1, the light Human-GEM ecModel and the GECKO 3 eciYali5-GEM
…lipolytica, and getStandardKcat with subsystems
The comments of the sigma fit, flexibilization, flux variability, subset, standard kcat, loader and real-model scenarios state what both sides do now: the plateau of sigmaFitter, the infeasible start of flexibilizeEnzConcs, the diagonal bounds of ecFVA, the case-insensitive subsystems, the light prefix of getSubsetEcModel, the empty enzymes entries and quoted cells that both readers load, and the numbers of the light Human-GEM FVA.
…lt of the fixes

Every new scenario is listed under the rows it covers, with the differences that remain: tied bottlenecks and the pFBA margin on ecYeastGEM, the ecFSEOF target set, the replicate check of loadProtData, the averages of calculateFfactor, the number of reactions upgradeEcModel turns, getECfromGEM for a model without EC codes, the genes and metabolites that geckopy keeps in a subset, and the solver tolerance in ecFVA. The notes state the sigmaFitter plateau, the infeasible start of flexibilizeEnzConcs on every solver and the scipy solver.
The table lists the real-model scenarios with their verdicts, the tier 4 section describes what they compare and what stays different, and the red scenarios are the 24 that report differences.
…fast solver

The python side read the context file with the YAML reader of raven_toolbox directly, which builds the scipy problem densely through optlang and does not finish for a genome-scale model. It now reads the file on glpk when the default solver is scipy and moves the model to scipy afterwards, so the scenario runs with every solver. The comment states that the subset now agrees in genes and metabolites.
…nd the scenario comments

ecFSEOF has equal levels and an equal target set with Gurobi on both sides, and the remaining differences are the order of tied or near-tied targets and the targets that follow the solver. getPfbaEnzymes agrees for the default fraction and differs by the margin for a given one. getSubsetEcModel agrees in genes and metabolites. The ec_fva notes give the scipy limit and the light Human-GEM numbers. The plan lists the solver combinations that were run, the counts per solver pair and the scipy limits.
…cord the scipy and GLPK results

ec_tuning_ecyeastgem sets the python models to 1e-9 as ec_proteomics_ecyeastgem does, so the scenario matches with Gurobi on both sides, GLPK on both sides and GLPK with scipy. The ledger, the plan and the scenario comments describe the GLPK acceptance of the infeasible flux-data LP, the scipy times of get_subset_ec_model and the light ecModel build, and the scipy result of ec_fva_light_humangem.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant