From a635a277ee1286a25b641fdaedde1eed14704b11 Mon Sep 17 00:00:00 2001 From: Logan Drescher Date: Fri, 4 Oct 2024 15:39:13 -0400 Subject: [PATCH] removed 0 duration sim logic --- biosimulators_copasi/core.py | 16 ++++------------ biosimulators_copasi/data_model.py | 14 ++++---------- tests/test_core.py | 23 +++++++++++++++-------- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/biosimulators_copasi/core.py b/biosimulators_copasi/core.py index 7a07b48..8568977 100644 --- a/biosimulators_copasi/core.py +++ b/biosimulators_copasi/core.py @@ -191,9 +191,6 @@ def exec_sed_task(task: Task, variables: List[Variable], preprocessed_task: Opti # prepare task basico.set_task_settings(preprocessed_task.task_type, preprocessed_task.get_simulation_configuration()) - # temporary work around for issue with 0.0 duration tasks - basico_task_settings = basico.get_task_settings(basico.T.TIME_COURSE) - # Execute Simulation data: pandas.DataFrame dh: COPASI.CDataHandler @@ -229,15 +226,10 @@ def exec_sed_task(task: Task, variables: List[Variable], preprocessed_task: Opti if not first_sub_series.equals(series.iloc[:, i]): raise RuntimeError("Different data sets for same variable") series: pandas.Series = first_sub_series - - if basico_task_settings["problem"]["Duration"] > 0.0: - variable_results[variable.id] = numpy.full(copasi_output_length, numpy.nan) - for index, value in enumerate(series): - adjusted_value = value if data_target != "Time" else value + offset - variable_results[variable.id][index] = adjusted_value - else: - value = series.get(0) if data_target != "Time" else series.get(0) + offset - variable_results[variable.id] = numpy.full(copasi_output_length, value) + variable_results[variable.id] = numpy.full(copasi_output_length, numpy.nan) + for index, value in enumerate(series): + adjusted_value = value if data_target != "Time" else value + offset + variable_results[variable.id][index] = adjusted_value except Exception as e: raise e diff --git a/biosimulators_copasi/data_model.py b/biosimulators_copasi/data_model.py index 04c6de1..d1665d4 100644 --- a/biosimulators_copasi/data_model.py +++ b/biosimulators_copasi/data_model.py @@ -984,6 +984,8 @@ def configure_simulation_settings(self, sim: Union[UniformTimeCourseSimulation, self.task_type = basico.T.TIME_COURSE self.init_time_offset: float = self.sim.initial_time self._duration_arg: float = self.sim.output_end_time - self.init_time_offset # COPASI is kept in the dark + if self._duration_arg <= 0: + raise ValueError("A simulation's initial_time can not be equal to or greater than the output end time.") self._step_size: float = BasicoInitialization._calc_biosimulators_simulation_step_size(self.sim) # What COPASI understands as number of steps and what biosimulators # understands as number of steps is different; we must manually calculate @@ -1044,15 +1046,7 @@ def generate_data_handler(self, output_selection: list[str]): @staticmethod def _calc_biosimulators_simulation_step_size(sim: UniformTimeCourseSimulation) -> int: - if sim.output_end_time - sim.output_start_time < 0: + if (time_diff := sim.output_end_time - sim.output_start_time) <= 0: raise ValueError('Output end time must be greater than the output start time.') - try: - time_diff = sim.output_end_time - sim.output_start_time - if time_diff == 0: - raise ZeroDivisionError # We want to have exactly 1 step, and that's what our except block does - step_size_arg = time_diff / sim.number_of_steps - except ZeroDivisionError: # sim.output_end_time == sim.output_start_time - step_size_arg = sim.number_of_points - - return step_size_arg + return time_diff / sim.number_of_steps diff --git a/tests/test_core.py b/tests/test_core.py index 1bbf9d6..f02e1eb 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -841,6 +841,9 @@ def test_raw_cli(self): def test_exec_sedml_docs_in_combine_archive_with_cli(self): doc, archive_filename = self._build_combine_archive() + self._prepare_and_assert_combine_archive_outputs(doc, archive_filename) + + def _prepare_and_assert_combine_archive_outputs(self, doc: sedml_data_model.SedDocument, archive_filename: str): out_dir = os.path.join(self.directory_name, 'out') env = TestCore._get_combine_archive_exec_env() @@ -867,14 +870,17 @@ def test_exec_sedml_docs_in_combine_archive_with_docker_image(self): self._assert_combine_archive_outputs(doc, out_dir) - def _build_combine_archive(self, algorithm=None, orig_model_filename='model.xml', var_targets=None): + def _build_combine_archive(self, algorithm: sedml_data_model.Algorithm = None, + orig_model_filename: str = 'model.xml', var_targets: str = None, + initial_time: float = 0., output_start_time: float = 0.1, output_end_time: float = 0.2): if var_targets is None: var_targets = [None, 'A', 'C', 'DA'] - doc = self._build_sed_doc(algorithm=algorithm) + doc = self._build_sed_doc(algorithm=algorithm, initial_time=initial_time, + output_start_time=output_start_time, output_end_time=output_end_time) for data_gen, target in zip(doc.data_generators, var_targets): if target is not None: - data_gen.variables[0].target = "/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='{}']".format(target) + data_gen.variables[0].target = f"/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='{target}']" archive_dirname = os.path.join(self.directory_name, 'archive') if not os.path.isdir(archive_dirname): @@ -897,12 +903,13 @@ def _build_combine_archive(self, algorithm=None, orig_model_filename='model.xml' ], ) archive_filename = os.path.join(self.directory_name, - 'archive.omex' if algorithm is None else 'archive-{}.omex'.format(algorithm.kisao_id)) + 'archive.omex' if algorithm is None else f'archive-{algorithm.kisao_id}.omex') CombineArchiveWriter().run(archive, archive_dirname, archive_filename) return doc, archive_filename - def _build_sed_doc(self, algorithm=None): + def _build_sed_doc(self, algorithm: sedml_data_model.Algorithm = None, initial_time: float = 0., + output_start_time: float = 0.1, output_end_time: float = 0.2): if algorithm is None: algorithm = sedml_data_model.Algorithm( kisao_id='KISAO_0000304', @@ -924,9 +931,9 @@ def _build_sed_doc(self, algorithm=None): doc.simulations.append(sedml_data_model.UniformTimeCourseSimulation( id='sim_1_time_course', algorithm=algorithm, - initial_time=0., - output_start_time=0.1, - output_end_time=0.2, + initial_time=initial_time, + output_start_time=output_start_time, + output_end_time=output_end_time, number_of_points=20, )) doc.tasks.append(sedml_data_model.Task(