Skip to content

Commit

Permalink
..
Browse files Browse the repository at this point in the history
  • Loading branch information
dweindl committed Nov 22, 2023
1 parent 35a70b7 commit f3da12c
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 130 deletions.
1 change: 0 additions & 1 deletion python/sdist/amici/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Package-level entrypoint"""

import os
import sys

from . import __version__, compiledWithOpenMP, has_clibs, hdf5_enabled
Expand Down
5 changes: 3 additions & 2 deletions python/sdist/amici/petab/cli/import_petab.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import argparse

import petab
from amici.petab_import import import_model

from ..petab_import import import_model_sbml


def _parse_cli_args():
Expand Down Expand Up @@ -142,7 +143,7 @@ def _main():
if args.flatten:
petab.flatten_timepoint_specific_output_overrides(pp)

import_model(
import_model_sbml(
model_name=args.model_name,
sbml_model=pp.sbml_model,
condition_table=pp.condition_df,
Expand Down
109 changes: 109 additions & 0 deletions python/sdist/amici/petab/simulator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""
PEtab Simulator
---------------
Functionality related to the use of AMICI for simulation with :class:`petab.Simulator`.
Use cases:
- generate data for use with PEtab's plotting methods
- generate synthetic data
"""

import inspect
import sys
from typing import Callable

import pandas as pd
import petab
from amici import AmiciModel, SensitivityMethod_none

from .petab_import import import_petab_problem
from .simulations import RDATAS, rdatas_to_measurement_df, simulate_petab

AMICI_MODEL = "amici_model"
AMICI_SOLVER = "solver"
MODEL_NAME = "model_name"
MODEL_OUTPUT_DIR = "model_output_dir"

PETAB_PROBLEM = "petab_problem"


class PetabSimulator(petab.simulate.Simulator):
"""Implementation of the PEtab `Simulator` class that uses AMICI."""

def __init__(self, *args, amici_model: AmiciModel = None, **kwargs):
super().__init__(*args, **kwargs)
self.amici_model = amici_model

def simulate_without_noise(self, **kwargs) -> pd.DataFrame:
"""
See :py:func:`petab.simulate.Simulator.simulate()` docstring.
Additional keyword arguments can be supplied to specify arguments for
the AMICI PEtab import, simulate, and export methods. See the
docstrings for the respective methods for argument options:
- :py:func:`amici.petab_import.import_petab_problem`, and
- :py:func:`amici.petab_objective.simulate_petab`.
Note that some arguments are expected to have already been specified
in the Simulator constructor (including the PEtab problem).
"""
if AMICI_MODEL in {*kwargs, *dir(self)} and (
any(
k in kwargs
for k in inspect.signature(import_petab_problem).parameters
)
):
print(
"Arguments related to the PEtab import are unused if "
f"`{AMICI_MODEL}` is specified, or the "
"`PetabSimulator.simulate()` method was previously called."
)

kwargs[PETAB_PROBLEM] = self.petab_problem

# The AMICI model instance for the PEtab problem is saved in the state,
# such that it need not be supplied with each request for simulated
# data. Any user-supplied AMICI model will overwrite the model saved
# in the state.
if AMICI_MODEL not in kwargs:
if self.amici_model is None:
if MODEL_NAME not in kwargs:
kwargs[MODEL_NAME] = AMICI_MODEL
# If the model name is the name of a module that is already
# cached, it can cause issues during import.
while kwargs[MODEL_NAME] in sys.modules:
kwargs[MODEL_NAME] += str(self.rng.integers(10))
if MODEL_OUTPUT_DIR not in kwargs:
kwargs[MODEL_OUTPUT_DIR] = self.working_dir
self.amici_model = _subset_call(import_petab_problem, kwargs)
kwargs[AMICI_MODEL] = self.amici_model
self.amici_model = kwargs[AMICI_MODEL]

if AMICI_SOLVER not in kwargs:
kwargs[AMICI_SOLVER] = self.amici_model.getSolver()
kwargs[AMICI_SOLVER].setSensitivityMethod(SensitivityMethod_none)

result = _subset_call(simulate_petab, kwargs)
return rdatas_to_measurement_df(
result[RDATAS], self.amici_model, self.petab_problem.measurement_df
)


