From 3179bbebafc537f1cc0b6c24f394c61218036320 Mon Sep 17 00:00:00 2001 From: Paul Jonas Jost <70631928+PaulJonasJost@users.noreply.github.com> Date: Thu, 18 Jul 2024 09:26:59 +0200 Subject: [PATCH] Disentangle amici and roadrunner (#1429) * Removed amici not installed warning, as we specifically moved the amici imports into non dependencies * Added petab and libsbml dependency to roadrunner. * Fixed import errors i stumbled across hierarchical when only installing base + roadrunner (should be with only base as well) * Fixed rather through `from __future__ import annotations` * Update setup.cfg Co-authored-by: Daniel Weindl --------- Co-authored-by: Daniel Weindl --- pypesto/hierarchical/base_problem.py | 15 ++++++------- pypesto/hierarchical/ordinal/calculator.py | 6 +++-- pypesto/hierarchical/ordinal/problem.py | 18 ++++++++------- pypesto/hierarchical/ordinal/solver.py | 2 +- pypesto/hierarchical/relative/solver.py | 2 ++ .../semiquantitative/calculator.py | 6 +++-- .../hierarchical/semiquantitative/problem.py | 22 ++++++++++--------- .../hierarchical/semiquantitative/solver.py | 2 ++ pypesto/petab/__init__.py | 7 +----- setup.cfg | 2 ++ 10 files changed, 45 insertions(+), 37 deletions(-) diff --git a/pypesto/hierarchical/base_problem.py b/pypesto/hierarchical/base_problem.py index af85d05ec..8adb5c721 100644 --- a/pypesto/hierarchical/base_problem.py +++ b/pypesto/hierarchical/base_problem.py @@ -1,8 +1,9 @@ """Inner optimization problem in hierarchical optimization.""" +from __future__ import annotations + import copy import logging -from typing import Union import numpy as np import pandas as pd @@ -60,10 +61,10 @@ def __init__(self, xs: list[InnerParameter], data: list[np.ndarray]): @staticmethod def from_petab_amici( - petab_problem: "petab.Problem", - amici_model: "amici.Model", - edatas: list["amici.ExpData"], - ) -> "InnerProblem": + petab_problem: petab.Problem, + amici_model: amici.Model, + edatas: list[amici.ExpData], + ) -> InnerProblem: """Create an InnerProblem from a PEtab problem and AMICI objects.""" def get_x_ids(self) -> list[str]: @@ -219,9 +220,7 @@ def scale_value_dict( return scaled_dct -def scale_value( - val: Union[float, np.array], scale: str -) -> Union[float, np.array]: +def scale_value(val: float | np.array, scale: str) -> float | np.array: """Scale a single value.""" if scale == "lin": return val diff --git a/pypesto/hierarchical/ordinal/calculator.py b/pypesto/hierarchical/ordinal/calculator.py index 5fb9e60c6..13859013e 100644 --- a/pypesto/hierarchical/ordinal/calculator.py +++ b/pypesto/hierarchical/ordinal/calculator.py @@ -1,5 +1,7 @@ """Definition of an optimal scaling calculator class.""" +from __future__ import annotations + import copy from collections.abc import Sequence @@ -86,12 +88,12 @@ def __call__( mode: str, amici_model: AmiciModel, amici_solver: AmiciSolver, - edatas: list["amici.ExpData"], + edatas: list[amici.ExpData], n_threads: int, x_ids: Sequence[str], parameter_mapping: ParameterMapping, fim_for_hess: bool, - rdatas: list["amici.ReturnData"] = None, + rdatas: list[amici.ReturnData] = None, ): """Perform the actual AMICI call. diff --git a/pypesto/hierarchical/ordinal/problem.py b/pypesto/hierarchical/ordinal/problem.py index 0323e4e7b..e7967d3bf 100644 --- a/pypesto/hierarchical/ordinal/problem.py +++ b/pypesto/hierarchical/ordinal/problem.py @@ -1,5 +1,7 @@ """Definition of an optimal scaling parameter class.""" +from __future__ import annotations + import numpy as np import pandas as pd @@ -172,10 +174,10 @@ def initialize(self) -> None: @staticmethod def from_petab_amici( petab_problem: petab.Problem, - amici_model: "amici.Model", - edatas: list["amici.ExpData"], + amici_model: amici.Model, + edatas: list[amici.ExpData], method: str = None, - ) -> "OrdinalProblem": + ) -> OrdinalProblem: """Construct the inner problem from the `petab_problem`.""" if not method: method = REDUCED @@ -475,8 +477,8 @@ def get_inner_parameter_dictionary(self) -> dict: def optimal_scaling_inner_problem_from_petab_problem( petab_problem: petab.Problem, - amici_model: "amici.Model", - edatas: list["amici.ExpData"], + amici_model: amici.Model, + edatas: list[amici.ExpData], method: str, ): """Construct the inner problem from the `petab_problem`.""" @@ -511,7 +513,7 @@ def optimal_scaling_inner_problem_from_petab_problem( def optimal_scaling_inner_parameters_from_measurement_df( df: pd.DataFrame, method: str, - amici_model: "amici.Model", + amici_model: amici.Model, ) -> list[OrdinalParameter]: """Create list of inner free parameters from PEtab measurement table dependent on the method provided.""" df = df.reset_index() @@ -611,8 +613,8 @@ def get_estimate_for_method(method: str) -> tuple[bool, bool]: def optimal_scaling_ixs_for_measurement_specific_parameters( - petab_problem: "petab.Problem", - amici_model: "amici.Model", + petab_problem: petab.Problem, + amici_model: amici.Model, inner_parameters: list[OrdinalParameter], ) -> dict[str, list[tuple[int, int, int]]]: """Create mapping of parameters to measurements. diff --git a/pypesto/hierarchical/ordinal/solver.py b/pypesto/hierarchical/ordinal/solver.py index 66930faec..57aeb39d4 100644 --- a/pypesto/hierarchical/ordinal/solver.py +++ b/pypesto/hierarchical/ordinal/solver.py @@ -39,7 +39,7 @@ try: from amici.petab.parameter_mapping import ParameterMapping except ImportError: - pass + ParameterMapping = None class OrdinalInnerSolver(InnerSolver): diff --git a/pypesto/hierarchical/relative/solver.py b/pypesto/hierarchical/relative/solver.py index b3000eaaa..00b7c93ed 100644 --- a/pypesto/hierarchical/relative/solver.py +++ b/pypesto/hierarchical/relative/solver.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import copy from typing import Any diff --git a/pypesto/hierarchical/semiquantitative/calculator.py b/pypesto/hierarchical/semiquantitative/calculator.py index 4991f6766..133157ab7 100644 --- a/pypesto/hierarchical/semiquantitative/calculator.py +++ b/pypesto/hierarchical/semiquantitative/calculator.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import copy from collections.abc import Sequence @@ -79,12 +81,12 @@ def __call__( mode: str, amici_model: AmiciModel, amici_solver: AmiciSolver, - edatas: list["amici.ExpData"], + edatas: list[amici.ExpData], n_threads: int, x_ids: Sequence[str], parameter_mapping: ParameterMapping, fim_for_hess: bool, - rdatas: list["amici.ReturnData"] = None, + rdatas: list[amici.ReturnData] = None, ): """Perform the actual AMICI call. diff --git a/pypesto/hierarchical/semiquantitative/problem.py b/pypesto/hierarchical/semiquantitative/problem.py index 3698a442c..3b4705278 100644 --- a/pypesto/hierarchical/semiquantitative/problem.py +++ b/pypesto/hierarchical/semiquantitative/problem.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import numpy as np import pandas as pd @@ -124,10 +126,10 @@ def initialize(self) -> None: @staticmethod def from_petab_amici( petab_problem: petab.Problem, - amici_model: "amici.Model", - edatas: list["amici.ExpData"], + amici_model: amici.Model, + edatas: list[amici.ExpData], spline_ratio: float = None, - ) -> "SemiquantProblem": + ) -> SemiquantProblem: """Construct the inner problem from the `petab_problem`.""" if spline_ratio is None: spline_ratio = get_default_options() @@ -289,8 +291,8 @@ def get_default_options() -> dict: def spline_inner_problem_from_petab_problem( petab_problem: petab.Problem, - amici_model: "amici.Model", - edatas: list["amici.ExpData"], + amici_model: amici.Model, + edatas: list[amici.ExpData], spline_ratio: float = None, ): """Construct the inner problem from the `petab_problem`.""" @@ -336,7 +338,7 @@ def spline_inner_problem_from_petab_problem( def spline_inner_parameters_from_measurement_df( df: pd.DataFrame, spline_ratio: float, - amici_model: "amici.Model", + amici_model: amici.Model, ) -> list[SplineInnerParameter]: """Create list of inner free spline parameters from PEtab measurement table.""" df = df.reset_index() @@ -382,8 +384,8 @@ def spline_inner_parameters_from_measurement_df( def noise_inner_parameters_from_parameter_df( - petab_problem: "petab.Problem", - amici_model: "amici.Model", + petab_problem: petab.Problem, + amici_model: amici.Model, ) -> list[SplineInnerParameter]: """Create list of inner free noise parameters from PEtab parameter table.""" # Select the semiquantitative measurements. @@ -432,8 +434,8 @@ def noise_inner_parameters_from_parameter_df( def spline_ixs_for_measurement_specific_parameters( - petab_problem: "petab.Problem", - amici_model: "amici.Model", + petab_problem: petab.Problem, + amici_model: amici.Model, inner_parameters: list[SplineInnerParameter], ) -> dict[str, list[tuple[int, int, int]]]: """Create mapping of parameters to measurements. diff --git a/pypesto/hierarchical/semiquantitative/solver.py b/pypesto/hierarchical/semiquantitative/solver.py index 49dfeec4c..c5fa2c4e5 100644 --- a/pypesto/hierarchical/semiquantitative/solver.py +++ b/pypesto/hierarchical/semiquantitative/solver.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import warnings import numpy as np diff --git a/pypesto/petab/__init__.py b/pypesto/petab/__init__.py index 526997aa2..4b5d186a1 100644 --- a/pypesto/petab/__init__.py +++ b/pypesto/petab/__init__.py @@ -24,9 +24,4 @@ try: import amici except ImportError: - warnings.warn( - "PEtab import requires an installation of amici " - "(https://github.com/AMICI-dev/AMICI). " - "Install via `pip3 install amici`.", - stacklevel=1, - ) + amici = None diff --git a/setup.cfg b/setup.cfg index 077d60e95..2bd27b133 100644 --- a/setup.cfg +++ b/setup.cfg @@ -97,6 +97,8 @@ amici = amici >= 0.21.0 roadrunner = libroadrunner >= 2.7.0 + %(petab)s + python-libsbml >= 5.20.2 petab = petab >= 0.4.0 ipopt =