diff --git a/python/sdist/amici/sbml_import.py b/python/sdist/amici/sbml_import.py index a26c6e7d4a..8891055c1c 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."""