Skip to content
1 change: 1 addition & 0 deletions doc/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ API Reference
petab.v1.core
petab.v1.distributions
petab.v1.lint
petab.v1.math
petab.v1.measurements
petab.v1.models
petab.v1.observables
Expand Down
16 changes: 11 additions & 5 deletions petab/v1/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
"observable_table_has_nontrivial_noise_formula",
]

#: Regular expression pattern for valid PEtab IDs
_petab_id_pattern = re.compile(r"^[a-zA-Z_]\w*$")


def _check_df(df: pd.DataFrame, req_cols: Iterable, name: str) -> None:
"""Check if given columns are present in DataFrame
Expand Down Expand Up @@ -1041,10 +1044,13 @@ def assert_model_parameters_in_condition_or_parameter_table(
mapping_df[MODEL_ENTITY_ID],
strict=True,
)
# mapping table entities mapping to already allowed parameters
if to_id in allowed_in_condition_cols
# mapping table entities mapping to species
or model.is_state_variable(to_id)
if not pd.isna(to_id)
and (
# mapping table entities mapping to already allowed parameters
to_id in allowed_in_condition_cols
# mapping table entities mapping to species
or model.is_state_variable(to_id)
)
}

allowed_in_parameter_table = (
Expand Down Expand Up @@ -1186,7 +1192,7 @@ def is_valid_identifier(x: str) -> bool:
if pd.isna(x):
return False

return re.match(r"^[a-zA-Z_]\w*$", x) is not None
return _petab_id_pattern.match(x) is not None


def check_ids(ids: Iterable[str], kind: str = "") -> None:
Expand Down
17 changes: 15 additions & 2 deletions petab/v1/math/sympify.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
def sympify_petab(expr: str | int | float) -> sp.Expr | sp.Basic:
"""Convert PEtab math expression to sympy expression.

.. note::

All symbols in the returned expression will have the `real=True`
assumption.

Args:
expr: PEtab math expression.

