Repository navigation
geckopy 4.0.0b2 - #83
Merged
Merged
Conversation
kcat.tsv/sa.tsv/mw.tsv (and the ecTestGEM test fixtures) are now kcat.tsv.xz/sa.tsv.xz/mw.tsv.xz -- load_brenda_data and the brenda-refresh CLI read/write through lzma transparently. Cuts the wheel from 1.65MB to 1.28MB; the sdist is unaffected (gzip already compresses this repetitive tabular data over the whole tar stream about as well as standalone xz does per-file, since it gets a much larger compression window that way). Also fixes scripts/kcat_aggregation_compare.py: a hardcoded /mnt/c/Work/GitHub/geckopy path (broken outside one specific WSL setup) replaced with a path relative to the script, and drops an unused cobra import. Neither scripts file is covered by CI's ruff check (scripts/ isn't in its path list), which is how this went unnoticed.
Reverts the previous approach (committing kcat.tsv.xz/sa.tsv.xz/ mw.tsv.xz directly) back to plain-text TSVs in the repo -- diffable, and what geckopy brenda-refresh regenerates. A new hatchling build hook (hatch_build.py), scoped to the wheel target only, compresses them into the wheel at build time; the raw .tsv files are excluded from the wheel via pyproject.toml. brenda_loader.py now looks for the .tsv.xz variant first and falls back to plain text, so it works against an installed wheel, an editable install, or a freshly regenerated dev checkout without caring which. Verified end-to-end: built the wheel, installed it into a clean venv, confirmed only the .xz files are present on disk and load_brenda_data reads them correctly (39,318 kcat rows). sdist keeps the plain-text files, matching git. Wheel: 1.28MB either way; sdist: 6.46MB (was 6.39MB pre-xz -- the extra ~70KB is hatch_build.py plus a few bytes of pyproject.toml diff, not the data).
Was Path(data) / brenda / _cache, a bare relative path that resolves against whatever the CLI's cwd happens to be at invocation time -- which is how src/geckopy/data/brenda/_cache/ ended up holding a stray download in this checkout (brenda-refresh was run from src/geckopy/ once). The raw bulk-JSON download is exactly the kind of disposable, multi-hundred-MB, re-fetchable artifact raven-toolbox already has a convention for (raven_toolbox.binaries._cache_dir: $XDG_CACHE_HOME or ~/.cache); this matches it. --out-dir (the aggregated TSVs, a chosen output rather than a cache) is unchanged.
…g MATLAB Within one EC number the six levels are tried in the order 1, 2, 3, 5, 4, 6 (a correct-organism specific activity before an any-organism any-substrate kcat), as in fuzzyKcatMatching.m. When a reaction has several EC numbers, fuzzyKcatMatching.m compares the matches in that same search order; geckopy compared the output origin numbers instead, so origin 4 beat origin 5. SEARCH_RANK, derived from SEARCH_LEVELS, now drives the selection across EC numbers too. Effect on the yeast-GEM tutorial: r_0005 (EC 2.4.1.34;3.6.5.2) got 0.0005 /s from a human GTPase value for the second EC, where MATLAB takes 13.3 /s from the S. cerevisiae specific activity for the first; r_0510 likewise (0.018 vs 603 /s). r_0005 alone held the pre-tuning growth rate at 0.0013 /hour; with this change it is 0.12 /hour, as in MATLAB.
cobra.io.load_yaml_model drops RAVEN-specific reaction fields, including the per-reaction eccodes list that RAVEN YAML uses for EC numbers, so a yeast-GEM loaded this way had no EC numbers at all and fill_eccodes_from_gem returned empty codes for every reaction. read_yaml_model lifts eccodes into annotation['ec-code'] and also reads plain cobra-style YAML, so it replaces cobra's reader for .yml/.yaml.
fuzzy_kcat_matching needs the KEGG phylogenetic distances to pick the closest organism when BRENDA has no value for the model's own organism. MATLAB reads them from RAVEN's keggPhylDist.mat; download_phyl_dist fetches that file (pinned to RAVEN 3.0.0b1) to a given path, typically adapter.get_phyl_dist_path(). The file is validated with load_phyl_dist before it replaces the destination.
…ht vs full - STEP 16-17: fill_eccodes_from_database gets kegg_db, as MATLAB's getECfromDatabase consults KEGG where UniProt has no or only an incomplete EC number. - STEP 18-19: data/PhylDist.mat was a two-organism stub, so the "closest organism" levels fell back to arbitrary values (r_0103_REV took 5e6 /s from Cupriavidus necator where MATLAB takes 3 /s from Aspergillus fumigatus). The tutorial now downloads RAVEN's keggPhylDist.mat on first run; the file is git-ignored. - STEP 26: merge_kcats replaces the deprecated merge_dlkcat_and_fuzzy_kcats. - STEP 43-44: the note about the unported ABC-SMC tuning is replaced by a pointer to evotune, not run, as in the MATLAB tutorial. - STEP 73-75: ecFVA runs (skipped on GLPK). The commented-out version ran ec_fva on the ecModel for the "bare GEM" column, duplicating the ecModel result. - STEP 76-77: code/plot_light_vs_full.py ports plotlightVSfull.m; light and full both reach 0.0280 /hour, as in MATLAB. - model_adapter.toml: max_growth_weight is applied to the max-growth term in both MATLAB and geckopy; the comment said otherwise. Together with the fuzzy_kcat_matching fix, the tutorial now tracks the MATLAB protocol: 7 kcats tuned (growth 0.428 vs 0.427 /hour), 0.0129 /hour after flux constraints (MATLAB 0.0129) and 123.75 mg/gDCW minimum pool usage (identical).
- EvotuneParams.max_growth_weight: MATLAB applies maxGrowthWeight to the max-growth term, like geckopy, so no conversion is needed. - prior_penalty_weight comment: GECKO 4's cmaesKcatTuning has the same priorPenaltyWeight term, so reproducing MATLAB does not require 0. - Migration guide: download_phyl_dist in the kcat example, and YAML starting GEMs load through raven-toolbox. - CHANGELOG: Unreleased section.
The three links to the "MATLAB ↔ Python translation guide" at gecko-docs.readthedocs.io/en/latest/api/translation/ return 404; that page does not exist on gecko-docs. The per-function differences they refer to are on the "GECKO vs. geckopy" page (gecko-to-geckopy.html).
…tutorial Match MATLAB kcat selection; full PhylDist, ecFVA and light vs full in full_ecModel tutorial
classify_kcat_source compared the whole ec.source string against each source_groups entry. geckopy writes "brenda (wc=0, origin=1)" where MATLAB writes "brenda", so every fuzzy database match missed its group and fell through to unlabelled, taking sigma0_log_default rather than the tier's width: 3497 of ecYeastGEM's 4671 kcats, which is the whole point of having tiers. Matching now ignores the bracketed fuzzy-match detail. A source_groups entry that lists the full string still matches it, so a project can still single out, say, wildcarded matches. This changes tuning results on any model whose kcats came from the fuzzy matcher.
cobra returns an annotation value as the object it was assigned, and as a list for a model read back from a file. A metabolite annotated in memory by find_met_smiles carries "CCO"; the same metabolite after save_ec_model + load_ec_model carries ["CCO"]. extract_enzyme_substrate_pairs -- which both write_dlkcat_input and the OpenKineticsPredictor input builder go through -- assumed the string. On a reloaded model the ignore-list membership test hashed a list and the whole step died with TypeError, and had it not, the list would have been written into the DLKcat input in place of the SMILES. The tutorial does not hit this because it annotates and writes in one session, but it documents reloading from the saved stage-1 model between those steps, which is enough to reach it. databases.met_smiles reads either shape and is the one place that knows the difference.
A BRENDA kcat is a turnover per molecule of one named substrate, so it becomes a reaction turnover by dividing by that substrate's coefficient. The division used the smallest coefficient in the reaction instead. Where a reaction is not written per the measured substrate, that inflates the kcat. yeast-GEM writes cytochrome c oxidase per one cytochrome c, so oxygen carries 0.25, and BRENDA's S. cerevisiae value of 1500/s became 6000/s in the full_ecModel tutorial. 26 of 4671 matched reactions change there, all previously inflated, by factors of 2, 3 and 4. None changes which BRENDA row or match level it draws from.
…tching Apply evotune trust tiers to fuzzy-matched kcats
`parse_okp_output`: indexing metabolites by `annotation['smiles']` used the annotation value as a dict key, which raises `TypeError: cannot use 'list' as a dict key` on a saved-and-reloaded model, the same shape mismatch `met_smiles` already handles for the DLKcat input writer.
…ion-round-trip # Conflicts: # CHANGELOG.md
…d-trip Read a metabolite SMILES annotation whatever shape it is in
…-coefficient Divide a BRENDA kcat by the substrate it was measured on
… 6 -> 4 (#58) * Document BRENDA 2026.1 data trap, floor fix, and the DLKcat/floor interaction Investigates every difference between the June-2026 ecYeastGEM build and mainline geckopy today: matcher bug fixes, standard-kcat scope, OKP tiering, BRENDA 2026.1, and prediction source (CatPred/DLKcat/EITLEM). Six changes tune to the same place as June within noise; DLKcat and EITLEM both improve on it. BRENDA 2026.1 breaks tuning outright via a specific-activity/molecular-weight data trap (EC 2.3.1.297), traced to a mouse row surviving a dropped yeast row in the SA-MW join. Two mitigations compared (top_origin_limit=4, and a relative floor on derived kcats); the floor alone gives the best results for three of four predictors but breaks DLKcat via a Crabtree-effect/overflow mismatch, traced by comparing per-condition simulated vs measured ethanol secretion. Combining both mitigations is clean for every predictor tested. * Note that floor+limit4 is redundant with limit4 alone for CatPred c3_fl4 vs c3_o4 differ in only 34 of 4834 kcats; b26_fl4 vs b26_o4 are byte-identical. Not a bug: top_origin_limit=4 already demotes every origin-5/6 BRENDA match below any prediction, and CatPred's coverage is broad enough that almost every such reaction already has a CatPred prediction to fall back to. The floor only has room to matter where a predictor's coverage is patchier (DLKcat, EITLEM). * Port the BRENDA outlier floor and default top_origin_limit=4 Two changes, meant to ship together (see docs/internal/pipeline_deltas_since_june.md): - load_brenda_data gains filter_outlier_kcats (default True): drops a kcat more than 4 orders of magnitude below the median of its own EC family (widening to a broader EC prefix when fewer than 5 reference values are available), computed from the union of the plain-kcat and SA-derived tables. Catches cases like EC 2.3.1.297, where the only molecular-weight row available is for the wrong organism and the resulting SA x MW join gives a kcat 8 orders of magnitude below a same-EC measurement that has no MW row and would otherwise be silently dropped instead of used. - merge_kcats' and merge_dlkcat_and_fuzzy_kcats' top_origin_limit default changes from 6 to 4, so a specific-activity-derived BRENDA match (origin 5-6) no longer automatically outranks a prediction. Redundant with the filter above when a predictor's coverage is broad (e.g. CatPred), but still needed on its own where coverage is patchier (DLKcat, EITLEM) -- see the doc for the Crabtree-effect mismatch this prevents when paired with the floor alone. Both changes are opt-out (filter_outlier_kcats=False, top_origin_limit=6 explicit) rather than removed, so the pre-existing behaviour stays reachable. Full test suite passes (1435 passed, 1 xfailed, 0 failed); added dedicated tests for the floor filter and updated the one test whose name and assertion encoded the old top_origin_limit default as intentional behaviour. * Drop the internal pipeline-deltas writeup from this PR Investigation notes, not part of the public change.
select_tunable_mask's target_impact_share picks a comparable *share* of leverage on any model, but the same share does not sit at a comparable point on the *fit* curve -- two models with similarly shaped leverage curves can have fit curves that diverge sharply. The only way to tell is to tune at a few candidate sizes and look at where the improvement stops. sweep_tunable_mask_size tunes at each of a list of target_impact_shares (and seeds) and reports the resulting fit per point. recommend_target_impact_share picks the smallest share past which further tuning stops paying for itself, using two independent checks against a later point's best result: a relative-improvement tolerance, and, where at least one of the two points compared has more than one seed, a check against their own local seed spread (not a sweep-wide pooled one, since how noisy a comparison is can differ across the sweep). MaskSizePoint.rmse takes min(rmse_trace) per seed rather than the final entry, since rmse_trace only advances at a step that improved the (possibly prior-penalised) objective, per cmaes_kcat_tuning's own docstring -- with the default nonzero prior_penalty_weight the last entry is not guaranteed to be the best one recorded. sweep_tunable_mask_size's default target_impact_shares now starts at 0.3 (previously 0.5) and its default seeds is (0, 1) (previously a single seed), so a default call's noise-floor check has something to compare against instead of silently degrading to the relative check alone.
…ple (#60) * complex_portal_download: page the search by record offset and total The Complex Portal search endpoint reports `size` as the number of elements in the page at hand and `totalNumberOfResults` as the grand total, and `first` counts records rather than pages. Reading `size` as the total ended the paging loop after the first page, so any organism with more than 100 complexes was silently truncated: S. cerevisiae (taxonomy 559292) returned 100 of its 634. Page by record offset, take the total from `totalNumberOfResults`, and warn rather than truncate silently if the page bound is ever reached. The test fixtures now use the real field semantics. * evotune docs: corrections() does not take annotate_from_model's sources `annotate_from_model` returns names, ec_codes and sources, but `EvotuneResult.corrections()` fills sources from `result.groups` itself and has no such keyword, so the documented `result.corrections(leverage=leverage, **annotations)` raises TypeError. Spell the two keywords it does take, and say where the third one goes.
GECKO (MATLAB) now reads model_adapter.toml as well. Two sections make that possible without code in an adapter class: - [spontaneous]: name_contains and/or file set which reactions are spontaneous; the default get_spontaneous_reactions reads them. - [matlab]: settings that only GECKO reads (function names for anaerobic conditions and protein content, and [matlab.params]); geckopy accepts and ignores them. adapterParameters.tsv, the table GECKO uses to map keys to its MATLAB field names and defaults, is shipped here too, and a test checks it against the schema.
CatRange predicts a class of kcat values, which OpenKineticsPredictor
returns as its range ("10 to 100 s^-1") in the column "Predicted kcat
range: kcat (1/s)". parse_okp_output required a column named exactly
"kcat (1/s)" and so rejected CatRange results. It now takes the one
column ending in "kcat (1/s)" and reads a range as its geometric
midpoint, or half the upper bound for the class starting at 0. The list
of available predictors is updated.
* feat: level complex abundances and flexibilize per complex level_complex_concs (and level_complex_abundances for molar data) gives every enzyme complex one abundance, the median per copy over its measured subunits, so a single badly quantified subunit no longer sets the complex's capacity. complex_families groups isozyme variants into one complex and leaves subunits shared between complexes as measured. flexibilize_enz_concs(per_complex=True) raises all subunits of a limiting complex by the same factor. See raven-gecko-parity#131. * fix: keep carriers out of complexes and relax per complex without lowering caps Two enzyme sets merge only when they share two or more subunits and half of the larger set, so electron carriers no longer chain complexes together; a subunit in two complexes belongs to the one with more reactions. per_complex ranks complexes by summed control coefficients, counts iterations per complex and never lowers a cap. * fix: rank units by the cap duals, and probe with the pool lifted when no dual is positive * feat: relax_enz_concs, the least total relaxation of enzyme caps in one LP * docs: describe relax_enz_concs and the complex options
Gathered kcats are written to data/kcats/<source>.tsv in the project, keyed by conventional reaction and enzyme set rather than model.ec.rxns, so a file stays valid when the ecModel is rebuilt and applies to full and light models alike. GECKO reads and writes the same files. - kcats_from_brenda, kcats_from_dlkcat and kcats_from_okp gather one source each, with that source's own options, and write its file. OKP keeps a job and a result per method, and only uses a stored result of the current job. - save_kcat_source writes any kcat list; read_kcat_source reads a file; load_kcat_source maps a file to a model and reports rows with an invalid kcat, rows that fit no reaction, and rows that match only part of an enzyme set. - ec_rxn_keys gives the conventional reaction and enzyme set of every model.ec reaction. - fuzzy_kcat_matching takes an explicit adapter, and fetch_open_kinetics_predictor the file to store the result in.
) * Share model_adapter.toml with GECKO GECKO (MATLAB) now reads model_adapter.toml as well. Two sections make that possible without code in an adapter class: - [spontaneous]: name_contains and/or file set which reactions are spontaneous; the default get_spontaneous_reactions reads them. - [matlab]: settings that only GECKO reads (function names for anaerobic conditions and protein content, and [matlab.params]); geckopy accepts and ignores them. adapterParameters.tsv, the table GECKO uses to map keys to its MATLAB field names and defaults, is shipped here too, and a test checks it against the schema. * Keep gathered kcats as kcat source files, one per source Gathered kcats are written to data/kcats/<source>.tsv in the project, keyed by conventional reaction and enzyme set rather than model.ec.rxns, so a file stays valid when the ecModel is rebuilt and applies to full and light models alike. GECKO reads and writes the same files. - kcats_from_brenda, kcats_from_dlkcat and kcats_from_okp gather one source each, with that source's own options, and write its file. OKP keeps a job and a result per method, and only uses a stored result of the current job. - save_kcat_source writes any kcat list; read_kcat_source reads a file; load_kcat_source maps a file to a model and reports rows with an invalid kcat, rows that fit no reaction, and rows that match only part of an enzyme set. - ec_rxn_keys gives the conventional reaction and enzyme set of every model.ec reaction. - fuzzy_kcat_matching takes an explicit adapter, and fetch_open_kinetics_predictor the file to store the result in. * Assign kcats from the kcat source files, as model_adapter.toml sets collect_kcats decides one kcat per reaction from the files in data/kcats, in the stages of [kcat_assignment] (a preset, or [[kcat_assignment.stage]] tables), without changing the model, and writes output/<model id>_kcatDecisions.tsv. assign_kcats applies the decisions and the kcat constraints. update_kcat_sources gathers the source files the configuration needs that are missing, or outdated against [kcat_sources.<name>]. The default preset, gecko_median, orders custom kcats, the BRENDA median of matches without EC wildcards at origins 1 to 4, DLKcat, then the other BRENDA matches. gecko_classic keeps the GECKO 3 order with the BRENDA maximum. The full_ecModel tutorial gives the same model as before, with the gecko_median stages and the BRENDA maximum. * Name GECKO's kcat source functions as they are now
…et (#67) measurements.tsv, next to the BRENDA kcat, sa and mw files, holds the wild-type BRENDA kcats with an EC number after the outlier screen, one row per measurement. kcats_from_ec_tree gives each reaction the median kcat of its EC number, shrunk toward its 3- and 2-digit EC classes with weight n / (n + k), and keeps it as data/kcats/ec_tree.tsv (ECTree, load_brenda_measurements). save_kcat_source takes further detail pairs from a detail column. The brenda_ec_tree preset, now the default, orders custom kcats, the BRENDA median of measurements of the organism on the reaction's substrate (origin 1), the EC tree, then DLKcat for reactions without an EC number. update_kcat_sources gathers ec_tree.tsv and marks it outdated for another k or BRENDA release.
…des (#68) * Download the BRENDA files from toolbox-assets instead of shipping them fetch_brenda_asset downloads the files of the toolbox-assets release brenda-2026.1-1 (kcat, sa, mw and measurements, and on request sequences, substrates and combination parameters) with raven-toolbox's checksummed download, and unpacks them in its cache. ModelAdapter.get_brenda_db_folder gives the project's data/brenda when it exists and these files otherwise. The wheel no longer carries BRENDA files, so the build hook that compressed them is gone. * Combine kcat sources; presets for OKP; OKP replaces DLKcat in the default A combine stage gives each open reaction the precision-weighted mean of its sources' values, each corrected for the source's bias and weighted by 1 / its error variance for the source's evidence (EC tree: measurements and EC level; OKP method: similarity to its training sequences), with an uncertainty for a new measurement. The parameters are kcatCombineParams.tsv of the BRENDA files. model.ec.source reads 'combined (sd=..., n=...)' and the decisions get sd_log10. okp in a stage stands for the OKP methods of [kcat_sources.okp] methods. OKP results keep the similarity to the method's training data, written as similarity= in the detail column, and load_kcat_source passes the detail on. Presets: brenda_ec_tree combines the OKP methods for the reactions without an EC number instead of using DLKcat; ec_tree_okp combines the EC tree with the OKP methods; okp uses the OKP methods only. * Convert custom kcats; upgrade GECKO 3 projects and ecModels convert_custom_kcats writes data/customKcats.tsv as the curated kcat source file data/kcats/custom.tsv: the kcats apply_custom_kcats gives the ecModel, one row per reaction keyed by conventional reaction and enzyme set. upgrade_ec_model turns the protein usage and pool reactions of a GECKO 3 ecModel forward. upgrade_project (geckopy upgrade) lists, and with dry_run=False carries out, the steps from a GECKO 3 project: custom kcats, stored predictions to source files, saved ecModels, project_format = 4; it lists script lines that call renamed or replaced functions. Originals go to legacy/<date>/. kcats_from_brenda downloads PhylDist.mat when missing. model_adapter.toml takes project_format. The full_ecModel tutorial shows how to choose a kcat strategy. * Estimate kcats from measured homologs kcats_from_homologs searches each enzyme of a reaction with DIAMOND (raven-toolbox's) against the sequences of the BRENDA measurements (at least 40% identity, 80% coverage of both), and takes the identity-weighted mean of the medians of up to 10 homologs measured on the reaction's substrate, matched by InChIKey through ChEBI or MetaNetX annotations, or else the name. It writes data/kcats/homologs.tsv with the nearest identity and the number of homologs in the detail column. extract_enzyme_substrate_pairs gives the substrates and now their met_id. The ec_tree_homologs preset combines the EC tree with homologs, and ec_tree_okp combines homologs too; update_kcat_sources gathers homologs.tsv. * Treat homologs at 95% identity and above as the same protein When a homolog at 95% identity or more was measured on the substrate, the homolog estimate is the median of those homologs alone, and the combination gives it the exact bin of kcatCombineParams.tsv: no bias and the smallest error variance, an assumption, as the benchmark the other bins were fitted on hides such homologs. The detail column writes the identity with three decimals, as DIAMOND reports it, so that it falls in the right bin. * Use OKP's TurNup name; reaction-level OKP methods are not run per enzyme-substrate pair OpenKineticsPredictor names the method TurNup. CatPred and TurNup take the substrates (and products) of a whole reaction, so the default OKP methods are the eight pair-based ones with combination parameters, and asking for CatPred or TurNup per pair is an error. * Write the enzyme-usage text as RAVEN's metabolite note makeEcModel puts it in metNotes. As a separate notes key it was written as a nested map, which RAVEN's readYAMLmodel cannot read, so GECKO could not load an ecModel that geckopy saved.
…#69) save_ec_model writes gecko_format and generator instead of geckopy_version and keeps the model's date. load_ec_model warns about a GECKO 3 ecModel naming upgrade_project and refuses a format it does not know. Part of CompMetEng/GECKO#5.
…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
fix: give the same result as GECKO where the parity scenarios found differences
…nd pFBA; scipy solver support (#72) * Decide an infeasible start from the solver status in flexibilize_enz_concs and sensitivity_tuning * Support the scipy solver: repair optlang's variable index map, read duals from HiGHS, build large models sparsely optlang's scipy interface renumbers variable columns wrongly after a removal and keeps a dense matrix that it copies on every edit. An EcModel now moves its scipy problem to a sparse class with correct renumbering whenever model.solver is read, Enzyme.shadow_price, get_enzyme_bottlenecks and relax_proteomics_greedy read HiGHS row marginals on scipy, and load_conventional_gem and make_ec_model build on glpk and convert to scipy at the end. * Return a solution with its status after an infeasible scipy solve; test the flexibilize start on scipy * Remove the genes of get_subset_ec_model with cobra's remove_genes and keep the ec rows of a light model A reaction that survives the removal of a gene of its rule lost the gene from model.genes but not from its rule, so removing it later raised that the gene was not found. The ec rows of a gecko-light model carry a 001_ prefix and were all dropped. * Compare subsystem names in assign_standard_kcat without regard to letter case * Read the cells of uniprot.tsv and uniprotConversion.tsv like textscan with %q * Load ecModel files with an empty enzymes map and unescaped quotes in a value, as GECKO's loadEcModel does * Remove the metabolites and genes no reaction uses from a subset ecModel getSubsetEcModel's removeGenes and removeReactions calls drop every metabolite and gene without a reaction. get_subset_ec_model left the pseudo-gene standard and six unused metabolites in the HT29-GEM subset of the light Human-GEM ecModel. * Load an ecModel and set its solver to scipy without optlang's dense clone load_ec_model reads the file on glpk and converts the ecModel when scipy is cobra's default solver, and setting EcModel.solver to scipy builds the sparse problem of switch_to_scipy. Loading ecYeastGEM on scipy did not finish in 25 minutes before. * Copy and pickle a scipy ecModel into the sparse problem optlang restores a pickled or copied scipy model by adding every variable and constraint to a dense problem, which took tens of minutes per ec_fva worker on ecYeastGEM. * Pass model.tolerance to HiGHS on the scipy solver optlang's scipy interface ignores every tolerance, so a model set to 1e-9 was solved at the HiGHS default of 1e-7. * Solve a scipy LP again at the default tolerance after numerical difficulties * Fix the objective at 0.999999 of its optimum in pfba_enzymes, as getPfbaEnzymes does * Fix the target flux in ec_fseof and list reaction targets before transport targets, as ecFSEOF does * Edit a scipy ecModel on glpk in get_subset_ec_model and apply_kcat_constraints, and populate the sparse problem in one pass optlang's scipy interface removes constraints through a loop that calls the generic removal once per constraint with the whole list, so removing two or more constraints raised LookupError; the sparse model removes them correctly. Removals, and the coefficient rewrites of apply_kcat_constraints, run on glpk and the model is converted back with switch_to_scipy, which now creates each constraint with its whole expression. * Use colons in the new load_ec_model docstring items * Install raven-toolbox from develop in the test workflow
* Check the starting LP of flexibilize_enz_concs and sensitivity_tuning from the solver status after slim_optimize * optimize_model returns the infeasible solution on every solver; the limit-protein, kcat-tuning and analysis solves use it
…efault, as getConcControlCoeffs does (#76) method="shadow_price" keeps the reduced-cost path.
…#77) * Rank get_enzyme_bottlenecks by the re-solved change of the objective The order no longer depends on the shadow price, which depends on the basis at a degenerate optimum. Enzymes at their bound are solved again with the bound raised by fold_change; multiple_active marks rows where another capacity constraint is active. * get_enzyme_bottlenecks reports the gain in the objective's direction and requires a fold_change above 1 * get_enzyme_bottlenecks logs a warning when no enzyme is at its usage bound * Migration notes: no dash in the get_enzyme_bottlenecks bullet
* Rank get_enzyme_bottlenecks by the re-solved change of the objective The order no longer depends on the shadow price, which depends on the basis at a degenerate optimum. Enzymes at their bound are solved again with the bound raised by fold_change; multiple_active marks rows where another capacity constraint is active. * get_enzyme_bottlenecks reports the gain in the objective's direction and requires a fold_change above 1 * get_enzyme_bottlenecks logs a warning when no enzyme is at its usage bound * Migration notes: no dash in the get_enzyme_bottlenecks bullet * Evotune: skip NaN rmse, stable screen order, full generations on a flat objective best_parsimonious ignores points with a NaN rmse, screen_kcat_leverage sorts stably, cmaes_kcat_tuning does not stop on a flat generation, and compute_excarbon warns for a model without metabolite formulas. * Export review_assignment, EcStats and ec_stats_from_brenda * fill_enz_concs and constrain_enz_concs raise for a negative concentration * load_flux_data raises for a ragged row and reads nested parentheses in headers * enzyme_usage warns about enzymes without usage reaction; report_enzyme_usage rejects a negative top_abs_usage * Add tests for the shared contract of calculate_f_factor, relax_proteomics_greedy, apply_complex_data and add_new_rxns_to_ec * Add the CHANGELOG entries of round 5 group 3 * read_kcat_source skips a row of empty quoted fields and raises for a field with an opening quote and no closing one * read_dlkcat_output drops infinite kcats; write_dlkcat_input writes the rows in the order of model.ec.rxns * ECTree raises for k = NaN; kcats_from_ec_tree takes an empty ec_rxns as no reaction * assign_standard_kcat leaves out reactions without a substrate or without a product as exchange reactions * save_ec_model keeps an existing metaData description The default description is written only when the model has none, as saveEcModel does. * review_assignment recognises the sources custom and standard without regard to case * find_met_smiles skips metabolites without a name with a warning * Changelog: source case in review_assignment, unnamed metabolites in find_met_smiles * pfba_enzymes multiplies a given fraction_of_optimum by 0.999999 * apply_kcat_constraints takes cobra reaction ids and ec ids on a gecko-light model * constrain_enz_concs resets the lower bound and the pool coefficient of a usage reaction * Add the CHANGELOG entries for pfba_enzymes, apply_kcat_constraints and constrain_enz_concs * geckopy.kcat_tuning.evotune exports the parsimony and isozyme-tying helpers * save_ec_model: write no enzymes entry for an ec reaction without enzymes Tests cover the round trip, the saved text and the light tutorial ecModel. The format page and the docstrings describe the optional enzymes entry. * ec_fseof orders targets by the score rounded to 9 significant digits * load_ec_model: comment on the criterion of the reader
* README: shorter, with the GECKO logo, the parity ledger and the protocol citation * README: link the gecko-docs pages first, badges for documentation and support
…ssignment and a missing final newline
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes since 4.0.0b1. The CHANGELOG entry
4.0.0b2lists every change with its reason.Changes that alter results or raise errors
brenda_ec_tree(#67), and the BRENDA filter for implausible SA-derived kcats applies with a defaulttop_origin_limitof 4, down from 6 (#58).get_enzyme_bottlenecksranks the enzymes by the re-solved change of the objective (#77);get_conc_control_coeffstakes the finite-difference coefficients by default (#76);pfba_enzymesworks for a negative or minimised objective (#81).ValueErrorwhere they skipped a value with a warning, and results agree with GECKO for subsets, subsystems, uniprot cells, FSEOF, the f factor, the KEGG database and the solver tolerance (#72, #74, #78).raven-toolbox>=3.0.0b2is required.Added
model_adapter.tomlsets (#64, #66);model_adapter.tomlis shared with GECKO (#61).relax_enz_concs(#63).sweep_tunable_mask_sizeandrecommend_target_impact_share(#59); the scipy solver is supported (#72).Fixes
Complex Portal search paging and the
corrections()example (#60); CatRange predictions returned as class ranges (#62).Repository
Links point to CompMetEng (#65) and the README is shorter, with the protocol citation (#79).