Skip to content

Commit

Permalink
Add debugging helper get_model_for_preeq
Browse files Browse the repository at this point in the history
Makes life easier when debugging preequilibration issues.
  • Loading branch information
dweindl committed Dec 18, 2023
1 parent 3f7f5bc commit 05dd9df
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
45 changes: 45 additions & 0 deletions python/sdist/amici/debugging/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""Functions for debugging AMICI simulation failures."""
import amici
import numpy as np


def get_model_for_preeq(model: amici.Model, edata: amici.ExpData):
"""Get a model set-up to simulate the preequilibration condition as
specified in `edata`.
Useful for analyzing simulation errors during preequilibration.
Simulating the returned model will reproduce the behavior of
simulation-based preequilibration.
Note that for models with events, the simulation results may differ.
During preequilibration, event-handling is disabled. However, when
simulating the returned model, event-handling will be enabled.
For events triggered at fixed timepoints, this can be avoided by setting
:meth:`t0 <amici.Model.setT0>` to a timepoints after the last trigger
timepoint.
:param model:
The model for which *edata* was generated.
:param edata:
The experimental data object with a preequilibration condition
specified.
:return:
A copy of *model* with the same parameters, initial states, ...
as *amici_model* for the preequilibration condition.
Output timepoints are set to ``[inf]`` and will have to be adjusted.
"""
model = model.clone()
model.setTimepoints([np.inf])
model.setFixedParameters(edata.fixedParametersPreequilibration)
if edata.pscale:
model.setParameterScale(edata.pscale)
if edata.parameters:
model.setParameters(edata.parameters)
if edata.plist:
model.setParameterList(edata.plist)
model.setInitialStates(edata.x0)
# has to be set *after* parameter list/scale!
model.setInitialStateSensitivities(edata.sx0)
model.setT0(edata.tstart_)

return model
32 changes: 32 additions & 0 deletions python/tests/test_preequilibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import amici
import numpy as np
import pytest
from amici.debugging import get_model_for_preeq
from numpy.testing import assert_allclose
from test_pysb import get_data

Expand Down Expand Up @@ -633,3 +634,34 @@ def test_simulation_errors(preeq_fixture):
assert rdata._swigptr.messages[2].identifier == "OTHER"
assert rdata._swigptr.messages[3].severity == amici.LogSeverity_debug
assert rdata._swigptr.messages[3].identifier == "BACKTRACE"


def test_get_model_for_preeq(preeq_fixture):
(
model,
solver,
edata,
edata_preeq,
edata_presim,
edata_sim,
pscales,
plists,
) = preeq_fixture
model.setSteadyStateSensitivityMode(
amici.SteadyStateSensitivityMode.integrationOnly
)
model_preeq = get_model_for_preeq(model, edata)
rdata1 = amici.runAmiciSimulation(model_preeq, solver)
rdata2 = amici.runAmiciSimulation(model, solver, edata_preeq)
assert_allclose(
rdata1.x,
rdata2.x,
atol=solver.getAbsoluteTolerance(),
rtol=solver.getRelativeTolerance(),
)
assert_allclose(
rdata1.sx,
rdata2.sx,
atol=solver.getAbsoluteTolerance(),
rtol=solver.getRelativeTolerance(),
)

0 comments on commit 05dd9df

Please sign in to comment.