def _subset_call(method: Callable, kwargs: dict):
"""
Helper function to call a method with the intersection of arguments in the
method signature and the supplied arguments.
:param method:
The method to be called.
:param kwargs:
The argument superset as a dictionary, similar to ``**kwargs`` in
method signatures.
:return:
The output of ``method``, called with the applicable arguments in
``kwargs``.
"""
method_args = inspect.signature(method).parameters
subset_kwargs = {k: v for k, v in kwargs.items() if k in method_args}
return method(**subset_kwargs)
4 changes: 2 additions & 2 deletions python/sdist/amici/petab_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
DeprecationWarning,
)

from .petab.import_helpers import (
from .petab.import_helpers import ( # noqa # pylint: disable=unused-import
get_fixed_parameters,
get_observation_model,
petab_noise_distributions_to_amici,
petab_scale_to_amici_scale,
)

# DEPRECATED - DON'T ADD ANYTHING NEW HERE
from .petab.petab_import import (
from .petab.petab_import import ( # noqa # pylint: disable=unused-import
check_model,
import_model,
import_model_sbml,
Expand Down
115 changes: 6 additions & 109 deletions python/sdist/amici/petab_simulate.py
Original file line number Diff line number Diff line change
@@ -1,113 +1,10 @@
"""
PEtab Simulate
--------------
Functionality related to the use of AMICI for simulation with PEtab's
Simulator class.
# THIS FILE IS TO BE REMOVED - DON'T ADD ANYTHING HERE!

Use cases:
import warnings

- generate data for use with PEtab's plotting methods
- generate synthetic data
"""

import inspect
import sys
from typing import Callable

import pandas as pd
import petab
from amici import AmiciModel, SensitivityMethod_none
from amici.petab_import import import_petab_problem
from amici.petab_objective import (
RDATAS,
rdatas_to_measurement_df,
simulate_petab,
warnings.warn(
f"Importing {__name__} is deprecated. Use `amici.petab.simulator` instead.",
DeprecationWarning,
)

AMICI_MODEL = "amici_model"
AMICI_SOLVER = "solver"
MODEL_NAME = "model_name"
MODEL_OUTPUT_DIR = "model_output_dir"

PETAB_PROBLEM = "petab_problem"


class PetabSimulator(petab.simulate.Simulator):
"""Implementation of the PEtab `Simulator` class that uses AMICI."""

def __init__(self, *args, amici_model: AmiciModel = None, **kwargs):
super().__init__(*args, **kwargs)
self.amici_model = amici_model

def simulate_without_noise(self, **kwargs) -> pd.DataFrame:
"""
See :py:func:`petab.simulate.Simulator.simulate()` docstring.
Additional keyword arguments can be supplied to specify arguments for
the AMICI PEtab import, simulate, and export methods. See the
docstrings for the respective methods for argument options:
- :py:func:`amici.petab_import.import_petab_problem`, and
- :py:func:`amici.petab_objective.simulate_petab`.
Note that some arguments are expected to have already been specified
in the Simulator constructor (including the PEtab problem).
"""
if AMICI_MODEL in {*kwargs, *dir(self)} and (
any(
k in kwargs
for k in inspect.signature(import_petab_problem).parameters
)
):
print(
"Arguments related to the PEtab import are unused if "
f"`{AMICI_MODEL}` is specified, or the "
"`PetabSimulator.simulate()` method was previously called."
)

kwargs[PETAB_PROBLEM] = self.petab_problem

# The AMICI model instance for the PEtab problem is saved in the state,
# such that it need not be supplied with each request for simulated
# data. Any user-supplied AMICI model will overwrite the model saved
# in the state.
if AMICI_MODEL not in kwargs:
if self.amici_model is None:
if MODEL_NAME not in kwargs:
kwargs[MODEL_NAME] = AMICI_MODEL
# If the model name is the name of a module that is already
# cached, it can cause issues during import.
while kwargs[MODEL_NAME] in sys.modules:
kwargs[MODEL_NAME] += str(self.rng.integers(10))
if MODEL_OUTPUT_DIR not in kwargs:
kwargs[MODEL_OUTPUT_DIR] = self.working_dir
self.amici_model = _subset_call(import_petab_problem, kwargs)
kwargs[AMICI_MODEL] = self.amici_model
self.amici_model = kwargs[AMICI_MODEL]

if AMICI_SOLVER not in kwargs:
kwargs[AMICI_SOLVER] = self.amici_model.getSolver()
kwargs[AMICI_SOLVER].setSensitivityMethod(SensitivityMethod_none)

result = _subset_call(simulate_petab, kwargs)
return rdatas_to_measurement_df(
result[RDATAS], self.amici_model, self.petab_problem.measurement_df
)


def _subset_call(method: Callable, kwargs: dict):
"""
Helper function to call a method with the intersection of arguments in the
method signature and the supplied arguments.
:param method:
The method to be called.
:param kwargs:
The argument superset as a dictionary, similar to ``**kwargs`` in
method signatures.
:return:
The output of ``method``, called with the applicable arguments in
``kwargs``.
"""
method_args = inspect.signature(method).parameters
subset_kwargs = {k: v for k, v in kwargs.items() if k in method_args}
return method(**subset_kwargs)
from .petab.simulator import PetabSimulator # noqa: F401
2 changes: 1 addition & 1 deletion python/tests/splines_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import sympy as sp
from amici.gradient_check import _check_results
from amici.petab.petab_import import import_petab_problem
from amici.petab_objective import EDATAS, LLH, RDATAS, SLLH, simulate_petab
from amici.petab.simulations import EDATAS, LLH, RDATAS, SLLH, simulate_petab
from amici.sbml_utils import (
add_compartment,
add_inflow,
Expand Down
2 changes: 0 additions & 2 deletions python/tests/test_conserved_quantities_rref.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import os

import numpy as np
import pytest
import sympy as sp
Expand Down
2 changes: 0 additions & 2 deletions python/tests/test_parameter_mapping.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Test for ``amici.parameter_mapping``"""
import os

import pytest
from amici.petab.parameter_mapping import (
ParameterMapping,
ParameterMappingForCondition,
Expand Down
5 changes: 2 additions & 3 deletions python/tests/test_petab_objective.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
from pathlib import Path

import amici
import amici.petab_objective
import numpy as np
import pandas as pd
import petab
import pytest
from amici.petab.petab_import import import_petab_problem
from amici.petab_objective import SLLH
from amici.petab.simulations import SLLH, simulate_petab

# Absolute and relative tolerances for finite difference gradient checks.
ATOL: float = 1e-3
Expand Down Expand Up @@ -54,7 +53,7 @@ def test_simulate_petab_sensitivities(lotka_volterra):
problem_parameters
)
results[(scaled_parameters, scaled_gradients)] = pd.Series(
amici.petab_objective.simulate_petab(
simulate_petab(
petab_problem=petab_problem,
amici_model=amici_model,
solver=amici_solver,
Expand Down
2 changes: 1 addition & 1 deletion python/tests/test_petab_simulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import petab
import petabtests
import pytest
from amici.petab_simulate import PetabSimulator
from amici.petab.simulator import PetabSimulator
from amici.testing import skip_on_valgrind


Expand Down
1 change: 0 additions & 1 deletion tests/benchmark-models/test_petab_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from pathlib import Path

import amici
import amici.petab_objective
import numpy as np
import pandas as pd
import petab
Expand Down
2 changes: 1 addition & 1 deletion tests/benchmark-models/test_petab_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import petab
import yaml
from amici.logging import get_logger
from amici.petab_objective import (
from amici.petab.simulations import (
LLH,
RDATAS,
rdatas_to_measurement_df,
Expand Down
7 changes: 2 additions & 5 deletions tests/petab_test_suite/test_petab_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@
from amici import SteadyStateSensitivityMode
from amici.gradient_check import check_derivatives as amici_check_derivatives
from amici.logging import get_logger, set_log_level
from amici.petab.conditions import create_parameterized_edatas
from amici.petab.petab_import import import_petab_problem
from amici.petab_objective import (
create_parameterized_edatas,
rdatas_to_measurement_df,
simulate_petab,
)
from amici.petab.simulations import rdatas_to_measurement_df, simulate_petab

logger = get_logger(__name__, logging.DEBUG)
set_log_level(get_logger("amici.petab_import"), logging.DEBUG)
Expand Down

0 comments on commit f3da12c

Please sign in to comment.