44import logging
55import os
66import tempfile
7+ import warnings
78from math import nan
89from pathlib import Path
910from typing import TYPE_CHECKING
2425from ..v1 .C import * # noqa: F403
2526from ..v1 .models .model import Model , model_factory
2627from ..v1 .yaml import get_path_prefix
28+ from . import experiments
2729
2830if TYPE_CHECKING :
2931 from ..v2 .lint import ValidationIssue , ValidationResultList , ValidationTask
@@ -38,6 +40,7 @@ class Problem:
3840
3941 - model
4042 - condition table
43+ - experiment table
4144 - measurement table
4245 - parameter table
4346 - observables table
@@ -47,6 +50,7 @@ class Problem:
4750
4851 Parameters:
4952 condition_df: PEtab condition table
53+ experiment_df: PEtab experiment table
5054 measurement_df: PEtab measurement table
5155 parameter_df: PEtab parameter table
5256 observable_df: PEtab observable table
@@ -60,6 +64,7 @@ def __init__(
6064 self ,
6165 model : Model = None ,
6266 condition_df : pd .DataFrame = None ,
67+ experiment_df : pd .DataFrame = None ,
6368 measurement_df : pd .DataFrame = None ,
6469 parameter_df : pd .DataFrame = None ,
6570 visualization_df : pd .DataFrame = None ,
@@ -70,6 +75,7 @@ def __init__(
7075 from ..v2 .lint import default_validation_tasks
7176
7277 self .condition_df : pd .DataFrame | None = condition_df
78+ self .experiment_df : pd .DataFrame | None = experiment_df
7379 self .measurement_df : pd .DataFrame | None = measurement_df
7480 self .parameter_df : pd .DataFrame | None = parameter_df
7581 self .visualization_df : pd .DataFrame | None = visualization_df
@@ -81,8 +87,22 @@ def __init__(
8187 ValidationTask
8288 ] = default_validation_tasks .copy ()
8389
90+ if self .experiment_df is not None :
91+ warnings .warn (
92+ "The experiment table is not yet supported and "
93+ "will be ignored." ,
94+ stacklevel = 2 ,
95+ )
96+
8497 def __str__ (self ):
8598 model = f"with model ({ self .model } )" if self .model else "without model"
99+
100+ experiments = (
101+ f"{ self .experiment_df .shape [0 ]} experiments"
102+ if self .experiment_df is not None
103+ else "without experiments table"
104+ )
105+
86106 conditions = (
87107 f"{ self .condition_df .shape [0 ]} conditions"
88108 if self .condition_df is not None
@@ -112,8 +132,8 @@ def __str__(self):
112132 parameters = "without parameter_df table"
113133
114134 return (
115- f"PEtab Problem { model } , { conditions } , { observables } , "
116- f"{ measurements } , { parameters } "
135+ f"PEtab Problem { model } , { conditions } , { experiments } , "
136+ f"{ observables } , { measurements } , { parameters } "
117137 )
118138
119139 @staticmethod
@@ -230,6 +250,16 @@ def get_path(filename):
230250 else None
231251 )
232252
253+ experiment_files = [
254+ get_path (f ) for f in problem0 .get (EXPERIMENT_FILES , [])
255+ ]
256+ # If there are multiple tables, we will merge them
257+ experiment_df = (
258+ core .concat_tables (experiment_files , experiments .get_experiment_df )
259+ if experiment_files
260+ else None
261+ )
262+
233263 visualization_files = [
234264 get_path (f ) for f in problem0 .get (VISUALIZATION_FILES , [])
235265 ]
@@ -260,6 +290,7 @@ def get_path(filename):
260290
261291 return Problem (
262292 condition_df = condition_df ,
293+ experiment_df = experiment_df ,
263294 measurement_df = measurement_df ,
264295 parameter_df = parameter_df ,
265296 observable_df = observable_df ,
0 commit comments