44
55import warnings
66from copy import deepcopy
7- from math import inf
87
98import libsbml
109from sbmlmath import sbml_math_to_sympy , set_math
1110
11+ from .C import TIME_PREEQUILIBRATION
1212from .core import Change , Condition , Experiment , ExperimentPeriod
1313from .models ._sbml_utils import add_sbml_parameter , check
1414from .models .sbml_model import SbmlModel
@@ -64,6 +64,12 @@ def __init__(self, problem: Problem):
6464
6565 self ._preprocess ()
6666
67+ def _get_experiment_indicator_condition_id (
68+ self , experiment_id : str
69+ ) -> str :
70+ """Get the condition ID for the experiment indicator parameter."""
71+ return f"_petab_experiment_condition_{ experiment_id } "
72+
6773 def _preprocess (self ):
6874 """Check whether we can handle the given problem and store some model
6975 information."""
@@ -74,7 +80,7 @@ def _preprocess(self):
7480 raise ValueError (
7581 "Cannot handle SBML models with SBML level < 3, "
7682 "because they do not support initial values for event "
77- "triggers and automatic upconversion failed."
83+ "triggers and automatic upconversion of the model failed."
7884 )
7985
8086 # Collect event priorities
@@ -139,23 +145,23 @@ def convert(self) -> Problem:
139145
140146 self ._add_preequilibration_indicator ()
141147
142- problem = self ._new_problem
143- for experiment in problem .experiment_table .experiments :
144- self ._convert_experiment (problem , experiment )
148+ for experiment in self ._new_problem .experiment_table .experiments :
149+ self ._convert_experiment (experiment )
145150
146- self ._add_indicators_to_conditions (problem )
151+ self ._add_indicators_to_conditions ()
147152
148- validation_results = problem .validate ()
153+ validation_results = self . _new_problem .validate ()
149154 validation_results .log ()
150155
151- return problem
156+ return self . _new_problem
152157
153- def _convert_experiment (self , problem : Problem , experiment : Experiment ):
158+ def _convert_experiment (self , experiment : Experiment ):
154159 """Convert a single experiment to SBML events."""
155160 model = self ._model
156161 experiment .sort_periods ()
157162 has_preequilibration = (
158- len (experiment .periods ) and experiment .periods [0 ].time == - inf
163+ len (experiment .periods )
164+ and experiment .periods [0 ].time == TIME_PREEQUILIBRATION
159165 )
160166
161167 # add experiment indicator
@@ -175,10 +181,12 @@ def _convert_experiment(self, problem: Problem, experiment: Experiment):
175181 # simulator -- we anyways keep the first period in the
176182 # returned Problem.
177183 raise NotImplementedError (
178- "Cannot represent non-zero initial time in SBML."
184+ f"The initial simulation time for experiment "
185+ f"`{ experiment .id } ` is nonzero: `{ period .time } `. "
186+ "This cannot be represented in SBML."
179187 )
180188
181- if period .time == - inf :
189+ if period .time == TIME_PREEQUILIBRATION :
182190 # pre-equilibration cannot be represented in SBML,
183191 # so we need to keep this period in the Problem.
184192 kept_periods .append (period )
@@ -192,15 +200,15 @@ def _convert_experiment(self, problem: Problem, experiment: Experiment):
192200 # or the only non-equilibration period (handled above)
193201 continue
194202
195- ev = self ._create_period_begin_event (
203+ ev = self ._create_period_start_event (
196204 experiment = experiment ,
197205 i_period = i_period ,
198206 period = period ,
199207 )
200208 self ._create_event_assignments_for_period (
201209 ev ,
202210 [
203- problem .condition_table [condition_id ]
211+ self . _new_problem .condition_table [condition_id ]
204212 for condition_id in period .condition_ids
205213 ],
206214 )
@@ -211,15 +219,15 @@ def _convert_experiment(self, problem: Problem, experiment: Experiment):
211219 # add conditions that set the indicator parameters
212220 for period in kept_periods :
213221 period .condition_ids = [
214- f"_petab_experiment_condition_ { experiment .id } " ,
222+ self . _get_experiment_indicator_condition_id ( experiment .id ) ,
215223 "_petab_preequilibration"
216- if period .time == - inf
224+ if period .time == TIME_PREEQUILIBRATION
217225 else "_petab_no_preequilibration" ,
218226 ]
219227
220228 experiment .periods = kept_periods
221229
222- def _create_period_begin_event (
230+ def _create_period_start_event (
223231 self , experiment : Experiment , i_period : int , period : ExperimentPeriod
224232 ) -> libsbml .Event :
225233 """Create an event that triggers at the beginning of a period."""
@@ -239,7 +247,7 @@ def _create_period_begin_event(
239247
240248 exp_ind_id = self .get_experiment_indicator (experiment .id )
241249
242- if period .time == - inf :
250+ if period .time == TIME_PREEQUILIBRATION :
243251 trig_math = libsbml .parseL3Formula (
244252 f"({ exp_ind_id } == 1) && ({ self ._preeq_indicator } == 1)"
245253 )
@@ -322,11 +330,12 @@ def _change_to_event_assignment(change: Change, event: libsbml.Event):
322330 sbml_model , id_ = sym .name , constant = True , value = 0
323331 )
324332
325- def _add_indicators_to_conditions (self , problem : Problem ) -> None :
333+ def _add_indicators_to_conditions (self ) -> None :
326334 """After converting the experiments to events, add the indicator
327335 parameters for the pre-equilibration period and for the different
328336 experiments to the remaining conditions.
329337 Then remove all other conditions."""
338+ problem = self ._new_problem
330339
331340 # create conditions for indicator parameters
332341 problem .condition_table .conditions .append (
@@ -347,17 +356,19 @@ def _add_indicators_to_conditions(self, problem: Problem) -> None:
347356 )
348357 # add conditions for the experiment indicators
349358 for experiment in problem .experiment_table .experiments :
359+ cond_id = self ._get_experiment_indicator_condition_id (
360+ experiment .id
361+ )
362+ changes = [
363+ Change (
364+ target_id = self .get_experiment_indicator (experiment .id ),
365+ target_value = 1 ,
366+ )
367+ ]
350368 problem .condition_table .conditions .append (
351369 Condition (
352- id = f"_petab_experiment_condition_{ experiment .id } " ,
353- changes = [
354- Change (
355- target_id = self .get_experiment_indicator (
356- experiment .id
357- ),
358- target_value = 1 ,
359- )
360- ],
370+ id = cond_id ,
371+ changes = changes ,
361372 )
362373 )
363374
0 commit comments