diff --git a/CHANGELOG.md b/CHANGELOG.md index 4491a12d..9ae718b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## 0.2 series +### 0.2.9 + +* Fixed a bug in `SbmlModel.get_free_parameter_ids_with_values` that led to + potentially wrong initial values in the parameter mapping for parameters that + are targets of `initialAssignment`s (the value from their `value` was taken + instead of the initial assignment) + by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/248 + ### 0.2.8 * Fixed pandas `FutureWarning` in `petab/visualize/lint.py` diff --git a/petab/models/sbml_model.py b/petab/models/sbml_model.py index 6e1b981c..26643abf 100644 --- a/petab/models/sbml_model.py +++ b/petab/models/sbml_model.py @@ -5,6 +5,7 @@ from typing import Iterable, Optional, Tuple import libsbml +import sympy as sp from ..sbml import ( get_sbml_model, @@ -103,10 +104,41 @@ def get_free_parameter_ids_with_values( ar.getVariable() for ar in self.sbml_model.getListOfRules() } + parser_settings = libsbml.L3ParserSettings( + self.sbml_model, + libsbml.L3P_PARSE_LOG_AS_LOG10, + libsbml.L3P_EXPAND_UNARY_MINUS, + libsbml.L3P_NO_UNITS, + libsbml.L3P_AVOGADRO_IS_CSYMBOL, + libsbml.L3P_COMPARE_BUILTINS_CASE_INSENSITIVE, + None, + libsbml.L3P_MODULO_IS_PIECEWISE, + ) + + def get_initial(p): + # return the initial assignment value if there is one, and it is a + # number; `None`, if there is a non-numeric initial assignment; + # otherwise, the parameter value + if ia := self.sbml_model.getInitialAssignmentBySymbol(p.getId()): + formula_str = libsbml.formulaToL3StringWithSettings( + ia.getMath(), parser_settings + ) + try: + return float(formula_str) + except ValueError: + sym_expr = sp.sympify(formula_str) + return ( + float(sym_expr.evalf()) + if sym_expr.evalf().is_Number + else None + ) + return p.getValue() + return ( - (p.getId(), p.getValue()) + (p.getId(), initial) for p in self.sbml_model.getListOfParameters() if p.getId() not in rule_targets + and (initial := get_initial(p)) is not None ) def get_parameter_ids(self) -> Iterable[str]: diff --git a/petab/version.py b/petab/version.py index 93848c2a..d5547869 100644 --- a/petab/version.py +++ b/petab/version.py @@ -1,2 +1,2 @@ """PEtab library version""" -__version__ = "0.2.8" +__version__ = "0.2.9" diff --git a/tests/test_visualization.py b/tests/test_visualization.py index feb02a49..cf427c80 100644 --- a/tests/test_visualization.py +++ b/tests/test_visualization.py @@ -107,7 +107,6 @@ def visu_file_Fujita_minimal(): ) -@pytest.mark.filterwarnings("ignore:Visualization table is empty") @pytest.fixture def visu_file_Fujita_empty(): return (