Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
150 changes: 83 additions & 67 deletions doc/example/distributions.ipynb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"id": "372289411a2aa7b3",
"metadata": {},
"source": [
"# Prior distributions in PEtab\n",
"\n",
Expand All @@ -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",
Expand All @@ -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": {
Expand Down
1 change: 1 addition & 0 deletions petab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 2 additions & 4 deletions petab/petablint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions petab/v1/C.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
This file contains constant definitions.
"""

import math as _math
import sys

Expand Down
1 change: 1 addition & 0 deletions petab/v1/composite_problem.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""PEtab problems consisting of multiple models"""

import os

import pandas as pd
Expand Down
1 change: 1 addition & 0 deletions petab/v1/core.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""PEtab core functions (or functions that don't fit anywhere else)"""

import logging
import os
import re
Expand Down
1 change: 1 addition & 0 deletions petab/v1/distributions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Probability distributions used by PEtab."""

from __future__ import annotations

import abc
Expand Down
1 change: 1 addition & 0 deletions petab/v1/format_version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"""PEtab file format version"""

__format_version__ = 1
12 changes: 5 additions & 7 deletions petab/v1/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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]}'."
)


Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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.")
Expand Down Expand Up @@ -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
]
Expand Down
1 change: 1 addition & 0 deletions petab/v1/mapping.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Functionality related to the PEtab entity mapping table"""

# TODO: Move to petab.v2.mapping
from pathlib import Path

Expand Down
1 change: 1 addition & 0 deletions petab/v1/math/SympyVisitor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""PEtab-math to sympy conversion."""

import sympy as sp
from sympy.logic.boolalg import Boolean, BooleanFalse, BooleanTrue

Expand Down
1 change: 1 addition & 0 deletions petab/v1/math/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"""Functions for parsing and evaluating mathematical expressions."""

from .sympify import sympify_petab # noqa: F401
1 change: 1 addition & 0 deletions petab/v1/models/__init__.py
Original file line number Diff line number Diff line change
@@ -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`.
Expand Down
Loading