From 41d19bb5d9dcbafae714260d8982da69223bba0c Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Tue, 7 May 2024 13:17:49 +0200 Subject: [PATCH] Support event-assignments to compartments that aren't rate rule targets (#2425) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Event-assignments to compartments weren't supported yet, now they are. Compartments that are targets of event assignments are now processed as "species", the same way as it is already done for parameters that are targets of event assignments. Closes #2424. --------- Co-authored-by: Fabian Fröhlich --- documentation/python_interface.rst | 2 +- python/sdist/amici/sbml_import.py | 37 +++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/documentation/python_interface.rst b/documentation/python_interface.rst index a919e925c4..2926abf963 100644 --- a/documentation/python_interface.rst +++ b/documentation/python_interface.rst @@ -26,7 +26,7 @@ AMICI can import :term:`SBML` models via the Status of SBML support in Python-AMICI ++++++++++++++++++++++++++++++++++++++ -Python-AMICI currently **passes 1247 out of the 1821 (~68%) test cases** from +Python-AMICI currently **passes 1252 out of the 1821 (~68%) test cases** from the semantic `SBML Test Suite `_ (`current status `_). diff --git a/python/sdist/amici/sbml_import.py b/python/sdist/amici/sbml_import.py index 608ceeed8f..5d71821f06 100644 --- a/python/sdist/amici/sbml_import.py +++ b/python/sdist/amici/sbml_import.py @@ -561,9 +561,9 @@ def _build_ode_model( assert dxdt.shape[0] - len(self.symbols[SymbolId.SPECIES]) == len( self.symbols.get(SymbolId.ALGEBRAIC_STATE, []) ), ( - self.symbols[SymbolId.SPECIES], + self.symbols.get(SymbolId.SPECIES), dxdt, - self.symbols[SymbolId.SPECIES], + self.symbols.get(SymbolId.ALGEBRAIC_STATE), ) # correct time derivatives for compartment changes @@ -954,6 +954,7 @@ def _process_species(self) -> None: } self._convert_event_assignment_parameter_targets_to_species() + self._convert_event_assignment_compartment_targets_to_species() self._process_species_initial() self._process_rate_rules() @@ -1564,6 +1565,36 @@ def _convert_event_assignment_parameter_targets_to_species(self): "dt": sp.Float(0), } + def _convert_event_assignment_compartment_targets_to_species(self): + """Find compartments that are event assignment targets and convert + those compartments to species.""" + for event in self.sbml.getListOfEvents(): + for event_assignment in event.getListOfEventAssignments(): + if event_assignment.getMath() is None: + # Ignore event assignments with no change in value. + continue + variable = symbol_with_assumptions( + event_assignment.getVariable() + ) + if variable not in self.compartments: + continue + if variable in self.symbols[SymbolId.SPECIES]: + # Compartments with rate rules are already present as + # species + continue + + self.symbols[SymbolId.SPECIES][variable] = { + "name": str(variable), + "init": self.compartments[variable], + # 'compartment': None, # can ignore for amounts + "constant": False, + "amount": True, + # 'conversion_factor': 1.0, # can be ignored + "index": len(self.symbols[SymbolId.SPECIES]), + "dt": sp.Float(0), + } + del self.compartments[variable] + @log_execution_time("processing SBML events", logger) def _process_events(self) -> None: """Process SBML events.""" @@ -1633,7 +1664,7 @@ def get_empty_bolus_value() -> sp.Float: "Could not process event assignment for " f"{str(variable_sym)}. AMICI currently only allows " "event assignments to species; parameters; or, " - "compartments with rate rules, at the moment." + "compartments." ) try: # Try working with the formula now to detect errors