Skip to content

Commit 55fdaf6

Browse files
committed
store ids
1 parent fda12a2 commit 55fdaf6

File tree

2 files changed

+89
-21
lines changed

2 files changed

+89
-21
lines changed

petab/v2/core.py

Lines changed: 88 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,27 @@
1818
from ..v1.math import sympify_petab
1919
from . import C
2020

21+
__all__ = [
22+
"Observable",
23+
"ObservablesTable",
24+
"ObservableTransformation",
25+
"NoiseDistribution",
26+
"Change",
27+
"ChangeSet",
28+
"ConditionsTable",
29+
"OperationType",
30+
"ExperimentPeriod",
31+
"Experiment",
32+
"ExperimentsTable",
33+
"Measurement",
34+
"MeasurementTable",
35+
"Mapping",
36+
"MappingTable",
37+
"Parameter",
38+
"ParameterScale",
39+
"ParameterTable",
40+
]
41+
2142

2243
class ObservableTransformation(str, Enum):
2344
"""Observable transformation types.
@@ -51,6 +72,44 @@ class NoiseDistribution(str, Enum):
5172
LAPLACE = C.LAPLACE
5273

5374

75+
class ObjectivePriorType(str, Enum):
76+
"""Objective prior types.
77+
78+
Objective prior types as used in the PEtab parameters table.
79+
"""
80+
81+
NORMAL = C.NORMAL
82+
LAPLACE = C.LAPLACE
83+
UNIFORM = C.UNIFORM
84+
LOG_NORMAL = C.LOG_NORMAL
85+
LOG_LAPLACE = C.LOG_LAPLACE
86+
PARAMETER_SCALE_NORMAL = C.PARAMETER_SCALE_NORMAL
87+
PARAMETER_SCALE_LAPLACE = C.PARAMETER_SCALE_LAPLACE
88+
PARAMETER_SCALE_UNIFORM = C.PARAMETER_SCALE_UNIFORM
89+
90+
91+
assert set(C.PRIOR_TYPES) == {e.value for e in ObjectivePriorType}, (
92+
"ObjectivePriorType enum does not match C.PRIOR_TYPES: "
93+
f"{set(C.PRIOR_TYPES)} vs { {e.value for e in ObjectivePriorType} }"
94+
)
95+
96+
97+
class InitializationPriorType(str, Enum):
98+
"""Initialization prior types.
99+
100+
Initialization prior types as used in the PEtab parameters table.
101+
"""
102+
103+
NORMAL = C.NORMAL
104+
LAPLACE = C.LAPLACE
105+
UNIFORM = C.UNIFORM
106+
LOG_NORMAL = C.LOG_NORMAL
107+
LOG_LAPLACE = C.LOG_LAPLACE
108+
PARAMETER_SCALE_NORMAL = C.PARAMETER_SCALE_NORMAL
109+
PARAMETER_SCALE_LAPLACE = C.PARAMETER_SCALE_LAPLACE
110+
PARAMETER_SCALE_UNIFORM = C.PARAMETER_SCALE_UNIFORM
111+
112+
54113
class Observable(BaseModel):
55114
"""Observable definition."""
56115

@@ -148,6 +207,9 @@ class OperationType(str, Enum):
148207
SET_CURRENT_VALUE = "setCurrentValue"
149208
SET_RATE = "setRate"
150209
SET_ASSIGNMENT = "setAssignment"
210+
ADD_TO_RATE = "addToRate"
211+
ADD_TO_ASSIGNMENT = "addToAssignment"
212+
NO_CHANGE = "noChange"
151213
CONSTANT = "constant"
152214
INITIAL = "initial"
153215
...
@@ -192,7 +254,7 @@ def sympify(cls, v):
192254
class ChangeSet(BaseModel):
193255
"""A set of changes to the model or model state.
194256
195-
A set of simultaneously occuring changes to the model or model state,
257+
A set of simultaneously occurring changes to the model or model state,
196258
corresponding to a perturbation of the underlying system. This corresponds
197259
to all rows of the PEtab conditions table with the same condition ID.
198260
"""
@@ -262,11 +324,21 @@ class ExperimentPeriod(BaseModel):
262324
"""
263325

