def test_namespace_deduced(self): namespace = 'https://github.com/synbiodex/pysbol3' identity = posixpath.join(namespace, 'collection1') collection = sbol3.Collection(identity) self.assertEqual(namespace, collection.namespace) # Now test a namespace with a trailing # identity2 = f'{namespace}#collection2' collection2 = sbol3.Collection(identity2) self.assertEqual(namespace, collection2.namespace)
def read_metadata(wb: openpyxl.Workbook, doc: sbol3.Document, config: dict): """ Extract metadata and build collections :param wb: Excel workbook to extract material from :param doc: SBOL document to build collections in :param config: dictionary of sheet parsing configuration variables :return: Tuple of SBOL collections for basic, composite, linear, and final parts """ # Read the metadata ws_b = wb[config['basic_sheet']] bp_name = ws_b[config['basic_parts_name']].value bp_description = ws_b[config['basic_parts_description']].value ws_c = wb[config['composite_sheet']] if config['composite_parts_name']: cp_name = ws_c[config['composite_parts_name']].value cp_description = ws_c[config['composite_parts_description']].value else: cp_name = bp_name cp_description = bp_description # Make the collections basic_parts = sbol3.Collection(BASIC_PARTS_COLLECTION, name=bp_name, description=bp_description) doc.add(basic_parts) composite_parts = sbol3.Collection(COMPOSITE_PARTS_COLLECTION, name=cp_name, description=cp_description) doc.add(composite_parts) linear_products = sbol3.Collection( LINEAR_PRODUCTS_COLLECTION, name='Linear DNA Products', description='Linear DNA constructs to be fabricated') doc.add(linear_products) final_products = sbol3.Collection( FINAL_PRODUCTS_COLLECTION, name='Final Products', description='Final products desired for actual fabrication') doc.add(final_products) # also collect any necessary data tables from extra sheets source_table = { row[config['source_name_col']].value: row[config['source_uri_col']].value for row in wb[config['sources_sheet']].iter_rows( min_row=config['sources_first_row']) if row[config['source_literal_col']].value } # return the set of created collections return basic_parts, composite_parts, linear_products, final_products, source_table
def test_namespace_set(self): # Test that namespace is properly set on an object after # using set_namespace() namespace = 'https://github.com/synbiodex/pysbol3' sbol3.set_namespace(namespace) collection = sbol3.Collection('collection1') self.assertEqual(namespace, collection.namespace)
def test_no_identity_exception(self): # See https://github.com/SynBioDex/pySBOL3/issues/357 sbol3.set_namespace('https://github.com/SynBioDex/pySBOL3') collection = sbol3.Collection('foo_collection') subc = sbol3.SubComponent( instance_of='https://github.com/SynBioDex/pySBOL3/c1') exc_regex = r'Object identity is uninitialized\.$' with self.assertRaisesRegex(ValueError, exc_regex): collection.members.append(subc)
def test_namespace_none(self): # Test the exception case when a namespace cannot be deduced identity = uuid.uuid4().urn collection = sbol3.Collection(identity) # The namespace should be None in this case. # We can't determine a namespace from a UUID and we don't # want to error and break file loading if we can't # determine a namespace. self.assertIsNone(collection.namespace)
def test_namespace_none(self): # Test the exception case when a namespace cannot be deduced identity = uuid.uuid4().urn collection = sbol3.Collection(identity) # The namespace should always be set per SBOL 3.0.1 # "A TopLevel object MUST have precisely one hasNamespace property" self.assertIsNotNone(collection.namespace) # There should be no validation errors on this object report = collection.validate() self.assertEqual(0, len(report))
def test_member_property(self): sbol3.set_namespace('https://github.com/synbiodex/pysbol3') self.assertTrue(hasattr(sbol3, 'SBOL_MEMBER')) collection = sbol3.Collection('collection1') self.assertIn(sbol3.SBOL_MEMBER, collection._properties) self.assertNotIn(sbol3.SBOL_ORIENTATION, collection._properties) uris = ['https://github.com/synbiodex/pysbol3/thing1', 'https://github.com/synbiodex/pysbol3/thing2'] collection.members = uris self.assertIn(sbol3.SBOL_MEMBER, collection._properties) self.assertNotIn(sbol3.SBOL_ORIENTATION, collection._properties) self.assertEqual(uris, collection.members)
def test_adding_referenced_objects(self): # Verify that sbol3 does not try to add objects # to the document when they are added to a referenced # object property. # # See https://github.com/SynBioDex/pySBOL3/issues/184 doc = sbol3.Document() sbol3.set_namespace('https://example.org') execution = sbol3.Activity('protocol_execution') doc.add(execution) foo = sbol3.Collection('http://example.org/baz') foo.members.append(execution) # Verify that foo did not get document assigned self.assertIsNone(foo.document) # Now explicitly add foo to the document and ensure # everything works as expected doc.add(foo) self.assertEqual(execution.identity, foo.members[0]) # Also verify that we can use lookup on the object # to get back to the original instance via document lookup self.assertEqual(execution.identity, foo.members[0].lookup().identity)
def derivation_to_collection( self, cd: sbol3.CombinatorialDerivation) -> sbol3.Collection: """Takes a CombinatorialDerivation and list of all those previously expanded, return a Collection of all of the variants generated from the CD, which have been added to its containing document Method: recursively instantiate all variables of the document We'll do this by a simple depth first search initially, since the numbers shouldn't be too large :param cd: derivation to expand :return: collection of derivative Components """ doc = cd.document sbol3.set_namespace( cd.namespace ) # use the namespace of the CD for all of its products sort_owned_objects(cd.template.lookup( )) # TODO: https://github.com/SynBioDex/pySBOL3/issues/231 # we've already converted this CombinatorialDerivation to a Collection, just return the conversion if cd in self.expanded_derivations.keys(): logging.debug('Found previous expansion of ' + cd.display_id) return self.expanded_derivations[cd] # if it doesn't already exist, we'll build it logging.debug("Expanding combinatorial derivation " + cd.display_id) # first get all of the values values = [ id_sort(self.cd_variable_values(v)) for v in id_sort(cd.variable_features) ] # if this is de facto a collection rather than a CD, just return it directly if is_library(cd): logging.debug("Interpreting combinatorial derivation " + cd.display_id + " as library") derivatives = sbol3.Collection(cd.identity + "_collection") doc.add(derivatives) derivatives.members += values[0] else: derivatives = sbol3.Collection(cd.identity + "_derivatives") doc.add(derivatives) # create a product-space of all of the possible assignments, then evaluate each in a scratch document assignments = itertools.product(*values) for a in assignments: # scratch_doc = sbol3.Document() derived = cd.template.lookup().clone( cd_assigment_to_display_id(cd, a)) logging.debug("Considering derived combination " + derived.display_id) # scratch_doc.add(derived) # add to the scratch document to enable manipulation of children doc.add( derived ) # add to the scratch document to enable manipulation of children # Replace variables with values newsubs = { derived.features[cd.template.lookup().features.index( f.variable.lookup())]: sbol3.SubComponent(v) for f, v in zip(id_sort(cd.variable_features), a) } for f in id_sort(newsubs.keys()): replace_feature(derived, f, newsubs[f]) # Need to remap everything that points to this feature as well # TODO: confirm that variant satisfies constraints # If constraints are satisfied, then copy back and add to success list # derived.copy(input_doc) derivatives.members.append(derived) # remember and return the collection of all successful derivatives self.expanded_derivations[cd] = derivatives return derivatives
def test_create(self): sbol3.set_namespace('https://github.com/synbiodex/pysbol3') collection = sbol3.Collection('collection1') self.assertIsNotNone(collection) self.assertEqual(0, len(collection.members)) self.assertEqual(sbol3.SBOL_COLLECTION, collection.type_uri)