From 5a693575bd33a87f7c04585c436e934143fdcf47 Mon Sep 17 00:00:00 2001 From: Philippe Rocca-Serra Date: Mon, 9 Sep 2024 15:01:39 +0100 Subject: [PATCH] adding a check on parameter values in write_study and write_assay methods --- isatools/isatab/dump/write.py | 15 ++++--- tests/isatab/test_isatab.py | 77 +++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/isatools/isatab/dump/write.py b/isatools/isatab/dump/write.py index bce3c2fb..51d7cbd3 100644 --- a/isatools/isatab/dump/write.py +++ b/isatools/isatab/dump/write.py @@ -151,9 +151,11 @@ def write_study_table_files(inv_obj, output_dir): protocol_in_path_count += 1 df_dict[olabel][-1] = node.executes_protocol.name for pv in node.parameter_values: - pvlabel = "{0}.Parameter Value[{1}]".format( - olabel, pv.category.parameter_name.term) - write_value_columns(df_dict, pvlabel, pv) + if pv.category: + pvlabel = "{0}.Parameter Value[{1}]".format(olabel, pv.category.parameter_name.term) + write_value_columns(df_dict, pvlabel, pv) + else: + raise(ValueError, "Protocol Value has no valid parameter_name") if node.date is not None: df_dict[olabel + ".Date"][-1] = node.date if node.performer is not None: @@ -405,8 +407,11 @@ def pbar(x): if node.performer is not None: df_dict[olabel + ".Performer"][-1] = node.performer for pv in node.parameter_values: - pvlabel = "{0}.Parameter Value[{1}]".format(olabel, pv.category.parameter_name.term) - write_value_columns(df_dict, pvlabel, pv) + if pv.category: + pvlabel = "{0}.Parameter Value[{1}]".format(olabel, pv.category.parameter_name.term) + write_value_columns(df_dict, pvlabel, pv) + else: + raise(ValueError, "Protocol Value has no valid parameter_name") for co in node.comments: colabel = "{0}.Comment[{1}]".format(olabel, co.name) df_dict[colabel][-1] = co.value diff --git a/tests/isatab/test_isatab.py b/tests/isatab/test_isatab.py index b7bef7c5..1e83d03e 100644 --- a/tests/isatab/test_isatab.py +++ b/tests/isatab/test_isatab.py @@ -512,6 +512,83 @@ def test_simple_investigation(self): self.assertEqual(i2.studies[0].samples[0].characteristics[0].value, investigation.studies[0].samples[0].characteristics[0].value) + def test_simple_investigation_protocol_well_formed_parameter_value_use(self): + unit_source = OntologySource(name='UO', description='Unit Ontology') + investigation = Investigation(ontology_source_references=[unit_source]) + unit = OntologyAnnotation(term='mg', term_source=unit_source) + concentration_category = OntologyAnnotation(term='concentration', term_source=unit_source) + concentration = Characteristic( + value=500, + unit=unit, + category=concentration_category + ) + protocol = Protocol(name="protest", protocol_type=OntologyAnnotation(term="extraction")) + parameter = ProtocolParameter(parameter_name="param_test") + protocol.parameters.append(parameter) + source = Source(name="source_1", id_="#isatest/source_1") + sample = Sample( + name='sample1', + id_="#isatest/sample1", + characteristics=[concentration] + ) + pv = ParameterValue(category=parameter, value="T4") + ps1 = Process(executes_protocol=protocol, parameter_values=[pv], inputs=[source], outputs=[sample]) + study = Study( + title='study1', + sources=[source], + samples=[sample], + units=[unit], + characteristic_categories=[concentration_category], + protocols=[protocol], + process_sequence=[ps1] + ) + investigation.studies = [study] + i_dict = investigation.to_dict() + + i2 = Investigation() + i2.from_dict(i_dict) + self.assertEqual(i2.studies[0].samples[0].characteristics[0].value, + investigation.studies[0].samples[0].characteristics[0].value) + self.assertEqual(i2.studies[0].process_sequence[0].parameter_values[0].value.term, "T4") + + + def test_simple_investigation_protocol_badly_formed_parameter_value_use(self): + unit_source = OntologySource(name='UO', description='Unit Ontology') + investigation = Investigation(ontology_source_references=[unit_source]) + unit = OntologyAnnotation(term='mg', term_source=unit_source) + concentration_category = OntologyAnnotation(term='concentration', term_source=unit_source) + concentration = Characteristic( + value=500, + unit=unit, + category=concentration_category + ) + protocol = Protocol(name="protest", protocol_type=OntologyAnnotation(term="extraction")) + parameter = ProtocolParameter(parameter_name="param_test") + protocol.parameters.append(parameter) + source = Source(name="source_1", id_="#isatest/source_1") + sample = Sample( + name='sample1', + id_="#isatest/sample1", + characteristics=[concentration] + ) + pv = ParameterValue(value="T4") # declaration of a parameter value without a catogory + ps1 = Process(executes_protocol=protocol, parameter_values=[pv], inputs=[source], outputs=[sample]) + study = Study( + title='study1', + sources=[source], + samples=[sample], + units=[unit], + characteristic_categories=[concentration_category], + protocols=[protocol], + process_sequence=[ps1] + ) + investigation.studies = [study] + + with self.assertRaises(ValueError): + isatab.dump(investigation, self._tmp_dir, i_file_name='i_investigation.txt') + # my_json_report_isa_flux = isatab.validate(open(os.path.join(self._tab_data_dir, "issue-569", "i_investigation.txt"))) + # print(my_json_report_isa_flux) + def test_isatab_dump_investigation_with_assay(self): # Create an empty Investigation object and set some values to the # instance variables.