@@ -475,7 +475,7 @@ def free_symbols(self) -> set[sp.Symbol]:
475475
476476class ExperimentPeriod (BaseModel ):
477477 """A period of a timecourse or experiment defined by a start time
478- and a condition ID .
478+ and a list of condition IDs .
479479
480480 This corresponds to a row of the PEtab experiments table.
481481 """
@@ -484,20 +484,19 @@ class ExperimentPeriod(BaseModel):
484484 time : Annotated [float , AfterValidator (_is_finite_or_neg_inf )] = Field (
485485 alias = C .TIME
486486 )
487- #: The ID of the condition to be applied at the start time.
488- condition_id : str | None = Field ( alias = C . CONDITION_ID , default = None )
487+ #: The IDs of the conditions to be applied at the start time.
488+ condition_ids : list [ str ] = []
489489
490490 #: :meta private:
491491 model_config = ConfigDict (populate_by_name = True , extra = "allow" )
492492
493- @field_validator ("condition_id " , mode = "before" )
493+ @field_validator ("condition_ids " , mode = "before" )
494494 @classmethod
495- def _validate_id (cls , condition_id ):
496- if pd .isna (condition_id ) or not condition_id :
497- return None
498- if not is_valid_identifier (condition_id ):
499- raise ValueError (f"Invalid ID: { condition_id } " )
500- return condition_id
495+ def _validate_ids (cls , condition_ids ):
496+ for condition_id in condition_ids :
497+ if not is_valid_identifier (condition_id ):
498+ raise ValueError (f"Invalid ID: { condition_id } " )
499+ return condition_ids
501500
502501
503502class Experiment (BaseModel ):
@@ -548,12 +547,20 @@ def from_df(cls, df: pd.DataFrame) -> ExperimentTable:
548547
549548 experiments = []
550549 for experiment_id , cur_exp_df in df .groupby (C .EXPERIMENT_ID ):
551- periods = [
552- ExperimentPeriod (
553- time = row [C .TIME ], condition_id = row [C .CONDITION_ID ]
550+ periods = []
551+ for timepoint in cur_exp_df [C .TIME ].unique ():
552+ condition_ids = [
553+ cid
554+ for cid in cur_exp_df .loc [
555+ cur_exp_df [C .TIME ] == timepoint , C .CONDITION_ID
556+ ]
557+ if not pd .isna (cid )
558+ ]
559+ periods .append (
560+ ExperimentPeriod (
561+ time = timepoint , condition_ids = condition_ids
562+ )
554563 )
555- for _ , row in cur_exp_df .iterrows ()
556- ]
557564 experiments .append (Experiment (id = experiment_id , periods = periods ))
558565
559566 return cls (experiments = experiments )
@@ -563,10 +570,12 @@ def to_df(self) -> pd.DataFrame:
563570 records = [
564571 {
565572 C .EXPERIMENT_ID : experiment .id ,
566- ** period .model_dump (by_alias = True ),
573+ C .TIME : period .time ,
574+ C .CONDITION_ID : condition_id ,
567575 }
568576 for experiment in self .experiments
569577 for period in experiment .periods
578+ for condition_id in period .condition_ids or ["" ]
570579 ]
571580 return (
572581 pd .DataFrame (records )
0 commit comments