Skip to content

Commit d140230

Browse files
authored
Add v2.Problem.get_{changes_for_period,measurements_for_experiment} (#411)
Easier access to changes associated with a given period, and measurements associated with a given experiment.
1 parent 79166e0 commit d140230

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

petab/v2/core.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,6 +2207,32 @@ def model_dump(self, **kwargs) -> dict[str, Any]:
22072207
)
22082208
return res
22092209

2210+
def get_changes_for_period(self, period: ExperimentPeriod) -> list[Change]:
2211+
"""Get the changes for a given experiment period.
2212+
2213+
:param period: The experiment period to get the changes for.
2214+
:return: A list of changes for the given period.
2215+
"""
2216+
return list(
2217+
chain.from_iterable(
2218+
self[condition].changes for condition in period.condition_ids
2219+
)
2220+
)
2221+
2222+
def get_measurements_for_experiment(
2223+
self, experiment: Experiment
2224+
) -> list[Measurement]:
2225+
"""Get the measurements for a given experiment.
2226+
2227+
:param experiment: The experiment to get the measurements for.
2228+
:return: A list of measurements for the given experiment.
2229+
"""
2230+
return [
2231+
measurement
2232+
for measurement in self.measurements
2233+
if measurement.experiment_id == experiment.id
2234+
]
2235+
22102236

22112237
class ModelFile(BaseModel):
22122238
"""A file in the PEtab problem configuration."""

tests/v2/test_core.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,3 +491,81 @@ def test_problem_config_paths():
491491
# pc.parameter_files[0] = "foo.tsv"
492492
# assert isinstance(pc.parameter_files[0], Path)
493493
# see also https://github.com/pydantic/pydantic/issues/8575
494+
495+
496+
def test_get_changes_for_period():
497+
"""Test getting changes for a specific period."""
498+
problem = Problem()
499+
ch1 = Change(target_id="target1", target_value=1.0)
500+
ch2 = Change(target_id="target2", target_value=2.0)
501+
ch3 = Change(target_id="target3", target_value=3.0)
502+
cond1 = Condition(id="condition1_1", changes=[ch1])
503+
cond2 = Condition(id="condition1_2", changes=[ch2])
504+
cond3 = Condition(id="condition2", changes=[ch3])
505+
problem += cond1
506+
problem += cond2
507+
problem += cond3
508+
509+
p1 = ExperimentPeriod(
510+
id="p1", time=0, condition_ids=["condition1_1", "condition1_2"]
511+
)
512+
p2 = ExperimentPeriod(id="p2", time=1, condition_ids=["condition2"])
513+
problem += Experiment(
514+
id="exp1",
515+
periods=[p1, p2],
516+
)
517+
assert problem.get_changes_for_period(p1) == [ch1, ch2]
518+
assert problem.get_changes_for_period(p2) == [ch3]
519+
520+
521+
def test_get_measurements_for_experiment():
522+
"""Test getting measurements for an experiment."""
523+
problem = Problem()
524+
problem += Condition(
525+
id="condition1",
526+
changes=[Change(target_id="target1", target_value=1.0)],
527+
)
528+
problem += Condition(
529+
id="condition2",
530+
changes=[Change(target_id="target2", target_value=2.0)],
531+
)
532+
533+
e1 = Experiment(
534+
id="exp1",
535+
periods=[
536+
ExperimentPeriod(id="p1", time=0, condition_ids=["condition1"]),
537+
],
538+
)
539+
e2 = Experiment(
540+
id="exp2",
541+
periods=[
542+
ExperimentPeriod(id="p2", time=1, condition_ids=["condition2"]),
543+
],
544+
)
545+
problem += e1
546+
problem += e2
547+
548+
m1 = Measurement(
549+
observable_id="observable1",
550+
experiment_id="exp1",
551+
time=0,
552+
measurement=10.0,
553+
)
554+
m2 = Measurement(
555+
observable_id="observable2",
556+
experiment_id="exp1",
557+
time=1,
558+
measurement=20.0,
559+
)
560+
m3 = Measurement(
561+
observable_id="observable3",
562+
experiment_id="exp2",
563+
time=1,
564+
measurement=30.0,
565+
)
566+
problem += m1
567+
problem += m2
568+
problem += m3
569+
570+
assert problem.get_measurements_for_experiment(e1) == [m1, m2]
571+
assert problem.get_measurements_for_experiment(e2) == [m3]

0 commit comments

Comments
 (0)