Repository navigation
chore: version 2.1.0 - #1123
chore: version 2.1.0#1123
Conversation
The gene-essentiality run calls a gene essential when its knockout breaks any of the 57 essential tasks. That list mixes viability tasks (GR growth, ER energy and redox) with capability tasks (SU, BS, IC), so genes needed only for a capability, such as the ETF complex for beta-oxidation, are scored as false positives against the Hart 2015 proliferation screen (issue #1076). - taskEssentialGenes: add find_task_essential_categories, reporting which task categories each knockout breaks. The scan and its progress logging are factored into shared helpers; find_task_essential_genes keeps its early exit and behaviour. - evaluateHart2015Essentiality: add bayes_factors, exposing the unthresholded Hart Bayes Factors in model-gene space for graded comparisons. - gradedEssentiality: new analysis entry point reporting, per cell line, the task categories behind each call, the single-gene-deletion biomass growth ratio under the growth task medium, both binary scorings (all tasks and viability only) and the threshold-free AUROC/AUPRC of the growth ratio against the Bayes Factors. Analysis only: no model changes and not wired into CI.
…ality Replaces the all-task binary scoring with the graded, task-scoped analysis, so a gene essential only for a capability task (SU, BS, IC) is no longer counted as a proliferation prediction alongside viability tasks (GR, ER). See issue #1076. - gene-essentiality.yml runs gradedEssentiality.py, which now overwrites the usual gene-essential.csv and gene-essential_summary.md; the posted comment explains the viability/capability split. - geneEssentiality.py is removed: the graded run reports the all-task scoring too, so nothing is lost. - The graded scoring (evaluate_graded, summary_to_markdown, auroc, auprc) lives in evaluateHart2015Essentiality.py, which needs only pandas, so /reevaluate gene-essentiality keeps working from the committed matrix without a solve. - reevaluateGeneEssentiality.py parses the new matrix, which carries the task categories and growth ratio per gene. - The growth ratio is rounded to a fixed precision before scoring and average precision is computed over tied scores as a group, so the summary regenerated from the committed matrix is identical to the one the run produced. - Results regenerated from the graded run; see the pull request for provenance.
A result file produced for the first time is untracked in the run that writes it, but is tracked at the branch tip as soon as an earlier run has committed it. Plain git stash leaves untracked files in the working tree, so the checkout that follows refuses to overwrite them and the job fails after the run has already finished.
…-metrics test: score gene essentiality per task category (replaces all-task binary scoring)
* chore: remove legacy getINITModel2 gene-essentiality code Gene essentiality now runs the Python ftINIT (tINIT2) pipeline (code/test/geneEssentiality.py + estimateEssentialGenes.py + evaluateHart2015Essentiality.py). Remove the superseded MATLAB implementation: - tINIT/getINITModel2.m old INIT algorithm; RAVEN ftINIT is its successor - tINIT/restoreModelGrRules.m orphan; restored grRules the old tINIT stripped - test/estimateEssentialGenes.m MATLAB; only caller of getINITModel2 - test/evaluateHart2015Essentiality.m MATLAB The Python equivalents, the Hart2015 data/results and the (already-Python) gene-essentiality workflow are the current pipeline and are untouched. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci]
* feat: add human_gem Python package with load_model()
First step towards a pip-installable Python interface to Human-GEM, on
raven-toolbox + cobrapy. human_gem.load_model() loads Human-GEM as a fully
annotated cobra model - reading the YAML via raven-toolbox and merging the
cross-references and SBO terms from the annotation tables, which a bare
cobra.io.load_yaml_model does not do:
import human_gem
model = human_gem.load_model() # 12877 rxns, 8460 mets, cross-refs attached
- pyproject.toml (deps: cobra, pandas, raven-toolbox)
- human_gem/io.py load_model(model_dir=None, annotate=True)
- human_gem/annotation.py TSV -> MIRIAM/SBO merge (packaged home of the logic
currently duplicated in code/annotateGEM.py)
Verified locally: load_model() attaches cross-references to 12698/12877
reactions and 8449/8460 metabolites; annotate=False returns the bare model.
Next increments: reduce code/annotateGEM.py to a shim importing from human_gem
(single source of truth) + install the package in CI; then promote the ftINIT
essentiality and task helpers into the package.
* chore: update model QC results [skip ci]
* chore: update model QC results [skip ci]
* chore: update model QC results [skip ci]
* Parallelize gene-essentiality across cell lines via a build matrix (#1079)
* feat: parallelize gene-essentiality across cell lines via a build matrix
The gene-essentiality workflow built and scored all five Hart 2015 cell-line
models in one sequential loop in a single job, taking hours end to end even
though every cell line is independent of the others.
`gradedEssentiality.py`: had no way to build a subset of cell lines, so
splitting the work across parallel processes or jobs was not possible.
Adds `--shard-index`/`--shard-count` to select a slice of cell lines, and
`--aggregate-only` to combine every cell line's checkpoint into the final
report without rebuilding any of them.
`gene-essentiality.yml`: ran Step 1 (prepINITModel) and every cell line's
ftINIT build and essentiality scan in one job, so wall-clock time scaled
with the number of cell lines. Splits into a `build` job matrixed one shard
per cell line and an `aggregate` job that combines their checkpoints into
the committed report; the `diagnose` path is unchanged but now runs as its
own job instead of an early exit inside the shared script.
* chore: update model QC results [skip ci]
* perf: dedupe and parallelize the gene-essentiality knockout scan
The per-tissue scan in taskEssentialGenes.py solved thousands of small, nearly
identical LPs sequentially, so its runtime did not benefit from genes sharing a
knockout or from the extra cores a CI runner has.
- `_scan`: genes that disable the identical reaction set (subunits of the same
AND-linked complex, e.g. an ETC complex) were each solved separately against
every task instead of once per distinct reaction set.
- `_task_feasible_without`'s solves ran under Gurobi's default automatic/
concurrent method, which spins up several threads per solve for a problem
this small, adding synchronisation overhead across thousands of solves for
no benefit.
- `find_task_essential_genes`/`find_task_essential_categories` had no way to
spread the scan's independent gene knockouts across more than one core.
Verified against the previous per-gene scan (sequential and processes=2) on a
synthetic model covering a lone-gene reaction, an isoenzyme pair and a
multi-subunit complex.
* fix: run the knockout-scan pool with a spawn context
`_scan`'s `ProcessPoolExecutor` used the platform default multiprocessing
context, which is `fork` on the Linux CI runners this targets. Forking after
`base`'s Gurobi environment is already running duplicates that environment,
and any internal license/logging threads it holds, into every worker; this is
the same non-fork-safe state that made cobra's default parallel FVA deadlock
on Linux CI runners, which is why `estimateEssentialGenes.estimate_essential_genes`
and `gradedEssentiality.main` both pin FVA to `processes=1`.
- `_scan`: pass `mp_context=multiprocessing.get_context("spawn")` to the pool
so each worker starts as a fresh interpreter and only creates its own Gurobi
environment inside `_init_worker`, after the fork boundary, leaving nothing
shared between workers to deadlock on.
* perf: scan each cell line's gene knockouts on all of the runner's cores
`gradedEssentiality.py` shards cell lines across CI jobs (#1079), but within
one cell line's `find_task_essential_categories` call every gene knockout
still ran on a single core, leaving a shard's other cores idle regardless of
how many the runner had.
- `main`: adds `--processes` (default: `os.cpu_count()`) and forwards it to
`find_task_essential_categories`, which already supports splitting its
independent gene knockouts across a process pool.
* chore: update model QC results [skip ci]
* fix: actually update the local branch before the results commit
The gene-essentiality run at
https://github.com/SysBioChalmers/Human-GEM/actions/runs/34445477424 computed
results for all five cell lines (posted as a PR comment) but its "Auto-commit
results" step failed to push: "Updates were rejected because the tip of your
current branch is behind its remote counterpart".
- `gene-essentiality.yml`: "Update local branch before committing changes"
ran `git fetch` then `git checkout $BRANCH_NAME`, but `git fetch` only moves
the `origin/$BRANCH_NAME` ref; the local branch stayed at whatever commit
the job started from. Anything pushed to the branch while the job ran left
the auto-commit step basing its commit on that stale tip, so its push was
rejected as non-fast-forward and the finished run's results were lost.
* Edit the /run gene-essentiality comment instead of replying (#1080)
* chore: restore generated model files removed by #1061
* chore: new version
* chore: add the release workflow so it can be dispatched
workflow_dispatch resolves against the default branch, so a Release workflow
that exists only on develop cannot be started. Adding it here makes it
available in the Actions tab.
The workflow calls code/io/increaseHumanGEMVersion.py from the develop
checkout it cuts the release branch from, so a release can only run once
#1078 is on develop.
* ci: edit the /run gene-essentiality comment instead of replying
`/run gene-essentiality` posted its "started" acknowledgement as a separate
new comment, so a PR thread that used the command showed two comments (the
command and the acknowledgement) instead of one.
- `pr-command.yml`: the `gene-essentiality` job's "started" notice is now
appended to the triggering comment itself (`gh api ... -X PATCH`) rather
than posted with `gh pr comment`.
* chore: update model QC results [skip ci]
* perf: share Step 1's prepData across shards instead of rebuilding it
Each of the 5 shards in `main` independently called `_prep_human_model_for_ftinit`
whenever it had a pending cell line, even though that step's output does not
depend on which cell line asks for it (it runs before any cell line's expression
data is applied), so the same tens-of-minutes computation ran five times over.
- `gradedEssentiality.py`: adds `_load_or_build_prep`, `--prep-cache` and
`--prep-only`. `--prep-cache PATH` loads Step 1's `PrepData` from `PATH` if
present instead of rebuilding it, and writes it there otherwise; `--prep-only`
builds it and exits without touching any cell line. Without `--prep-cache`, a
run still builds its own Step 1, as before.
* ci: build the shared prepData once instead of once per shard
The `build` matrix ran `gradedEssentiality.py` for each of its 5 shards without
sharing anything between them, so the newly cacheable Step 1 still ran once per
shard by default.
- `gene-essentiality.yml`: adds a `prep` job that builds `PrepData` once with
`--prep-only --prep-cache` and uploads it as an artifact; `build` now depends
on `prep`, downloads that artifact, and passes `--prep-cache` so every shard
loads the shared prepData instead of rebuilding its own.
* chore: update model QC results [skip ci]
* Partial revert "Edit the /run gene-essentiality comment instead of replying (#1080)"
This partially reverts commit 5883d7e.
* Fix metabolicTasks_Full.txt so it parses with parseTaskList (#1070)
The full metabolic task list was missing the leading (empty) column that
metabolicTasks_Essential.txt has, so RAVEN parseTaskList read the whole file as
a single task. Add the leading column to align the format; parseTaskList now
returns 257 tasks and compareMultipleModels runs against the full list. No task
definitions are changed.
* chore: update model QC results [skip ci]
* Serialize the gene-essentiality build matrix under the WLS session baseline
The five build shards each open a Gurobi session, and --processes previously
defaulted to the runner's core count, opening one more session per worker
process inside each shard. Both ran concurrently against the same
Gurobi_Eduard WLS license, whose session baseline is 2, so the license
server eventually kills sessions once the overage runs too long.
* Split cell-line model-building and essentiality-scanning into separate shards
Each holds its own Gurobi session for the whole step, so running five of one
concurrently already sustains more sessions than the Gurobi_Eduard WLS
license's baseline of 2 for as long as the step takes; --processes further
multiplied that within a single shard's scan. Splitting them into build-model
and build-test lets both still run all five shards at once (no session
survives from one job into the next, so the two 5-way bursts do not merge
into one sustained overage), instead of serializing everything to stay under
the baseline.
* Let build-test run for shards whose build-model succeeded despite others failing
needs: build-model implicitly ANDs an overall success() onto its condition, so
one failed shard (build-model (4)/RPE1 hit the 90-minute job timeout in
34494319341) skipped build-test entirely, even for the four shards whose
context model had already built fine.
* Give build-model room for slow cell lines and report ftINIT progress
build-model's 90-minute timeout was below what one cell line's ftINIT build
can legitimately take: two extraction steps, each up to three solves (the
proven-gap solve plus resolve_ties' two tie-break phases) capped at
TIME_LIMIT = 30 min apiece, i.e. up to 180 min before task gap-filling.
RPE1 needs about 91 min (its first step's proven-gap solve and parsimony
phase both run to the 30-min cap), so its shard was cut off at the end of
extraction in 34494319341 while the other four finished in 9-24 min.
240 min covers the 180-min ceiling with headroom for gap-filling and setup.
The build step also went silent for the whole extraction: ftinit() only
prints its step and gap-fill progress with verbose=True, and optlang sets
OutputFlag = 0 on every Gurobi model it creates, so the global OutputFlag
set by _set_solver_verbosity never reaches the ftINIT MILPs. verbose=True
restores the step/gap-fill lines, and FTINIT_DEBUG=1 adds each solve's
status and achieved gap as it finishes.
Replayed locally for shard 4/5 (RPE1) with the CI's dependency versions
(Python 3.11, gurobipy 13.0.3, cobra 0.32.1, raven-toolbox 61da432):
prep 27 min, build-model 91 min, build-test (--processes 1) 14 min, all
exiting cleanly.
* Fix aggregate job's spurious Gurobi session, add retry and disposal
The gene-essentiality workflow's aggregate job crashed with "Too many
sessions, 5 active sessions for a baseline of 2": cobra prefers Gurobi
automatically whenever gurobipy is importable, so loading the model for
--aggregate-only opened a Gurobi WLS session even though that step never
solves anything and does not need one, and the build-test matrix's 5
just-finished sessions had not yet cleared from the license server.
Force glpk as the default solver before loading the model, letting only
the branches that actually need Gurobi's MILP solver switch to it. Also
add retry-with-backoff around that switch (a sibling shard's session is
far more likely to clear within a minute or two than the license being
genuinely exhausted) and explicit disposal of the default Gurobi
environment at the end of each Gurobi-using branch, so a shard's session
is released to the license server immediately instead of waiting on its
own connection timeout.
* Bound the Gurobi session disposal call with a timeout
disposeDefaultEnv() releasing a WLS session is a network round trip to
the license server, unlike a local/named-user license's instant close.
Running it inline risked an already-finished, already-written-to-disk
shard sitting "in progress" indefinitely if that round trip stalled --
plausibly what the currently running gene-essentiality workflow run is
hitting, since every shard passes through this same code regardless of
how fast its own MILP solve was. Run it on a background thread with a
bounded join instead: a timeout is logged and the process exits anyway,
which releases the session itself, just a little later.
* Add process/resource monitoring and harden Gurobi session retries
The gene-essentiality workflow's job logs are only retrievable after a
job completes, so a currently running (or stuck) build-model/build-test
shard is a black box from the outside -- no way to tell whether it is
genuinely solving or wedged. Add a background resource monitor to both
jobs (CPU/memory/top processes every 60s to a file, uploaded as an
artifact with if: always() so it survives a timeout or failure) to give
visibility into a run while or after it happens, without needing live
log streaming.
Also harden _use_gurobi_solver: a failed session-acquisition attempt
leaves gurobipy's process-wide default environment half-initialised
(the crash is inside its own construction), so best-effort dispose it
before each retry rather than reusing whatever state a broken attempt
left behind. Log how many attempts and how long acquisition took, plus
CPU count and Gurobi's resolved Threads, separating "time spent getting
a session" from "time spent solving" and surfacing possible CPU
oversubscription across the 5 concurrent shards.
* Disable ftINIT's resolve_ties/prove_abs_gap for the gene-essentiality CI check
Both add extra Gurobi solves (a 3-7x and ~2.4x build-time cost respectively)
specifically to pin which of many equally-scoring optima ftINIT returns, for
reproducibility across builds. But at the genome scale and the 1e-9 solver
tolerances this pipeline uses, that pinning is exquisitely sensitive to
floating-point differences between CPU vendors -- and GitHub-hosted
ubuntu-latest runners are not hardware-homogeneous: three consecutive
workflow_dispatch runs of an isolated benchmark just drew an Intel Xeon
Platinum 8573C, an AMD EPYC 7763, and an AMD EPYC 9V45. Raw CPU and Gurobi
throughput were healthy on all three, so this isn't a runner/license
slowdown; it's the extra tie-break/proven-gap solves turning "expensive but
bounded" into occasional multi-hour solves that blow through TIME_LIMIT
depending on which chip a run happens to land on.
Turning both off trades exact cross-build reproducibility (which the CI
check doesn't need -- it just needs to confirm the pipeline still runs and
predictions are still reasonable) for being robust to that hardware
lottery. Tolerances are being looked at separately.
* Re-enable PROVE_ABS_GAP; keep RESOLVE_TIES off
Dropping both in 756a56d removed the tie-break overhead but exposed a worse
failure mode: without PROVE_ABS_GAP, ftinit() falls back to the relative-gap
escalation, an open-ended loop of full-TIME_LIMIT re-solves rather than a
single bounded one. On PR #1069 (run 35517420976, 2026-09-20) that took over
an hour per extraction step; with five shards holding Gurobi sessions that
long concurrently, two tripped the WLS license's "Overage for too long" kill,
and the crashed (not gracefully closed) sessions then poisoned the
downstream build-test jobs for the rest of the run.
PROVE_ABS_GAP's single proven-gap solve costs ~2.4x a quick solve but has a
known ceiling (TIME_LIMIT), unlike the escalation's TIME_LIMIT-times-unbounded-
rounds. RESOLVE_TIES stays off since its tie-break phases are pure additional
cost on top of the base solve.
* Cap build-model at 2 concurrent shards to match the WLS session baseline
The build-model/build-test split assumed each 5-way-parallel burst was short
enough that sustained over-baseline usage wouldn't matter. It isn't: a cell
line's ftINIT build now commonly takes 1-2+ hours, so five shards each
holding a Gurobi session that long is a sustained 5-session stretch far past
the Gurobi_Eduard WLS license's baseline of 2. On PR #1069 (2026-09-20/21)
this reliably killed shards outright ("Overage for too long") and, once one
crashed mid-solve instead of releasing its session cleanly, poisoned other
shards' sessions for the rest of the run too ("Maximum number of failing
server authorization attempts reached") -- reproducing the original
aggregate failure this workflow started from, twice, across two different
attempts to fix it via solve-time settings alone.
max-parallel: 2 caps build-model at the WLS baseline directly: at most 2
sessions are ever open at once, independent of how long any individual
shard's solve takes. Same shard count and SHARD_COUNT (still one shard per
cell line), just throttled concurrency.
* chore: add gene essentiality test result [skip ci]
* fix: couple non-ETF flavoenzymes to ubiquinone instead of the ETF pathway (#1015) MAR06911 (EC 1.5.5.1) represents the ETF:ubiquinone oxidoreductase (ETFDH) step that reoxidises the matrix FADH2 pool. Its gene rule had accumulated into an 'or' of nine genes, six of which encode flavoenzymes that reduce ubiquinone directly and do not use ETF: GPD2, PRODH, PRODH2, CHDH, DHODH and SQOR (Banerjee et al. 2022, FEBS J, PMID:34428349). This caused two artefacts, most visible in enzyme-constrained (GECKO) models: - all FADH2-to-ubiquinone flux was constrained by the single ETFDH kcat, so e.g. the glycerol-3-phosphate shuttle was constrained twice; - beta-oxidation electrons could reach the ETC without ETFDH (via the GPD2 branch of the 'or' rule), which is biologically incorrect. Changes: - Restore MAR00483 (sn-glycerol-3-phosphate:ubiquinone oxidoreductase, GPD2, EC 1.1.5.3); remove FAD-linked MAR00449 and its Recon3D duplicate MAR01169. - Restore MAR03838 (L-proline:ubiquinone oxidoreductase, PRODH/PRODH2); remove FAD-linked MAR08611 (PRODH electron transfer to ubiquinone: Tanner 2018, PMID:28990412). - Set the MAR06911 gene rule to the ETF system only, "ENSG00000105379 and ENSG00000140374 and ENSG00000171503" (ETFB and ETFA and ETFDH), matching the and-joined convention used for the other obligate ETC complexes. DHODH already reduces ubiquinone through its own reaction (MAR20167) and needs no further change. CHDH (MAR08441) and SQOR (MAR20186) still deposit electrons in the matrix FADH2 pool and should be given direct ubiquinone reactions in a follow-up. Removed reactions are recorded in deprecatedReactions.tsv. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * fix: remove orphaned mitochondrial DHAP node after GPD2 recoupling Removing the FAD-linked MAR00449 left MAM01690m (mitochondrial DHAP) without a producer, since the restored ubiquinone-linked GPD2 (MAR00483) releases cytosolic DHAP. The metabolite and its only remaining reaction, the export transport MAR08111, are a MACAW dead-end and are removed and moved to the deprecated identifier lists. Drop the stale MAR00483 and MAR03838 rows from deprecatedReactions.tsv, as those identifiers are active reactions again after this PR. * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] * Scope the gene-essentiality PR comment to genes a change could affect The existing summary table aggregates predictions across ~3000 genes against Hart 2015, which is dominated by ftINIT's run-to-run noise and does not say whether a specific model edit made things better or worse. - `diffGeneEssentiality.py`: diffs the already-committed gene-essential.csv against the target branch's own copy, scoped to genes in the reactions a diff changed plus genes one metabolite hop away, keeping only flips that agree in direction across most cell lines. A flip in whether growth is blocked is checked against Hart 2015 and labelled correct or wrong; a flip in some other task capability is reported but not scored, since Hart only measures growth. - `gene-essentiality.yml`: runs the scoped diff after aggregating results and folds it into the PR comment, with the per-gene detail as a workflow artifact. - `pr-command.yml`: passes the pull request's base branch through to the dispatched workflow so it has something to diff against. * Group identical rows in the gene-essentiality diff table Several genes commonly change for the same reason (all three ETF complex subunits here), and one row per gene just repeats the same cells; group genes sharing the same lines/role/change into a single comma-joined row instead. * Replace the global essentiality table in the PR comment, not append to it The scoped diff section was being added alongside the full ~3000-gene table instead of instead of it, defeating the point: that table is dominated by ftINIT noise in genes the PR never touched. Show the scoped section when a base to diff against is available, falling back to the full table only when it is not (manual dispatch, or no gene-essential.csv on the target branch yet). * Tighten formatting in the scoped gene-essentiality report Bold the reaction/gene counts so they read at a glance, italicize the consensus-threshold explanation, fold the likely-noise gene list behind details instead of listing it inline, name the actual base branch instead of a generic placeholder, and link the committed gene-essential.csv instead of leaving it as plain text. * Collapse unchanged checks in the model quality report Every row rendered on every run regardless of status, so a clean pull request still posted 18 always-expanded rows of zeros and pre-existing findings. Merge the model-checks and MACAW/balance tables (the split was already noted as arbitrary), fold clean and pre-existing rows behind one details block since neither is this pull request's problem, and keep only a new regression or a still-running check inline. The two merge gates get a one-line summary next to the verdict so they stay visible without opening anything. Drop the per-row README link (rarely used, most of the raw markup) in favor of one link at the top; keep the per-value CSV link where there is a finding to look at. The metabolic-tasks table (every row there is a gate) compacts to one line when everything passes instead of folding. * chore: update model QC results [skip ci] * Redesign the model quality report: one row per section, not per check The folded 18-row table still duplicated the full breakdown into the comment on every run; nothing about a clean or pre-existing check needed to be there at all, since the point of comparing against base is that unchanged is not this pull request's problem. Split into two files: model_qc_summary.md keeps every individual check, unabridged, and is what the comment now links to; model_qc_comment.md is the new condensed report actually posted -- one row per section (network checks, file/task gates, MEMOTE, gene essentiality) naming only the checks that need attention, with everything else folded into that row's count. The two merge gates stay in the verdict line itself. * Redesign the gene-essentiality report: one row per category The two mini-tables plus a folded 32-gene noise list still put every gene's name in the comment somewhere. Replace with one table, one row per category (growth effect changed, other role changed, likely noise, no change) -- gene names stay only for the two small, actionable categories; noise and unchanged genes are counted, never named, since nobody needs 32 or 397 names in a comment. The per-gene detail CSV is now committed to data/testResults/gene-essential-diff.csv alongside gene-essential.csv itself, replacing the 30-day workflow artifact with a permanent, linkable file. * chore: update model QC results [skip ci] * Add an improved icon and tighten wording in the model quality report A count that fell since base, a score that rose, or growth that got fixed all rendered as the same clean/warning icons as "nothing changed", so a genuine improvement from this pull request was invisible. Add a distinct icon (:sparkles:) for that case, in both _icon() and its own "Improved:" callout. Also: drop the "Gene essentiality" row (that result lives in its own comment now, not here); add a "Full report" row linking model_qc_summary.md instead of a separate sentence below the table; "5" instead of "5 gates"; bullet points instead of a comma-joined sentence for the pre-existing list, each with a colon before its (now bolded) count. * Move gene names out of the comment, add an improved icon, drop /reevaluate The condensed table still put every gene's name and what changed for it in the Genes/Detail columns. Replace with a single Status column (icon and count only, matching the model-quality report's style); the per-gene detail that used to sit there is now appended to the committed gene-essential_summary.md instead, with the comment linking to it. Growth effect changed also gets :sparkles: when Hart 2015 agrees with the flip, distinct from the plain check used for "no change" elsewhere. Dropped the reaction-change counts from the lead sentence (kept the gene counts) and removed the /reevaluate gene-essentiality command: it fully overwrote gene-essential_summary.md, which would have silently dropped the appended section on the next run. * chore: add the scoped gene-essentiality diff for this change Computed with diffGeneEssentiality.py against the already-committed gene-essential.csv on both develop and this branch -- no ftINIT/Gurobi re-run needed. Appends the per-gene breakdown to gene-essential_summary.md and adds the full per-gene, per-line CSV, matching what the gene-essentiality workflow will write on its next real run. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
#1082) * fix: build the ftINIT MILP on Gurobi in the gene-essentiality driver The GLPK default set at the start of main() stayed in place after the template model was switched to Gurobi, so prepINITModel's merged min_model, which cobra builds from scratch, got GLPK, and ftINIT's MILP ran on it. Switching a model to Gurobi now also makes Gurobi the global default, and Step 1 logs the MILP's solver backend. * test: resolve ftINIT ties in the gene-essentiality builds With RESOLVE_TIES on, the same prepData loaded onto Gurobi by two routes gives identical context models for all five Hart2015 cell lines, where without it they differed by 4-9 reactions. Summed build time goes from about 92 to 124 min. * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] Produced outside GitHub Actions with the same code and pinned stack (raven-toolbox 98d02a8, gurobipy 13.0.3, cobra 0.32.1, Python 3.11): prep, one build and one scan per cell line, then gradedEssentiality.py --aggregate-only and the workflow's diffGeneEssentiality.py step. With RESOLVE_TIES on, context models built this way match those built by GitHub Actions reaction for reaction on all five cell lines. * chore: scope the gene essentiality diff to every gene [skip ci] This pull request changes the algorithm rather than the model, so the diff against develop covers all 2848 genes in the matrix instead of the genes of changed reactions.
… reactions (#1081) * fix: route SQOR and CHDH through ubiquinone, drop PRODH2 from proline reactions Follow-up to #1028, addressing the three refinements confirmed in the last comment on #1015 that #1028 itself didn't include. - `MAR20186` (SQOR): wrote its electrons into the matrix FADH2 pool even though its EC (1.8.5.8) is a direct quinone reductase, so once #1028 restricted `MAR06911` to the ETF complex only, SQOR's electrons would have had no route to the ETC at all. - `MAR08441` (CHDH): same FADH2-pool problem for the same reason -- a purified bacterial homolog shows physiological turnover with quinone as acceptor, and ETF-deficiency disorders show choline accumulation rather than accumulation of CHDH's own product, both against a shared-FAD model. - `MAR03838` and `MAR08610`: PRODH2's gene rule on both proline reactions assumed it shares PRODH's activity, but PRODH2 is a hydroxyproline dehydrogenase (no hydroxyproline reaction exists in this model) with a turnover on proline too low to carry physiological flux, and neither PRODH2 knockout nor overexpression affects proline levels the way PRODH's does. `MAR08610`'s only gene was PRODH2, so removing it leaves no valid gene for that reaction; deprecated accordingly. * fix: give PRODH2 its own ubiquinone-linked hydroxyproline reaction PRODH2 (ENSG00000250799) is a mitochondrial FAD-dependent hydroxyproline dehydrogenase (EC 1.5.5.3) that reduces ubiquinone directly, not the proline-oxidizing, NAD(P)+-linked activity it was previously attributed with on MAR03838/MAR08610 (PMID:25697095). The model already has the rest of the pathway: MAR09002 transports hydroxyproline into the mitochondrion, and the product this reaction feeds, L-1-pyrroline-3-hydroxy-5-carboxylate (MAM02320m), already has four downstream consumers -- so this does not introduce a new dead end, it gives PRODH2 a route into a part of the network that was previously only reachable via PYCR1/PYCRL/PYCR2 running in reverse. * chore: add KEGG/Rhea cross-references for MAR20192 KEGG R03295 confirmed directly from KEGG's own EC 1.5.5.3 entry. Rhea master RHEA:52512 confirmed independently via UniProt's PRODH2 catalytic- activity annotation and a direct Rhea search hit for the same equation. RHEA:52513 (the directional entry) follows the rxnRheaID = rxnRheaMasterID + 1 pattern every other row in this file uses, but is not independently confirmed since rhea-db.org blocked direct fetches. * fix: stop counting one-direction reversible reactions as MACAW dead ends MACAW marks a reversible reaction that structural propagation limits to one direction as `only when going forwards` or `only when going backwards`. The model quality report counted these with the true dead ends, so a change that made a reversible reaction directional (for example removing the only irreversible producer of a metabolite) raised the dead-end count and showed a regression even though the reaction can still carry flux. Only true dead ends are counted now; the per-reaction values stay in macaw_results.csv. * Write only MACAW findings, as a TSV macaw_results.csv listed all 12,875 reactions, of which 10k+ passed both tests. The file is now macaw_results.tsv and holds only reactions with a true dead end or a duplicate flag (1,518 rows); reversible reactions merely limited to one direction are not findings and are omitted. The report's dead-end and duplicate counts are unchanged (1,141 and 377); the base-branch fetch lists and the README follow the new name. * chore: add gene essentiality test result [skip ci] Context models and knockout scans are those of GitHub Actions run 35901385430, whose model and code are unchanged by the rebase onto develop; the scoped diff is regenerated against develop's results from #1082. * chore: add gene essentiality test result [skip ci]
) * fix: correct SAM synthesis GPR and remove non-catalytic MAT2B (#1013) MAR03875 (SAM synthesis) and MAR07139 (SeAdoMet synthesis) had the GPR "MAT2B or MAT1A or MAT2A", which incorrectly lets MAT2B catalyse the reaction on its own. MAT2B (ENSG00000038274) is a non-catalytic regulatory subunit: it stabilises MAT2A and lowers the Km for methionine and the Ki for SAM, but its knockout leaves cellular SAM levels unchanged while only MAT2A depletion reduces SAM (PMID:39353892). MAT2A forms a catalytically active homotetramer without MAT2B and is the catalytic subunit; MAT1A is the catalytic isozyme. Set both GPRs to "ENSG00000151224 or ENSG00000168906" (MAT1A or MAT2A). MAT2B was associated only with these two reactions, so it is removed from the gene list. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * ci: overwrite the /run gene-essentiality comment with the results * chore: add gene essentiality test result [skip ci] * chore: add the scoped gene-essentiality diff for this change The /run gene-essentiality run was dispatched without a base branch, so it skipped the scoped diff and posted the unscoped table. Computed with diffGeneEssentiality.py from the committed gene-essential.csv on develop and on this branch (no re-run); appends the per-gene breakdown to gene-essential_summary.md and replaces the stale gene-essential-diff.csv inherited from #1028 with this change's own. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix: export each metabolite's InChI from metabolites.tsv annotateGEM.py merged the database identifiers from metabolites.tsv but not metInChI, so the Excel InChI column and the SBML took the YAML's inline inchis field instead: 1063 values, 417 of them in the non-standard InChI=1/ form and 479 differing from the curated metabolites.tsv. The metInChI column now fills notes['inchis'] (Excel InChI column) and annotation['inchi'] (SBML), as annotateGEM.m does, and the YAML no longer carries its own InChIs. A trial export gives 6409 InChIs in both the .xlsx and the .xml. * fix: add and re-protonate metabolite structures to match formula and charge - 81 SMILES/InChI pairs re-protonated to the state whose formula and charge match the model (dimorphite-dl enumeration; only protons change, the InChIKey connectivity and stereo blocks are unchanged). - 8 compartment copies without a structure take it from another compartment of the same metabolite with identical formula and charge (5-deoxyadenosine, FMN, hexanoate, FMNH2). - 2 new structures from MetaNetX whose protonation state matches the model: [2Fe-2S] cluster (MAM20085m) and S-sulfanylglutathione (MAM20086m). Structure/formula-charge inconsistencies: 397 -> 316. * chore: update model QC results [skip ci]
* feat: add ModelSEED reaction and compound cross-references - metSeedID: fill 721 empty cells. Matched by InChIKey (protonation-insensitive, exact protonation preferred, core ModelSEED compounds preferred), via MetaNetX, and for metabolites without a concrete structure by exact name. Existing ids are kept. - rxnSeedID: new column in reactions.tsv with 2881 reactions, matched by stoichiometry over the mapped compounds (H+ kept when it crosses a membrane) or via MetaNetX when the ModelSEED reaction shares the compounds and the transport type. - annotateGEM.py/.m map rxnSeedID to seed.reaction; annotationTest.py checks the metSeedID/rxnSeedID formats and metSeedID across compartments; verifyAnnotations.py knows rxnSeedID. * fix: correct three existing ModelSEED compound ids hydroxide pointed to water (cpd00001) and D-ribulose to the generic Ribuloses (cpd28115); hydrochloride pointed to chloride (cpd00099), and ModelSEED has no HCl entry. * chore: update model QC results [skip ci] * fix: correct four ModelSEED compound ids to the model's compound Resolved against the model's own KEGG id and ModelSEED's KEGG aliases: - (3S)-citramalyl-CoA: cpd00671 (unspecified, C00904) -> cpd00743 (C01011) - L-2-amino-3-oxobutanoate: cpd02053 (C03214) -> cpd02211 (C03508) - L-erythro-4-hydroxyglutamate: cpd01974 (C03079) -> cpd19042 (C05947) - Pectin: cpd00280 (D-galacturonate, the monomer) -> cpd11601 (Pectin, C00714)
* fix: add and correct reaction cross-references (KEGG, BiGG, MetaNetX, Rhea) New ids come from matching each reaction's structural signature to MetaNetX (participants by InChIKey, H+ kept only when it crosses a membrane, BiGG ids restricted to the reaction's own compartments), and from each metabolite's BiGG id for exchange reactions (EX_<id>_e). Existing ids were verified against the reaction they point to in MetaNetX. An id is corrected when all participants have a structure and they differ (skeleton, MetaNetX id, name and heavy-atom formula all disagree), when it is a BiGG id for other compartments, when a same-formula participant is a different isomer (reviewed by name), or when the KEGG reaction no longer exists. Ids that differ only in cofactors (NAD(P), FAD, FMN, O2/H2O2, quinones, ATP/ADP/AMP, CO2/HCO3-) or that cannot be verified are kept. Added: BiGG 1176, MetaNetX 1067, Rhea (master) 888, KEGG 6. Replaced: BiGG 624 (181 misaligned exchange ids), MetaNetX 40, KEGG 6. Removed: BiGG 312, KEGG 78 (28 no longer in KEGG), Rhea 36 (+8 directional ids of the same reaction), MetaNetX 35. * chore: update model QC results [skip ci] * fix: add and correct metabolite cross-references Existing ids were verified against the compound they point to (MetaNetX, and PubChem by InChIKey) and against the source databases for ids MetaNetX lacks. - PubChem: 1037 CIDs added by InChIKey (neutral form); 7 CIDs of a different compound replaced (e.g. 7alpha-hydroxycholesterol had 20alpha-, chloride had chlorine, deoxyribose the L-enantiomer). - Ids that no longer exist in their database: 78 replaced by the current id (LipidMaps acyl-CoAs, ChEBI numbers that are not ChEBI ids, obsolete CHEBI:17208, KEGG C00425 -> C05422 and others), 6 LipidMaps ids removed. - Wrong compound: guanidine, acetanilide and a tridecanoyl lysophosphatidate had the MetaNetX id of another compound; isocaproic aldehyde the LipidMaps id of hexanal; 3-ketopristanoyl-CoA the HMDB id of pristanoyl-CoA; C16:1-ethanolamide all ids of the C16:0 compound. - 69 ids added for metabolites without a concrete structure, from their MetaNetX id where its name matches. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci]
…AR11311 (#1033) * feat: associate Ca2+ influx channels with MAR11311 (#1001) MAR11311 (Ca2+[e] -> Ca2+[c]) was labelled passive diffusion with no GPR, but uncoupled Ca2+ entry is channel-mediated. It is the only uncoupled Ca2+ influx reaction in the model (the other extracellular/cytosol Ca2+ reactions are antiporters and ATPases). Because every plasma-membrane Ca2+ influx channel catalyses the identical Ca2+[e] -> Ca2+[c] reaction, separate per-channel reactions would be duplicates, so they share this reaction's GPR. - Set the GPR of MAR11311 to the voltage-gated (Cav1/2/3) and store- operated (ORAI) Ca2+ channel pore-forming subunits: CACNA1A, CACNA1B, CACNA1C, CACNA1D, CACNA1E, CACNA1F, CACNA1G, CACNA1H, CACNA1I, CACNA1S and ORAI1, ORAI2, ORAI3 (13 genes, joined by OR). - Rename MAR11311 from "...via Diffusion..." to "...via Ion Channels...". - Add the 13 genes (all new to the model) to the gene list and genes.tsv. The genes.tsv rows carry gene identity only (Ensembl ID, symbol, name); their transcript/protein/UniProt/Entrez annotations and localisation should be populated by code/GPRs/fetch_ensembl_gene_annotations.py, the standard generator for that file. Exported model files regenerate at release. Expands the L-type request in #1001 to the other voltage-gated and store-operated channels that share the same reaction. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci]
ci: start the slowest gene-essentiality shards (GBM, RPE1) first
ci: always post the scoped gene-essentiality comment
…1038) * fix: remove LDHAL6A from MAR11479 GPR for consistency with MAR11476 (#528) MAR11476 and MAR11479 are the same promiscuous lactate dehydrogenase side-reaction on adjacent branched-chain 2-oxo acids. The GPR curation in #847 / #885 removed LDHAL6A (ENSG00000166800) from MAR11476 as not relevant to the reaction, but left it on MAR11479, leaving the two inconsistent. Remove LDHAL6A from MAR11479 as well so both carry the same five-gene rule (LDHB, LDHA, LDHC, LDHD, LDHAL6B). * chore: add macaw test result * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* ci: show which MEMOTE run the score comes from, and the full-suite score when current * chore: update model QC results [skip ci]
* feat: add cellular succinate export via MCT proton symport (#424) Human-GEM has three Na-coupled succinate import reactions across the plasma membrane (MAR09610, MAR04939, MAR04938) but no export, so cytosolic succinate could not be secreted. Succinate export is relevant in hypoxia and is mediated by the monocarboxylate transporters MCT1 (SLC16A1) and MCT4 (SLC16A3) (PMID:35363247). Add MAR20192, a reversible succinate + H+ symport across the plasma membrane (GPR SLC16A1 or SLC16A3), modelled like the existing lactate MCT reaction MAR05998. Secretion now works through the existing exchange reaction MAR09415. Mitochondrial succinate export is already possible via the reversible SLC25A10/SLC25A1 antiporters, so no mitochondrial reaction is added. * chore: add macaw test result * chore: update model QC results [skip ci] * chore: full MEMOTE result [skip ci] * fix: make MAR20193 succinate transport export-only * chore: add gene essentiality test result [skip ci] * chore: update model QC results [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…1098) * ci: test growth on a capped Ham's medium instead of the default bounds * ci: show MEMOTE per-test scores, not raw metrics, and leave out skipped tests * ci: copy model QC results onto the head branch instead of stash-merging them * chore: update model QC results [skip ci] * chore: update model QC results [skip ci]
* fix: balance MAR20189, the ThDP intermediates and the H-protein lipoyl cycle * chore: update model QC results [skip ci] * chore: update model QC results [skip ci]
…1101) * feat: flag diffusion transports as spontaneous so ftINIT keeps them * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] * ci: count correct and wrong essentiality changes separately in the summary * chore: update model QC results [skip ci]
* feat: add PXMP2 as the peroxisomal pore for small-solute transport * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: flag non-enzymatic reactions as spontaneous * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…etaNetX ids (#1090) * fix: one base id per metabolite, and correct cytochrome c and water MetaNetX ids - 14 metabolites existed under two base ids in different compartments (same name, structure and cross-references): biomass (MAM03971e -> MAM03970e) and 13 metabolites added in the MAM200xx range, e.g. 1,4-benzoquinone (MAM20009c -> MAM20007c). Each second id is renamed to the first base id with its own compartment and added to the deprecated metabolites. - Ferricytochrome c, ferrocytochrome c and cytochrome c all had MNXM5749, which MetaNetX no longer has: now MNXM731952, MNXM731957 and MNXM731958, the MetaNetX entries of their KEGG ids C00125, C00126 and C00524. - H2O gets MetaNetX's id WATER; annotationTest.py accepts it. * chore: update model QC results [skip ci] * fix: MetaNetX ids of glycogenin (apo) and hydrogen chloride * fix: merge 37 duplicate metabolites and the reactions they made identical * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * fix: MAR08607 is glutamine transaminase K, producing 2-oxoglutaramate (charge-imbalanced as glutamate) * revert: keep memoteSnapshot.py as on develop * ci: run model QC check groups as parallel jobs, all on GLPK Seven check groups (structural, annotation, MACAW, balance, model file, metabolic tasks, MEMOTE core subset) run as a matrix. A report job merges their result files and changed qc_status.tsv keys, commits once and posts the comment. The MEMOTE core subset now solves with GLPK, so model QC never uses a Gurobi licence session; the full suite keeps Gurobi. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…#1040) * fix: remove charge-imbalanced duplicate lipoxygenase reactions (#348) Five arachidonate/DHA peroxidation reactions are 1:1 duplicates of balanced multi-stoichiometry reactions that produce the same hydroperoxide (same substrate and product, no GPR), but with charge-imbalanced stoichiometry. Remove the imbalanced 1:1 versions and keep the balanced counterparts: removed kept product MAR01364 MAR03880 12-peroxy-eicosatetraenoate MAR01355 MAR03882 8-peroxy-eicosatetraenoate MAR01358 MAR03878 9-peroxy-eicosatetraenoate MAR01361 MAR03884 11-peroxy-eicosatetraenoate MAR01405 MAR03261 10-peroxy-docosahexaenoate Each product is still produced by its balanced counterpart, so the model stays balanced. Removed reactions moved to deprecatedReactions.tsv. The deeper cause (hydroperoxide and hydroxy fatty-acid metabolites that are one H short, affecting ~105 reactions) is tracked in a separate issue. * chore: update model QC results [skip ci] * fix: load models with GLPK in diffGeneEssentiality, which solves nothing The scoped diff loads the base and head models only. With gurobipy installed, cobra made Gurobi the default solver, so each load took a WLS licence session; straight after the build-test shards these can all still be held, and the diff failed with "Too many sessions". * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…ions (#1041) * fix: correct mechanism and stoichiometry of duplicate transport reactions (#347) Resolves the remaining similar-reaction pairs from #347, which split into distinct mechanistic groups rather than a single "2 vs 1 ATP" problem. Vesicular secretion (SLC18A1/A2/A3, SLC32A1): these transporters are H+ antiporters, but their gradient is across the secretory-vesicle membrane, which the model does not represent, so the ATP acts as a proxy for the V-ATPase loading cost. Standardised to 1 ATP per molecule (Recon3D form), removed the inconsistent HMR 2-ATP-per-3-molecule duplicates, and added a rxnNotes comment. Kept MAR01442,00052,00065,00334,01555,00058,00087,01396, 01314,01518; removed MAR07633-37,07681,07736-38,08922. Na+-multivitamin symport (SLC5A6/SMVT, biotin, pantothenate): removed the spurious ATP and modelled as Na+ symport, 2 Na+ : 1 substrate (PMID:25809983). Kept MAR00094, MAR01636; removed MAR07667, MAR08930. Na+/Cl- symport (SLC6A12/BGT1, betaine, GABA): set coupling to 3 Na+ : 1 Cl- : 1 substrate. Kept MAR09873, MAR09886; removed MAR09603, MAR09604. The GAT reaction MAR09613 (2 Na+ : 1 Cl-) is a distinct transporter and is unchanged. Bile acid / bile-acid-CoA transport (ABC transporters, 2 ATP): kept the HMR 2-ATP form, removed the Recon3D 1-ATP duplicate. Kept MAR01702, MAR01857, MAR01861; removed MAR02283, MAR02290, MAR02298. Sterol 4-methyl oxidation (MSMO1): kept MAR00116 (3 NADPH/3 O2, the correct 3-step monooxygenation), removed MAR02300 (1 NADPH/2 O2). Removed reactions moved to deprecatedReactions.tsv. The sulfate pair (MAR01913/MAR02304) is left for a closer look, as its mechanism is not clearly ABC. All modified reactions remain mass and charge balanced; no genes are orphaned. * chore: update model QC results [skip ci] * fix: merge the SMVT symports MAR00094 and MAR01636 into MAR09609 and MAR09607 With the Na+ symport corrected to 2 Na+ : 1 substrate, MAR00094 (biotin) and MAR01636 (pantothenate) became identical to the HMR reactions MAR09609 and MAR09607. The HMR reactions are kept: the BiGG and MetaNetX ids of MAR00094 and MAR01636 describe the ATP-coupled form, while MNXR158886 on MAR09609 is the Na+ symport. Their references move to the kept reactions, which are renamed to describe the symport. * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: enable collagen secretion and remove duplicate MAR09553 (#335) The collagen synthesis pathway (MAR06983 -> MAR06984 -> MAR06985) ended at the dead-end metabolite 1,2-D-glucosyl-5-D-(galactosyloxy)-L-lysine- procollagen (MAM00232c), so it could not carry flux. MAR09553 was a redundant duplicate of MAR06983 (same product, same GPR) whose substrate procollagen-L-lysine (MAM02768c) was itself a dead-end input. - Remove MAR09553 and its orphaned dead-end substrate MAM02768c (moved to the deprecated lists). - Add secretion of the final procollagen precursor: MAM00232e, a transport MAR20192 (MAM00232c -> MAM00232e) and an exchange MAR20193, modelled like the existing hyaluronate secretion, giving the collagen pathway a sink so it can carry flux. A general secreted-protein-export framework and collagen proline hydroxylation are out of scope for the generic Human-GEM and left for context-specific / specialised models. * chore: add QC test results [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…f those found (#1095) * fix: check and correct reactions split across compartments * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…omega-hydroxylation (#1096) * fix: mitochondrial GPRs and FAD for vitamin E beta-oxidation, CYP4F2 for its omega-hydroxylation * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
#1085) (#1104) * fix: metabolite identity, structure and formula inconsistencies from #1085 - The 2-oxoadipate/BCKDH thiamine adduct gets its own id, MAM20089m, since MAM20077 is 2-O-acetyl-ADP-D-ribose; the copied KEGG and MetaNetX ids of that compound are dropped. - Structures that differed between compartments of one metabolite now match the fully specified one (elaidate, 15(R)-HEPE, all-trans-decaprenyl diphosphate, 3-methylhistidine, lysophosphatidylethanolamines and others). - MAM03652c is C16:1-ethanolamide, as in [e], and its hydrolysis (MAR20093) gives palmitoleate. - MAM00270 is 20-HETE (structure, KEGG, LIPID MAPS and its reactions); it was named 10-HETE. - H2S has the HS- structure the model uses; (2R)/(2S)-pristanic acid and pristanal get their (6R,10R) structures. - Cholesterol ester formula uses R, not X. * fix: curate metabolites whose structure contradicts their formula (#1085) Each metabolite flagged by the structure consistency check, other than a plain proton shift, was checked against its name, its reactions and its cross-references: - Structure of a different compound replaced (e.g. 2-bromopyridine on an epoxy-alkoxyl radical, 3-hydroxybutyrate on (2R)-pristanoyl-CoA, 11-cis- retinyl palmitate on 11-peroxy-DHA, oxypurinol on alloxan, neutral atoms on chloride and K+), and the cross-references that belonged to that compound removed. Lipid peroxy intermediates get peroxyl radical structures, as their formulas and reactions require. - Formula or charge corrected where the structure was right: the lysophosphatidylcholines and sphingomyelins (zwitterions, one H less), paclitaxel and 6-hydroxypaclitaxel (20 H), insulin, somatostatin, peptide charges, methylcobalamin, and the eicosanoid charges that differed between compartments. - Structures removed from polymers, protein-bound glycans and the dolichol family, whose chain length varies. - MAR01070, MAR05427, MAR06350, MAR08993 and MAR12993 get the reactants their corrected metabolites need to balance. - His-Gly-Lys, docosatrienoic acid and docosatetraenoylcarnitine renamed to match their reactions and structures. No reaction becomes imbalanced; 12 become balanced. The structure check drops from 315 to 71 rows, mostly plain proton shifts. * chore: update model QC results [skip ci] * fix: MAR20093 hydrolyses palmitoylethanolamide; ThDP adduct and O-acetyl-ADP-ribose ids; review corrections MAR20093 is NAAA's palmitoylethanolamide hydrolysis (RHEA:45064), and its substrate was added in 2023 as palmitoylethanolamide (CHEBI:71464) under the C16:1-ethanolamide base id. It now uses MAM03885c (palmitoylethanolamide) and gives palmitate again; MAM03652c is deprecated into it. - KEGG C22667 and MNXM37367 are the ThDP adduct and move to MAM20089m, which records MAM20077m as retired; 2-O-acetyl-ADP-ribose (MAM20077n) gets KEGG C20658 and MNXM732228. - Dopachrome o-semiquinone has the L (2S) configuration of L-dopachrome. - Chloride uses MNXM735978 (MNXM43 is deprecated in MetaNetX). - ModelSEED ids of Leu-Gly (cpd32743) and C16:1-ethanolamide (cpd40310) corrected; those of GalN-6-P, oxypurinol and retinyl palmitate removed from galactosamine, alloxan and 11-peroxy-DHA. - LPE(18:2) PubChem 90657442 (9Z,12Z); ubiquinol-10 CHEBI:64183. - Pristanoyl-CoA (MAM03887) leaves C2 undefined, as a generic metabolite. * chore: update model QC results [skip ci] * fix: merge MAM20017n into MAM20015 (13,14-dihydro-15-oxo-PGE2) MAM20015g and MAM20017n have the same name, structure, formula, charge and cross-references (CHEBI:57402, MNXM733372) in disjoint compartments, a pair from #626 that #1090 missed. The nuclear one becomes MAM20015n and records MAM20017n as retired. * fix: MAR20019 reduces 15-oxo-PGE2; deprecate the free-cobalamin methionine synthase MAR03138 - MAR20019 is PTGR3's 15-oxoprostaglandin 13-reductase (UniProt Q8N4Q0, RHEA:11912), written in the NADPH-reducing direction with a single gene. - MAR03138 methylated free cob(II)alamin with SAM, duplicating the MTRR reactivation of methionine synthase already modelled with the enzyme-bound cofactor (MAR09550); its product methylcobalamin had no other reaction. Both are deprecated. * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] * fix: peptide charges follow the model convention; Asp/Glu peptides named correctly Lys-Arg-Leu is +2, Pro-His-Tyr and Trp-Pro-Gly are 0 (termini as zwitterion, charge from the side chains), with the H+ of their hydrolysis reactions adjusted. MAM03464, MAM03606 and MAM03607 are the Asp-Ala-Arg, Glu-Arg-Leu and Glu-Asn-Leu that their structures, formulas, reactions and Recon3D ids describe. * chore: update model QC results [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
) * fix: corrections to #1039, #1041, #1040, #1090, #1028, #1099 and #1038 from the curation review - MAR20193: MCT1 carries succinate with 2 H+ (UniProt P53985, RHEA:29303, PMID:32946811); MCT4 has no succinate evidence, so the GPR is SLC16A1. - Vesicular secretion goes back to the HMR stoichiometries (2 ATP per 3 amines or acetylcholine, 1 ATP per 3 GABA, glycine or beta-alanine): VMAT exchanges 2 H+ per amine and the V-ATPase pumps about 10 H+ per 3 ATP (PMID:32165585), so 1 ATP per molecule overestimates the cost. - BGT1 (SLC6A12) couples 3 Na+ and 2 Cl- (human BGT-1, PMID:7589472). - MAR01857/MAR01861 exported bile salts straight from the peroxisome with 2 ATP and no gene; ABCB11 uses 1 ATP (RHEA:50052/50064), as in MAR01870/MAR01872. - Kept reactions record the reactions #1040 and #1041 deprecated into them. - #1090 GPR unions: MAR01762 and MAR01605 are CYP27A1 only, MAR01765 is CYP7B1 (CH25H only 25-hydroxylates, CYP2E1 and CYP27A1 do not 7alpha-hydroxylate); duplicate genes removed from joined GPRs. - MAR08607 has the cross-references and EC of glutamine transaminase K (RHEA:30391, EC 2.6.1.117); HCl keeps MNXM735978; MAM03543 has the (2E,4Z) structure its name and DECR1 require; renamed ids are recorded in metRetired; MAR00751 is merged into MAR06346 with its gene; MAR00036 uses one 15-deoxy-PGD2. - MAR00483 and MAR03838 carry the ids of their quinone reactions, and no deprecated reaction lists them as retired any more. - MAR08433/MAR08434 carry the BiGG/MetaNetX ids of their glycine cleavage steps. - LDHD, a mitochondrial FAD (R)-2-hydroxyacid dehydrogenase (UniProt Q86WU2), is removed from the NADH reactions MAR11476/MAR11479. * fix: corrections to #1101, #1103, #1084, #1086 and #1087 from the curation review - H2O2 crosses the plasma, ER and inner mitochondrial membranes through peroxiporins, as water does through aquaporins in the model: MAR08408 AQP3/AQP8/AQP9, MAR13002 AQP11/AQP8, MAR03946 AQP8 (PMID:20724658, PMID:31546170, PMID:22910329); no longer flagged spontaneous. AQP11 is added as a gene. - Histone import (MAR08024) is by importin-4 (PMID:36103578): GPR IPO4 (new gene), cytosol to nucleus only, not spontaneous. - Prostacyclin and thromboxane A2 hydrolysis are one-way (PMID:29320, PMID:1059088); MAR06877 is written as the spontaneous addition of cysteine to dopaquinone. - Leu-Gly-type errors of #1084: palmitoleoylcarnitine and selenohomocysteine get their own structures back. - ModelSEED ids of a different reaction (proton-pumping variants on plain hydrolases, 18:2 on 18:3 elongation, degenerate or plant reactions) or compound are removed or corrected. - #1087: unrelated ids on the NH4+/NH3 and xanthurenate protonation reactions removed; the respiratory chain BiGG ids NADH2_u10mi, CYOR_u10mi, CYOOm2i and CYOOm3i restored; the carnitine-shuttle MetaNetX ids it added use (R)-carnitine; ids inherited from misannotated metabolites removed; D-ribulose 1-phosphate ids removed from the D-xylulose 1-phosphate aldolase; RHEA:10160 restored on MAR09470. - PubChem ids that #1087 took from wrong model structures (a different compound, D-peptides, all-trans lipids) are replaced by the correct one where verified, otherwise removed; 14,15-DiHETE has CHEBI:133916 and 13(S)-HODE loses the 13R LIPID MAPS id. * fix: remaining corrections from the curation review (deprecated rows, #1099 ids, LDH GPRs, notes) - Deprecated rows of MAR00449, MAR08610 and MAM01690m are complete copies of their last model rows. - MAR08441 (choline to ubiquinone) loses the ids of the FAD reaction and cites the evidence for the quinone route (PMID:1218095, PMID:9630673, PMID:34428349). - #1099: the apo H protein is named as such (CHEBI:29969); the aminomethyl H protein has CHEBI:83143 and KEGG C01242 and records MAM02878m as retired; S-propanoyldihydrolipoamide loses the protein-bound ids; MAR20168 is named after LIPT1 and filed under lipoic acid metabolism. - TPO iodination (MAR06793/MAR06794) is tyrosine metabolism. - The 40 PXMP2 pore reactions note that Pxmp2 loss only partly restricts peroxisomal permeability (PMID:19352492). - MAR11476, MAR11479 and MAR05351 get every LDH with demonstrated activity (LDHA, LDHB, LDHC, LDHAL6A): LDH reduces the branched-chain 2-oxo acid (PMID:26014429) and 2-oxobutyrate (PMID:26059096); LDHAL6B has no demonstrated activity. * fix: remaining low-priority corrections from the curation review Diffusion and non-enzymatic reactions (#1101, #1103): - 14 missed diffusion transports (CO, ethanol, methanol, acetaldehyde, formaldehyde) flagged spontaneous; acetone diffuses mitochondria <=> cytosol <=> extracellular (MAR02222, MAR08364) and is not an MCT1 substrate (MAR08365 deprecated). - Plasma-membrane NH3 transport also by RHBG and RHCG (PMID:24077989); the NH4+ Rhea id is removed from NH3 transports. - Lipid nuclear transports named for what they move, with a note on lateral diffusion in the ER/nuclear envelope; flagged nuclear diffusions reversible. - MAM01739 is 5,6-dihydroxyindole (its ChEBI, KEGG and structure); the reactions that used it as aminochrome now use aminochrome (MAM02160); the two resulting duplicates are merged into the NQO1 and GSTM2 reactions, and the two glutathionyl-aminochrome ids into MAM01136. - MAR04840 (thiosulfate hydrolysis) has no chemical or enzymatic basis and is deprecated; H2S2O3 is merged into thiosulfate; mitochondrial TST transfers sulfur from GSSH to sulfite (MAR20203, RHEA:55976, PMID:25225291). - Further non-enzymatic reactions flagged (statin lactonisation, 1-pyrroline, aminochrome tautomerisation, mevalonolactone, PAH diols); Pictet-Spengler condensations are written as condensations. Annotations (#1084, #1086, #1087, #1090, #1033): - Deprecated MetaNetX reaction ids replaced by their matching successor or removed; R_-prefixed BiGG ids removed; KEGG ids of the lipoamide half-reactions and chloro-compound hydrolyses restored; ModelSEED ids that differ in proton coupling removed. - L-form PubChem/ChEBI ids for stereo-less amino-acid derivatives; iodide, ammonium and ascorbate ids of the ionic forms. - Chemically sensible protonation sites in 11 re-protonated SMILES; synaptamide structure; more precise names for kept ids of #1090 merges; (11Z)- and (7Z)-octadecenoylcarnitine and cis-vaccenoyl-CoA structures. - Gene rows of the Ca2+ channels, IPO4 and AQP11 completed; TRPV5 and TRPV6 added to MAR11311 (UniProt RHEA:29671, PMIDs 11097838, 19261737). - Genes without evidence removed from #1090 unions: CYP2J2 (MAR06700), ALDH3A1/ALDH9A1 (MAR01611); MAR04049 keeps CYP1A1 and CYP1B1. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * fix: corrections to #1043, #1088, #1093-#1096 from an evidence review Retired pointers for merged ids (MAR09553, MAM02768c, MAM20076n, the cytosolic tocopherol copies); I-antigen MAM03584g merged into MAM02186g and MAR08317 into MAR00082 with B4GALT1-4; PTGS peroxidase steps MAR01307/MAR01392/MAR01393 use NADPH and are irreversible; tocopherol side-chain beta-oxidation gets ACAA2, and MAR06435/MAR06451 DECR1 and ECI1/ECI2 with separate NADPH and NAD+; CYP3A4 on MAR08034; references and notes for MAR03859, MAR04280, MAR20195, MAR20021-MAR20029 and the CYP4F2 13'-carboxylation steps. * fix: corrections to #1044 and #1089 from an evidence review Retinoate 4-hydroxylation and 4-oxo GPRs follow single-isoform human data (CYP2C9, CYP2B6, CYP2C19, CYP3A5, CYP26A1 added where shown), Rhea ids for the 9-cis steps, lumped MetaNetX ids removed from the split hydroxylations, ids for 4-hydroxy-9-cis-retinoate; retired pointers for the galactose merges and UniProt-backed references for GALK1, GALT and UGP2 on galactose-1-phosphate. * chore: update model QC results [skip ci] * feat: add CYP26C1 to the retinoate 4-hydroxylation and 4-oxo reactions UniProt Q6V0L0 gives human CYP26C1 the all-trans and 9-cis 4-hydroxylations and 4-oxo steps (RHEA:51984, 75851, 75847, 75855; PMID:14532297); it also 4-hydroxylates 13-cis-retinoate (PMID:29476041). * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
#1106) * fix: corrections to #1039, #1041, #1040, #1090, #1028, #1099 and #1038 from the curation review - MAR20193: MCT1 carries succinate with 2 H+ (UniProt P53985, RHEA:29303, PMID:32946811); MCT4 has no succinate evidence, so the GPR is SLC16A1. - Vesicular secretion goes back to the HMR stoichiometries (2 ATP per 3 amines or acetylcholine, 1 ATP per 3 GABA, glycine or beta-alanine): VMAT exchanges 2 H+ per amine and the V-ATPase pumps about 10 H+ per 3 ATP (PMID:32165585), so 1 ATP per molecule overestimates the cost. - BGT1 (SLC6A12) couples 3 Na+ and 2 Cl- (human BGT-1, PMID:7589472). - MAR01857/MAR01861 exported bile salts straight from the peroxisome with 2 ATP and no gene; ABCB11 uses 1 ATP (RHEA:50052/50064), as in MAR01870/MAR01872. - Kept reactions record the reactions #1040 and #1041 deprecated into them. - #1090 GPR unions: MAR01762 and MAR01605 are CYP27A1 only, MAR01765 is CYP7B1 (CH25H only 25-hydroxylates, CYP2E1 and CYP27A1 do not 7alpha-hydroxylate); duplicate genes removed from joined GPRs. - MAR08607 has the cross-references and EC of glutamine transaminase K (RHEA:30391, EC 2.6.1.117); HCl keeps MNXM735978; MAM03543 has the (2E,4Z) structure its name and DECR1 require; renamed ids are recorded in metRetired; MAR00751 is merged into MAR06346 with its gene; MAR00036 uses one 15-deoxy-PGD2. - MAR00483 and MAR03838 carry the ids of their quinone reactions, and no deprecated reaction lists them as retired any more. - MAR08433/MAR08434 carry the BiGG/MetaNetX ids of their glycine cleavage steps. - LDHD, a mitochondrial FAD (R)-2-hydroxyacid dehydrogenase (UniProt Q86WU2), is removed from the NADH reactions MAR11476/MAR11479. * fix: corrections to #1101, #1103, #1084, #1086 and #1087 from the curation review - H2O2 crosses the plasma, ER and inner mitochondrial membranes through peroxiporins, as water does through aquaporins in the model: MAR08408 AQP3/AQP8/AQP9, MAR13002 AQP11/AQP8, MAR03946 AQP8 (PMID:20724658, PMID:31546170, PMID:22910329); no longer flagged spontaneous. AQP11 is added as a gene. - Histone import (MAR08024) is by importin-4 (PMID:36103578): GPR IPO4 (new gene), cytosol to nucleus only, not spontaneous. - Prostacyclin and thromboxane A2 hydrolysis are one-way (PMID:29320, PMID:1059088); MAR06877 is written as the spontaneous addition of cysteine to dopaquinone. - Leu-Gly-type errors of #1084: palmitoleoylcarnitine and selenohomocysteine get their own structures back. - ModelSEED ids of a different reaction (proton-pumping variants on plain hydrolases, 18:2 on 18:3 elongation, degenerate or plant reactions) or compound are removed or corrected. - #1087: unrelated ids on the NH4+/NH3 and xanthurenate protonation reactions removed; the respiratory chain BiGG ids NADH2_u10mi, CYOR_u10mi, CYOOm2i and CYOOm3i restored; the carnitine-shuttle MetaNetX ids it added use (R)-carnitine; ids inherited from misannotated metabolites removed; D-ribulose 1-phosphate ids removed from the D-xylulose 1-phosphate aldolase; RHEA:10160 restored on MAR09470. - PubChem ids that #1087 took from wrong model structures (a different compound, D-peptides, all-trans lipids) are replaced by the correct one where verified, otherwise removed; 14,15-DiHETE has CHEBI:133916 and 13(S)-HODE loses the 13R LIPID MAPS id. * fix: remaining corrections from the curation review (deprecated rows, #1099 ids, LDH GPRs, notes) - Deprecated rows of MAR00449, MAR08610 and MAM01690m are complete copies of their last model rows. - MAR08441 (choline to ubiquinone) loses the ids of the FAD reaction and cites the evidence for the quinone route (PMID:1218095, PMID:9630673, PMID:34428349). - #1099: the apo H protein is named as such (CHEBI:29969); the aminomethyl H protein has CHEBI:83143 and KEGG C01242 and records MAM02878m as retired; S-propanoyldihydrolipoamide loses the protein-bound ids; MAR20168 is named after LIPT1 and filed under lipoic acid metabolism. - TPO iodination (MAR06793/MAR06794) is tyrosine metabolism. - The 40 PXMP2 pore reactions note that Pxmp2 loss only partly restricts peroxisomal permeability (PMID:19352492). - MAR11476, MAR11479 and MAR05351 get every LDH with demonstrated activity (LDHA, LDHB, LDHC, LDHAL6A): LDH reduces the branched-chain 2-oxo acid (PMID:26014429) and 2-oxobutyrate (PMID:26059096); LDHAL6B has no demonstrated activity. * fix: remaining low-priority corrections from the curation review Diffusion and non-enzymatic reactions (#1101, #1103): - 14 missed diffusion transports (CO, ethanol, methanol, acetaldehyde, formaldehyde) flagged spontaneous; acetone diffuses mitochondria <=> cytosol <=> extracellular (MAR02222, MAR08364) and is not an MCT1 substrate (MAR08365 deprecated). - Plasma-membrane NH3 transport also by RHBG and RHCG (PMID:24077989); the NH4+ Rhea id is removed from NH3 transports. - Lipid nuclear transports named for what they move, with a note on lateral diffusion in the ER/nuclear envelope; flagged nuclear diffusions reversible. - MAM01739 is 5,6-dihydroxyindole (its ChEBI, KEGG and structure); the reactions that used it as aminochrome now use aminochrome (MAM02160); the two resulting duplicates are merged into the NQO1 and GSTM2 reactions, and the two glutathionyl-aminochrome ids into MAM01136. - MAR04840 (thiosulfate hydrolysis) has no chemical or enzymatic basis and is deprecated; H2S2O3 is merged into thiosulfate; mitochondrial TST transfers sulfur from GSSH to sulfite (MAR20203, RHEA:55976, PMID:25225291). - Further non-enzymatic reactions flagged (statin lactonisation, 1-pyrroline, aminochrome tautomerisation, mevalonolactone, PAH diols); Pictet-Spengler condensations are written as condensations. Annotations (#1084, #1086, #1087, #1090, #1033): - Deprecated MetaNetX reaction ids replaced by their matching successor or removed; R_-prefixed BiGG ids removed; KEGG ids of the lipoamide half-reactions and chloro-compound hydrolyses restored; ModelSEED ids that differ in proton coupling removed. - L-form PubChem/ChEBI ids for stereo-less amino-acid derivatives; iodide, ammonium and ascorbate ids of the ionic forms. - Chemically sensible protonation sites in 11 re-protonated SMILES; synaptamide structure; more precise names for kept ids of #1090 merges; (11Z)- and (7Z)-octadecenoylcarnitine and cis-vaccenoyl-CoA structures. - Gene rows of the Ca2+ channels, IPO4 and AQP11 completed; TRPV5 and TRPV6 added to MAR11311 (UniProt RHEA:29671, PMIDs 11097838, 19261737). - Genes without evidence removed from #1090 unions: CYP2J2 (MAR06700), ALDH3A1/ALDH9A1 (MAR01611); MAR04049 keeps CYP1A1 and CYP1B1. * chore: update model QC results [skip ci] * fix: pre-existing reaction and GPR errors found in the curation review - MAR01453 hydroxypyruvate reductase is 1:1 (it made reducing equivalents), with LDHA/LDHB (PMID:16198644). - No cytosolic NAD+ choline dehydrogenase or NAD+ D-lactate dehydrogenase exists in human: MAR04696 (with the cytosolic betaine aldehyde reactions MAR04697/MAR04698) and MAR08512 are deprecated; LDHD is removed from NAD reactions; choline is oxidised by CHDH in mitochondria. - CH25H only 25-hydroxylates cholesterol: the ER 26- and 20-hydroxylations MAR01785/MAR01781 (and MAR01783, which followed from 20-hydroxycholesterol) are deprecated. - NIS carries 2 Na+ per iodide (MAR06989 into MAR08924); pendrin exchanges 1 Cl- per I- (RHEA:72379); the H+/K+-ATPase exports its proton (MAR08892; MAR01444 merged into it). - HCl is replaced by chloride + H+; hydrogen bromide was bromide already and is renamed and re-annotated. - 15-deoxy-PGD2 forms by dehydration of PGD2 (one-way, spontaneous); the 1-pyrroline-5-carboxylate ring openings are non-enzymatic (no ALDH4A1); nuclear transports of CMP-Neu5Ac, UTP and deoxycytidine are diffusion, like the other nucleotides (NUP62CL and NUP210L, left on no reaction, are removed); MAR01597 and MAR10395 are deprecated. - CYP27A1 steps are mitochondrial monooxygenations; 15-oxo-PGE2 13-reduction by PTGR3 (MAR20018) is written in its direction. - 2-hydroxyglutarate: L- (MAM03188) and D-2-hydroxyglutarate (MAM20012) are separate; L2HGDH oxidises L-2HG in mitochondria (ubiquinone), new D2HGDH (MAR20204, via ETF) oxidises D-2HG; PHGDH makes D-2HG; MDH2 and LDHA/MDH1 make L-2HG; OAT1/NaDC3 transports. - MAR08773 is named for D-xylulose 1-phosphate. * fix: bile acid, globoside, 2-hydroxyglutarate export and PGD2 dehydration reactions - No human enzyme makes beta-GalNAc-globoside (para-Forssman): B3GALNT1 only makes globoside and B3GALNT2 does not act on glycolipids (PMID:14724282); its synthesis, reversed lysosomal breakdown and transports are deprecated. NAGA hydrolyses alpha-GalNAc-globoside with water (RHEA:48412). - MAR01787, MAR03259, MAR02184 and MAR02881 turned sterols without a 7alpha-hydroxyl into 7alpha-hydroxycholest-4-en-3-one; HSD3B7 acts only on 7alpha-hydroxylated sterols (PMID:11067870); deprecated. - CYP27A1 is mitochondrial (UniProt Q02318): duplicate and cytosolic copies of its steps are merged into the mitochondrial reactions. - 2-hydroxyglutarate efflux (MAR11733) is OAT4 exchange with estrone sulfate (PMID:18365245). - PGD2 dehydrates to delta-12-PGJ2 and PGJ2 non-enzymatically (one-way; PMID:6578214, PMID:11786541). * fix: review corrections on the reaction branch - Deprecations left dead ends: the Golgi GalNAc transport MAR08193, and MAR01578/MAR02895 (20-hydroxycholesterol and 7alpha-hydroxycholest-4-en-3-one in mitochondria, each in one reaction only) are deprecated with their metabolites. - OAT4 also exchanges D-2-hydroxyglutarate (MAR20211, PMID:18365245). - The L-glycerate ids MNXR100701/HPYRR2x belong to the LDH hydroxypyruvate reduction (MAR01453), not to GRHPR's D-glycerate reaction (MAR08782). - Pendrin 1:1 exchange cited (PMID:18565999); an unrelated citation removed from MAR11731; MAR02184 is deprecated without a merge target; chloride records the HMR id of the merged HCl. * chore: update model QC results [skip ci] * fix: MAR01453 lists its BiGG id once * chore: update model QC results [skip ci] * fix: deprecate the blocked ER copy MAR20031 of 4-nitrophenol hydroxylation into MAR08034 MAR20031 is MAR08034 (CYP2E1, RHEA:26205, MNXR102281) in the ER, where PNP and 4-nitrocatechol have no other reaction or transport, so it cannot carry flux. MAR08034 keeps the connected cytosolic copy and records MAR20031 in rxnRetired; PNP[r] and 4-nitrocatechol[r] are deprecated. * chore: update model QC results [skip ci] * fix: cholesterol synthesis goes through HSD17B7 and MSMO1 in the ER copy The Recon3D ER copy of the second C4 demethylation lumped it into 3-keto-4-methylzymosterol + O2 -> zymosterone (MAR00117, MAR00118) and had a gene-less hydrolytic demethylation (MAR02302), which bypassed HSD17B7 and MSMO1; these are deprecated and replaced by MSMO1 (MAR20217) and NSDHL (MAR20218) steps with the new MAM00955r. MAR00115 gets HSD17B7 instead of HSD17B4, MAR01500 and MAR02301 reduce with NADPH instead of producing it, and MAR00116 gets EC 1.14.18.9. * chore: update model QC results [skip ci] * fix: do not complete the ER copy of cholesterol synthesis The MSMO1 and NSDHL steps in the ER (and 4alpha-carboxyzymosterol[r]) are dropped: the cytosolic and ER copies of the pathway are to be reconciled into one, and cholesterol is made by the complete cytosolic copy. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…errors (#1107) * fix: corrections to #1039, #1041, #1040, #1090, #1028, #1099 and #1038 from the curation review - MAR20193: MCT1 carries succinate with 2 H+ (UniProt P53985, RHEA:29303, PMID:32946811); MCT4 has no succinate evidence, so the GPR is SLC16A1. - Vesicular secretion goes back to the HMR stoichiometries (2 ATP per 3 amines or acetylcholine, 1 ATP per 3 GABA, glycine or beta-alanine): VMAT exchanges 2 H+ per amine and the V-ATPase pumps about 10 H+ per 3 ATP (PMID:32165585), so 1 ATP per molecule overestimates the cost. - BGT1 (SLC6A12) couples 3 Na+ and 2 Cl- (human BGT-1, PMID:7589472). - MAR01857/MAR01861 exported bile salts straight from the peroxisome with 2 ATP and no gene; ABCB11 uses 1 ATP (RHEA:50052/50064), as in MAR01870/MAR01872. - Kept reactions record the reactions #1040 and #1041 deprecated into them. - #1090 GPR unions: MAR01762 and MAR01605 are CYP27A1 only, MAR01765 is CYP7B1 (CH25H only 25-hydroxylates, CYP2E1 and CYP27A1 do not 7alpha-hydroxylate); duplicate genes removed from joined GPRs. - MAR08607 has the cross-references and EC of glutamine transaminase K (RHEA:30391, EC 2.6.1.117); HCl keeps MNXM735978; MAM03543 has the (2E,4Z) structure its name and DECR1 require; renamed ids are recorded in metRetired; MAR00751 is merged into MAR06346 with its gene; MAR00036 uses one 15-deoxy-PGD2. - MAR00483 and MAR03838 carry the ids of their quinone reactions, and no deprecated reaction lists them as retired any more. - MAR08433/MAR08434 carry the BiGG/MetaNetX ids of their glycine cleavage steps. - LDHD, a mitochondrial FAD (R)-2-hydroxyacid dehydrogenase (UniProt Q86WU2), is removed from the NADH reactions MAR11476/MAR11479. * fix: corrections to #1101, #1103, #1084, #1086 and #1087 from the curation review - H2O2 crosses the plasma, ER and inner mitochondrial membranes through peroxiporins, as water does through aquaporins in the model: MAR08408 AQP3/AQP8/AQP9, MAR13002 AQP11/AQP8, MAR03946 AQP8 (PMID:20724658, PMID:31546170, PMID:22910329); no longer flagged spontaneous. AQP11 is added as a gene. - Histone import (MAR08024) is by importin-4 (PMID:36103578): GPR IPO4 (new gene), cytosol to nucleus only, not spontaneous. - Prostacyclin and thromboxane A2 hydrolysis are one-way (PMID:29320, PMID:1059088); MAR06877 is written as the spontaneous addition of cysteine to dopaquinone. - Leu-Gly-type errors of #1084: palmitoleoylcarnitine and selenohomocysteine get their own structures back. - ModelSEED ids of a different reaction (proton-pumping variants on plain hydrolases, 18:2 on 18:3 elongation, degenerate or plant reactions) or compound are removed or corrected. - #1087: unrelated ids on the NH4+/NH3 and xanthurenate protonation reactions removed; the respiratory chain BiGG ids NADH2_u10mi, CYOR_u10mi, CYOOm2i and CYOOm3i restored; the carnitine-shuttle MetaNetX ids it added use (R)-carnitine; ids inherited from misannotated metabolites removed; D-ribulose 1-phosphate ids removed from the D-xylulose 1-phosphate aldolase; RHEA:10160 restored on MAR09470. - PubChem ids that #1087 took from wrong model structures (a different compound, D-peptides, all-trans lipids) are replaced by the correct one where verified, otherwise removed; 14,15-DiHETE has CHEBI:133916 and 13(S)-HODE loses the 13R LIPID MAPS id. * fix: remaining corrections from the curation review (deprecated rows, #1099 ids, LDH GPRs, notes) - Deprecated rows of MAR00449, MAR08610 and MAM01690m are complete copies of their last model rows. - MAR08441 (choline to ubiquinone) loses the ids of the FAD reaction and cites the evidence for the quinone route (PMID:1218095, PMID:9630673, PMID:34428349). - #1099: the apo H protein is named as such (CHEBI:29969); the aminomethyl H protein has CHEBI:83143 and KEGG C01242 and records MAM02878m as retired; S-propanoyldihydrolipoamide loses the protein-bound ids; MAR20168 is named after LIPT1 and filed under lipoic acid metabolism. - TPO iodination (MAR06793/MAR06794) is tyrosine metabolism. - The 40 PXMP2 pore reactions note that Pxmp2 loss only partly restricts peroxisomal permeability (PMID:19352492). - MAR11476, MAR11479 and MAR05351 get every LDH with demonstrated activity (LDHA, LDHB, LDHC, LDHAL6A): LDH reduces the branched-chain 2-oxo acid (PMID:26014429) and 2-oxobutyrate (PMID:26059096); LDHAL6B has no demonstrated activity. * fix: remaining low-priority corrections from the curation review Diffusion and non-enzymatic reactions (#1101, #1103): - 14 missed diffusion transports (CO, ethanol, methanol, acetaldehyde, formaldehyde) flagged spontaneous; acetone diffuses mitochondria <=> cytosol <=> extracellular (MAR02222, MAR08364) and is not an MCT1 substrate (MAR08365 deprecated). - Plasma-membrane NH3 transport also by RHBG and RHCG (PMID:24077989); the NH4+ Rhea id is removed from NH3 transports. - Lipid nuclear transports named for what they move, with a note on lateral diffusion in the ER/nuclear envelope; flagged nuclear diffusions reversible. - MAM01739 is 5,6-dihydroxyindole (its ChEBI, KEGG and structure); the reactions that used it as aminochrome now use aminochrome (MAM02160); the two resulting duplicates are merged into the NQO1 and GSTM2 reactions, and the two glutathionyl-aminochrome ids into MAM01136. - MAR04840 (thiosulfate hydrolysis) has no chemical or enzymatic basis and is deprecated; H2S2O3 is merged into thiosulfate; mitochondrial TST transfers sulfur from GSSH to sulfite (MAR20203, RHEA:55976, PMID:25225291). - Further non-enzymatic reactions flagged (statin lactonisation, 1-pyrroline, aminochrome tautomerisation, mevalonolactone, PAH diols); Pictet-Spengler condensations are written as condensations. Annotations (#1084, #1086, #1087, #1090, #1033): - Deprecated MetaNetX reaction ids replaced by their matching successor or removed; R_-prefixed BiGG ids removed; KEGG ids of the lipoamide half-reactions and chloro-compound hydrolyses restored; ModelSEED ids that differ in proton coupling removed. - L-form PubChem/ChEBI ids for stereo-less amino-acid derivatives; iodide, ammonium and ascorbate ids of the ionic forms. - Chemically sensible protonation sites in 11 re-protonated SMILES; synaptamide structure; more precise names for kept ids of #1090 merges; (11Z)- and (7Z)-octadecenoylcarnitine and cis-vaccenoyl-CoA structures. - Gene rows of the Ca2+ channels, IPO4 and AQP11 completed; TRPV5 and TRPV6 added to MAR11311 (UniProt RHEA:29671, PMIDs 11097838, 19261737). - Genes without evidence removed from #1090 unions: CYP2J2 (MAR06700), ALDH3A1/ALDH9A1 (MAR01611); MAR04049 keeps CYP1A1 and CYP1B1. * chore: update model QC results [skip ci] * fix: pre-existing metabolite identity, structure and cross-reference errors - L-carnitine (MAM02348) had the D-carnitine structure and ids in every field but HMDB: now (R)-carnitine (CHEBI:16347, C00318, MNXM1105737, cpd00266, PubChem 10917); the carnitine-shuttle reactions carry the (R)-carnitine MetaNetX and ModelSEED ids. - Peptides: 221 peptide metabolites had D or undefined residues; they get all-L structures, and all-L PubChem/MetaNetX ids replace the D ones. - Statins: the rosuvastatin, pitavastatin, pravastatin, fluvastatin and cerivastatin metabolites were Ca/Na salt dimers (cerivastatin also one CH2 short); they are monomers at physiological charge, and their reactions are rewritten to stay balanced; statin acyl glucuronide lactonisation by UGT1A1/UGT1A3/UGT2B7 (PMID:26412035). - D-xylulose 1-phosphate, beta-GalNAc-globoside (penicillin G ids removed), 4-cis-decenoyl-CoA, (6Z,9Z)-octadecadienoyl-CoA, 10,11-dihydro-12-epi-LTB4, A2PE, lactosylceramide and alpha-/omega-muricholoyl-CoA get their own structures and cross-references; the reaction ids that followed the wrong compound are corrected or removed; KHK (MAR08772) has the D-xylulose MetaNetX id. - Shifted BiGG ids from the HMR/Recon mapping: 59 exchanges carry their own EX_ id, and 97 internal reactions the matching BiGG and MetaNetX ids. * fix: merge duplicate lactosylceramide and Leb glycolipid ids; linoleoyl-CoA, dihydro-LTB4 and peptide names - MAM03586 is merged into MAM02328 (lactosylceramide), which now carries lactosylceramide's BiGG/MetaNetX ids instead of digalactosylceramide's; the six Recon reactions that became identical to HMR ones are merged into them, and the GLA/PSAP globotriaosylceramide hydrolysis (MAR00804) gets its genes. - MAM01999 'glycolipid' is the Lewis b glycolipid (two fucoses, made by FUT3) and is merged into MAM03578; MAR08287 makes Lewis y (FUT9); duplicate reactions merged; MAR08271 is FUT3 or FUT5. - Linoleoyl-CoA has the (9Z,12Z) PubChem id; 10,11-dihydro-LTB4 and its CoA ester the 5S,12S structure and ids (CHEBI:133324); MAM00091m's metRetired is well formed. - Asp-Ala-Arg, Glu-Arg-Leu and Glu-Asn-Leu are named by their formula, BiGG ids and hydrolysis products. * fix: review corrections on the metabolite branch - MAR02660/MAR02662 unchanged (acyl-CoA reactions follow their own issues). - Cerivastatin M-22 and M-31 are the neutral lactones of M-1 and M-23, and the M-1/M-23 glucuronides are acyl glucuronides (only these lactonise); the lactonisation and hydrolysis reactions no longer use SAM/SAH to balance. - The fluvastatin acids have the 3R,5S configuration of fluvastatin and its lactone (PubChem 37888681). - MetaNetX ids of other isomers removed (MAR00150; the 10,11-dihydro-LTB4 reactions; two polyglutamyl-folates); MAR00766 duplicates MAR12035 in reverse and is merged into it; exchange names follow the renamed peptides; FUT5 evidence cited on MAR08271. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * ci: relative links in the committed test-result reports model_qc_summary.md and gene-essential_summary.md sit in data/testResults next to the README and the CSVs they link to, so they now link relatively. The absolute links pinned the pull-request branch and broke once it was deleted after merging. The posted comments keep absolute links, which they need. * chore: relative links in the committed test-result reports * chore: add gene essentiality test result [skip ci]
…release (#1116) * fix: separate the Ca2+ ATPases by membrane and add ER and Golgi Ca2+ release (#1000) MAR07629 exported 2 Ca2+ per ATP with the GPR of all Ca2+ ATPase families; it is deprecated into the PMCA reaction MAR00119, which gets its ATP-hydrolysis proton in the cytosol and EC 7.2.2.10. SERCA pumps Ca2+ into the ER and Golgi, SPCA into the Golgi, and IP3 receptors, ryanodine receptors and TMCO1 release it again (new Ca2+[r], Ca2+[g], MAR20212-MAR20216 and seven genes). * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * ci: halve the ftINIT time limit in the gene-essentiality test * fix: keep develop's reinstated vesicle-transport reactions out of the deprecated list * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
) (#1121) * fix: vitamin D C-23 pathway to CYP24A1, FAD hydrolysis to NT5E, drop SDR16C5 from 9-cis-retinol reactions (#887) * chore: update model QC results [skip ci] * fix: take the vitamin D C-23 and 24-oxo biomass catabolites from mitochondria and drop the cytosolic CYP24A1 pathway copies (#887) * chore: update model QC results [skip ci] * chore: add gene essentiality test result [skip ci] --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…unit tests (#1078) * feat: automate the release from develop to a published GitHub release Releases were cut by running code/io/increaseHumanGEMVersion.py by hand on main, which left the split between main and develop unenforced: v2.0.1 dropped the generated model files and needed a follow-up commit to restore them. - `release.yml`: cuts `release/<version>` from `develop`, stamps the version and regenerates the exports, opens the release pull request into `main`, and on merge tags `v<version>`, publishes the release from its notes file and opens the sync-back pull request into `develop`. - `branch-hygiene.yml`: fails when a generated model file or `version.txt` is tracked on `develop`. Exact paths, since a `*.xlsx` or `*.txt` glob would match the Hart 2015 datasets and the requirements files. - `increaseHumanGEMVersion.py`: takes an explicit version through `validate` and `build` subcommands instead of bumping from the branch it runs on, so the build runs on a release branch cut from `develop`. `validate` reads the released version from `origin/main` and refuses a version whose release notes are missing. - `docs/releaseNotes/<version>.md`: the body of the GitHub release, written before the release branch is cut and reviewed with the release pull request. * chore: update model QC results [skip ci] * test: add an SBML round-trip gate, a naming check, and unit tests for the QC code The scripts under code/test decide whether a pull request passes model QC, and model/Human-GEM.xml is written at release time and read back by nothing, so both were unverified. - `testSbmlConversion.py`: writes the annotated model to SBML, reads it back and compares the two, which catches annotation losses and identifier rewrites in the file that is published as SBML. Identifiers are compared as sets, because the writer emits an identifier listed twice on one entity only once, and returns a single cross-reference as a string rather than a one-element list. Wired into `model-qc.yml` as `roundtrip_sbml`, a gate alongside the YAML round-trips. - `qcModelChecks.check_name_consistency`: reports entities with no name and metabolites whose name differs between compartments. `reactions.tsv` and `metabolites.tsv` carry cross-references only, so a name has no second copy to drift against, but one chemical can still be named differently per compartment. - `code/test/unit`: pytest cover for `qcStatus`, `buildReport`'s counting and delta helpers, and the new naming check, run with ruff by `python-tests.yml` on every pull request. They build small cobra models, so they need no solver or licence. - `qcStatus.read_status`: the default path was bound at import, so a reassigned STATUS_FILE was written but not read. It is resolved per call now. * test: pin the ruff rule set instead of relying on its defaults An unpinned ruff in CI applies whatever rule set its current release defaults to, so a ruff release fails the build rather than a change to this repository. The selected rules report mistakes rather than layout; line length is left out because nothing formats this repository and the existing scripts run to 147 characters. * test: declare the PyYAML dependency of qcModelChecks qcModelChecks.py reads model/Human-GEM.yml with PyYAML to find duplicate keys before cobra loads the file, but reached it through another package's dependencies rather than declaring it, so a job installing only these requirements failed on the import. * chore: update model QC results [skip ci] * fix: stash untracked result files before the QC branch checkout A result file produced for the first time is untracked in the run that writes it, but is tracked at the branch tip as soon as an earlier run has committed it. Plain git stash leaves untracked files in the working tree, so the checkout that follows refused to overwrite them and the job failed after every check had already run. * chore: update model QC results [skip ci] * chore: full MEMOTE result [skip ci] * docs: add the release notes of every earlier release * chore: update model QC results [skip ci] * feat: write the release notes in the release pull request, not in a file The notes are published as the text of the GitHub release, which Zenodo archives with each version, so a copy in the repository only duplicates it. The release pull request opens with a notes placeholder, a check keeps it from merging until the notes are written, and the merged description is published as the release text. * feat: publish the release pull request's description as the release notes The release pull request opens with a notes placeholder, a check keeps it from merging until the notes are written, and the merged description is published as the release text. validate only checks the version increment. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Model quality report
Improved:
Pre-existing:
✅ unchanged · ✨ improved vs Full workflow run · this comment is edited as results come in |
…n the checks (#1124) * ci: accept the RAVEN 3 YAML format in the checks and the release - YAML lint: allow list items at their key's indentation, as writeYAMLmodel.m (RAVEN 3) and raven-toolbox write them. - structureConsistencyTest: read charges written as floats (-1.0). - increaseHumanGEMVersion build: stamp the release date, which the writer otherwise keeps from the stored model. - release: keep develop's Human-GEM.yml in the sync-back, as the build stamps the version into the release copy. * chore: write Human-GEM.yml in the RAVEN 3 YAML format Rewritten by raven-toolbox's write_yaml_model, as the release build writes it (and as v2.0.1 was released), so develop and main use one format. No model content changes: reading the file before and after gives the same metabolites, reactions, genes and compartments; only a reaction's subsystem is now a one-element list and the metaData bounds are numbers. qcModelChecks' split-compartment check accepts a subsystem written as a list. * chore: update model QC results [skip ci] * chore: update model QC results [skip ci] * ci: run the checks with raven-toolbox#164 * chore: update model QC results [skip ci]
The package now follows the model's version.
main was re-created as a new root commit on 2026-09-09 (v2.0.1 plus the release workflow) and shares no history with develop. This merge keeps the release branch's content unchanged and makes main an ancestor, so the release pull request merges into main and the sync-back merges main into develop.
ea8ebf8 to
1fda591
Compare
|
/run gene-essentiality |
|
/run memote |
|
Gene essentiality was run on this pull request via GH Actions. Gene essentiality: effect of this changeChecked 319 gene(s) directly affected plus 2368 more that share a metabolite with one of them. A gene counts as changed below only if the flip agrees in direction across at least 3 of the 5 cell-line models; fewer than that is grouped as likely noise from ftINIT's run-to-run variability instead.
Full detail: gene-essential_summary.md. ✅ unchanged · ✨ correct vs Hart 2015 · ❌ wrong vs Hart 2015 · ℹ️ not comparable to Hart 2015 The unscoped, every-gene matrix behind the table above is committed to gene-essential.csv.
|
|
🔬 Started the full MEMOTE suite on |
Short summary:
This release contains three sets of changes:
human_gemPython package withload_model(): feat: add human_gem Python package with load_model() #1069Compared with 2.0.1, 26 reactions were added and 155 removed (duplicates, unsupported or chemically incorrect reactions), 211 reactions had their stoichiometry corrected, 92 their gene-reaction rule, and 259 metabolites their formula or charge.
Longer details
Each reaction, metabolite and gene that differs between 2.0.1 and 2.1.0 is listed once, with its final change, under the last pull request that changed it; removed identifiers are kept in
data/deprecatedIdentifiers/. Changes to names and annotations (cross-references, EC numbers, references, InChI, thespontaneousflag) are not listed per entity. Metabolite merges are written as base ids ("A → B" merges A into B in every compartment where it occurred).spontaneouscolumn ofreactions.tsv)