Skip to content

Feat: convert MATLAB/RAVEN CI workflows to Python#1027

Merged
edkerk merged 23 commits into
developfrom
worktree-matlab-to-python-workflows
Jul 15, 2026
Merged

Feat: convert MATLAB/RAVEN CI workflows to Python#1027
edkerk merged 23 commits into
developfrom
worktree-matlab-to-python-workflows

Conversation

@edkerk

@edkerk edkerk commented Jul 11, 2026

Copy link
Copy Markdown
Member

Main improvements in this PR:

Converts the three MATLAB/RAVEN GitHub Actions workflows to Python using the raven-toolbox, so they no longer require MATLAB or the self-hosted runner.

Workflow Before (MATLAB, self-hosted) After (Python, ubuntu-latest)
yaml-conversion testYamlConversion.m testYamlConversion.py
check-metabolictasks testMetabolicTasks.m testMetabolicTasks.py
gene-essentiality estimateEssentialGenes.m + evaluateHart2015Essentiality.m Python port (Gurobi via secret)
  • YAML round-trip — reads the model, writes it, reads and writes again, and compares the two written files; uses the bundled GLPK.
  • Metabolic taskscheck_tasks(model, tasks, close_boundaries=True) (replacing the MATLAB addBoundaryMets step), pinned to GLPK. 69 essential and 21 verification tasks pass.
  • Gene essentiality — builds cell-line-specific tINIT models from the Hart 2015 RNA-seq data, identifies task-essential genes, and compares the predictions with the Hart 2015 CRISPR fitness screen (TP/TN/FP/FN, accuracy, sensitivity, specificity, F1, MCC). Ensembl gene ids are kept through the computation and mapped to symbols only for the comparison (Incorrect evaluation workflow for essential genes in estimateEssentialGenes #970). Writes data/testResults/gene-essential.csv.
  • Adds a reevaluate-gene-essentiality workflow that regenerates the summary from the committed per-gene matrix without re-solving, plus the Python requirements files.

The MATLAB CI scripts are kept in code/test/ alongside the Python ports for now.

Action required before merge: the gene-essentiality workflow needs a full Gurobi license in the Gurobi_Eduard secret (WLS or named-user); the size-limited license bundled with pip gurobipy cannot handle a genome-scale model. The workflow writes the secret to $HOME/gurobi.lic, points GRB_LICENSE_FILE at it, and fails early with a clear message if the secret is absent.

I hereby confirm that I have:

  • Any removed reactions and metabolites have been moved to the corresponding deprecated identifier lists in data/deprecatedIdentifiers/. (No reactions or metabolites are changed in this PR.)
  • This PR has develop as target branch, and will be resolved with a squash-merge.
  • This PR has main as target branch, and will be resolved with a merge commit.

@edkerk edkerk changed the title Convert YAML-conversion and metabolic-task CI tests from MATLAB to Python Convert MATLAB/RAVEN CI workflows to Python (raven-toolbox) Jul 11, 2026
@edkerk edkerk added this to the 2.0.1 milestone Jul 11, 2026
@edkerk
edkerk changed the base branch from main to develop July 11, 2026 19:17
Converts the three MATLAB/RAVEN GitHub Actions workflows to Python using the
raven-toolbox, so they no longer need MATLAB or the self-hosted runner:

- yaml-conversion: testYamlConversion.py (read/write round-trip, GLPK).
- check-metabolictasks: testMetabolicTasks.py (check_tasks with close_boundaries).
- gene-essentiality: estimateEssentialGenes.py + taskEssentialGenes.py +
  evaluateHart2015Essentiality.py + geneEssentiality.py, building cell-line tINIT
  models from the Hart 2015 RNA-seq data and comparing predictions with the
  Hart 2015 CRISPR fitness screen (Gurobi via the Gurobi_Eduard secret).

Adds a reevaluate-gene-essentiality workflow that regenerates the summary from the
committed per-gene matrix without re-solving, and the Python requirements files.
@edkerk
edkerk force-pushed the worktree-matlab-to-python-workflows branch from 5698cf0 to 591b41a Compare July 11, 2026 19:55
@edkerk edkerk changed the title Convert MATLAB/RAVEN CI workflows to Python (raven-toolbox) Feat: convert MATLAB/RAVEN CI workflows to Python Jul 11, 2026
edkerk and others added 2 commits July 11, 2026 20:02
@SysBioChalmers SysBioChalmers deleted a comment from github-actions Bot Jul 11, 2026
@SysBioChalmers SysBioChalmers deleted a comment from github-actions Bot Jul 11, 2026
@SysBioChalmers SysBioChalmers deleted a comment from github-actions Bot Jul 11, 2026
@edkerk
edkerk force-pushed the worktree-matlab-to-python-workflows branch from 7b06a96 to aa72e00 Compare July 11, 2026 21:09
@edkerk edkerk closed this Jul 11, 2026
@edkerk edkerk reopened this Jul 11, 2026
@edkerk
edkerk force-pushed the worktree-matlab-to-python-workflows branch from aa72e00 to 8be90bd Compare July 11, 2026 21:48
Classic get_init_model kept every isozyme gene of each retained reaction, unlike
MATLAB getINITModel2 (called with removeGenes=true), so context models carried
unexpressed alternatives that masked genes essential for the expressed isozyme
and depressed the essentiality metrics. Apply remove_low_score_genes to each
context model with the tissue gene scores, keeping the highest-scoring isozyme
per OR rule.
@edkerk
edkerk force-pushed the worktree-matlab-to-python-workflows branch from 8be90bd to 888f4e8 Compare July 11, 2026 21:53
edkerk added 5 commits July 12, 2026 08:29
find_task_essential_reactions runs sequentially per task with no solver time
limit, so a single hard task can stall the step (as happens on develop's model,
6h timeout). Add diagnoseTaskEssential.py to time each task with a per-solve
cap and an overall budget, exposed via a 'diagnose' workflow_dispatch input, to
locate which task/reaction is pathological.
…EMOTE

Combines yaml-validation and yaml-conversion into one Model file checks workflow:
- Removes the "Basic MEMOTE" step (memoteTest.py) whose two checks (no duplicate
  reactions; reactions have metabolites) are a strict subset of the full MEMOTE
  suite the Model QC workflow runs, and are also covered by MACAW's duplicate_test.
  yaml-validation no longer needs the memote-docker container.
- Round-trip now runs with both cobra (no RAVEN toolbox) and raven-toolbox, so the
  committed .yml is verified canonical for both toolchains.
- Keeps the YAML lint and model/annotation-file consistency (sanityCheck) checks.
…ity comment command

- Drop the reevaluate-gene-essentiality workflow (the recompute script
  reevaluateGeneEssentiality.py is kept, e.g. for a future /reevaluate command).
- Add pr-command.yml: a collaborator-gated issue_comment dispatcher so maintainers
  can start the (hours-long) gene-essentiality run by commenting
  '/run gene-essentiality' on a pull request. Same-repo branches only; forks get a
  clear message. Structured so more commands are easy to add.
Recompute gene-essential_summary.md from the committed matrix (no solve) on the PR
branch when a maintainer comments '/reevaluate gene-essentiality'. Same-repo only.
Reconcile the CI migration with the QC consolidation (#1056) and combined QC
workflow (#1059) merged into develop meanwhile:
- gene-essentiality.yml: keep this branch's pull_request guard and updated comment
  wording, but post via github-script (develop dropped the deprecated comment-pr
  action and the commentGeneEssential.md template).
- yaml-validation.yml: accept its removal; model-file-checks.yml now does the YAML
  lint.
- model-file-checks.yml: drop the model/annotation consistency step - sanityCheck.py
  was removed on develop and its check is now in qcModelChecks.py (Model QC workflow).
- README.md: use develop's model QC / MEMOTE / MACAW result mentions.
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

Model quality report

⚠️ 6 pre-existing finding(s), no regressions vs develop. Non-blocking.

Structural checks

Duplicate keys (model unloadable) and no growth block the merge; the other rows are non-blocking.

Check Result Δ vs develop
Duplicate !!omap keys 0 0
Reactions with no metabolites 0 0
Model / annotation-table inconsistencies 0 0
Growth (biomass producible) 125 0

Model QC reports

Check Result Δ vs develop
Metabolites missing formula 0 0
Metabolites missing charge 0 0
Reaction bound / GPR issues 0 0
Exact-duplicate reaction groups 0 0
Unused metabolites 0 0
Unused genes 0 0
Malformed cross-references 0 0
Cross-refs inconsistent across compartments 3 0 ⚠️

MACAW and mass/charge balance

Check Result Δ vs develop
Reactions flagged by MACAW dead-end test 2510 0 ⚠️
Reactions flagged as MACAW duplicates 377 0 ⚠️
Mass-imbalanced reactions 87 0 ⚠️
Charge-imbalanced reactions 234 0 ⚠️
Structure vs formula/charge inconsistencies 397 0 ⚠️

Model file and metabolic tasks

Check Result
YAML round-trip (cobrapy) pass
YAML round-trip (RAVEN) pass
YAML lint pass
Essential metabolic tasks 57 passed
Verification metabolic tasks 21 passed

MEMOTE

Total score: 20.2% (core subset)   0

Section Score Δ vs base
consistency 42.4% 0
annotation_met 25.0% 0
annotation_rxn 25.0% 0
annotation_gene 0.0% 0
annotation_sbo 0.0% 0
Per-test scores
Section Test Score
Consistency Stoichiometric Consistency 100.0%
Consistency Mass Balance 0.8%
Consistency Charge Balance 2.1%
Consistency Metabolite Connectivity 0.0%
Consistency Unbounded Flux In Default Medium 100.0%
Annotation - Metabolites Presence of Metabolite Annotation 100.0%
Annotation - Metabolites Metabolite Annotations Per Database 100.0%
Annotation - Metabolites Metabolite Annotation Conformity Per Database 100.0%
Annotation - Metabolites Uniform Metabolite Identifier Namespace 0.0%
Annotation - Reactions Presence of Reaction Annotation 100.0%
Annotation - Reactions Reaction Annotations Per Database 100.0%
Annotation - Reactions Reaction Annotation Conformity Per Database 100.0%
Annotation - Reactions Uniform Reaction Identifier Namespace 0.0%
Annotation - Genes Presence of Gene Annotation 100.0%
Annotation - Genes Gene Annotations Per Database 100.0%
Annotation - Genes Gene Annotation Conformity Per Database 100.0%
Annotation - SBO Terms Metabolite General SBO Presence 100.0%
Annotation - SBO Terms Metabolite SBO:0000247 Presence 100.0%
Annotation - SBO Terms Reaction General SBO Presence 100.0%
Annotation - SBO Terms Metabolic Reaction SBO:0000176 Presence 100.0%
Annotation - SBO Terms Transport Reaction SBO:0000185 Presence 100.0%
Annotation - SBO Terms Exchange Reaction SBO:0000627 Presence 100.0%
Annotation - SBO Terms Demand Reaction SBO:0000628 Presence 100.0%
Annotation - SBO Terms Sink Reactions SBO:0000632 Presence 100.0%
Annotation - SBO Terms Gene General SBO Presence 100.0%
Annotation - SBO Terms Gene SBO:0000243 Presence 100.0%
Annotation - SBO Terms Biomass Reactions SBO:0000629 Presence 100.0%

The score above is the fast core subset. Comment /run memote to run the full suite on this pull request; the score updates here when it finishes.

Gene essentiality (Hart 2015)

Not run automatically (it takes hours). Comment /run gene-essentiality to run it on this pull request; the result posts as its own comment.

❌ = a count rose vs the target branch (regression) · ⚠️ = a pre-existing non-zero finding (non-blocking) · ⏳ = still running. Counts link to the CSV listing the exact entries.

Full workflow run · this comment is edited as results come in

edkerk and others added 6 commits July 14, 2026 07:25
Consolidate the model-file-checks and check-metabolictasks workflows into the one
Model QC workflow, reported in the single QC comment:
- add YAML round-trip (cobrapy + RAVEN), YAML lint and the metabolic tasks as steps;
  each writes a one-line pass/fail status the comment shows in a new 'Model file and
  metabolic tasks' section, and the final gate fails the build on any of them.
- combine the two metabolic-task lists: testMetabolicTasks.py now runs essential and
  verification in one job (they were a 2-way matrix of the same script, not two tests).
- delete model-file-checks.yml and check-metabolictasks.yml.

Gene essentiality (hours long) is now run on demand only: remove its pull_request
trigger, and the QC comment states it is not run with the /run command to run it.
/run gene-essentiality passes the PR number so the result still posts its own comment.
(Full MEMOTE on demand is not wired yet - noted for follow-up.)
The full MEMOTE suite (hours long) no longer runs automatically on PRs to main;
Model QC runs only the fast core subset on every pull request. Comment /run memote
to run the full suite: pr-command dispatches memote-full.yml on the PR branch with
the PR number, it runs the full suite, commits the score and updates the Model QC
comment in place (the comment now says the row is the subset and how to get the
full score). The post-qc-comment action gains an issue-number input so a
workflow_dispatch run, which has no pull-request context, can target the PR.
Pull MEMOTE out of the Model QC reports table into its own section: the total
score with its mode (core subset / full), a per-section score table with a delta
versus the target branch, and a collapsible per-test breakdown. buildReport parses
the section and detailed tables that memoteSnapshot.py already writes.
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

Gene essentiality was run on this pull request via GH Actions. Summary:

Gene essentiality vs Hart 2015 fitness genes

cellLine TP TN FP FN accuracy sensitivity specificity F1 MCC
DLD1 125 2172 124 224 0.8684 0.3582 0.946 0.4181 0.3525
GBM 111 2145 138 251 0.8529 0.3066 0.9396 0.3633 0.2897
HCT116 141 2189 130 246 0.861 0.3643 0.9439 0.4286 0.3595
HELA 114 2233 164 197 0.8667 0.3666 0.9316 0.3871 0.3132
RPE1 86 2183 162 214 0.8578 0.2867 0.9309 0.3139 0.2367
all 59 2355 159 69 0.9137 0.4609 0.9368 0.341 0.3103

The full per-gene essentiality matrix is committed to data/testResults/gene-essential.csv.

Note: in the case of multiple test runs, this post is edited.

edkerk and others added 8 commits July 15, 2026 00:25
Install raven-toolbox from fix/ftinit-raven-parity (PR #69) so the gene
essentiality workflow picks up the corrected task-essential-reaction discovery,
which now matches RAVEN's checkTasks (397 essential reactions on Human-GEM v2.0.0
instead of 259). Revert to the default branch after that PR merges.
Rewrite estimateEssentialGenes.py to reproduce the DevelopWBM Gen_ftINIT_models
Human2 pipeline instead of classic tINIT2:

- Port prepHumanModelForftINIT: remove drug reactions and amino-acid-triplet
  reactions (getAATripletReactions matches MATLAB at 735) and MAR13081, load
  spontaneous reactions from model/reactions.tsv, then run prep_init_model once
  (== prepINITModel) with ext_comp='e' and the protein/pool custom-ignore list.
- Build each cell-line model with ftinit(series='1+1', gene_scores=...,
  fill_gaps=True), i.e. ftINIT with removeGenes=true and useScoresForTasks=true,
  scoring reactions per cell line from the Hart 2015 expression.
- Essential genes still via find_task_essential_genes (== checkTasksGenes).

Raise the recursion limit for cobra's recursive deepcopy of the genome-scale
model during gap-filling.
find_task_essential_genes keyed each task's pFBA flux set by task.id, but the
metabolic task list reuses 5 ids across 57 tasks (ER/BS/SU/IC/GR), so same-id
tasks overwrote each other's flux set. The per-task filter then tested genes
against the wrong task's flux distribution and skipped genes essential for the
overwritten tasks, under-counting by ~50 (226 vs RAVEN checkTasksGenes 276 on
the same context model). Pair each task with its own flux set by position; the
count now matches RAVEN exactly (276/276 on the DLD1 model).
…table

gene-essential.csv now holds, per cell line, the confusion class of each gene's
prediction against the Hart 2015 fitness call (TP/TN/FP/FN, or P/. when Hart did
not score the gene) instead of a bare yes/no prediction, so the experimental
truth and the correctness are visible per gene. All model genes are kept as
stable rows, so a diff between runs shows only changed cells and a gene gaining
FN/FP marks a regression. The Hart-to-Ensembl symbol mapping is factored into a
shared experimental_status() helper reused by the summary evaluator.
@edkerk
edkerk merged commit 9ed8c65 into develop Jul 15, 2026
1 check passed
@edkerk
edkerk deleted the worktree-matlab-to-python-workflows branch July 15, 2026 14:15
@edkerk edkerk mentioned this pull request Jul 15, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant