Skip to content

PEtab export reads SBML initial values from the wrong place when an initial assignment sets them #795

Description

@wshlavacek

SBML lets a model set a parameter's initial value in two places: the value
attribute on the parameter element, and an initialAssignment. When both are
present the initial assignment wins, and the value attribute is often left as a
placeholder. The same is true for a species, where the placeholder is the
initialAmount or initialConcentration attribute.

PyBNF's SBML reader, pybnf/petab/_sbml.py, only ever reads the attributes. It
has no branch for listOfInitialAssignments. So when a model uses an initial
assignment, the reader reports a number the model does not actually start from,
and says nothing about it.

That number is used. pybnf/petab/export.py:1421 (_numeric_nominal) hands it to
pybnf/petab/conditions.py:183-195, which turns a relative condition, such as
multiply this parameter by two, into an absolute number written to
conditions.tsv. The exported problem then carries a wrong number with no
diagnostic.

Repro. Write this file as m.xml:

<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
  <model id="m">
    <listOfCompartments><compartment id="c" size="1" constant="true"/></listOfCompartments>
    <listOfParameters>
      <parameter id="koff" value="1" constant="true"/>
      <parameter id="Kd" value="2" constant="true"/>
      <parameter id="kon" value="0" constant="true"/>
    </listOfParameters>
    <listOfInitialAssignments>
      <initialAssignment symbol="kon">
        <math xmlns="http://www.w3.org/1998/Math/MathML">
          <apply><divide/><ci>koff</ci><ci>Kd</ci></apply>
        </math>
      </initialAssignment>
    </listOfInitialAssignments>
  </model>
</sbml>

Then run:

from pathlib import Path
from pybnf.petab.export import _read_model, _numeric_nominal
from pybnf.petab.conditions import mutation_target_value
v = _read_model(Path('m.xml').read_text(), Path('m.xml'), 'sbml')
print(_numeric_nominal(v, 'kon'))
print(mutation_target_value('*', 2, nominal=_numeric_nominal(v, 'kon')))

It prints 0.0 and then 0. The model's effective kon is koff/Kd, which is 0.5,
so doubling it should export 1.0.

BioNetGen models are not affected, and only by accident. A BioNetGen expression
is read as a string, so float() on it raises and the relative condition is
refused at conditions.py:183-188 rather than computed from a wrong number.

How much this bites is not yet known, which is why this is an issue rather than
a change folded into other work. Two SBML models in the repository contain
initial assignments: tests/petab_fixtures/boehm_v2, where STAT5A and STAT5B
carry initialConcentration="1" while the initial assignments set them from
207.6*ratio, and tests/full_tests/T2-ade-abcd, which assigns species A. Neither
is currently the target of a relative condition, so no committed artifact is
wrong today. Someone needs to work out how far this reaches, including the
species path, before choosing between the two plausible fixes: read
listOfInitialAssignments and evaluate an assignment when it refers to nothing
else, or refuse the relative condition with a clear error, which is what the
BioNetGen path already does in effect.

For context, the petab library is making the same call for BioNetGen models in
PEtab-dev/libpetab-python#517: a value the model file alone cannot settle is not
reported at all, because a PEtab parameter table may override or estimate what
it depends on. Our SBML reader should end up following the same rule.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions