Skip to content

Releases: CompMetEng/raven-toolbox

raven-toolbox 3.0.0b1

raven-toolbox 3.0.0b1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 08 Sep 06:39

First beta toward 3.0, matching the upcoming MATLAB RAVEN 3.0 beta.

  • keep ftinit() as the only extraction pipeline.
  • analysis.compare_fluxes replaces follow_changed — a compareFluxes port, following RAVEN
    dropping followChanged/followFluxes/mapCompartments.
  • comparison.compare_models gained EC-code / metabolite-name / equation overlap matrices,
    folded from compareRxnsGenesMetsComps.
  • New: curation.rename_model_genes, ported from renameModelGenes.
  • New: curation.get_gene_data, download_genome_data, process_protein_fasta_file — the
    genome-data cluster.
  • New: manipulation.replace_metabolite, ported from replaceMets.
  • New: gapfilling.find_leak_metabolite, ported from findLeakMetabolite.
  • New: manipulation.remove_bad_reactions, ported from removeBadRxns.
  • New: gapfilling.gap_report, ported from gapReport.
  • New: analysis.trace_flux_path, ported from traceFluxPath.
  • New: analysis.get_flux_z / analyze_sampling, ported from getFluxZ/analyzeSampling.
  • New: analysis.fit_parameters, ported from fitParameters.
  • New: utils.guess_composition, ported from guessComposition.
  • New: analysis.walk_fluxes / FluxWalker, ported from walkFluxes.
  • New: analysis.get_min_nr_fluxes, ported from getMinNrFluxes.
  • New: utils.generate_new_ids, ported from generateNewIds.
  • init.ftinit implements the metabolomics production-bonus (metabolomics=, prod_weight=).
  • init.ftinit reproducibility parameters renamed: strict_gap/canonical are now
    prove_abs_gap/resolve_ties, with corrected determinism numbers.
  • ftINIT task gap-filling now edits the reference model in place instead of copying it — ~23%
    faster on a genome-scale extraction.
  • Fixed three ftINIT/task-essential bugs: a task-essential boundary default, a checkpoint
    file-handle leak, and a non-finite tie-break objective.
  • manipulation.close_model boundary-reaction detection is now structural, matching RAVEN.
  • manipulation.convert_to_irreversible now splits exchange reactions too, carries a negative
    objective coefficient onto the reverse reaction, and gained an optional rxns restriction.
  • conditions.apply_condition raises on unknown charge during charge balancing instead of
    silently miscalculating.
  • annotation.load_delta_g_csv now always records CSV values literally, matching deltaGCSV.
  • manipulation.remove_dead_end_reactions dead-end detection is now bounds-blind, matching RAVEN.
  • analysis.get_min_nr_fluxes no longer crashes with GurobiError reading fluxes from an
    infeasible solve.
  • analysis.fseof gained an explicit min_target scan-floor override.
  • Fixed six redundant-calculation hot spots: merge_linear, batched add_reactions callers,
    analyse_topology, trace_flux_path, remove_dead_end_reactions, find_task_essential_reactions.
  • random_sampling and fill_gaps_fast_lp parallelized with ProcessPool.
  • io.write_yaml_model fixed: an infinite/NaN bound wrote as a bare word instead of the YAML
    token; sort_ids=True dropped the !!omap tag on compartments; unknown metaData fields
    are now preserved on write; empty gene_reaction_rule is now dropped. read_yaml_model treats
    a null genes/reactions/metabolites key as empty.
  • Parameter defaults measured and unified: BLAST/DIAMOND/HMMER threading, homology
    min_align_len/evalue, get_init_model.allow_excretion.
  • Removed io.export_model_to_sif — a mislabeled port of a MATLAB function that never existed.

raven-toolbox 0.4.0

Choose a tag to compare

@github-actions github-actions released this 28 Aug 20:42
57d0c42

