Skip to content

fix: give the same result as GECKO where the parity scenarios found differences - #70

Merged
edkerk merged 13 commits into
developfrom
parity/round-2
Oct 28, 2026
Merged

edkerk merged 13 commits into
developfrom
parity/round-2

Conversation

@edkerk

@edkerk edkerk commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

geckopy and GECKO now give the same result on the same input in the cases below. The cases come from the scenarios of the parity harness in CompMetEng/raven-gecko-parity (the companion changes are in CompMetEng/GECKO).

Sensitivities and tuning

  • get_conc_control_coeffs reads the reduced cost of each usage reaction's forward variable and keeps it where a 0.01 percent rise of the bound raises the optimum by at least half of the predicted rise. An enzyme whose own bound does not bind gets 0 while the protein pool binds, where every used enzyme used to get the pool's price. The reduced cost is read from the variable duals of glpk, glpk_exact and gurobi and from the HiGHS bound marginal of the scipy solver; where no usable dual exists the finite-difference loop runs.
  • fit_sigma scans the 0.01 grid of GECKO's sigmaFitter by default (method="bisect" stays available). A target that growth cannot reach gives the first sigma of the growth plateau, the bounds of the objective reaction are set to [0, 1000] and stay so, and bisect gives the first grid sigma for a model that cannot grow.
  • sensitivity_tuning follows sensitivityTuning.m: tuned reactions are listed in model order with the kcat and source of the input model, ec.notes prints the pre-tune kcat as num2str does, a prot_to_ignore ID is matched without regard to case and raises when unknown, a tuned kcat has no upper limit, and a gecko-light model is tuned.
  • truncate_values rounds values exactly halfway away from zero.

Kcat lists

  • save_kcat_source writes the detail text as saveKcatSource does (tabs and line breaks become spaces, no empty parts).
  • fill_kcats_from_isozymes and get_kcat_across_isozymes default to apply=False and fill only a kcat of 0.
  • apply_kcat_constraints lets every isozyme of a reaction compete in light ecModels and treats an empty update list as all reactions.
  • apply_custom_kcats reads a quoted reaction list without its quotes.
  • set_kcat_for_reactions follows setKcatForReactions: apply defaults to False, IDs match without regard to case, an unknown ID is ignored, and a light-model base ID matches nothing.

Lookups and building

  • find_ec_in_db splits an EC cell on ; and whitespace.
  • enzyme_usage gives cap_usage NaN where the usage upper bound is 0.
  • flexibilize_enz_concs uses the growth reached after the protein-pool branch as its target.
  • make_ec_model refuses reaction IDs ending in _REV or _EXP_<n> or starting with usage_prot_ or prot_pool, metabolite IDs starting with prot_, an enzyme_comp that is not a compartment name, and a model without genes. It splits only reversible reactions that are not exchanges, so [-10, -1] and a multi-metabolite sink stay as they are.

Behaviour that callers may notice: the apply defaults of set_kcat_for_reactions and the fill functions, the refusals of make_ec_model (a compartment without a name), the default of fit_sigma, and the removed kcat cap of sensitivity_tuning.

Not checked: the changes on models other than the unit-test ecModel and the tutorial yeast model, cplex and SCIP (not installed), and get_conc_control_coeffs with scipy releases other than the one installed.

Companion changes: CompMetEng/GECKO#13 (GECKO), CompMetEng/raven-gecko-parity#141 (scenarios and ledger), CompMetEng/raven-toolbox#183 (write_yaml_model writes a single ec-code as a list).

edkerk added 12 commits October 24, 2026 13:04
…ze target and light-model isozymes

find_ec_in_db splits a database EC cell on semicolons and whitespace, so UniProt cells ("1.1.1.1; 2.2.2.2") and KEGG cells ("1.1.1.4 1.1.1.-") give one code per token.

enzyme_usage gives a NaN capacity for an enzyme whose usage upper bound is 0, as Enzyme.cap_usage does.

flexibilize_enz_concs takes the growth it reached as the target of the final pass and of the reported model when no enzyme limits growth any more.

apply_kcat_constraints on a gecko-light model recomputes the cheapest cost over all isozyme rows of a reaction when one of its rows is named.
…onfirmed by a small raise of the bound, in place of the prot_<id> shadow price
… kcat source file, and the defaults of fill_kcats_from_isozymes
…ning

fit_sigma scans the 0.01 grid by default, gives the first sigma of the growth plateau for a target growth cannot reach, and opens the bounds of the objective reaction. sensitivity_tuning lists the tuned reactions in model order, reports the kcat and source of the input model, prints the pre-tune kcat as num2str does, matches prot_to_ignore without regard to case and raises for an unknown id, has no upper limit on a tuned kcat and tunes a gecko-light model.
… fit_sigma bisect gives the first grid sigma for a model that cannot grow
…usage reaction held at its lower bound; tests for the verification rule
…and apply_custom_kcats reads a quoted reaction list, as GECKO does
…ible non-exchange reactions; set_kcat_for_reactions follows setKcatForReactions
…arginal with the scipy solver, in place of the finite-difference loop
…no reduced costs; set_kcat_for_reactions takes a per-match kcat list by position even when an ID matches nothing
@edkerk
edkerk merged commit 9ebc61a into develop Oct 28, 2026
5 checks passed
@edkerk
edkerk deleted the parity/round-2 branch October 28, 2026 21:25
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