Skip to content

Fix SBML import constant-folding parameters out of initial conditions - #3216

Open
FFroehlich wants to merge 3 commits into
mainfrom
claude/amici-issue-3214-733y22
Open

Fix SBML import constant-folding parameters out of initial conditions#3216
FFroehlich wants to merge 3 commits into
mainfrom
claude/amici-issue-3214-733y22

Conversation

@FFroehlich

Copy link
Copy Markdown
Member

Summary

Fixed a bug in SBML import where parameters with initialAssignment elements were being constant-folded out of initial conditions, causing their sensitivities to be silently reported as zero even though they remained in the free-parameter list.

Key Changes

  • Modified _make_initial() in sbml/__init__.py: Added logic to skip substitution of initial assignments for parameters that AMICI keeps as symbolic quantities (free/fixed parameters or expressions). This prevents constant-folding of parameter dependencies into initial conditions.

    • Checks if a variable is a parameter that should remain symbolic rather than being folded
    • Handles both direct parameters and those reached through chains of initial assignments
    • Excludes parameters that become states (rate-rule targets or converted to species)
  • Added regression tests in test_sbml_import.py:

    • test_initial_assignment_parameter_not_constant_folded(): Tests the case where a parameter with a compound-expression initial assignment (e.g., X0 = 6 * 1) defines a species' initial condition
    • test_chained_initial_assignment_parameter_not_constant_folded(): Tests the transitive case where a parameter's initial assignment references another parameter with its own initial assignment

Implementation Details

The fix recognizes that during parameter classification in _process_parameters, certain parameters are intentionally kept as symbolic quantities rather than being folded to numeric values. When processing initial conditions, the code now skips substituting initial assignments for such parameters, preserving the symbolic dependence chain. This ensures that sensitivity analysis correctly reports non-zero derivatives with respect to these parameters.

The solution handles both direct cases (a parameter with a numeric initial assignment) and transitive cases (chains of parameter initial assignments), addressing issue #3214.

https://claude.ai/code/session_012xf5RqvErY7po9N9DNfpKQ

claude added 2 commits July 28, 2026 18:17
…#3214)

A parameter that both carries an initialAssignment with a numeric
right-hand side and defines a species' initial value was constant-folded
out of x0 by `_make_initial`: the parameter's initial-assignment value was
substituted in, dropping the symbolic dependence. The parameter remained
in the free-parameter list, so its initial-condition sensitivity was
silently reported as zero (e.g. `init_STAT` in `jakstat_adjoint`).

`_make_initial` now leaves symbols that AMICI keeps as free or fixed
parameters untouched, since their value has already been captured as the
parameter's nominal value in `_process_parameters`. This matches the
existing design, where x0 is expected to be expressed in terms of free
and fixed parameters (and time).

Add a regression test covering the minimal reproducer from the issue.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xf5RqvErY7po9N9DNfpKQ
Extend the `_make_initial` guard so a parameter reached only through a
chain of parameter initial assignments is not constant-folded either.
`par_id_to_ia` in `_process_parameters` calls `_make_initial` before the
free/fixed-parameter dicts are populated, so the guard now also recognizes
a parameter directly from the SBML model (excluding parameters that become
states). A parameter whose numeric value derives from another free
parameter is now classified as an expression rather than an independent,
constant-folded free parameter, keeping the initial-condition sensitivity.

Also assert that the regression test's premise holds (the parameter really
carries an initial assignment), guarding against a silent false negative if
antimony/libSBML ever folds the compound right-hand side to a plain value,
and add a regression test for the chained-parameter variant.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xf5RqvErY7po9N9DNfpKQ
@FFroehlich
FFroehlich requested a review from a team as a code owner July 28, 2026 19:15
Copilot AI review requested due to automatic review settings July 28, 2026 19:15
Cover the FIXED_PARAMETER branch of the initial-condition guard: a
constant parameter that both carries a numeric initialAssignment and
defines a species' initial value must keep its symbol in x0, so changing
the constant still moves the initial condition.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xf5RqvErY7po9N9DNfpKQ

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an SBML-import bug where parameters that have initialAssignment definitions could be substituted into species initial conditions (x0), causing the generated model to lose symbolic dependence on those parameters and therefore report zero initial-condition sensitivities even though the parameters remain in the free-parameter list (issue #3214).

Changes:

  • Updated _make_initial() to skip substituting initial assignments for symbols that represent parameters AMICI keeps symbolic (free/fixed parameters and parameter expressions), preventing constant-folding into x0.
  • Added two regression tests covering both the direct and chained-parameter initial-assignment cases to ensure x0 retains parameter dependence.
  • Documented the fix in the v1.0.2 (unreleased) changelog.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
python/sdist/amici/importers/sbml/init.py Prevents substituting parameter initialAssignments during initial-condition construction to preserve symbolic parameter dependence in x0.
python/tests/test_sbml_import.py Adds regression tests for direct and transitive initial-assignment parameter folding into x0.
CHANGELOG.md Notes the SBML import fix and its impact on sensitivities, referencing #3214.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.84%. Comparing base (8935e72) to head (0dbc499).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3216      +/-   ##
==========================================
- Coverage   78.46%   77.84%   -0.63%     
==========================================
  Files         317      317              
  Lines       20974    20976       +2     
  Branches     1483     1482       -1     
==========================================
- Hits        16458    16328     -130     
- Misses       4508     4640     +132     
  Partials        8        8              
Flag Coverage Δ
cpp 72.08% <100.00%> (-0.02%) ⬇️
cpp_python 36.67% <100.00%> (+<0.01%) ⬆️
petab 47.16% <100.00%> (+<0.01%) ⬆️
petab_sciml 16.21% <50.00%> (+<0.01%) ⬆️
petab_sciml_benchmarks 14.77% <50.00%> (+<0.01%) ⬆️
python 70.32% <100.00%> (+<0.01%) ⬆️
sbmlsuite-jax ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
python/sdist/amici/importers/sbml/__init__.py 82.52% <100.00%> (-11.84%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

3 participants