Skip to content

Commit

Permalink
Support event-assignments to compartments that aren't rate rule targe…
Browse files Browse the repository at this point in the history
…ts (#2425)

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 <[email protected]>
  • Loading branch information
dweindl and FFroehlich authored May 7, 2024
1 parent 0464b83 commit 41d19bb
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
2 changes: 1 addition & 1 deletion documentation/python_interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/sbmlteam/sbml-test-suite/>`_
(`current status <https://github.com/AMICI-dev/AMICI/actions>`_).
Expand Down
37 changes: 34 additions & 3 deletions python/sdist/amici/sbml_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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."""
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 41d19bb

Please sign in to comment.