From 5c7d227a1994d47adb722455fd9aed10bbe0b752 Mon Sep 17 00:00:00 2001 From: Metehan Unal <13197858+metehanunal@users.noreply.github.com> Date: Wed, 16 Apr 2025 17:25:26 +0100 Subject: [PATCH 1/2] Model conversion and test are done --- sbol_utilities/sbol3_sbol2_conversion.py | 32 +++++++++++++++---- test/test_files/example_model_sbol2.xml | 11 +++++++ test/test_files/example_model_sbol2_tmp.xml | 12 +++++++ test/test_files/example_model_sbol2_tmp_2.xml | 12 +++++++ test/test_files/example_model_sbol3.ttl | 10 ++++++ test/test_files/generated_model_sbol3.ttl | 10 ++++++ test/test_sbol2_sbol3_direct.py | 21 ++++++++++++ 7 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 test/test_files/example_model_sbol2.xml create mode 100644 test/test_files/example_model_sbol2_tmp.xml create mode 100644 test/test_files/example_model_sbol2_tmp_2.xml create mode 100644 test/test_files/example_model_sbol3.ttl create mode 100644 test/test_files/generated_model_sbol3.ttl diff --git a/sbol_utilities/sbol3_sbol2_conversion.py b/sbol_utilities/sbol3_sbol2_conversion.py index ac44446f..fd3bac5c 100644 --- a/sbol_utilities/sbol3_sbol2_conversion.py +++ b/sbol_utilities/sbol3_sbol2_conversion.py @@ -1,3 +1,4 @@ +import sbol2.model import sbol3 import sbol2 from sbol2 import mapsto, model, sequenceconstraint @@ -226,9 +227,16 @@ def visit_measure(self, a: sbol3.Measure): # Priority: 3 raise NotImplementedError('Conversion of Measure from SBOL3 to SBOL2 not yet implemented') - def visit_model(self, a: sbol3.Model): - # Priority: 3 - raise NotImplementedError('Conversion of Model from SBOL3 to SBOL2 not yet implemented') + def visit_model(self, model3: sbol3.Model): + # Priority: 3 + model2 = sbol2.model.Model(uri=model3.identity, source=model3.source, + language=model3.language, framework=model3.framework) + self.doc2.add(model2) + # Map over all other TopLevel properties and extensions not covered by the constructor + self._convert_toplevel(model3, model2) + # seq2 = sbol2.Sequence(seq3.identity, seq3.elements, + # encoding=encoding2, + # version=self._sbol2_version(seq3)) def visit_participation(self, a: sbol3.Participation): # Priority: 2 @@ -257,7 +265,9 @@ def visit_sequence(self, seq3: sbol3.Sequence): sbol3.SMILES_ENCODING: sbol2.SBOL_ENCODING_SMILES} encoding2 = encoding_map.get(seq3.encoding, seq3.encoding) # Make the Sequence object and add it to the document - seq2 = sbol2.Sequence(seq3.identity, seq3.elements, encoding=encoding2, version=self._sbol2_version(seq3)) + seq2 = sbol2.Sequence(seq3.identity, seq3.elements, + encoding=encoding2, + version=self._sbol2_version(seq3)) self.doc2.addSequence(seq2) # Map over all other TopLevel properties and extensions not covered by the constructor self._convert_toplevel(seq3, seq2) @@ -496,9 +506,19 @@ def visit_measure(self, a: sbol2.measurement.Measurement): # Priority: 3 raise NotImplementedError('Conversion of Measure from SBOL2 to SBOL3 not yet implemented') - def visit_model(self, a: sbol2.model.Model): + def visit_model(self, model2: sbol2.model.Model): # Priority: 3 - raise NotImplementedError('Conversion of Model from SBOL2 to SBOL3 not yet implemented') + + model3 = sbol3.Model(model2.identity, source=model2.source, language=model2.language, + framework=model2.framework) + self.doc3.add(model3) + + # Map over all other TopLevel properties and extensions not covered by the constructor + self._convert_toplevel(model2, model3) + + + + def visit_module(self, a: sbol2.Module): # Priority: 3 diff --git a/test/test_files/example_model_sbol2.xml b/test/test_files/example_model_sbol2.xml new file mode 100644 index 00000000..978413f5 --- /dev/null +++ b/test/test_files/example_model_sbol2.xml @@ -0,0 +1,11 @@ + + + + + pIKE_Toggle_1 + pIKE_Toggle_1 toggle switch + + + + + \ No newline at end of file diff --git a/test/test_files/example_model_sbol2_tmp.xml b/test/test_files/example_model_sbol2_tmp.xml new file mode 100644 index 00000000..fa14cc88 --- /dev/null +++ b/test/test_files/example_model_sbol2_tmp.xml @@ -0,0 +1,12 @@ + + + + pIKE_Toggle_1 toggle switch + + + pIKE_Toggle_1 + + 1 + + + diff --git a/test/test_files/example_model_sbol2_tmp_2.xml b/test/test_files/example_model_sbol2_tmp_2.xml new file mode 100644 index 00000000..5ca40d9b --- /dev/null +++ b/test/test_files/example_model_sbol2_tmp_2.xml @@ -0,0 +1,12 @@ + + + pIKE_Toggle_1 + 1 + + + + + pIKE_Toggle_1 toggle switch + + + diff --git a/test/test_files/example_model_sbol3.ttl b/test/test_files/example_model_sbol3.ttl new file mode 100644 index 00000000..a5ceddc0 --- /dev/null +++ b/test/test_files/example_model_sbol3.ttl @@ -0,0 +1,10 @@ +@prefix sbol: . +@prefix ex: . +@prefix edam: . +@prefix sbo: . +@prefix xsd: . + +ex:mymodel a sbol:Model ; + sbol:source ; + sbol:language edam:format_2585 ; + sbol:framework sbo:SBO:0000064 . diff --git a/test/test_files/generated_model_sbol3.ttl b/test/test_files/generated_model_sbol3.ttl new file mode 100644 index 00000000..460c45fc --- /dev/null +++ b/test/test_files/generated_model_sbol3.ttl @@ -0,0 +1,10 @@ +@prefix sbol: . + + a sbol:Model ; + sbol:displayId "pIKE_Toggle_1" ; + sbol:framework ; + sbol:hasNamespace ; + sbol:language ; + sbol:name "pIKE_Toggle_1 toggle switch" ; + sbol:source . + diff --git a/test/test_sbol2_sbol3_direct.py b/test/test_sbol2_sbol3_direct.py index 94791fcf..21db3861 100644 --- a/test/test_sbol2_sbol3_direct.py +++ b/test/test_sbol2_sbol3_direct.py @@ -1,6 +1,9 @@ +from sbol2 import Config, ConfigOptions + import tempfile from pathlib import Path + import unittest import sbol2 @@ -129,6 +132,24 @@ def test_2to3_collection_conversion(self): doc2_loop.write(tmp2) self.assertFalse(file_diff(str(tmp2), str(TEST_FILES / 'sbol_3to2_collection.xml'))) + def test_2to3_and_3to2_model_conversion(self): + """Test ability to convert a model from SBOL2 to SBOL3""" + # Load an SBOL2 document and check its contents + Config.setOption(ConfigOptions.SBOL_COMPLIANT_URIS, False) + Config.setOption(ConfigOptions.SBOL_TYPED_URIS, False) + doc2 = sbol2.Document() + doc2.read(TEST_FILES / 'example_model_sbol2.xml') + model2 = doc2.models[0] + doc3 = convert2to3(doc2, use_native_converter=True) + self.assertEqual(len(doc3.validate()), 0) + doc3.write(TEST_FILES / 'generated_model_sbol3.ttl',file_format='turtle') + doc2_loop = convert3to2(doc3, True) + model2_loop = doc2_loop.models[0] + self.assertEqual(model2.language, model2_loop.language) + self.assertEqual(model2.framework, model2_loop.framework) + self.assertEqual(model2.source, model2_loop.source) + self.assertEqual(model2.name, model2_loop.name) + if __name__ == '__main__': unittest.main() From 351863a1555a53c2f14770099f8871c0a4e21568 Mon Sep 17 00:00:00 2001 From: Metehan Unal <13197858+metehanunal@users.noreply.github.com> Date: Thu, 17 Apr 2025 10:56:01 +0100 Subject: [PATCH 2/2] Removed the commenting lines introduced by GitHub --- test/test_sbol2_sbol3_direct.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/test_sbol2_sbol3_direct.py b/test/test_sbol2_sbol3_direct.py index e862673b..7cfaa8c3 100644 --- a/test/test_sbol2_sbol3_direct.py +++ b/test/test_sbol2_sbol3_direct.py @@ -20,7 +20,7 @@ class TestDirectSBOL2SBOL3Conversion(unittest.TestCase): # TODO: turn on validation # J23101.xml is not SBOL compliant. Leaving conversions involving it for after the compliant converter is done - ''' + def test_3to2_conversion(self): """Test ability to convert a simple part from SBOL3 to SBOL2""" # Load an SBOL3 document and check its contents @@ -39,10 +39,10 @@ def test_3to2_conversion(self): tmp3 = Path(tmpdir) / 'doc3_loop.nt' doc3_loop.write(tmp3) self.assertFalse(file_diff(str(tmp3), str(TEST_FILES / 'BBa_J23101_patched.nt'))) - ''' + # J23101.xml is not SBOL compliant. Leaving conversions involving it for after the compliant converter is done - ''' + def test_2to3_conversion(self): """Test ability to convert a simple part from SBOL2 to SBOL3""" # Load an SBOL2 document and check its contents @@ -61,10 +61,10 @@ def test_2to3_conversion(self): tmp2 = Path(tmpdir) / 'doc2_loop.xml' doc2_loop.write(tmp2) self.assertFalse(file_diff(str(tmp2), str(TEST_FILES / 'BBa_J23101.xml'))) - ''' + # sbol_3to2_implementation.xml is not SBOL compliant. Leaving conversions involving it for after the compliant converter is done - ''' + def test_3to2_implementation_conversion(self): """Test ability to convert an implementation from SBOL3 to SBOL2""" # Load an SBOL3 document and check its contents @@ -83,10 +83,10 @@ def test_3to2_implementation_conversion(self): tmp3 = Path(tmpdir) / 'doc3_loop.nt' doc3_loop.write(tmp3) self.assertFalse(file_diff(str(tmp3), str(TEST_FILES / 'sbol3_implementation.nt'))) - ''' + # sbol_3to2_implementation.xml is not SBOL compliant. Leaving conversions involving it for after the compliant converter is done - ''' + def test_2to3_implementation_conversion(self): """Test ability to convert an implementation from SBOL2 to SBOL3""" # Load an SBOL2 document and check its contents @@ -105,10 +105,10 @@ def test_2to3_implementation_conversion(self): tmp2 = Path(tmpdir) / 'doc2_loop.xml' doc2_loop.write(tmp2) self.assertFalse(file_diff(str(tmp2), str(TEST_FILES / 'sbol_3to2_implementation.xml'))) - ''' + # sbol_3to2_collection.xml is not SBOL compliant. Leaving conversions involving it for after the compliant converter is done - ''' + # sbol_3to2_collection.xml is not SBOL compliant. Leaving conversions involving it for after the compliant converter is done def test_3to2_collection_conversion(self): """Test ability to convert a collection from SBOL3 to SBOL2""" @@ -128,10 +128,10 @@ def test_3to2_collection_conversion(self): tmp3 = Path(tmpdir) / 'doc3_loop.nt' doc3_loop.write(tmp3) self.assertFalse(file_diff(str(tmp3), str(TEST_FILES / 'sbol3_collection.nt'))) - ''' + # sbol_3to2_collection.xml is not SBOL compliant. Leaving conversions involving it for after the compliant converter is done - ''' + def test_2to3_collection_conversion(self): """Test ability to convert a collection from SBOL2 to SBOL3""" # Load an SBOL2 document and check its contents