264326
start: float = Field(alias=C.TIME)
265-
conditions: list[ChangeSet]
327+
condition_ids: list[str] = Field(alias=C.CONDITION_ID)
266328

267329
class Config:
268330
populate_by_name = True
269331

332+
@field_validator("condition_ids")
333+
@classmethod
334+
def validate_id(cls, v):
335+
for condition_id in v:
336+
if not condition_id:
337+
raise ValueError("ID must not be empty.")
338+
if not is_valid_identifier(condition_id):
339+
raise ValueError(f"Invalid ID: {condition_id}")
340+
return v
341+
270342

271343
class Experiment(BaseModel):
272344
"""An experiment or a timecourse defined by an ID and a set of different
@@ -283,32 +355,35 @@ class Config:
283355
populate_by_name = True
284356
arbitrary_types_allowed = True
285357

358+
@field_validator("id")
359+
@classmethod
360+
def validate_id(cls, v):
361+
if not v:
362+
raise ValueError("ID must not be empty.")
363+
if not is_valid_identifier(v):
364+
raise ValueError(f"Invalid ID: {v}")
365+
return v
366+
286367

287368
class ExperimentsTable(BaseModel):
288369
"""PEtab experiments table."""
289370

290371
experiments: list[Experiment]
291372

292373
@classmethod
293-
def from_dataframe(
294-
cls, df: pd.DataFrame, conditions: ConditionsTable = None
295-
) -> ExperimentsTable:
374+
def from_dataframe(cls, df: pd.DataFrame) -> ExperimentsTable:
296375
if df is None:
297376
return cls(experiments=[])
298377

299-
if conditions is None:
300-
conditions = {}
301-
302378
experiments = []
303379
for experiment_id, cur_exp_df in df.groupby(C.EXPERIMENT_ID):
304380
periods = []
305381
for time, cur_period_df in cur_exp_df.groupby(C.TIME):
306-
period_conditions = [
307-
conditions[row[C.CONDITION_ID]]
308-
for _, row in cur_period_df.iterrows()
309-
]
382+
period_conditions = list(cur_period_df[C.CONDITION_ID])
310383
periods.append(
311-
ExperimentPeriod(start=time, conditions=period_conditions)
384+
ExperimentPeriod(
385+
start=time, condition_ids=period_conditions
386+
)
312387
)
313388
experiments.append(Experiment(id=experiment_id, periods=periods))
314389

@@ -334,7 +409,6 @@ class Measurement(BaseModel):
334409
experiment.
335410
"""
336411

337-
# TODO: ID vs object
338412
observable_id: str = Field(alias=C.OBSERVABLE_ID)
339413
experiment_id: str | None = Field(alias=C.EXPERIMENT_ID, default=None)
340414
time: float = Field(alias=C.TIME)
@@ -396,8 +470,6 @@ class MeasurementTable(BaseModel):
396470
def from_dataframe(
397471
cls,
398472
df: pd.DataFrame,
399-
observables_table: ObservablesTable,
400-
experiments_table: ExperimentsTable,
401473
) -> MeasurementTable:
402474
if df is None:
403475
return cls(measurements=[])

petab/v2/problem.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,13 @@ def __init__(
115115
self.conditions: list[ChangeSet] = self.conditions_table.conditions
116116

117117
self.experiments_table: ExperimentsTable = (
118-
ExperimentsTable.from_dataframe(
119-
self.experiment_df, self.conditions_table
120-
)
118+
ExperimentsTable.from_dataframe(self.experiment_df)
121119
)
122120
self.experiments: list[Experiment] = self.experiments_table.experiments
123121

124122
self.measurement_table: MeasurementTable = (
125123
MeasurementTable.from_dataframe(
126124
self.measurement_df,
127-
observables_table=self.observables_table,
128-
experiments_table=self.experiments_table,
129125
)
130126
)
131127

0 commit comments

Comments
 (0)