Skip to content

Commit

Permalink
Merge branch 'develop' into jax_export
Browse files Browse the repository at this point in the history
  • Loading branch information
FFroehlich authored Oct 24, 2024
2 parents 7c27a21 + 56e6956 commit b84dbdb
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 85 deletions.
6 changes: 6 additions & 0 deletions include/amici/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,13 @@ constexpr int AMICI_CONSTR_FAIL= -15;
constexpr int AMICI_CVODES_CONSTR_FAIL= -15;
constexpr int AMICI_IDAS_CONSTR_FAIL= -11;
constexpr int AMICI_ILL_INPUT= -22;
constexpr int AMICI_BAD_T= -25;
constexpr int AMICI_BAD_DKY= -26;
constexpr int AMICI_FIRST_QRHSFUNC_ERR= -32;
constexpr int AMICI_SRHSFUNC_FAIL= -41;
constexpr int AMICI_FIRST_SRHSFUNC_ERR= -42;
constexpr int AMICI_REPTD_SRHSFUNC_ERR= -43;
constexpr int AMICI_UNREC_SRHSFUNC_ERR= -44;
constexpr int AMICI_ERROR= -99;
constexpr int AMICI_NO_STEADY_STATE= -81;
constexpr int AMICI_DAMPING_FACTOR_ERROR= -86;
Expand Down
26 changes: 12 additions & 14 deletions python/sdist/amici/petab/import_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,27 @@ def get_observation_model(

observables = {}
sigmas = {}

nan_pat = r"^[nN]a[nN]$"

for _, observable in observable_df.iterrows():
oid = str(observable.name)
# need to sanitize due to https://github.com/PEtab-dev/PEtab/issues/447
name = re.sub(nan_pat, "", str(observable.get(OBSERVABLE_NAME, "")))
formula_obs = re.sub(nan_pat, "", str(observable[OBSERVABLE_FORMULA]))
formula_noise = re.sub(nan_pat, "", str(observable[NOISE_FORMULA]))
observables[oid] = {"name": name, "formula": formula_obs}
sigmas[oid] = formula_noise

# PEtab does currently not allow observables in noiseFormula and AMICI
# cannot handle states in sigma expressions. Therefore, where possible,
# replace species occurring in error model definition by observableIds.
replacements = {
sp.sympify(observable["formula"], locals=_clash): sp.Symbol(
observable_id
formula_noise_sym = sp.sympify(formula_noise, locals=_clash)
formula_obs_sym = sp.sympify(formula_obs, locals=_clash)
# PEtab does currently not allow observables in noiseFormula, and
# AMICI cannot handle state variables in sigma expressions.
# Therefore, where possible, replace state variables occurring in
# the error model definition by equivalent observableIds.
# Do not use observableIds from other rows
# (https://github.com/AMICI-dev/AMICI/issues/2561).
formula_noise_sym = formula_noise_sym.subs(
formula_obs_sym, sp.Symbol(oid)
)
for observable_id, observable in observables.items()
}
for observable_id, formula in sigmas.items():
repl = sp.sympify(formula, locals=_clash).subs(replacements)
sigmas[observable_id] = str(repl)
sigmas[oid] = str(formula_noise_sym)

noise_distrs = petab_noise_distributions_to_amici(observable_df)

Expand Down
6 changes: 6 additions & 0 deletions src/amici.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ std::map<int, std::string> simulation_status_to_str_map = {
{AMICI_LSETUP_FAIL, "AMICI_LSETUP_FAIL"},
{AMICI_FIRST_QRHSFUNC_ERR, "AMICI_FIRST_QRHSFUNC_ERR"},
{AMICI_WARNING, "AMICI_WARNING"},
{AMICI_BAD_T, "AMICI_BAD_T"},
{AMICI_BAD_DKY, "AMICI_BAD_DKY"},
{AMICI_FIRST_SRHSFUNC_ERR, "AMICI_FIRST_SRHSFUNC_ERR"},
{AMICI_SRHSFUNC_FAIL, "AMICI_SRHSFUNC_FAIL"},
{AMICI_REPTD_SRHSFUNC_ERR, "AMICI_REPTD_SRHSFUNC_ERR"},
{AMICI_UNREC_SRHSFUNC_ERR, "AMICI_UNREC_SRHSFUNC_ERR"},
};

std::unique_ptr<ReturnData> runAmiciSimulation(
Expand Down
83 changes: 24 additions & 59 deletions src/solver_cvodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,65 +34,30 @@ static_assert((int)InterpolationType::polynomial == CV_POLYNOMIAL, "");
static_assert((int)LinearMultistepMethod::adams == CV_ADAMS, "");
static_assert((int)LinearMultistepMethod::BDF == CV_BDF, "");

static_assert(AMICI_ROOT_RETURN == CV_ROOT_RETURN, "");

static_assert(
amici::AMICI_SUCCESS == CV_SUCCESS, "AMICI_SUCCESS != CV_SUCCESS"
);
static_assert(
amici::AMICI_DATA_RETURN == CV_TSTOP_RETURN,
"AMICI_DATA_RETURN != CV_TSTOP_RETURN"
);
static_assert(
amici::AMICI_ROOT_RETURN == CV_ROOT_RETURN,
"AMICI_ROOT_RETURN != CV_ROOT_RETURN"
);
static_assert(
amici::AMICI_ILL_INPUT == CV_ILL_INPUT, "AMICI_ILL_INPUT != CV_ILL_INPUT"
);
static_assert(amici::AMICI_NORMAL == CV_NORMAL, "AMICI_NORMAL != CV_NORMAL");
static_assert(
amici::AMICI_ONE_STEP == CV_ONE_STEP, "AMICI_ONE_STEP != CV_ONE_STEP"
);
static_assert(
amici::AMICI_TOO_MUCH_ACC == CV_TOO_MUCH_ACC,
"AMICI_TOO_MUCH_ACC != CV_TOO_MUCH_ACC"
);
static_assert(
amici::AMICI_TOO_MUCH_WORK == CV_TOO_MUCH_WORK,
"AMICI_TOO_MUCH_WORK != CV_TOO_MUCH_WORK"
);
static_assert(
amici::AMICI_ERR_FAILURE == CV_ERR_FAILURE,
"AMICI_ERR_FAILURE != CV_ERR_FAILURE"
);
static_assert(
amici::AMICI_CONV_FAILURE == CV_CONV_FAILURE,
"AMICI_CONV_FAILURE != CV_CONV_FAILURE"
);
static_assert(
amici::AMICI_LSETUP_FAIL == CV_LSETUP_FAIL,
"AMICI_LSETUP_FAIL != CV_LSETUP_FAIL"
);
static_assert(
amici::AMICI_CONSTR_FAIL == CV_CONSTR_FAIL,
"AMICI_CONSTR_FAIL != CV_CONSTR_FAIL"
);
static_assert(
amici::AMICI_RHSFUNC_FAIL == CV_RHSFUNC_FAIL,
"AMICI_RHSFUNC_FAIL != CV_RHSFUNC_FAIL"
);
static_assert(
amici::AMICI_FIRST_RHSFUNC_ERR == CV_FIRST_RHSFUNC_ERR,
"AMICI_FIRST_RHSFUNC_ERR != CV_FIRST_RHSFUNC_ERR"
);
static_assert(
amici::AMICI_FIRST_QRHSFUNC_ERR == CV_FIRST_QRHSFUNC_ERR,
"AMICI_FIRST_QRHSFUNC_ERR != CV_FIRST_QRHSFUNC_ERR"
);
static_assert(
amici::AMICI_WARNING == CV_WARNING, "AMICI_WARNING != CV_WARNING"
);
#define STATIC_ASSERT_EQUAL(amici_constant, cv_constant) \
static_assert(amici_constant == cv_constant, #amici_constant " != " #cv_constant)

STATIC_ASSERT_EQUAL(amici::AMICI_SUCCESS, CV_SUCCESS);
STATIC_ASSERT_EQUAL(amici::AMICI_ROOT_RETURN, CV_ROOT_RETURN);
STATIC_ASSERT_EQUAL(amici::AMICI_DATA_RETURN, CV_TSTOP_RETURN);
STATIC_ASSERT_EQUAL(amici::AMICI_ILL_INPUT, CV_ILL_INPUT);
STATIC_ASSERT_EQUAL(amici::AMICI_NORMAL, CV_NORMAL);
STATIC_ASSERT_EQUAL(amici::AMICI_ONE_STEP, CV_ONE_STEP);
STATIC_ASSERT_EQUAL(amici::AMICI_TOO_MUCH_ACC, CV_TOO_MUCH_ACC);
STATIC_ASSERT_EQUAL(amici::AMICI_TOO_MUCH_WORK, CV_TOO_MUCH_WORK);
STATIC_ASSERT_EQUAL(amici::AMICI_ERR_FAILURE, CV_ERR_FAILURE);
STATIC_ASSERT_EQUAL(amici::AMICI_CONV_FAILURE, CV_CONV_FAILURE);
STATIC_ASSERT_EQUAL(amici::AMICI_LSETUP_FAIL, CV_LSETUP_FAIL);
STATIC_ASSERT_EQUAL(amici::AMICI_CONSTR_FAIL, CV_CONSTR_FAIL);
STATIC_ASSERT_EQUAL(amici::AMICI_RHSFUNC_FAIL, CV_RHSFUNC_FAIL);
STATIC_ASSERT_EQUAL(amici::AMICI_FIRST_RHSFUNC_ERR, CV_FIRST_RHSFUNC_ERR);
STATIC_ASSERT_EQUAL(amici::AMICI_FIRST_QRHSFUNC_ERR, CV_FIRST_QRHSFUNC_ERR);
STATIC_ASSERT_EQUAL(amici::AMICI_BAD_T, CV_BAD_T);
STATIC_ASSERT_EQUAL(amici::AMICI_BAD_DKY, CV_BAD_DKY);
STATIC_ASSERT_EQUAL(amici::AMICI_SRHSFUNC_FAIL, CV_SRHSFUNC_FAIL);
STATIC_ASSERT_EQUAL(amici::AMICI_FIRST_SRHSFUNC_ERR, CV_FIRST_SRHSFUNC_ERR);
STATIC_ASSERT_EQUAL(amici::AMICI_REPTD_SRHSFUNC_ERR, CV_REPTD_SRHSFUNC_ERR);
STATIC_ASSERT_EQUAL(amici::AMICI_UNREC_SRHSFUNC_ERR, CV_UNREC_SRHSFUNC_ERR);

/*
* The following static members are callback function to CVODES.
Expand Down
29 changes: 18 additions & 11 deletions tests/benchmark-models/test_petab_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
from amici.petab.petab_import import import_petab_problem
import benchmark_models_petab
from collections import defaultdict
from dataclasses import dataclass
from dataclasses import dataclass, field
from amici import SensitivityMethod
from petab.v1.lint import measurement_table_has_timepoint_specific_mappings
from fiddy import MethodId, get_derivative
from fiddy.derivative_check import NumpyIsCloseDerivativeCheck
from fiddy.extensions.amici import simulate_petab_to_cached_functions
Expand Down Expand Up @@ -58,14 +59,18 @@ class GradientCheckSettings:
atol_consistency: float = 1e-5
rtol_consistency: float = 1e-1
# Step sizes for finite difference gradient checks.
step_sizes = [
1e-1,
5e-2,
1e-2,
1e-3,
1e-4,
1e-5,
]
step_sizes: list[float] = field(
default_factory=lambda: [
2e-1,
1e-1,
5e-2,
1e-2,
5e-1,
1e-3,
1e-4,
1e-5,
]
)
rng_seed: int = 0
ss_sensitivity_mode: amici.SteadyStateSensitivityMode = (
amici.SteadyStateSensitivityMode.integrateIfNewtonFails
Expand Down Expand Up @@ -97,7 +102,6 @@ class GradientCheckSettings:
noise_level=0.01,
atol_consistency=1e-3,
)
settings["Okuonghae_ChaosSolitonsFractals2020"].step_sizes.extend([0.2, 0.005])
settings["Oliveira_NatCommun2021"] = GradientCheckSettings(
# Avoid "root after reinitialization"
atol_sim=1e-12,
Expand Down Expand Up @@ -176,7 +180,10 @@ def test_benchmark_gradient(model, scale, sensitivity_method, request):
pytest.skip()

petab_problem = benchmark_models_petab.get_problem(model)
petab.flatten_timepoint_specific_output_overrides(petab_problem)
if measurement_table_has_timepoint_specific_mappings(
petab_problem.measurement_df,
):
petab.flatten_timepoint_specific_output_overrides(petab_problem)

# Only compute gradient for estimated parameters.
parameter_ids = petab_problem.x_free_ids
Expand Down
7 changes: 6 additions & 1 deletion tests/benchmark-models/test_petab_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
)
from timeit import default_timer as timer
from petab.v1.visualize import plot_problem
from petab.v1.lint import measurement_table_has_timepoint_specific_mappings
import benchmark_models_petab

logger = get_logger(f"amici.{__name__}", logging.WARNING)
Expand Down Expand Up @@ -109,7 +110,11 @@ def main():

# load PEtab files
problem = benchmark_models_petab.get_problem(args.model_name)
petab.flatten_timepoint_specific_output_overrides(problem)

if measurement_table_has_timepoint_specific_mappings(
problem.measurement_df
):
petab.flatten_timepoint_specific_output_overrides(problem)

# load model
from amici.petab.petab_import import import_petab_problem
Expand Down

0 comments on commit b84dbdb

Please sign in to comment.