diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d32e5b68..4ba9c6fb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v5.0.0 hooks: - id: check-added-large-files - id: check-merge-conflict @@ -12,7 +12,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.11 + rev: v0.9.10 hooks: # Run the linter. - id: ruff diff --git a/doc/example/distributions.ipynb b/doc/example/distributions.ipynb index 86235fe1..7776ef8d 100644 --- a/doc/example/distributions.ipynb +++ b/doc/example/distributions.ipynb @@ -1,8 +1,9 @@ { "cells": [ { - "metadata": {}, "cell_type": "markdown", + "id": "372289411a2aa7b3", + "metadata": {}, "source": [ "# Prior distributions in PEtab\n", "\n", @@ -18,14 +19,16 @@ "* *Initialization priors* can be used as a hint for the optimization algorithm. They will not enter the objective function. They are specified in the `initializationPriorType` and `initializationPriorParameters` columns of the parameter table.\n", "\n", "\n" - ], - "id": "372289411a2aa7b3" + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "initial_id", "metadata": { "collapsed": true }, - "cell_type": "code", + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", @@ -45,143 +48,156 @@ " sample = prior.sample(10000)\n", "\n", " # pdf\n", - " xmin = min(sample.min(), prior.lb_scaled if prior.bounds is not None else sample.min())\n", - " xmax = max(sample.max(), prior.ub_scaled if prior.bounds is not None else sample.max())\n", + " xmin = min(\n", + " sample.min(),\n", + " prior.lb_scaled if prior.bounds is not None else sample.min(),\n", + " )\n", + " xmax = max(\n", + " sample.max(),\n", + " prior.ub_scaled if prior.bounds is not None else sample.max(),\n", + " )\n", " x = np.linspace(xmin, xmax, 500)\n", " y = prior.pdf(x)\n", - " ax.plot(x, y, color='red', label='pdf')\n", + " ax.plot(x, y, color=\"red\", label=\"pdf\")\n", "\n", - " sns.histplot(sample, stat='density', ax=ax, label=\"sample\")\n", + " sns.histplot(sample, stat=\"density\", ax=ax, label=\"sample\")\n", "\n", " # bounds\n", " if prior.bounds is not None:\n", " for bound in (prior.lb_scaled, prior.ub_scaled):\n", " if bound is not None and np.isfinite(bound):\n", - " ax.axvline(bound, color='black', linestyle='--', label='bound')\n", + " ax.axvline(bound, color=\"black\", linestyle=\"--\", label=\"bound\")\n", "\n", " ax.set_title(str(prior))\n", - " ax.set_xlabel('Parameter value on the parameter scale')\n", + " ax.set_xlabel(\"Parameter value on the parameter scale\")\n", " ax.grid(False)\n", " handles, labels = ax.get_legend_handles_labels()\n", - " unique_labels = dict(zip(labels, handles))\n", + " unique_labels = dict(zip(labels, handles, strict=False))\n", " ax.legend(unique_labels.values(), unique_labels.keys())\n", " plt.show()" - ], - "id": "initial_id", - "outputs": [], - "execution_count": null + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "The basic distributions are the uniform, normal, Laplace, log-normal, and log-laplace distributions:\n", - "id": "db36a4a93622ccb8" + "id": "db36a4a93622ccb8", + "metadata": {}, + "source": "The basic distributions are the uniform, normal, Laplace, log-normal, and log-laplace distributions:\n" }, { - "metadata": {}, "cell_type": "code", + "execution_count": null, + "id": "4f09e50a3db06d9f", + "metadata": {}, + "outputs": [], "source": [ "plot(Prior(UNIFORM, (0, 1)))\n", "plot(Prior(NORMAL, (0, 1)))\n", "plot(Prior(LAPLACE, (0, 1)))\n", "plot(Prior(LOG_NORMAL, (0, 1)))\n", "plot(Prior(LOG_LAPLACE, (1, 0.5)))" - ], - "id": "4f09e50a3db06d9f", - "outputs": [], - "execution_count": null + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "If a parameter scale is specified (`parameterScale=lin|log|log10` not a `parameterScale*`-type distribution), the sample is transformed accordingly (but not the distribution parameters):\n", - "id": "dab4b2d1e0f312d8" + "id": "dab4b2d1e0f312d8", + "metadata": {}, + "source": "If a parameter scale is specified (`parameterScale=lin|log|log10` not a `parameterScale*`-type distribution), the sample is transformed accordingly (but not the distribution parameters):\n" }, { - "metadata": {}, "cell_type": "code", + "execution_count": null, + "id": "f6192c226f179ef9", + "metadata": {}, + "outputs": [], "source": [ "plot(Prior(NORMAL, (10, 2), transformation=LIN))\n", "plot(Prior(NORMAL, (10, 2), transformation=LOG))\n", "\n", - "# Note that the log-normal distribution is different from a log-transformed normal distribution:\n", + "# Note that the log-normal distribution is different\n", + "# from a log-transformed normal distribution:\n", "plot(Prior(LOG_NORMAL, (10, 2), transformation=LIN))" - ], - "id": "f6192c226f179ef9", - "outputs": [], - "execution_count": null + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "On the log-transformed parameter scale, `Log*` and `parameterScale*` distributions are equivalent:", - "id": "4281ed48859e6431" + "id": "4281ed48859e6431", + "metadata": {}, + "source": "On the log-transformed parameter scale, `Log*` and `parameterScale*` distributions are equivalent:" }, { - "metadata": {}, "cell_type": "code", + "execution_count": null, + "id": "34c95268e8921070", + "metadata": {}, + "outputs": [], "source": [ "plot(Prior(LOG_NORMAL, (10, 2), transformation=LOG))\n", "plot(Prior(PARAMETER_SCALE_NORMAL, (10, 2)))" - ], - "id": "34c95268e8921070", - "outputs": [], - "execution_count": null + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "Prior distributions can also be defined on the parameter scale by using the types `parameterScaleUniform`, `parameterScaleNormal` or `parameterScaleLaplace`. In these cases, 1) the distribution parameter are interpreted on the transformed parameter scale, and 2) a sample from the given distribution is used directly, without applying any transformation according to `parameterScale` (this implies, that for `parameterScale=lin`, there is no difference between `parameterScaleUniform` and `uniform`):", - "id": "263c9fd31156a4d5" + "id": "263c9fd31156a4d5", + "metadata": {}, + "source": "Prior distributions can also be defined on the parameter scale by using the types `parameterScaleUniform`, `parameterScaleNormal` or `parameterScaleLaplace`. In these cases, 1) the distribution parameter are interpreted on the transformed parameter scale, and 2) a sample from the given distribution is used directly, without applying any transformation according to `parameterScale` (this implies, that for `parameterScale=lin`, there is no difference between `parameterScaleUniform` and `uniform`):" }, { - "metadata": {}, "cell_type": "code", + "execution_count": null, + "id": "5ca940bc24312fc6", + "metadata": {}, + "outputs": [], "source": [ "plot(Prior(UNIFORM, (0.01, 2), transformation=LOG10))\n", "plot(Prior(PARAMETER_SCALE_UNIFORM, (0.01, 2), transformation=LOG10))\n", "\n", "plot(Prior(UNIFORM, (0.01, 2), transformation=LIN))\n", - "plot(Prior(PARAMETER_SCALE_UNIFORM, (0.01, 2), transformation=LIN))\n" - ], - "id": "5ca940bc24312fc6", - "outputs": [], - "execution_count": null + "plot(Prior(PARAMETER_SCALE_UNIFORM, (0.01, 2), transformation=LIN))" + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "To prevent the sampled parameters from exceeding the bounds, the sampled parameters are clipped to the bounds. The bounds are defined in the parameter table. Note that the current implementation does not support sampling from a truncated distribution. Instead, the samples are clipped to the bounds. This may introduce unwanted bias, and thus, should only be used with caution (i.e., the bounds should be chosen wide enough):", - "id": "b1a8b17d765db826" + "id": "b1a8b17d765db826", + "metadata": {}, + "source": "To prevent the sampled parameters from exceeding the bounds, the sampled parameters are clipped to the bounds. The bounds are defined in the parameter table. Note that the current implementation does not support sampling from a truncated distribution. Instead, the samples are clipped to the bounds. This may introduce unwanted bias, and thus, should only be used with caution (i.e., the bounds should be chosen wide enough):" }, { - "metadata": {}, "cell_type": "code", - "source": [ - "plot(Prior(NORMAL, (0, 1), bounds=(-4, 4))) # negligible clipping-bias at 4 sigma\n", - "plot(Prior(UNIFORM, (0, 1), bounds=(0.1, 0.9))) # significant clipping-bias" - ], + "execution_count": null, "id": "4ac42b1eed759bdd", + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "plot(\n", + " Prior(NORMAL, (0, 1), bounds=(-4, 4))\n", + ") # negligible clipping-bias at 4 sigma\n", + "plot(Prior(UNIFORM, (0, 1), bounds=(0.1, 0.9))) # significant clipping-bias" + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "Further distribution examples:", - "id": "45ffce1341483f24" + "id": "45ffce1341483f24", + "metadata": {}, + "source": "Further distribution examples:" }, { - "metadata": {}, "cell_type": "code", + "execution_count": null, + "id": "581e1ac431860419", + "metadata": {}, + "outputs": [], "source": [ "plot(Prior(NORMAL, (10, 1), bounds=(6, 14), transformation=\"log10\"))\n", - "plot(Prior(PARAMETER_SCALE_NORMAL, (10, 1), bounds=(10**6, 10**14), transformation=\"log10\"))\n", + "plot(\n", + " Prior(\n", + " PARAMETER_SCALE_NORMAL,\n", + " (10, 1),\n", + " bounds=(10**6, 10**14),\n", + " transformation=\"log10\",\n", + " )\n", + ")\n", "plot(Prior(LAPLACE, (10, 2), bounds=(6, 14)))" - ], - "id": "581e1ac431860419", - "outputs": [], - "execution_count": null + ] } ], "metadata": { diff --git a/petab/__init__.py b/petab/__init__.py index 36110069..dd30d186 100644 --- a/petab/__init__.py +++ b/petab/__init__.py @@ -8,6 +8,7 @@ PEtab should use for operations that can be performed in parallel. By default, all operations are performed sequentially. """ + import importlib import sys from functools import partial diff --git a/petab/petablint.py b/petab/petablint.py index 43796c42..244b7536 100755 --- a/petab/petablint.py +++ b/petab/petablint.py @@ -161,7 +161,7 @@ def main(): validate(args.yaml_file_name) except SchemaValidationError as e: logger.error( - "Provided YAML file does not adhere to PEtab " f"schema: {e}" + f"Provided YAML file does not adhere to PEtab schema: {e}" ) sys.exit(1) @@ -205,9 +205,7 @@ def main(): if args.parameter_file_name: logger.debug(f"\tParameter table: {args.parameter_file_name}") if args.visualization_file_name: - logger.debug( - "\tVisualization table: " f"{args.visualization_file_name}" - ) + logger.debug(f"\tVisualization table: {args.visualization_file_name}") try: problem = petab.Problem.from_files( diff --git a/petab/v1/C.py b/petab/v1/C.py index be044a5c..0c9310b2 100644 --- a/petab/v1/C.py +++ b/petab/v1/C.py @@ -2,6 +2,7 @@ """ This file contains constant definitions. """ + import math as _math import sys diff --git a/petab/v1/composite_problem.py b/petab/v1/composite_problem.py index 5f07d523..f887ec03 100644 --- a/petab/v1/composite_problem.py +++ b/petab/v1/composite_problem.py @@ -1,4 +1,5 @@ """PEtab problems consisting of multiple models""" + import os import pandas as pd diff --git a/petab/v1/core.py b/petab/v1/core.py index 3b4a4082..1149c67e 100644 --- a/petab/v1/core.py +++ b/petab/v1/core.py @@ -1,4 +1,5 @@ """PEtab core functions (or functions that don't fit anywhere else)""" + import logging import os import re diff --git a/petab/v1/distributions.py b/petab/v1/distributions.py index 418f5b44..23deb423 100644 --- a/petab/v1/distributions.py +++ b/petab/v1/distributions.py @@ -1,4 +1,5 @@ """Probability distributions used by PEtab.""" + from __future__ import annotations import abc diff --git a/petab/v1/format_version.py b/petab/v1/format_version.py index a8d63484..f303237e 100644 --- a/petab/v1/format_version.py +++ b/petab/v1/format_version.py @@ -1,2 +1,3 @@ """PEtab file format version""" + __format_version__ = 1 diff --git a/petab/v1/lint.py b/petab/v1/lint.py index e970bfde..b2260b83 100644 --- a/petab/v1/lint.py +++ b/petab/v1/lint.py @@ -556,7 +556,7 @@ def check_parameter_bounds(parameter_df: pd.DataFrame) -> None: ] in [LOG, LOG10]: raise AssertionError( f"Bounds for {row[PARAMETER_SCALE]} scaled parameter " - f"{ row.name} must be positive." + f"{row.name} must be positive." ) if ( row.get(PARAMETER_SCALE, LIN) in [LOG, LOG10] @@ -586,8 +586,7 @@ def assert_parameter_prior_type_is_valid(parameter_df: pd.DataFrame) -> None: for _, row in parameter_df.iterrows(): if row[col] not in PRIOR_TYPES and not core.is_empty(row[col]): raise AssertionError( - f"{col} must be one of {PRIOR_TYPES} but is " - f"'{row[col]}'." + f"{col} must be one of {PRIOR_TYPES} but is '{row[col]}'." ) @@ -945,7 +944,7 @@ def lint_problem(problem: "petab.Problem") -> bool: for obs_id in problem.observable_df.index: if problem.model.has_entity_with_id(obs_id): logger.error( - f"Observable ID {obs_id} shadows model " "entity." + f"Observable ID {obs_id} shadows model entity." ) errors_occurred = True else: @@ -1002,8 +1001,7 @@ def lint_problem(problem: "petab.Problem") -> bool: or problem.observable_df is None ): logger.warning( - "Not all files of the PEtab problem definition could " - "be checked." + "Not all files of the PEtab problem definition could be checked." ) else: logger.info("PEtab format check completed successfully.") @@ -1213,7 +1211,7 @@ def check_ids(ids: Iterable[str], kind: str = "") -> None: offset = 2 error_output = "\n".join( [ - f"Line {index+offset}: " + f"Line {index + offset}: " + ("Missing ID" if pd.isna(_id) else _id) for index, _id in invalids ] diff --git a/petab/v1/mapping.py b/petab/v1/mapping.py index 813cf7d3..81f77017 100644 --- a/petab/v1/mapping.py +++ b/petab/v1/mapping.py @@ -1,4 +1,5 @@ """Functionality related to the PEtab entity mapping table""" + # TODO: Move to petab.v2.mapping from pathlib import Path diff --git a/petab/v1/math/SympyVisitor.py b/petab/v1/math/SympyVisitor.py index 016e872c..b8154301 100644 --- a/petab/v1/math/SympyVisitor.py +++ b/petab/v1/math/SympyVisitor.py @@ -1,4 +1,5 @@ """PEtab-math to sympy conversion.""" + import sympy as sp from sympy.logic.boolalg import Boolean, BooleanFalse, BooleanTrue diff --git a/petab/v1/math/__init__.py b/petab/v1/math/__init__.py index 27ebacd2..b9a4f59b 100644 --- a/petab/v1/math/__init__.py +++ b/petab/v1/math/__init__.py @@ -1,2 +1,3 @@ """Functions for parsing and evaluating mathematical expressions.""" + from .sympify import sympify_petab # noqa: F401 diff --git a/petab/v1/models/__init__.py b/petab/v1/models/__init__.py index 938f55fb..a35ad432 100644 --- a/petab/v1/models/__init__.py +++ b/petab/v1/models/__init__.py @@ -1,4 +1,5 @@ """Handling of different model types supported by PEtab.""" + #: SBML model type as used in a PEtab v2 yaml file as `language`. MODEL_TYPE_SBML = "sbml" #: PySB model type as used in a PEtab v2 yaml file as `language`. diff --git a/petab/v1/models/model.py b/petab/v1/models/model.py index 795c7f0b..e25ca0b2 100644 --- a/petab/v1/models/model.py +++ b/petab/v1/models/model.py @@ -1,4 +1,5 @@ """PEtab model abstraction""" + from __future__ import annotations import abc @@ -13,8 +14,7 @@ class Model(abc.ABC): """Base class for wrappers for any PEtab-supported model type""" @abc.abstractmethod - def __init__(self): - ... + def __init__(self): ... def __repr__(self): return f"<{self.__class__.__name__} {self.model_id!r}>" @@ -41,13 +41,11 @@ def to_file(self, filename: [str, Path]): @classmethod @property @abc.abstractmethod - def type_id(cls): - ... + def type_id(cls): ... @property @abc.abstractmethod - def model_id(self): - ... + def model_id(self): ... @abc.abstractmethod def get_parameter_value(self, id_: str) -> float: diff --git a/petab/v1/models/pysb_model.py b/petab/v1/models/pysb_model.py index f0147990..0b69d797 100644 --- a/petab/v1/models/pysb_model.py +++ b/petab/v1/models/pysb_model.py @@ -192,7 +192,7 @@ def parse_species_name( match = complex_constituent_pattern.match(complex_constituent) if not match: raise ValueError( - f"Invalid species name: '{name}' " f"('{complex_constituent}')" + f"Invalid species name: '{name}' ('{complex_constituent}')" ) monomer = match.groupdict()["monomer"] site_config_str = match.groupdict()["site_config"] @@ -208,7 +208,7 @@ def parse_species_name( elif config.startswith("'"): if not config.endswith("'"): raise ValueError( - f"Invalid species name: '{name}' " f"('{config}')" + f"Invalid species name: '{name}' ('{config}')" ) # strip quotes config = config[1:-1] diff --git a/petab/v1/models/sbml_model.py b/petab/v1/models/sbml_model.py index 55cd7b4d..8e8cf498 100644 --- a/petab/v1/models/sbml_model.py +++ b/petab/v1/models/sbml_model.py @@ -1,4 +1,5 @@ """Functions for handling SBML models""" + from __future__ import annotations import itertools diff --git a/petab/v1/parameter_mapping.py b/petab/v1/parameter_mapping.py index 014b4a8e..06e31fe4 100644 --- a/petab/v1/parameter_mapping.py +++ b/petab/v1/parameter_mapping.py @@ -133,7 +133,7 @@ def get_optimization_to_simulation_parameter_mapping( if model: raise ValueError( - "Arguments `model` and `sbml_model` are " "mutually exclusive." + "Arguments `model` and `sbml_model` are mutually exclusive." ) model = SbmlModel(sbml_model=sbml_model) @@ -383,7 +383,7 @@ def get_parameter_mapping_for_condition( if model: raise ValueError( - "Arguments `model` and `sbml_model` are " "mutually exclusive." + "Arguments `model` and `sbml_model` are mutually exclusive." ) model = SbmlModel(sbml_model=sbml_model) @@ -495,7 +495,7 @@ def _apply_overrides_for_observable( overrides: list of overrides for noise or observable parameters """ for i, override in enumerate(overrides): - overridee_id = f"{override_type}Parameter{i+1}_{observable_id}" + overridee_id = f"{override_type}Parameter{i + 1}_{observable_id}" mapping[overridee_id] = override diff --git a/petab/v1/parameters.py b/petab/v1/parameters.py index c2f37f62..82e23669 100644 --- a/petab/v1/parameters.py +++ b/petab/v1/parameters.py @@ -201,7 +201,7 @@ def create_parameter_df( if model: raise ValueError( - "Arguments `model` and `sbml_model` are " "mutually exclusive." + "Arguments `model` and `sbml_model` are mutually exclusive." ) model = SbmlModel(sbml_model=sbml_model) if include_optional: diff --git a/petab/v1/priors.py b/petab/v1/priors.py index e1263946..1d2b9802 100644 --- a/petab/v1/priors.py +++ b/petab/v1/priors.py @@ -1,4 +1,5 @@ """Functions related to prior handling.""" + from __future__ import annotations import copy @@ -384,17 +385,17 @@ def scaled_observable_formula(parameter_id, parameter_scale): ].iloc[0], } if PREEQUILIBRATION_CONDITION_ID in new_problem.measurement_df: - new_measurement[ - PREEQUILIBRATION_CONDITION_ID - ] = new_problem.measurement_df[PREEQUILIBRATION_CONDITION_ID].iloc[ - 0 - ] + new_measurement[PREEQUILIBRATION_CONDITION_ID] = ( + new_problem.measurement_df[PREEQUILIBRATION_CONDITION_ID].iloc[ + 0 + ] + ) new_measurement_dicts.append(new_measurement) # remove prior from parameter table - new_problem.parameter_df.loc[ - parameter_id, OBJECTIVE_PRIOR_TYPE - ] = np.nan + new_problem.parameter_df.loc[parameter_id, OBJECTIVE_PRIOR_TYPE] = ( + np.nan + ) new_problem.parameter_df.loc[ parameter_id, OBJECTIVE_PRIOR_PARAMETERS ] = np.nan diff --git a/petab/v1/problem.py b/petab/v1/problem.py index 91bbcd64..2405f5c0 100644 --- a/petab/v1/problem.py +++ b/petab/v1/problem.py @@ -1,4 +1,5 @@ """PEtab Problem class""" + from __future__ import annotations import os @@ -123,7 +124,7 @@ def __getattr__(self, name): if name in {"sbml_model", "sbml_reader", "sbml_document"}: return getattr(self.model, name) if self.model else None raise AttributeError( - f"'{self.__class__.__name__}' object has no " f"attribute '{name}'" + f"'{self.__class__.__name__}' object has no attribute '{name}'" ) def __setattr__(self, name, value): @@ -486,7 +487,7 @@ def to_files_generic( if self.model: if not isinstance(self.model, SbmlModel): raise NotImplementedError( - "Saving non-SBML models is " "currently not supported." + "Saving non-SBML models is currently not supported." ) filenames["model_file"] = "model.xml" diff --git a/petab/v1/sbml.py b/petab/v1/sbml.py index 6395e41b..9e5549d2 100644 --- a/petab/v1/sbml.py +++ b/petab/v1/sbml.py @@ -258,9 +258,9 @@ def get_model_for_condition( condition_dict = {petab.SIMULATION_CONDITION_ID: sim_condition_id} if preeq_condition_id: - condition_dict[ - petab.PREEQUILIBRATION_CONDITION_ID - ] = preeq_condition_id + condition_dict[petab.PREEQUILIBRATION_CONDITION_ID] = ( + preeq_condition_id + ) cur_measurement_df = petab.measurements.get_rows_for_condition( measurement_df=petab_problem.measurement_df, condition=condition_dict, diff --git a/petab/v1/simplify.py b/petab/v1/simplify.py index c4cdeb91..78c039b1 100644 --- a/petab/v1/simplify.py +++ b/petab/v1/simplify.py @@ -1,4 +1,5 @@ """Functionality for simplifying PEtab problems""" + from math import nan import pandas as pd diff --git a/petab/v1/simulate.py b/petab/v1/simulate.py index 682c470f..334929ad 100644 --- a/petab/v1/simulate.py +++ b/petab/v1/simulate.py @@ -1,4 +1,5 @@ """PEtab simulator base class and related functions.""" + from __future__ import annotations import abc diff --git a/petab/v1/visualize/__init__.py b/petab/v1/visualize/__init__.py index 924be86a..15385697 100644 --- a/petab/v1/visualize/__init__.py +++ b/petab/v1/visualize/__init__.py @@ -6,6 +6,7 @@ ``import petab.visualize``. """ + # ruff: noqa: F401 import importlib.util diff --git a/petab/v1/visualize/cli.py b/petab/v1/visualize/cli.py index 72074936..1416cae0 100644 --- a/petab/v1/visualize/cli.py +++ b/petab/v1/visualize/cli.py @@ -1,4 +1,5 @@ """Command-line interface for visualization.""" + import argparse from pathlib import Path diff --git a/petab/v1/visualize/helper_functions.py b/petab/v1/visualize/helper_functions.py index b1a6f1b1..85b5d936 100644 --- a/petab/v1/visualize/helper_functions.py +++ b/petab/v1/visualize/helper_functions.py @@ -4,7 +4,6 @@ hence not be directly visible/usable when using `import petab.visualize`. """ - import pandas as pd from ..C import * diff --git a/petab/v1/visualize/lint.py b/petab/v1/visualize/lint.py index b5de74bc..29ea4f7d 100644 --- a/petab/v1/visualize/lint.py +++ b/petab/v1/visualize/lint.py @@ -1,4 +1,5 @@ """Validation of PEtab visualization files""" + from __future__ import annotations import logging diff --git a/petab/v1/visualize/plot_data_and_simulation.py b/petab/v1/visualize/plot_data_and_simulation.py index c76bcd43..5ca8c6fb 100644 --- a/petab/v1/visualize/plot_data_and_simulation.py +++ b/petab/v1/visualize/plot_data_and_simulation.py @@ -2,7 +2,6 @@ the same format. """ - import matplotlib.pyplot as plt import pandas as pd @@ -73,7 +72,7 @@ def plot_with_vis_spec( plotter = MPLPlotter(figure, dataprovider) else: raise NotImplementedError( - "Currently, only visualization with " "matplotlib is possible." + "Currently, only visualization with matplotlib is possible." ) return plotter.generate_figure(subplot_dir, format_=format_) @@ -150,7 +149,7 @@ def plot_without_vis_spec( plotter = MPLPlotter(figure, dataprovider) else: raise NotImplementedError( - "Currently, only visualization with " "matplotlib is possible." + "Currently, only visualization with matplotlib is possible." ) return plotter.generate_figure(subplot_dir, format_=format_) diff --git a/petab/v1/visualize/plot_residuals.py b/petab/v1/visualize/plot_residuals.py index 90298154..a45fcde3 100644 --- a/petab/v1/visualize/plot_residuals.py +++ b/petab/v1/visualize/plot_residuals.py @@ -1,6 +1,7 @@ """ Functions for plotting residuals. """ + from pathlib import Path import matplotlib diff --git a/petab/v1/visualize/plotter.py b/petab/v1/visualize/plotter.py index 2a1eaaa9..14af5650 100644 --- a/petab/v1/visualize/plotter.py +++ b/petab/v1/visualize/plotter.py @@ -1,4 +1,5 @@ """PEtab visualization plotter classes""" + import os from abc import ABC, abstractmethod diff --git a/petab/v1/visualize/plotting.py b/petab/v1/visualize/plotting.py index b607350b..e474c4c8 100644 --- a/petab/v1/visualize/plotting.py +++ b/petab/v1/visualize/plotting.py @@ -1,4 +1,5 @@ """PEtab visualization data selection and visualization settings classes""" + import warnings from numbers import Number, Real from pathlib import Path @@ -609,9 +610,9 @@ def get_data_series( isinstance(tmp_noise, Number) or tmp_noise.dtype == "float64" ): - measurements_to_plot.at[ - var_cond_id, "noise_model" - ] = tmp_noise + measurements_to_plot.at[var_cond_id, "noise_model"] = ( + tmp_noise + ) # standard error of mean measurements_to_plot.at[var_cond_id, "sem"] = np.std( @@ -619,9 +620,9 @@ def get_data_series( ) / np.sqrt(len(data_measurements)) # single replicates - measurements_to_plot.at[ - var_cond_id, "repl" - ] = data_measurements.values + measurements_to_plot.at[var_cond_id, "repl"] = ( + data_measurements.values + ) data_series = DataSeries(conditions_, measurements_to_plot) data_series.add_offsets(dataplot.xOffset, dataplot.yOffset) @@ -964,7 +965,7 @@ def _get_vis_spec_dependent_columns_dict( # get number of plots and create plotId-lists plot_id_column = [ - "plot%s" % str(ind + 1) + f"plot{ind + 1}" for ind, inner_list in enumerate(dataset_id_list) for _ in inner_list ] diff --git a/petab/v1/yaml.py b/petab/v1/yaml.py index ac134d5b..b8330028 100644 --- a/petab/v1/yaml.py +++ b/petab/v1/yaml.py @@ -1,4 +1,5 @@ """Code regarding the PEtab YAML config files""" + from __future__ import annotations import os diff --git a/petab/v2/C.py b/petab/v2/C.py index 1ab6f795..0a406fac 100644 --- a/petab/v2/C.py +++ b/petab/v2/C.py @@ -2,6 +2,7 @@ """ This file contains constant definitions. """ + import math as _math import sys diff --git a/petab/v2/__init__.py b/petab/v2/__init__.py index adeb0e84..4d147828 100644 --- a/petab/v2/__init__.py +++ b/petab/v2/__init__.py @@ -2,6 +2,7 @@ Contains all functionality related to handling PEtab 2.0 problems. """ + from warnings import warn # TODO: remove v1 star imports diff --git a/petab/v2/_helpers.py b/petab/v2/_helpers.py index a7522f35..3201769a 100644 --- a/petab/v2/_helpers.py +++ b/petab/v2/_helpers.py @@ -1,2 +1,3 @@ """Various internal helper functions.""" + from ..v1.core import to_float_if_float # noqa: F401, E402 diff --git a/petab/v2/conditions.py b/petab/v2/conditions.py index 7bb6d262..8d5a3067 100644 --- a/petab/v2/conditions.py +++ b/petab/v2/conditions.py @@ -1,4 +1,5 @@ """Functions operating on the PEtab condition table""" + from __future__ import annotations from pathlib import Path diff --git a/petab/v2/experiments.py b/petab/v2/experiments.py index 17137b5c..9837b953 100644 --- a/petab/v2/experiments.py +++ b/petab/v2/experiments.py @@ -1,4 +1,5 @@ """Functions operating on the PEtab experiments table.""" + from pathlib import Path import pandas as pd diff --git a/petab/v2/lint.py b/petab/v2/lint.py index c5cf5eb9..2deb0ebd 100644 --- a/petab/v2/lint.py +++ b/petab/v2/lint.py @@ -1,4 +1,5 @@ """Validation of PEtab problems""" + from __future__ import annotations import logging diff --git a/petab/v2/models/__init__.py b/petab/v2/models/__init__.py index a387c27b..79ec7639 100644 --- a/petab/v2/models/__init__.py +++ b/petab/v2/models/__init__.py @@ -1,2 +1,3 @@ """Handling of different model types supported by PEtab.""" + from ...v1.models import * # noqa: F401, F403 diff --git a/petab/v2/models/model.py b/petab/v2/models/model.py index 403a03e2..345247eb 100644 --- a/petab/v2/models/model.py +++ b/petab/v2/models/model.py @@ -1,2 +1,3 @@ """PEtab model abstraction""" + from ...v1.models.model import * # noqa: F401, F403 diff --git a/petab/v2/models/pysb_model.py b/petab/v2/models/pysb_model.py index 111c9864..4da866e7 100644 --- a/petab/v2/models/pysb_model.py +++ b/petab/v2/models/pysb_model.py @@ -1,2 +1,3 @@ """Functions for handling PySB models""" + from ...v1.models.pysb_model import * # noqa: F401, F403 diff --git a/petab/v2/models/sbml_model.py b/petab/v2/models/sbml_model.py index 2a0eadc7..b696ce31 100644 --- a/petab/v2/models/sbml_model.py +++ b/petab/v2/models/sbml_model.py @@ -1,2 +1,3 @@ """Functions for handling SBML models""" + from ...v1.models.sbml_model import * # noqa: F401, F403 diff --git a/petab/v2/petab1to2.py b/petab/v2/petab1to2.py index 0d48d9cf..dc1b2b8c 100644 --- a/petab/v2/petab1to2.py +++ b/petab/v2/petab1to2.py @@ -1,4 +1,5 @@ """Convert PEtab version 1 problems to version 2.""" + import shutil from contextlib import suppress from itertools import chain diff --git a/petab/v2/problem.py b/petab/v2/problem.py index d07c7f2e..32684d0b 100644 --- a/petab/v2/problem.py +++ b/petab/v2/problem.py @@ -1,4 +1,5 @@ """PEtab v2 problems.""" + from __future__ import annotations import logging @@ -87,9 +88,9 @@ def __init__( self.mapping_df: pd.DataFrame | None = mapping_df self.model: Model | None = model self.extensions_config = extensions_config or {} - self.validation_tasks: list[ - ValidationTask - ] = default_validation_tasks.copy() + self.validation_tasks: list[ValidationTask] = ( + default_validation_tasks.copy() + ) self.config = config def __str__(self): diff --git a/petab/version.py b/petab/version.py index c59cab99..ca57250b 100644 --- a/petab/version.py +++ b/petab/version.py @@ -1,2 +1,3 @@ """PEtab library version""" + __version__ = "0.5.0" diff --git a/petab/versions.py b/petab/versions.py index e19d0cd0..b1fdecf4 100644 --- a/petab/versions.py +++ b/petab/versions.py @@ -1,4 +1,5 @@ """Handling of PEtab version numbers.""" + from __future__ import annotations import re diff --git a/tests/v1/math/test_math.py b/tests/v1/math/test_math.py index 4b350d4e..828aac88 100644 --- a/tests/v1/math/test_math.py +++ b/tests/v1/math/test_math.py @@ -61,13 +61,13 @@ def test_parse_cases(expr_str, expected): else: try: result = float(result.evalf()) - assert np.isclose( - result, expected - ), f"{expr_str}: Expected {expected}, got {result}" + assert np.isclose(result, expected), ( + f"{expr_str}: Expected {expected}, got {result}" + ) except TypeError: - assert ( - result == expected - ), f"{expr_str}: Expected {expected}, got {result}" + assert result == expected, ( + f"{expr_str}: Expected {expected}, got {result}" + ) def test_ids(): diff --git a/tests/v1/test_calculate.py b/tests/v1/test_calculate.py index ca93c33a..526ea7c9 100644 --- a/tests/v1/test_calculate.py +++ b/tests/v1/test_calculate.py @@ -15,7 +15,7 @@ def model_simple(): - "Simple model." "" + "Simple model." measurement_df = pd.DataFrame( data={ OBSERVABLE_ID: ["obs_a", "obs_a", "obs_b", "obs_b"], diff --git a/tests/v1/test_combine.py b/tests/v1/test_combine.py index 4fca4105..e685bf2b 100644 --- a/tests/v1/test_combine.py +++ b/tests/v1/test_combine.py @@ -1,4 +1,5 @@ """Test COMBINE archive""" + import tempfile from pathlib import Path diff --git a/tests/v1/test_conditions.py b/tests/v1/test_conditions.py index b240241d..45059ba1 100644 --- a/tests/v1/test_conditions.py +++ b/tests/v1/test_conditions.py @@ -1,4 +1,5 @@ """Tests related to petab.conditions""" + import os import tempfile from pathlib import Path diff --git a/tests/v1/test_deprecated.py b/tests/v1/test_deprecated.py index b78e7856..ef96f2e9 100644 --- a/tests/v1/test_deprecated.py +++ b/tests/v1/test_deprecated.py @@ -1,4 +1,5 @@ """Check that deprecated functionality raises but still works.""" + import tempfile from pathlib import Path diff --git a/tests/v1/test_lint.py b/tests/v1/test_lint.py index d75bdcea..4ad2e9b1 100644 --- a/tests/v1/test_lint.py +++ b/tests/v1/test_lint.py @@ -202,9 +202,9 @@ def test_assert_overrides_match_parameter_count(): # 3 observable parameters given, 2 expected measurement_df = measurement_df_orig.copy() - measurement_df.loc[ - 1, OBSERVABLE_PARAMETERS - ] = "override1;override2;oneTooMuch" + measurement_df.loc[1, OBSERVABLE_PARAMETERS] = ( + "override1;override2;oneTooMuch" + ) with pytest.raises(AssertionError): petab.assert_overrides_match_parameter_count( measurement_df, observable_df diff --git a/tests/v1/test_measurements.py b/tests/v1/test_measurements.py index ac3e59a3..10f5ba98 100644 --- a/tests/v1/test_measurements.py +++ b/tests/v1/test_measurements.py @@ -1,4 +1,5 @@ """Tests related to petab.measurements""" + import tempfile from pathlib import Path diff --git a/tests/v1/test_model_pysb.py b/tests/v1/test_model_pysb.py index 922dab2f..57371c79 100644 --- a/tests/v1/test_model_pysb.py +++ b/tests/v1/test_model_pysb.py @@ -1,4 +1,5 @@ """Test related to petab.models.model_pysb""" + import pysb import pytest diff --git a/tests/v1/test_observables.py b/tests/v1/test_observables.py index e870ac12..c9932b0d 100644 --- a/tests/v1/test_observables.py +++ b/tests/v1/test_observables.py @@ -1,4 +1,5 @@ """Tests for petab.observables""" + import tempfile from pathlib import Path diff --git a/tests/v1/test_parameters.py b/tests/v1/test_parameters.py index c28528fe..33e7c97d 100644 --- a/tests/v1/test_parameters.py +++ b/tests/v1/test_parameters.py @@ -1,4 +1,5 @@ """Tests for petab/parameters.py""" + import tempfile from pathlib import Path diff --git a/tests/v1/test_petab.py b/tests/v1/test_petab.py index ff9621fa..564dcb7f 100644 --- a/tests/v1/test_petab.py +++ b/tests/v1/test_petab.py @@ -331,9 +331,9 @@ def test_create_parameter_df( assert parameter_df.index.values.tolist() == expected # test with condition parameter override: - condition_df_2_conditions.loc[ - "condition2", "fixedParameter1" - ] = "overrider" + condition_df_2_conditions.loc["condition2", "fixedParameter1"] = ( + "overrider" + ) expected = ["p3", "p4", "p1", "p2", "p5", "overrider"] parameter_df = petab.create_parameter_df( diff --git a/tests/v1/test_sbml.py b/tests/v1/test_sbml.py index 5c262d43..b29f1ea7 100644 --- a/tests/v1/test_sbml.py +++ b/tests/v1/test_sbml.py @@ -85,9 +85,9 @@ def check_model(condition_model): condition_model.getSpecies("species_4").getInitialConcentration() == 3.25 ) - assert ( - len(condition_model.getListOfInitialAssignments()) == 0 - ), "InitialAssignment not removed" + assert len(condition_model.getListOfInitialAssignments()) == 0, ( + "InitialAssignment not removed" + ) assert condition_model.getCompartment("compartment_1").getSize() == 2.0 assert condition_model.getParameter("parameter_1").getValue() == 1.25 assert condition_model.getParameter("parameter_2").getValue() == 2.25 diff --git a/tests/v1/test_simplify.py b/tests/v1/test_simplify.py index 9aa25f8f..1724f8bb 100644 --- a/tests/v1/test_simplify.py +++ b/tests/v1/test_simplify.py @@ -1,4 +1,5 @@ """Tests for petab.simplify.*""" + from math import nan import pandas as pd diff --git a/tests/v1/test_simulate.py b/tests/v1/test_simulate.py index e23b63cb..7945b1bb 100644 --- a/tests/v1/test_simulate.py +++ b/tests/v1/test_simulate.py @@ -1,4 +1,5 @@ """Tests for petab/simulate.py.""" + import functools from collections.abc import Callable from pathlib import Path diff --git a/tests/v1/test_yaml.py b/tests/v1/test_yaml.py index 82ab242c..168d7697 100644 --- a/tests/v1/test_yaml.py +++ b/tests/v1/test_yaml.py @@ -1,4 +1,5 @@ """Test for petab.yaml""" + import tempfile from pathlib import Path diff --git a/tests/v2/test_experiments.py b/tests/v2/test_experiments.py index 234552f2..205f200d 100644 --- a/tests/v2/test_experiments.py +++ b/tests/v2/test_experiments.py @@ -1,4 +1,5 @@ """Tests related to ``petab.v2.experiments``.""" + from tempfile import TemporaryDirectory import pandas as pd diff --git a/tests/v2/test_mapping.py b/tests/v2/test_mapping.py index 60ba6b49..e60e9082 100644 --- a/tests/v2/test_mapping.py +++ b/tests/v2/test_mapping.py @@ -1,4 +1,5 @@ """Tests related to petab.v2.mapping""" + import tempfile import pandas as pd