Expand All @@ -26,14 +31,22 @@ def sympify_petab(expr: str | int | float) -> sp.Expr | sp.Basic:
The sympy expression corresponding to `expr`.
Boolean values are converted to numeric values.
"""
if isinstance(expr, sp.Expr):
# TODO: check if only PEtab-compatible symbols and functions are used
return expr

if isinstance(expr, int) or isinstance(expr, np.integer):
return sp.Integer(expr)
if isinstance(expr, float) or isinstance(expr, np.floating):
return sp.Float(expr)

# Set error listeners
input_stream = InputStream(expr)
try:
input_stream = InputStream(expr)
except TypeError as e:
raise TypeError(f"Error parsing {expr!r}: {e.args[0]}") from e

lexer = PetabMathExprLexer(input_stream)
# Set error listeners
lexer.removeErrorListeners()
lexer.addErrorListener(MathErrorListener())

Expand Down
33 changes: 11 additions & 22 deletions petab/v2/C.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,28 +125,14 @@

#: Condition ID column in the condition table
CONDITION_ID = "conditionId"
# TODO: removed?
#: Condition name column in the condition table
CONDITION_NAME = "conditionName"
#: Column in the condition table with the ID of an entity that is changed
TARGET_ID = "targetId"
#: Column in the condition table with the operation type
OPERATION_TYPE = "operationType"
#: Column in the condition table with the new value of the target entity
TARGET_VALUE = "targetValue"
# operation types:
OT_CUR_VAL = "setCurrentValue"
OT_NO_CHANGE = "noChange"

OPERATION_TYPES = [
OT_CUR_VAL,
OT_NO_CHANGE,
]

CONDITION_DF_COLS = [
CONDITION_ID,
TARGET_ID,
OPERATION_TYPE,
TARGET_VALUE,
]

Expand All @@ -161,25 +147,25 @@

# OBSERVABLES

#: Observable name column in the observables table
#: Observable name column in the observable table
OBSERVABLE_NAME = "observableName"
#: Observable formula column in the observables table
#: Observable formula column in the observable table
OBSERVABLE_FORMULA = "observableFormula"
#: Noise formula column in the observables table
#: Noise formula column in the observable table
NOISE_FORMULA = "noiseFormula"
#: Observable transformation column in the observables table
#: Observable transformation column in the observable table
OBSERVABLE_TRANSFORMATION = "observableTransformation"
#: Noise distribution column in the observables table
#: Noise distribution column in the observable table
NOISE_DISTRIBUTION = "noiseDistribution"

#: Mandatory columns of observables table
#: Mandatory columns of observable table
OBSERVABLE_DF_REQUIRED_COLS = [
OBSERVABLE_ID,
OBSERVABLE_FORMULA,
NOISE_FORMULA,
]

#: Optional columns of observables table
#: Optional columns of observable table
OBSERVABLE_DF_OPTIONAL_COLS = [
OBSERVABLE_NAME,
OBSERVABLE_TRANSFORMATION,
Expand Down Expand Up @@ -382,14 +368,17 @@
PETAB_ENTITY_ID = "petabEntityId"
#: Model entity ID column in the mapping table
MODEL_ENTITY_ID = "modelEntityId"
#: Arbitrary name
NAME = "name"

#: Required columns of the mapping table
MAPPING_DF_REQUIRED_COLS = [PETAB_ENTITY_ID, MODEL_ENTITY_ID]

# MORE

#: Simulated value column in the simulation table
SIMULATION = "simulation"
#: Residual value column in the residuals table
#: Residual value column in the residual table
RESIDUAL = "residual"
#: ???
NOISE_VALUE = "noiseValue"
Expand Down
38 changes: 21 additions & 17 deletions petab/v2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,31 @@

from warnings import warn

# TODO: remove v1 star imports
from ..v1.calculate import * # noqa: F403, F401, E402
from ..v1.composite_problem import * # noqa: F403, F401, E402
from ..v1.core import * # noqa: F403, F401, E402
from ..v1.format_version import __format_version__ # noqa: F401, E402
from ..v1.mapping import * # noqa: F403, F401, E402
from ..v1.measurements import * # noqa: F403, F401, E402
from ..v1.observables import * # noqa: F403, F401, E402
from ..v1.parameter_mapping import * # noqa: F403, F401, E402
from ..v1.parameters import * # noqa: F403, F401, E402
from ..v1.sampling import * # noqa: F403, F401, E402
from ..v1.sbml import * # noqa: F403, F401, E402
from ..v1.simulate import * # noqa: F403, F401, E402
from ..v1.yaml import * # noqa: F403, F401, E402

warn(
"Support for PEtab2.0 and all of petab.v2 is experimental "
"and subject to changes!",
stacklevel=1,
)

# TODO: move this module to v2
from petab.v1.mapping import ( # noqa: F403, F401, E402
get_mapping_df,
write_mapping_df,
)
from petab.v1.measurements import ( # noqa: F401, E402
get_measurement_df,
write_measurement_df,
)
from petab.v1.observables import ( # noqa: F401, E402
get_observable_df,
write_observable_df,
)
from petab.v1.parameters import ( # noqa: F401, E402
get_parameter_df,
write_parameter_df,
)
from petab.v1.yaml import load_yaml # noqa: F401, E402

# import after v1
from ..version import __version__ # noqa: F401, E402
from . import ( # noqa: F401, E402
Expand All @@ -38,5 +42,5 @@
write_experiment_df,
)
from .lint import lint_problem # noqa: F401, E402
from .models import Model # noqa: F401, E402
from .problem import Problem # noqa: F401, E402
from .models import MODEL_TYPE_PYSB, MODEL_TYPE_SBML, Model # noqa: F401, E402
from .problem import Problem, ProblemConfig # noqa: F401, E402
22 changes: 1 addition & 21 deletions petab/v2/conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@
from pathlib import Path

import pandas as pd
import sympy as sp

from .. import v2
from ..v1.math import sympify_petab
from .C import *
from .lint import assert_no_leading_trailing_whitespace
from ..v1.lint import assert_no_leading_trailing_whitespace

__all__ = [
"get_condition_df",
Expand Down Expand Up @@ -50,19 +46,3 @@ def write_condition_df(df: pd.DataFrame, filename: str | Path) -> None:
"""
df = get_condition_df(df)
df.to_csv(filename, sep="\t", index=False)


def get_condition_table_free_symbols(problem: v2.Problem) -> set[sp.Basic]:
"""Free symbols from condition table assignments.

Collects all free symbols from the condition table `targetValue` column.

:returns: Set of free symbols.
"""
if problem.condition_df is None:
return set()

free_symbols = set()
for target_value in problem.condition_df[TARGET_VALUE]:
free_symbols |= sympify_petab(target_value).free_symbols
return free_symbols
Loading