@@ -761,7 +761,7 @@ def _build_ode_model(
761
761
args += ["value" ]
762
762
763
763
if symbol_name == SymbolId .EVENT :
764
- args += ["state_update " , "initial_value" , "priority" ]
764
+ args += ["assignments " , "initial_value" , "priority" ]
765
765
elif symbol_name == SymbolId .OBSERVABLE :
766
766
args += ["transformation" ]
767
767
elif symbol_name == SymbolId .EVENT_OBSERVABLE :
@@ -1769,13 +1769,6 @@ def _process_events(self) -> None:
1769
1769
"""Process SBML events."""
1770
1770
events = self .sbml .getListOfEvents ()
1771
1771
1772
- def get_empty_bolus_value () -> sp .Float :
1773
- """
1774
- Used in the event update vector for species that are not affected
1775
- by the event.
1776
- """
1777
- return sp .Symbol ("AMICI_EMTPY_BOLUS" )
1778
-
1779
1772
# Used to update species concentrations when an event affects a
1780
1773
# compartment.
1781
1774
concentration_species_by_compartment = {
@@ -1811,7 +1804,7 @@ def get_empty_bolus_value() -> sp.Float:
1811
1804
trigger = _parse_event_trigger (trigger_sym )
1812
1805
1813
1806
# parse the boluses / event assignments
1814
- bolus = [ get_empty_bolus_value () for _ in state_vector ]
1807
+ assignment_exprs = {}
1815
1808
event_assignments = event .getListOfEventAssignments ()
1816
1809
compartment_event_assignments : set [tuple [sp .Symbol , sp .Expr ]] = (
1817
1810
set ()
@@ -1826,8 +1819,8 @@ def get_empty_bolus_value() -> sp.Float:
1826
1819
formula = self ._sympify (event_assignment )
1827
1820
try :
1828
1821
# Try to find the species in the state vector.
1829
- index = state_vector .index (variable_sym )
1830
- bolus [ index ] = formula
1822
+ _ = state_vector .index (variable_sym )
1823
+ assignment_exprs [ variable_sym ] = formula
1831
1824
except ValueError :
1832
1825
raise SBMLException (
1833
1826
"Could not process event assignment for "
@@ -1864,30 +1857,17 @@ def get_empty_bolus_value() -> sp.Float:
1864
1857
]:
1865
1858
# If the species was not affected by an event assignment,
1866
1859
# then the old value should be updated.
1867
- if (
1868
- bolus [state_vector .index (species_sym )]
1869
- == get_empty_bolus_value ()
1870
- ):
1860
+ if species_sym not in assignment_exprs :
1871
1861
species_value = species_sym
1872
1862
# else the species was affected by an event assignment,
1873
1863
# hence the updated value should be updated further.
1874
1864
else :
1875
- species_value = bolus [ state_vector . index ( species_sym ) ]
1865
+ species_value = assignment_exprs [ species_sym ]
1876
1866
# New species value is old amount / new volume.
1877
- bolus [ state_vector . index ( species_sym ) ] = (
1867
+ assignment_exprs [ species_sym ] = (
1878
1868
species_value * compartment_sym / formula
1879
1869
)
1880
1870
1881
- # Subtract the current species value from each species with an
1882
- # update, as the bolus will be added on to the current species
1883
- # value during simulation.
1884
- for index in range (len (bolus )):
1885
- if bolus [index ] != get_empty_bolus_value ():
1886
- bolus [index ] -= state_vector [index ]
1887
- bolus [index ] = bolus [index ].subs (
1888
- get_empty_bolus_value (), sp .Float (0.0 )
1889
- )
1890
-
1891
1871
initial_value = (
1892
1872
trigger_sbml .getInitialValue ()
1893
1873
if trigger_sbml is not None
@@ -1917,7 +1897,7 @@ def get_empty_bolus_value() -> sp.Float:
1917
1897
self .symbols [SymbolId .EVENT ][event_sym ] = {
1918
1898
"name" : event_id ,
1919
1899
"value" : trigger ,
1920
- "state_update " : sp . MutableDenseMatrix ( bolus ) ,
1900
+ "assignments " : assignment_exprs ,
1921
1901
"initial_value" : initial_value ,
1922
1902
"use_values_from_trigger_time" : use_trig_val ,
1923
1903
"priority" : self ._sympify (event .getPriority ()),
@@ -1966,10 +1946,10 @@ def try_solve_t(expr: sp.Expr) -> list:
1966
1946
# if all assignments are absolute (not referring to other non-constant
1967
1947
# model entities), we are fine.
1968
1948
if all (
1969
- update . is_zero or ( update + variable ) .is_Number
1949
+ assignment .is_Number
1970
1950
for event in self .symbols [SymbolId .EVENT ].values ()
1971
- for variable , update in zip ( state_vector , event ["state_update" ] )
1972
- if not update . is_zero
1951
+ for assignment in event ["assignments" ]. values ( )
1952
+ if event [ "assignments" ] is not None
1973
1953
):
1974
1954
return
1975
1955
@@ -2796,13 +2776,16 @@ def _replace_in_all_expressions(
2796
2776
for element in self .symbols [symbol ].values ():
2797
2777
element ["value" ] = smart_subs (element ["value" ], old , new )
2798
2778
2799
- # replace in event state updates (boluses)
2779
+ # replace in event assignments
2800
2780
if self .symbols .get (SymbolId .EVENT , False ):
2801
2781
for event in self .symbols [SymbolId .EVENT ].values ():
2802
- for index in range (len (event ["state_update" ])):
2803
- event ["state_update" ][index ] = smart_subs (
2804
- event ["state_update" ][index ], old , new
2805
- )
2782
+ if event ["assignments" ] is not None :
2783
+ event ["assignments" ] = {
2784
+ smart_subs (target , old , new ): smart_subs (
2785
+ expr , old , new
2786
+ )
2787
+ for target , expr in event ["assignments" ].items ()
2788
+ }
2806
2789
2807
2790
for state in {
2808
2791
** self .symbols [SymbolId .SPECIES ],
0 commit comments