simulator.executor_amici¶
The executor of AMICI runs a plan on a model of AMICI.
AMICI is the integrator (CVODES) and the root finder, the executor fires the
events of the model: the model AMICI compiles keeps the trigger of every
event and records, instead of its assignments, that the event fired in an
integration and the time of its first execution, see
sbmlsim.model.model_amici. An integration from a time runs on the model
without the assignments of its events, so its rows up to the first root of a
trigger are the ones of the model; there the executor applies the semantics
of SBML, see sbmlsim.simulator.changes.fire_events (the order of the
priorities, the persistence of the triggers, the values of the assignments at
the trigger or at the execution, the events an assignment triggers, the
events of one time one after the other), and integrates on from the state
after the events (_Course._advance), so no row of the output is past an
event without its assignments.
It has the semantics of the executor of roadrunner, see
sbmlsim.simulator.executor, so the results of the engines are comparable:
- The model is initialized with the pre-initialization values, see
AmiciSBMLModel.initialize, from the free parameters as loaded, so nothing of an earlier simulation is left. - The events whose trigger is false before the time 0
(
AmiciSBMLModel.start_events) and true in the initial state fire at the start, in the initial state before a change at the start, with the events they trigger, as in roadrunner (_Course.start_events); AMICI fires no event at the start of an integration, seesbmlsim.model.model_amici. With a presimulation they fire at its start, the time 0. - A presimulation integrates from the time 0 until the rates of change
vanish, see
steady_state. - The segments between the changes are the ones of
sbmlsim.simulator.segments.simulate_segments, with the events a change triggers fired by the executor, the stop of a segment just before a change and the events at the end. AMICI integrates in absolute time, every segment from the state the one before it ended in. - AMICI evaluates a comparison which is exactly at its threshold at the
start of an integration as written and keeps the value for the whole
integration, since CVODES reports no root at the start and the root
function does not change its sign afterwards, see
sbmlsim.model.model_amici: a comparison of a trigger as true, also a strict one, e.g.time > 1from the time 1 after a change there orX > 2after a change which setsX = 2, and does not find the crossing when the comparison becomes true. Every strict comparison of a trigger is compiled shifted by a parameter,a > b + shift, which is 0 but at the start of an integration at which the comparison is exactly at its threshold (_Course._arm): there the executor integrates the resolution of the time ahead (_Course._probe) to tell the events whose trigger is true right after the start. Such an event which did not fire at the start fires there, after the row of the start, as in roadrunner, which fires it in its first step (the steps of the integrator have it as two rows at the start); one which fired at the start, e.g.time > 10at the end of a horizon of a steady state, stays true for AMICI and does not fire again. Every other comparison at its threshold is shifted byTHRESHOLD_ULPSunits in the last place of the largest term of its operands (_Course._shift), so AMICI finds the crossing when it comes: an event which sets its own trigger back to its threshold,Y > 2byY = 2, fires again whenYrises above 2 later, as in roadrunner. A comparison of a math of the model, e.g. the condition of a piecewise in a rate,piecewise(2, time <= tend, 0), is compiled shifted as well (AmiciSBMLModel.switches); before every integration from a time at which it is exactly at its threshold, e.g. from the timetendafter an event or a change there, the executor shifts it the same way (_Course._arm_switches, for a comparison of the time by at least its change over the resolution of the time, so the explicit root of AMICI at the shifted time is after the start, alsotime > tlagwithtlag = 0at the start 0, and the comparison turns at most about the resolution late whatever its scale,time/86400 > tlag), so it keeps its value until the operands move by the shift in the direction which changes it,time <= tendfalse right aftertend, as roadrunner evaluates it at every step. An output row exactly at the threshold of such a comparison, e.g. attend, has the rates and the assignment rules evaluated with the comparison as written, the value of the SBML, as roadrunner and COPASI have it (Rate = Riattend); AMICI evaluates the expressions of the row after the root (_Course._switch_rows). - AMICI finds the root of a trigger where it crosses its threshold, so the
event is at its time; a strict trigger of the time is at its time
exactly. The events of a root within the resolution of the time of a
grid time are at the grid time, whose state the integration gave. An
output time at the root has the state before the events there unless the
trigger is true at the time, every comparison within the tolerance of
the integrator of its threshold taken at it (
_Course._visible): a comparison which is not strict is true there, a strict one false, so the output has the state afterX >= 2and beforeX > 2at the timeXreaches 2, as in roadrunner, where a strict trigger fires in the first step after the time. A root AMICI finds again at the start of the next integration within the resolution of the time, the crossing fired for, is no event: the integration starts again from it (_Course._advance). A trigger which an integration makes true within the rounding of its stop, without a root reported by AMICI, fires at the stop, where the next integration would start with the trigger true. - The output of
OutputMode.TIMESare the plan times of a segment. AMICI outputs the states at given times only, so the steps of the integrator (OutputMode.INTEGRATOR) are a substitute: a grid ofSTEPSintervals of the same length per segment, refined where the linear interpolation between two rows misses the solution at their midpoint by more than the square root of the relative tolerance of the integrator times the largest magnitude of the selection in the segment, so the rows interpolate as accurately as the steps of roadrunner, whose density CVODE chose (_Course.steps,_Course._refine:1e-5of the largest value at the default tolerances,6e-6on the HCTZ model against3e-5with the steps of roadrunner, at about twice the rows of roadrunner and one integration per round of the refinement and piece between two events, three to four times the cost of the grid alone), and every event of the model as two rows at its time, the states before and after it; the rows at the changes, at the events and at the end correspond to the ones of roadrunner. - The integration from a time runs to the end of the segment, after an
event over the distance between the last two events, doubled after every
integration without an event (
_Course._advance): the integration past the first root, which is discarded, is at most as long as the one before it, so the cost of a simulation is linear in the number of its events.
Known differences to roadrunner:
- roadrunner evaluates the triggers of the events when the model is initialized, at the time 0, also for a simulation from a negative start; AMICI evaluates them at the start.
- An event whose trigger is false before the time 0 and which a
pre-initialization makes true, e.g. a dose
dose > 0withdoseset before the initialization, fires at the start in AMICI and COPASI, as in libroadrunner afterresetAlland in the SBML Test Suite; the executor of roadrunner does not fire it (#439). - roadrunner integrates a model which does not read the time in local time, every segment from its time 0; AMICI integrates every model in absolute time.
- The steps of the integrator are the refined grid with the events, see 7.; the steps of CVODES in AMICI are not exposed.
- AMICI has one absolute tolerance for every state, a concentration species
in its concentration, see
AmiciSBMLModel.set_integrator_settings; the steps differ between the engines, the rows at the changes, at the events and at the end correspond. - The rows of an event of the model in the steps are the states before and after it at its time, the ones of roadrunner a little before and after it, at a distance which depends on the last step of CVODE.
- Simultaneous events of the same priority execute in the order of the document, roadrunner orders them at random.
- The output row at the exact time of a root of a strict trigger of the time
shows the state before the event (the trigger is false at the time, see
6.); the row of roadrunner depends on where CVODE lands its root, e.g. the
state before at
time > 0.1,time > 0.7andtime > 12and the state after attime > 1/3. - A trigger which compares for equality,
a == bora != b, raises when the model is loaded, seesbmlsim.model.model_amici. - AMICI 1.2 computes the time of a trigger of the time with a precision of
about eight digits (
time >= 1 + 1e-8triggers at 1 in AMICI, withtime >= 1): the executor fires the event when AMICI finds it, after the events of the roots before it, so its assignments see the state after them, as in roadrunner, at a time a little before the one of roadrunner. - AMICI 1.2 does not import a trigger with a negation of a comparison
(
!(X <= 3)), the model raises when it is loaded.
The absolute tolerance of AMICI is the one of roadrunner times
sbmlsim.model.model_amici.AMICI_ATOL_FACTOR, so AMICI integrates the HCTZ
model at least as accurately as roadrunner at the defaults of Simulator
(the largest relative error 1.1e-7 against 1.5e-7 of roadrunner, see the
measurement there).
The delays of events, the delay csymbol and the other features AMICI does
not simulate as roadrunner are refused when the model is loaded, see
AmiciSBMLModel.
execute
¶
Run a plan on a model of AMICI.
The contract of sbmlsim.simulator.executor.execute: the output has two
rows at the time of a change after the start, the state before the
change and the state after it, and the steps of the integrator have two
at an event of the model, see the module.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plan
|
Plan
|
the plan, compiled against the model. |
required |
model
|
AmiciSBMLModel
|
the model. |
required |
selections
|
Sequence[str]
|
the columns of the result, |
required |
Returns:
| Type | Description |
|---|---|
TimecourseResult
|
The result, with the time shifted by |
Raises:
| Type | Description |
|---|---|
SteadyStateError
|
if the presimulation does not reach a steady state. |
RuntimeError
|
if AMICI fails to integrate, with its message. |
NotImplementedError
|
for a plan AMICI does not simulate, see
|
check_supported
¶
Refuse a plan which sets a compartment AMICI keeps out of its states.
execute checks every plan, and Simulator.run the plan of the first
point of every simulation and model before it runs a point, see
sbmlsim.simulator.engines.check_plan. A compartment whose size in the
SBML is not a number and which has no initial assignment is a number of
AMICI, which integrates no state which is not finite, see
sbmlsim.model.model_amici.
Raises:
| Type | Description |
|---|---|
UnsupportedModelError
|
a |
steady_state
¶
Integrate a model until its rates of change vanish, see sbmlsim.simulator.segments.steady_state.
Every horizon fires the events of the model, see _Course.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
AmiciSBMLModel
|
the model in the state the integration starts from. |
required |
plan
|
SteadyStatePlan
|
the steady state. |
required |
start
|
float
|
the time the integration starts at. |
0.0
|
Returns:
| Type | Description |
|---|---|
float
|
The time the steady state was reached at. |
Raises:
| Type | Description |
|---|---|
SteadyStateError
|
if the steady state is not reached by |
RuntimeError
|
if AMICI fails to integrate, with its message. |