Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add debugging helper get_model_for_preeq #2250

Merged
merged 2 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)

Check warning on line 35 in python/sdist/amici/debugging/__init__.py

View check run for this annotation

Codecov / codecov/patch

python/sdist/amici/debugging/__init__.py#L35

Added line #L35 was not covered by tests
if edata.parameters:
model.setParameters(edata.parameters)

Check warning on line 37 in python/sdist/amici/debugging/__init__.py

View check run for this annotation

Codecov / codecov/patch

python/sdist/amici/debugging/__init__.py#L37

Added line #L37 was not covered by tests
if edata.plist:
model.setParameterList(edata.plist)

Check warning on line 39 in python/sdist/amici/debugging/__init__.py

View check run for this annotation

Codecov / codecov/patch

python/sdist/amici/debugging/__init__.py#L39

Added line #L39 was not covered by tests
model.setInitialStates(edata.x0)
# has to be set *after* parameter list/scale!
model.setInitialStateSensitivities(edata.sx0)
model.setT0(edata.tstart_)

return model
31 changes: 30 additions & 1 deletion python/tests/test_preequilibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import amici
import numpy as np
import pytest
from numpy.testing import assert_allclose
from amici.debugging import get_model_for_preeq
from numpy.testing import assert_allclose, assert_equal
from test_pysb import get_data


Expand Down Expand Up @@ -633,3 +634,31 @@ 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)
# the exactly same settings are used, so results should match exactly
rdata1 = amici.runAmiciSimulation(model_preeq, solver)
rdata2 = amici.runAmiciSimulation(model, solver, edata_preeq)
assert_equal(
rdata1.x,
rdata2.x,
)
assert_equal(
rdata1.sx,
rdata2.sx,
)