diff --git a/python/sdist/amici/petab/sbml_import.py b/python/sdist/amici/petab/sbml_import.py index 6388d6f8b0..e349683505 100644 --- a/python/sdist/amici/petab/sbml_import.py +++ b/python/sdist/amici/petab/sbml_import.py @@ -518,14 +518,26 @@ def _get_fixed_parameters_sbml( petab_problem, non_estimated_parameters_as_constants ) - # exclude targets of rules or initial assignments + # exclude targets of rules or initial assignments that are not numbers sbml_model = petab_problem.model.sbml_model + parser_settings = libsbml.L3ParserSettings() + parser_settings.setModel(sbml_model) + parser_settings.setParseUnits(libsbml.L3P_NO_UNITS) + for fixed_parameter in fixed_parameters.copy(): # check global parameters - if sbml_model.getInitialAssignmentBySymbol( - fixed_parameter - ) or sbml_model.getRuleByVariable(fixed_parameter): + if sbml_model.getRuleByVariable(fixed_parameter): fixed_parameters.remove(fixed_parameter) + continue + if ia := sbml_model.getInitialAssignmentBySymbol(fixed_parameter): + sym_math = sp.sympify( + libsbml.formulaToL3StringWithSettings( + ia.getMath(), parser_settings + ) + ) + if not sym_math.is_Number: + fixed_parameters.remove(fixed_parameter) + continue return list(sorted(fixed_parameters)) diff --git a/python/sdist/amici/sbml_import.py b/python/sdist/amici/sbml_import.py index 55d6dad903..8f7f67b02f 100644 --- a/python/sdist/amici/sbml_import.py +++ b/python/sdist/amici/sbml_import.py @@ -187,18 +187,11 @@ def __init__( self._reset_symbols() - # http://sbml.org/Software/libSBML/5.18.0/docs/python-api/classlibsbml_1_1_l3_parser_settings.html#abcfedd34efd3cae2081ba8f42ea43f52 + # https://sbml.org/software/libsbml/5.18.0/docs/formatted/python-api/classlibsbml_1_1_l3_parser_settings.html#ab30d7ed52ca24cbb842d0a7fed7f4bfd # all defaults except disable unit parsing - self.sbml_parser_settings = sbml.L3ParserSettings( - self.sbml, - sbml.L3P_PARSE_LOG_AS_LOG10, - sbml.L3P_EXPAND_UNARY_MINUS, - sbml.L3P_NO_UNITS, - sbml.L3P_AVOGADRO_IS_CSYMBOL, - sbml.L3P_COMPARE_BUILTINS_CASE_INSENSITIVE, - None, - sbml.L3P_MODULO_IS_PIECEWISE, - ) + self.sbml_parser_settings = sbml.L3ParserSettings() + self.sbml_parser_settings.setModel(self.sbml) + self.sbml_parser_settings.setParseUnits(sbml.L3P_NO_UNITS) self._discard_annotations: bool = discard_annotations diff --git a/python/sdist/setup.cfg b/python/sdist/setup.cfg index 0d27a0918e..d34d42f98f 100644 --- a/python/sdist/setup.cfg +++ b/python/sdist/setup.cfg @@ -47,7 +47,7 @@ zip_safe = False # Don't include any URLs here - they are not supported by PyPI: # HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/ # Invalid value for requires_dist. Error: Can't have direct dependency: ... -petab = petab>=0.2.1 +petab = petab>=0.2.9 pysb = pysb>=1.13.1 test = benchmark_models_petab @ git+https://github.com/Benchmarking-Initiative/Benchmark-Models-PEtab.git@master#subdirectory=src/python diff --git a/python/tests/test_petab_import.py b/python/tests/test_petab_import.py index 7a476f272d..fca319e11f 100644 --- a/python/tests/test_petab_import.py +++ b/python/tests/test_petab_import.py @@ -36,8 +36,30 @@ def simple_sbml_model(): return document, model +@pytest.fixture() +def get_fixed_parameters_model(): + """Create test SBML model for test_get_fixed_parameters""" + ant_model = """ + p1 = 1 + p2 = 2 + p3 = 3 + p4 = 4 + p5 = 5 + p6 = 3^2 + p7 = p6 + p8 = 8 + p8' = 1 + p9 := p8 + """ + from amici.antimony_import import antimony2sbml + + sbml_str = antimony2sbml(ant_model) + sbml_doc = libsbml.SBMLReader().readSBMLFromString(sbml_str) + return sbml_doc, sbml_doc.getModel() + + @skip_on_valgrind -def test_get_fixed_parameters(simple_sbml_model): +def test_get_fixed_parameters(get_fixed_parameters_model): """Check for correct identification of fixed parameters: p1: fixed (via condition table) @@ -45,13 +67,18 @@ def test_get_fixed_parameters(simple_sbml_model): p3: fixed (via parameter table `estimate=0`) p4: not fixed (via parameter table `estimate=1`) p5: fixed (implicitly, because not listed as estimated) + p6: fixed (implicitly, because not listed as estimated + initial assignment is a number) + p7: not fixed (initial assignment is not a number) + p8: not fixed (rate rule target) + p9: not fixed (assignment rule target) """ from amici.petab.sbml_import import ( _get_fixed_parameters_sbml as get_fixed_parameters, ) from petab.models.sbml_model import SbmlModel - sbml_doc, sbml_model = simple_sbml_model + sbml_doc, sbml_model = get_fixed_parameters_model condition_df = petab.get_condition_df( pd.DataFrame( { @@ -77,13 +104,14 @@ def test_get_fixed_parameters(simple_sbml_model): "p1", "p3", "p5", + "p6", } assert set( get_fixed_parameters( petab_problem, non_estimated_parameters_as_constants=False ) - ) == {"p1", "p5"} + ) == {"p1", "p5", "p6"} @skip_on_valgrind