From 8271da178d915bf098767aa0c0bd7a0e814bd4f3 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 26 Feb 2024 13:44:43 +0100 Subject: [PATCH] Don't eliminate parameters that are initial assignment targets (pt1) (#2304) Currently, parameters that are targets of initial assignments don't show up as parameters or expressions in the amici model. This is rather not what most users would expect. As a first step: treat all SBML parameters that are initial assignment targets and whose initial assignment evaluates to a number as amici parameters. Related to #2150. --- python/sdist/amici/sbml_import.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/python/sdist/amici/sbml_import.py b/python/sdist/amici/sbml_import.py index 8d36ad7b81..9d6b7229c5 100644 --- a/python/sdist/amici/sbml_import.py +++ b/python/sdist/amici/sbml_import.py @@ -1051,15 +1051,23 @@ def _process_parameters( "Parameter does not exist." % parameter ) + # parameter ID => initial assignment sympy expression + par_id_to_ia = { + par.getId(): ia + for par in self.sbml.getListOfParameters() + if (ia := self._get_element_initial_assignment(par.getId())) + is not None + } + fixed_parameters = [ parameter for parameter in self.sbml.getListOfParameters() if parameter.getId() in constant_parameters ] for parameter in fixed_parameters: + ia_math = par_id_to_ia.get(parameter.getId()) if ( - self._get_element_initial_assignment(parameter.getId()) - is not None + (ia_math is not None and not ia_math.is_Number) or self.is_assignment_rule_target(parameter) or self.is_rate_rule_target(parameter) ): @@ -1074,7 +1082,10 @@ def _process_parameters( parameter for parameter in self.sbml.getListOfParameters() if parameter.getId() not in constant_parameters - and self._get_element_initial_assignment(parameter.getId()) is None + and ( + (ia_math := par_id_to_ia.get(parameter.getId())) is None + or ia_math.is_Number + ) and not self.is_assignment_rule_target(parameter) and parameter.getId() not in hardcode_symbols ] @@ -1091,16 +1102,16 @@ def _process_parameters( for par in settings["var"]: self.symbols[partype][_get_identifier_symbol(par)] = { "name": par.getName() if par.isSetName() else par.getId(), - "value": sp.Float(par.getValue()), + "value": par_id_to_ia.get( + par.getId(), sp.Float(par.getValue()) + ), } # Parameters that need to be turned into expressions # so far, this concerns parameters with initial assignments containing rateOf(.) # (those have been skipped above) for par in self.sbml.getListOfParameters(): - if ( - ia := self._get_element_initial_assignment(par.getId()) - ) is not None and ia.find( + if (ia := par_id_to_ia.get(par.getId())) is not None and ia.find( sp.core.function.UndefinedFunction("rateOf") ): self.symbols[SymbolId.EXPRESSION][ @@ -1877,7 +1888,10 @@ def _process_initial_assignments(self): for ia in self.sbml.getListOfInitialAssignments(): identifier = _get_identifier_symbol(ia) if identifier in itt.chain( - self.symbols[SymbolId.SPECIES], self.compartments + self.symbols[SymbolId.SPECIES], + self.compartments, + self.symbols[SymbolId.PARAMETER], + self.symbols[SymbolId.FIXED_PARAMETER], ): continue