Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9cf5823
add pytest-xdist to setup.cfg
dilpath May 16, 2023
069dbc7
fail on missing sbml files
dilpath May 16, 2023
ef1347c
add fiddy to sbml test suite
dilpath May 16, 2023
fa7ede0
add fsa gradient checks
dilpath May 16, 2023
1afa02d
run on gha
dweindl May 16, 2023
153de46
fix yaml
dweindl May 16, 2023
175c716
venv
dweindl May 16, 2023
7dff2b4
add fiddy to installAmiciSource; disabling caching for now; fix resha…
dilpath May 18, 2023
99d9a94
Merge branch 'develop' into check_grad_sbml_test_suite
dilpath May 22, 2023
5846b85
Merge branch 'develop' into check_grad_sbml_test_suite
dilpath May 23, 2023
4351ca1
temp skip DAEs (#2102); skip models with no parameters
dilpath May 23, 2023
2a699e2
skip sens.eq. for dae+event
dweindl May 23, 2023
459c1ad
fix semantic suite check
dweindl May 23, 2023
147039b
Fix cblas error for models without solver states in combination with …
dweindl May 23, 2023
98c19f1
Expected failures
dweindl May 23, 2023
fcd467d
Fix DAE check
dweindl May 23, 2023
f278b8e
Fix compilation error for models with events and xdot=0
dweindl May 23, 2023
c9f37da
Unskip 01355
dweindl May 23, 2023
af7fd07
additional eps
dilpath May 23, 2023
7de0769
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl May 25, 2023
731ad05
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl Jun 6, 2023
78e4f3c
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl Jun 26, 2023
cf34778
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl Sep 20, 2023
7bdb35c
Merge branch 'main' into check_grad_sbml_test_suite
dweindl Jun 25, 2025
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
4 changes: 4 additions & 0 deletions .github/workflows/test_sbml_semantic_test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: SBML
on:
push:
branches:
- check_grad_sbml_test_suite
- main
pull_request:
paths:
Expand Down Expand Up @@ -43,6 +44,9 @@ jobs:
- name: Install apt dependencies
uses: ./.github/actions/install-apt-dependencies

- run: |
source build/venv/bin/activate && pip install git+https://github.com/ICB-DCM/fiddy.git

- run: AMICI_PARALLEL_COMPILE="" ./scripts/installAmiciSource.sh
- run: AMICI_PARALLEL_COMPILE="" ./scripts/run-SBMLTestsuite.sh ${{ matrix.cases }}

Expand Down
1 change: 1 addition & 0 deletions python/sdist/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ test = [
"pytest",
"pytest-cov",
"pytest-rerunfailures",
"pytest-xdist",
"coverage",
"shyaml",
"antimony>=2.13",
Expand Down
1 change: 1 addition & 0 deletions scripts/installAmiciSource.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ python -m pip install --upgrade pip wheel
# --no-build-isolation below.
# The latter is necessary for code coverage to work.
python -m pip install --upgrade pip setuptools cmake_build_extension==0.6.0 numpy petab swig
pip install --upgrade git+https://github.com/ICB-DCM/fiddy.git
python -m pip install git+https://github.com/pysb/pysb@master # for SPM with compartments
AMICI_BUILD_TEMP="${AMICI_PATH}/python/sdist/build/temp" \
python -m pip install --verbose -e "${AMICI_PATH}/python/sdist[petab,test,vis,jax]" --no-build-isolation
Expand Down
7 changes: 7 additions & 0 deletions tests/sbml/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ def pytest_generate_tests(metafunc):
# Get CLI option
cases = metafunc.config.getoption("cases")
if cases:
# iff specific case IDs are given and the SBML semantic test suite is not there, we should fail.
if not SBML_SEMANTIC_CASES_DIR.exists():
raise ValueError(
"The SBML semantic cases are missing. You can install them with "
"'AMICI/scripts/run-SBMLTestsuite.sh'."
)

# Run selected tests
last_id = int(list(get_all_semantic_case_ids())[-1])
test_numbers = sorted(set(parse_selection(cases, last_id)))
Expand Down
111 changes: 96 additions & 15 deletions tests/sbml/testSBMLSuite.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@
import amici
import pandas as pd
import pytest
from amici.gradient_check import check_derivatives

from fiddy import MethodId, get_derivative
from fiddy.extensions.amici import (
reshape,
run_amici_simulation_to_cached_functions,
)
from fiddy.success import Consistency
from utils import (
verify_results,
write_result_file,
find_model_file,
read_settings_file,
apply_settings,
)
import libsbml
import numpy as np


@pytest.fixture(scope="session")
Expand All @@ -37,12 +43,12 @@ def test_sbml_testsuite_case(test_id, result_path, sbml_semantic_cases_dir):

# test cases for which sensitivities are to be checked
# key: case ID; value: epsilon for finite differences
sensitivity_check_cases = {
# parameter-dependent conservation laws
"00783": 1.5e-2,
# initial events
"00995": 1e-3,
}
# sensitivity_check_cases = {
# # parameter-dependent conservation laws
# "00783": 1.5e-2,
# # initial events
# "00995": 1e-3,
# }

try:
current_test_path = sbml_semantic_cases_dir / test_id
Expand All @@ -55,13 +61,29 @@ def test_sbml_testsuite_case(test_id, result_path, sbml_semantic_cases_dir):
inplace=True,
)

# TODO remove after https://github.com/AMICI-dev/AMICI/pull/2101
# and https://github.com/AMICI-dev/AMICI/issues/2106
# Don't attempt to generate sensitivity code for models with events+algebraic rules, which will fail
sbml_file = find_model_file(current_test_path, test_id)
sbml_document = libsbml.SBMLReader().readSBMLFromFile(str(sbml_file))
sbml_model = sbml_document.getModel()
has_events = sbml_model.getNumEvents() > 0
has_algebraic_rules = any(
rule.getTypeCode() == libsbml.SBML_ALGEBRAIC_RULE
for rule in sbml_model.getListOfRules()
)
generate_sensitivity_code = not (has_events and has_algebraic_rules)
# TODO https://github.com/AMICI-dev/AMICI/issues/2109
generate_sensitivity_code &= test_id not in {"01240"}
# ^^^^^^^^

# setup model
model_dir = Path(__file__).parent / "SBMLTestModels" / test_id
model, solver, wrapper = compile_model(
current_test_path,
test_id,
model_dir,
generate_sensitivity_code=test_id in sensitivity_check_cases,
generate_sensitivity_code=generate_sensitivity_code,
)
settings = read_settings_file(current_test_path, test_id)

Expand All @@ -75,19 +97,78 @@ def test_sbml_testsuite_case(test_id, result_path, sbml_semantic_cases_dir):
else:
raise RuntimeError("Simulation failed unexpectedly")

# verify
# verify simulation results
simulated = verify_results(
settings, rdata, results, wrapper, model, atol, rtol
)

# record results
write_result_file(simulated, test_id, result_path)

# check sensitivities for selected models
if epsilon := sensitivity_check_cases.get(test_id):
solver.setSensitivityOrder(amici.SensitivityOrder.first)
solver.setSensitivityMethod(amici.SensitivityMethod.forward)
check_derivatives(model, solver, epsilon=epsilon)
# test sensitivities
if not model.getParameters():
pytest.skip("No parameters -> no sensitivities to check")

# TODO see https://github.com/AMICI-dev/AMICI/pull/2101
if not generate_sensitivity_code:
pytest.skip("Sensitivity analysis is known to fail.")
if any(id_ == 0 for id_ in model.idlist):
pytest.skip("Sensitivity analysis for DAE is known to fail.")

solver.setSensitivityOrder(amici.SensitivityOrder.first)
solver.setSensitivityMethod(amici.SensitivityMethod.forward)
# currently only checking "x"/"sx" for FSA
(
amici_function_f,
amici_derivative_f,
structures_f,
) = run_amici_simulation_to_cached_functions(
amici_model=model,
amici_solver=solver,
derivative_variables=["x"],
cache=False,
)
rdata_f = amici.runAmiciSimulation(model, solver)

# solver.setSensitivityMethod(amici.SensitivityMethod.adjoint)
# (
# amici_function_a,
# amici_derivative_a,
# structures_a,
# ) = run_amici_simulation_to_cached_functions(
# amici_model=model,
# amici_solver=solver,
# derivative_variables=["x"],
# cache=False,
# )
# rdata_a = amici.runAmiciSimulation(model, solver)

point = np.asarray(model.getParameters())

derivative = get_derivative(
# can use `_f` or `_a` here, should be no difference
function=amici_function_f,
point=point,
sizes=[1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1],
direction_ids=model.getParameterIds(),
method_ids=[MethodId.FORWARD, MethodId.BACKWARD, MethodId.CENTRAL],
relative_sizes=True,
success_checker=Consistency(rtol=1e-2, atol=1e-4),
)

derivative_fd = reshape(
derivative.value.flat,
structures_f["derivative"],
sensitivities=True,
)["x"]
derivative_fsa = rdata_f.sx
# derivative_asa = rdata_a.sllh # currently None, define some objective?

# could alternatively use a `fiddy.DerivativeCheck` class
if not np.isclose(
derivative_fd, derivative_fsa, rtol=5e-2, atol=5e-2
).all():
raise ValueError("Gradients were not validated.")

except amici.sbml_import.SBMLException as err:
pytest.skip(str(err))
Expand Down
1 change: 1 addition & 0 deletions tests/sbml/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import numpy as np
import pandas as pd
from amici.constants import SymbolId

from numpy.testing import assert_allclose


Expand Down
Loading