diff --git a/petab/v2/converters.py b/petab/v2/converters.py index 1c9acfd8..d47412c3 100644 --- a/petab/v2/converters.py +++ b/petab/v2/converters.py @@ -249,6 +249,14 @@ def _convert_experiment(self, experiment: Experiment) -> None: # single-period experiments. if i_period == 0: exp_ind_id = self.get_experiment_indicator(experiment.id) + # Skip if condition ids are set by array data + # importers handle this + if self._new_problem.extensions.sciml: + if set(period.condition_ids).issubset( + self._new_problem.extensions.sciml._get_array_data_condition_ids() + ): + continue + for change in self._new_problem.get_changes_for_period(period): period0_assignments.setdefault( change.target_id, [] diff --git a/petab/v2/extensions/sciml.py b/petab/v2/extensions/sciml.py index 808b0643..58189279 100644 --- a/petab/v2/extensions/sciml.py +++ b/petab/v2/extensions/sciml.py @@ -303,3 +303,12 @@ def from_config( hybridization_tables=hybridization_tables, array_data_files=array_data_files, ) + + def _get_array_data_condition_ids(self) -> set[str]: + """Get the set of condition IDs that are referenced in the array data + files.""" + condition_ids = set() + for array_data in self.array_data_files: + for input in array_data.inputs.values(): + condition_ids.update(input.keys()) + return condition_ids diff --git a/petab/v2/lint.py b/petab/v2/lint.py index c6fef280..80f47b04 100644 --- a/petab/v2/lint.py +++ b/petab/v2/lint.py @@ -532,6 +532,13 @@ class CheckExperimentConditionsExist(ValidationTask): def run(self, problem: Problem) -> ValidationIssue | None: messages = [] available_conditions = {c.id for c in problem.conditions} + if problem.extensions.sciml: + available_conditions |= { + key + for array_data in problem.extensions.sciml.array_data_files + for input_array in array_data.inputs.values() + for key in input_array.keys() + } for experiment in problem.experiments: missing_conditions = ( set( diff --git a/tests/v2/test_sciml.py b/tests/v2/test_sciml.py index d743c082..390605ec 100644 --- a/tests/v2/test_sciml.py +++ b/tests/v2/test_sciml.py @@ -48,9 +48,9 @@ def _get_test_problem(): -> B; gamma_; end """) - problem.add_experiment("e1", 0, "") + problem.add_experiment("e1", 0, "cond1") problem.add_mapping("net1_input1", "net1.inputs[0][0]") - problem.add_mapping("net1_input2", "net1.inputs[0][1]") + problem.add_mapping("net1_input2", "net1.inputs[1]") problem.add_mapping("net1_output1", "net1.outputs[0][0]") problem.add_mapping("net1_ps", "net1.parameters") problem.add_measurement("B_obs", time=1, measurement=1, experiment_id="e1") @@ -62,7 +62,7 @@ def _get_test_problem(): "net1_ps", estimate=True, lb=-np.inf, ub=np.inf, nominal_value="array" ) problem.extensions.sciml.add_hybridization("net1_input1", "A") - problem.extensions.sciml.add_hybridization("net1_input2", "B") + problem.extensions.sciml.add_hybridization("net1_input2", "array") problem.extensions.sciml.add_hybridization("gamma_", "net1_output1") problem.extensions.sciml.add_neural_network_from_dict( "net1", @@ -106,7 +106,11 @@ def _get_test_problem(): problem.extensions.sciml.add_array_data_from_dict( { "metadata": {"pytorch_format": True}, - "inputs": {}, + "inputs": { + "net1_input2": { + "cond1": np.random.randn(2), + } + }, "parameters": { "net1": { "layer1": {