Skip to content

fix: gapFillTopological seed detection and zero-substrate reactions - #674

Merged
edkerk merged 1 commit into
develop3from
fix/gapfill-topological
Jul 17, 2026
Merged

fix: gapFillTopological seed detection and zero-substrate reactions#674
edkerk merged 1 commit into
develop3from
fix/gapfill-topological

Conversation

@edkerk

@edkerk edkerk commented Jul 17, 2026

Copy link
Copy Markdown
Member

Main improvements in this PR:

  • fix:
    • gapFillTopological reported reachable metabolites as blocked: seed detection missed 'in' exchanges, and zero-substrate reactions never fired.
  • documentation:
    • Reachability assertions in tGapfilling.m.

Instructions on merging this PR:

  • This PR has develop3 as target branch, and will be resolved with a squash-merge.

gapFillTopological reported every metabolite as blocked on models fed
through RAVEN's own 'in' exchanges. Two independent defects, both hitting
the same reactions:

Seed detection tested lb < 0. That is correct under cobra's convention,
where analyse_topology reads it and every exchange is written "met <=>", but
addExchangeRxns writes an 'in' exchange as "=> met" with lb = 0. The test
therefore found no uptake at all, warned as much, and seeded nothing. Ask
getExchangeRxns instead of hand-rolling the rule. 'uptake' on its own is not
enough: it means the bounds allow *only* uptake, so a reversible exchange is
classified 'reverse' despite supplying the metabolite. The union of the two
is exactly "forward flux produces it, or reverse flux does".

Zero-substrate reactions never fired. subCountFwd is 0 for them, but firing
is only ever checked while walking subOf, and a reaction with no substrates
is in no metabolite's subOf list, so the countdown could not reach it. Fire
them before the loop, as _compute_scope does. This is how "=> met" exchanges
enter the scope.

Reproduced on A -> B -> C with addExchangeRxns(m,'in',{'A'}): reachableMets
was [0 0 0] and all three metabolites came back blocked; now [1 1 1] and
none. It escapes to the public API via fillGaps(...,'algorithm','topological').

Only the forward pre-fire is ported. _compute_scope does not pre-fire in
reverse either, and it needs no equivalent here: the reactions with no
products are exactly the "met =>" exchanges, which the seed rule above
already covers.

Tests: the existing case asserted only isfield, so it stayed green while the
function was inverted. Adds three behavioural tests covering 'in' exchanges,
reversible exchanges, and a no-exchange positive control.
@github-actions

Copy link
Copy Markdown

Function test results

243 tests   221 ✅  1m 10s ⏱️
 23 suites   22 💤
  1 files      0 ❌

Results for commit 6131a83.

@edkerk
edkerk merged commit 99fa9d5 into develop3 Jul 17, 2026
4 checks passed
@edkerk
edkerk deleted the fix/gapfill-topological branch July 17, 2026 16:53
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