A raven-gecko-parity cross-validation harness went live this release and immediately paid for itself:
six behavioural divergences from MATLAB RAVEN closed (task checking, condition application, duplicate-
reaction contraction, Excel export, ΔG loading, reaction creation), the YAML writer brought to byte-parity
with writeYAMLmodel.m, and BLAST/homology defaults matched to RAVEN's own. Also: deterministic
compartment placement, confidence-score interoperability (Thiele-Palsson, ECO), a new set_exchange_bounds
port, and merge_compartments promoted to public API and fixed.

  • convert_to_irreversible now carries the reaction's annotations, subsystem and notes onto the
    _REV reaction.
    MATLAB's convertToIrrev copies the per-reaction fields (eccodes, rxnMiriams,
    subSystems, rxnNotes, ...) across when it splits a reversible reaction; the Python port copied only
    the name and the gene rule. Downstream that silently cost the reverse reaction its EC code — in geckopy,
    fill_eccodes_from_gem returned '' for every _REV reaction, fuzzy BRENDA matching then found no
    kcat, and the reverse direction ended up unconstrained.

  • Opt-in deterministic ftINIT extraction: ftinit(..., strict_gap=True, canonical=True). The extraction
    MILP is highly degenerate — many reaction subsets reach the same score optimum — so Threads=1 + a fixed
    Seed make the solver's choice reproducible but not unique: a different Gurobi version or platform
    lands on a different optimum. Two new keyword flags, both default off so existing behaviour is
    unchanged, pin it instead. strict_gap proves each step to a fixed absolute gap (0.05, below the 0.1
    reaction-score granularity) in a single solve, replacing RAVEN's relative-gap escalation, whose final
    near-zero-objective run otherwise accepts an arbitrary within-gap incumbent. canonical adds a
    lexicographic phase 2 over the removable reactions — hold the score objective at its optimum, minimise the
    count of kept reactions, then their summed id rank — selecting the sparsest, lowest-id optimum instead of a
    solver tie-break; it applies to both each extraction step and the task gap-fill (fill_tasks(..., canonical=True)). A solve that ends at the time limit with no incumbent now raises a clear error (or, for
    the canonical phase, falls back to the primary optimum) rather than an opaque AttributeError on a null
    primal. These are a reproducibility/parsimony tool, not an accuracy or a gene-essentiality fix: on
    Human-GEM/DLD1 they cut the reaction-level seed-swing 125 → 34 but worsened essential-gene determinism
    (5 → 19 flips) at a 3–7× build-time cost, because the sparser model is more sensitive to the residual
    transport degeneracy. For reproducible essentiality, pin the solver stack instead. Measurements and the
    full trade-off: docs/studies/ftinit_determinism.md.

  • assign_compartments gap-fill: a reliable flux-based fill instead of cobra's MILP. The
    universal-DB gap-fill in localization.certify no longer calls cobra.flux_analysis.gapfill, whose
    indicator MILP, at genome scale, fails to find a valid fill in the majority of cases even when the
    exact reaction that restores growth is present in the universal
    (it returns an incumbent its own
    validation rejects, and raises rather than offering a fill). The replacement adds the candidates on a
    working copy, holds biomass at the floor, runs pFBA, and returns the flux-carrying additions — sorted,
    so the result does not depend on which co-optimal vertex the solver picked. A plain LP cannot have the
    MILP's failure mode: a returned set is a real flux solution that reaches the floor. On single-reaction
    knockout-recovery (remove an essential reaction, fill from a universal that contains it), recall is
    60/60 — the exact reaction each time — vs cobra's 45 %; on realistic incomplete drafts (12% of
    internal reactions dropped, many simultaneous gaps) it restores growth 12/12 vs cobra's 0/12. The universal must share the draft's
    metabolite namespace: candidates are matched by id, as cobra's gapfill required, and a mismatch now
    warns instead of returning [] silently. The set is flux-parsimonious (pFBA) but not guaranteed
    reaction-count-minimal; the caller re-certifies with a real FBA, so no false certificate is possible.

  • Deterministic, score-aligned reaction placement in assign_compartments. The placement master
    maximises a gene-localisation objective that never mentions the per-reaction placement variable, so
    each reaction's compartment was a free co-optimum: the pinned solver returned it reproducibly but
    arbitrarily, and reaction agreement with curated yeast-GEM was only 52.8 % (an earlier un-pinned
    build happened to land ~72 %). A lexicographic second pass now fixes the gene layout to the primary
    optimum, then places each reaction in the compartment its own enzymes are predicted to occupy — the
    summed DeepLoc score of the reaction's genes, with a small default_compartment prior so genes-free
    and score-tied reactions fall there deterministically. Yeast reaction agreement rises to 72.5 %
    (1408/1943) and now rests on the localisation evidence rather than a solver tie-break; gene agreement
    is unchanged
    (88.7 %, 716/807 — the gene layout is untouched); coherent placement fragments fewer
    metabolites, so it adds fewer transports (1001 → 967); growth and blocked-fraction are unchanged;
    the second solve is warm-started and adds ~4 s. Reproducible run-to-run (identical placement across
    independent runs).

  • diff_models compares grRules as logic, not text. The GPR check now DNF-expands each rule (via the
    existing manipulation.gpr_to_dnf), sorts the genes within each isozyme clause and sorts the clauses, so
    operand order no longer registers as a difference: a and b == b and a and a or b == b or a. The
    previous heuristic only lowercased and collapsed whitespace, so it flagged logically identical rules that
    differed only in operand order. This brings diff_models in line with MATLAB RAVEN's diffModels
    (RAVEN #686); a rule cobra cannot parse falls back to
    the old string comparison, so malformed rules are still compared rather than silently equated.

  • load_delta_g_csv defaults to stamping every matched value literally, matching deltaGCSV
    (raven-gecko-parity#16).
    An earlier change taught the loader to treat the ΔG side-car tables' "no
    measurement" sentinel (10000000, matching yeast-GEM's own checkrxnDirection.m) as missing rather than
    a real value, defaulting to skip it. RAVEN's deltaGCSV has no sentinel concept at all and stores
    whatever the CSV says, verbatim, so the two implementations disagreed about whether an entity had a value
    on record. The default is now literal stamping, matching RAVEN; the sentinel-skipping behaviour remains
    available by passing the keyword-only missing_value=DELTA_G_MISSING explicitly.

  • Wire the confidence facets together. confidence.annotate_confidence(model, proposal=..., scores=...)
    runs every applicable scorer in one call and returns {facet: reactions_scored} — equation and
    gene_association need only the model, localization runs only when a proposal and its scores are given
    (skipped, not failed, otherwise). curation_priority now drops a placement a curator has settled with
    mark_curated from the review queue (new include_curated=False), so a settled reaction stops
    resurfacing; include_curated=True keeps it. The no-SBO-terms warning now names its remedy,
    raven_toolbox.annotation.add_sbo_terms(model).

  • Confidence facets mapped onto the field's standard vocabulary. New thiele_palsson_score(reaction)
    derives the Thiele & Palsson 2010 reconstruction confidence score (0–4) from the gene_association
    facet's evidence basis (gpr+literature → 3, gpr → 2, no-gpr → 1); every ECO evidence id used
    (ECO:0000044, ECO:0000015, ECO:0000002) was checked against EBI's OLS. Cross-model validation on
    Human-GEM, iYali and panAsp/pAo confirmed the equation facet's bands are calibrated rather than
    yeast-GEM-fixture artefacts (two of its three bands fire on the other models too).

  • manipulation.merge_compartments / copy_to_compartment are now public API, and merge_compartments
    no longer breaks growth.
    Both functions existed in manipulation/compartments.py but were never
    imported into manipulation/__init__.py, so neither was reachable as documented despite migration.md
    listing both as ported. Exporting them also surfaced two silent defects: any reaction left with a single
    metabolite after merging was dropped — including reactions that already had one metabolite before
    merging, i.e. every exchange reaction — and the merged model's objective was never carried over, so a
    flattened model silently optimised to 0.0. Both now match RAVEN's mergeCompartments: single-metabolite
    reactions are recorded before the merge and excluded from deletion, and the objective (with its direction)
    is copied onto the rebuilt model, raising a warning rather than returning a zero-objective model if every
    objective-carrying reaction genuinely was removed.

  • Six behavioural divergences from MATLAB RAVEN closed, found by the new raven-gecko-parity
    cross-validation harness:

    • check_tasks / find_task_essential_reactions now default to RAVEN checkTasks' additive boundary
      semantics (close_boundaries=False): a task is checked by relaxing metabolite balance for its declared
      inputs/outputs, not by closing every exchange first. A task the model can already satisfy through its
      own open boundary, without naming it, now agrees with RAVEN's feasible verdict instead of reporting
      ...
Read more

raven-toolbox 0.3.0

Choose a tag to compare

@github-actions github-actions released this 16 Jul 17:56
906dc4d

Compartment localisation and per-reaction confidence tracking, new gap-filling and flux-sampling
algorithms, ftINIT parity with RAVEN, and KEGG artefact hosting moved to the dedicated raven-data
repository.

  • export_for_git can pin the MATLAB .mat variable name. New keyword-only varname, forwarded
    to save_matlab_model, so a repository that expects a specific struct name (Human-GEM expects
    humanGEM) no longer has to write the .mat itself. Default None keeps cobra's own fallback (the
    model id), so existing callers are unaffected.
  • ftINIT now matches RAVEN's model preparation, solver parameters, and gap schedule. A line-by-line
    review against RAVEN's ftINIT / prepINITModel found the formulation faithfully ported, with the
    real divergences concentrated in model simplification and solver/gap handling. prep_init_model runs
    both RAVEN simplifications in prepINITModel order and broadens the exchange mask to RAVEN
    getExchangeRxns' one-sided rule (any reaction with no products or no substrates) — previously only
    the topological dead-end pass ran, leaving a ~10 % larger model. ftinit adopts RAVEN optimizeProb
    solver parameters (Threads=1 for a deterministic MILP incumbent, Presolve=2, 1e-9 feasibility /
    optimality / integrality tolerances), nudges tiny reaction scores off zero, forces permanent essential
    reactions at min(0.99*|carried flux|, force_on) while tracking carried flux across steps, and
    escalates the MIP gap per step (RAVEN MILPParams / AbsMIPGaps). New manipulation.simplify_model
    mirrors RAVEN's simplifyModel boolean-flag interface, adding remove_zero_interval_reactions
    (deleteZeroInterval) and remove_no_flux_reactions (FVA-blocked removal, deleteMinMax).
    Task-essential discovery follows RAVEN checkTasks, and task gap-fill follows ftINITFillGaps. On
    Human-GEM / DLD1 the prep model now matches RAVEN's sizes (ref_model 10240 against RAVEN's ~10198;
    merged min_model 6959 against ~6917 — previously 11532 / 8252). allow_excretion deliberately keeps
    S*v >= 0, matching the flag's name and classic INIT rather than RAVEN's csense 'L'; it is unused in
    the default '1+1' schedule and documented inline.
  • Structural confidence facets: equation and gene_association. confidence gains
    score_equation_confidence (mass & charge balance, formula completeness) and
    score_gene_association_confidence (GPR presence + literature corroboration), plus the public
    equation_exempt / gene_association_exempt predicates and facet_summary. Two rules govern every
    score, both forced by overall = min(facets): a facet that does not apply to a reaction is not
    written at all
    (an exchange reaction is imbalanced by construction, so writing 1.0 would make 469
    never-checked yeast-GEM reactions indistinguishable from the 3617 verified ones), and 0.0 always means
    evidence contradicts the model — never evidence is missing, which keeps overall == 0.0 a usable
    filter. Exemptions are SBO-driven, never name-driven: a \bgrowth\b regex would silence the chemistry
    check on "non-growth associated maintenance reaction". Validated on yeast-GEM, where the gene rubric
    recovers the model's own curator-assigned Confidence Level (99.9% / 91.5% / 95.3% per band) without
    ever reading it. mark_curated now takes a facet, and clear_confidence is exported
    (design).
  • Fix get_elemental_balance crashing on an unparseable formula. A parenthesised polymer such as
    (C5H8)n (glycogen, starch) makes cobra's Metabolite.elements return None, which
    check_mass_balance() turns into a ValueError — so the shipped helper raised part-way through a model
    instead of reporting it. A present-but-uninterpretable formula is now unknown, which is what the
    function's own contract already promised.
  • Fix score_localization_confidence vetoing reactions it could not measure. A reaction whose genes are
    absent from the score table was written 0.0/connectivity, which under overall = min(facets) vetoed
    the whole reaction on the strength of a missing input rather than of evidence. It now abstains; a gene
    that is scored but scores zero at the assigned compartment still earns a real 0.0.
  • Fix gap-fill materialisation landing on the wrong compartment metabolite.
    apply_assignment's _add_universal_reaction matched a universal candidate's metabolite ids
    verbatim against the target model instead of resolving them through the same base-id/compartment
    lookup _move_reaction already uses for relocated reactions. Wherever a draft's non-default-
    compartment species only exist because a relocated reaction created them (any id scheme other
    than the universal database's own), the gap-fill reaction silently materialised as a disconnected
    island: the assignment's own solved objective already accounted for the correct shared node, only
    the applied model was wrong. Fixed with a regression test
    (test_gapfill_reuses_relocated_compartment_metabolite).
  • Evidence-aware transport scoring (first increment). New localization.transport_evidence turns
    per-gene transporter evidence into the per-metabolite transport_cost mapping the assignment MILPs
    already accept, so a transport is cheap when a transporter gene supports it (right substrate, right
    membrane) and pays the full prior otherwise: evidence_aware_transport_cost
    (cost = base·(1−evidence)), annotate_transporters (bring-your-own annotation table), and
    TransporterAnnotation. Carrier-general and organism-agnostic; the hmmsearch (Pfam) / diamond
    (TCDB) annotation back-ends are the next increment
    (plan).
  • Consolidated assign_compartments into raven-toolbox. The functionality-constrained
    compartment-assignment MILP — biomass/growth floor + flux gating + optional gap-fill + sound
    reaction-level multi-localisation — moves from the standalone edkerk/assignCompartments repo into
    localization/ (as assign_compartments/apply_assignment/AssignmentProposal), coexisting with
    the score-driven predict_localization (design). The
    MATLAB port is tracked in MATLAB back-ports.
  • CarveFungi assignment head-to-head on its own MILP. Ran CarveFungi's own minmax_reduction
    carve-MILP (CPLEX, unmodified) with our transport-minimising term swapped into its objective, on its
    real universal-DB candidate set + DeepLoc-injected scores
    (study, scripts/run_carvefungi_cplex.py;
    scripts/benchmark_carvefungi_milp.py is a Gurobi re-implementation for the formulation study).
    Adversarially verified (which caught and fixed a compartment-id parsing bug). Findings: adding our
    transport cost yields ~1.6× fewer inter-compartment transports per reaction (41% fewer) at no
    detectable assignment-accuracy cost (86.0% vs 85.5% recall; 93% identical placements). The carve's
    MILP formulation is hard — neither CPLEX nor a tighter Gurobi port proves optimality — so these are
    deterministic, time-budget-stable near-optimal incumbents, reported with their gaps. Also surfaced
    that CarveFungi's shipped yeast localisation file is inert (RefSeq vs ORF id mismatch).
  • Head-to-head vs RAVEN predictLocalization + CarveFungi positioning. Benchmarked the
    deterministic compartment-assignment MILP against RAVEN's stochastic predictLocalization on
    identical yeast-GEM + DeepLoc inputs (study,
    scripts/compare_predictlocalization.py + scripts/run_predictlocalization.m): on the common gene
    set the MILP is ~7 pp more accurate (83.9% vs 76.8%), deterministic (vs 35% of genes flipping
    between SA runs), and faster (90 s vs a multi-minute budget). Also a source-level
    analysis of CarveFungi, the contemporary
    carve-a-universal-model method, showing how our transport-minimising assignment differs.
  • Curation triage for localisation. Added triage_localization — an optional companion to
    compartment assignment that ranks the genes/reactions whose localisation is shakiest (low DeepLoc
    confidence, borderline top-two margin, multi-source disagreement, no evidence, low-trust
    compartment, multi-localised), each with a plain-English reason, so a curator knows where to look.
    Returns a ReviewReport. load_deeploc gained keep_raw_confidence=True and LocalizationScores
    a raw_confidence field (per-gene normalisation otherwise discards the confidence the triage needs).
  • Finetuned localisation hyperparameters on the slow yeast run. Refreshed the triage
    DEEPLOC_COMPARTMENT_TRUST table from the slow (ProtT5) data (mitochondrion 0.67 → 0.86, mm now
    trustworthy via the validated split, Golgi 0.23 → 0.01) and re-validated the min_confidence gate
    (0.7 → 88.3% corroboration, 80% kept) and membrane_threshold (0.50 is inside the optimal plateau)
    in a new finetuning study
    (scripts/finetune_localization_yeast.py).
  • Cross-species DeepLoc benchmark. Generalised the predictor benchmark to any curated model
    (scripts/benchmark_deeploc.py --species {yeast,aracore,icre1355}, a per-species compartment
    config) and added independent non-yeast eukaryotes. DeepLoc 2.1 generalises across kingdoms — the
    chloroplast is recovered in both Arabidopsis
    (AraCore, 80.3% overall, plastid 89.9%) and the
    green alga Chlamydomonas (iCre1355, plastid 78%,
    though algal cytosol/mito are poor on an auto-generated model). A gene-level
    Human-GEM control
    (`scripts/benchmark_deepl...
Read more

v0.2.0

v0.2.0 Pre-release
Pre-release

Choose a tag to compare

@edkerk edkerk released this 14 Jun 19:43

0.2.0 — 2026-06-14

Project rename plus KEGG-reconstruction and CI improvements.

  • Project renamed raven-python → raven-toolbox. The import package is now
    raven_toolbox (was raven_python) and the repository moved to
    SysBioChalmers/raven-toolbox. Update imports and any raven-python git/URL
    references accordingly. (#34)
  • De-novo KEGG query uses hmmsearch instead of hmmscan.
    get_kegg_model_from_sequences now runs one hmmsearch over the concatenated KO
    library (-Z set to the profile count, so E-values and KO assignments are identical
    to the previous hmmscan path) — the faster, more parallel search direction.
    ensure_kegg_hmm_library no longer runs hmmpress (just gunzips); the published
    .hmm.gz artefact is unchanged. (#32)
  • Domain-mode get_kegg_model_for_organism_from_artefacts auto-resolves the
    taxonomy artefact
    from the artefact directory, so "prokaryotes" /
    "eukaryotes" no longer require an explicit taxonomy= path. (#31)
  • Test data no longer ships real KEGG records. The on-disk
    tests/data/kegg_dump is replaced by a session fixture that generates a fully
    fictional KEGG-format dump at runtime, so no KEGG-derived data is redistributed. (#33)
  • Removed the visualization stub and the [visualization] extra — an
    unimplemented placeholder. (#30)
  • CI on Node 24 — actions/checkout@v5, actions/setup-python@v6. (#35)

raven-python 0.1.0a1 — first alpha

Pre-release

Choose a tag to compare

@edkerk edkerk released this 30 May 21:07
587ab4d

First alpha release of raven-python — the Python counterpart of the RAVEN Toolbox 2, built on cobrapy. Released under the MIT license.

⚠️ Alpha software: APIs may change before 0.1.0.

What's included

  • De-novo reconstruction — KEGG and protein homology (BLAST / DIAMOND).
  • Context-specific modeling — tINIT / ftINIT, with task-aware gap-filling and the linear-merge MILP reduction.
  • Metabolic-task validation, connectivity gap-filling, HPA omics ingestion.
  • Sub-cellular localisation (MILP), N-model comparison, reporter metabolites, FSEOF, flux sampling.
  • I/O — cobra-standard YAML (+ GECKO ec-* fields), SIF, RAVEN-style Excel export.

Validated against MATLAB RAVEN on Human-GEM (5 Hart2015 cell lines, Jaccard 0.975–0.980).

Not yet implemented

  • Visualization (plotting/)
  • Metabolomics-based scoring in tINIT / ftINIT
  • Published binary release ZIPs (BLAST / DIAMOND / HMMER)
  • Published KEGG data-artefact releases

MetaCyc-based reconstruction and dynamic FBA are intentionally out of scope.

Install

pip install "git+https://github.com/SysBioChalmers/raven-python.git@v0.1.0a1"

Requires Python ≥ 3.11. Genome-scale (f)tINIT currently needs Gurobi; smaller work runs on GLPK.

See the README and docs/ for details.

raven-python 0.1.0

raven-python 0.1.0 Pre-release
Pre-release

Choose a tag to compare

@edkerk edkerk released this 10 Jun 22:06
587ab4d

First published KEGG artefacts (kegg116).

Now available through https://github.com/SysBioChalmers/raven-data