Esempio n. 1
0
 def test_create(self):
     sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
     instance_of = sbol3.Component('comp1', sbol3.SBO_DNA)
     sc1 = sbol3.SubComponent(instance_of)
     self.assertIsNotNone(sc1)
     self.assertEqual(instance_of.identity, sc1.instance_of)
     sc2 = sbol3.SubComponent(instance_of.identity)
     self.assertEqual(instance_of.identity, sc2.instance_of)
Esempio n. 2
0
 def test_cloning_with_children(self):
     # This test does not use `sbol3.set_namespace` as the other
     # cloning unit tests do. This is on purpose to verify that
     # cloning does not rely on the default namespace.
     doc = sbol3.Document()
     namespace = 'https://github.com/synbiodex/pysbol3'
     c1_identity = posixpath.join(namespace, 'c1')
     c2_identity = posixpath.join(namespace, 'c2')
     s1_identity = posixpath.join(namespace, 's1')
     c1 = sbol3.Component(c1_identity, sbol3.SBO_DNA)
     doc.add(c1)
     seq1 = sbol3.Sequence(s1_identity)
     doc.add(seq1)
     c1.sequences.append(seq1)
     sc1 = sbol3.SubComponent(c1)
     es1 = sbol3.EntireSequence(seq1)
     sc1.source_locations.append(es1)
     c1.features = [sc1]
     c2 = c1.clone(c2_identity)
     self.assertEqual(c2_identity, c2.identity)
     self.assertIsNone(c2.document)
     # Check on the SubComponent
     sc2 = c2.features[0]
     self.assertIsInstance(sc2, sbol3.SubComponent)
     self.assertNotEqual(sc1.identity, sc2.identity)
     self.assertTrue(sc2.identity.startswith(c2.identity))
     # Ensure that the reference was updated properly
     self.assertEqual(c2.identity, sc2.instance_of)
     self.assertIsNone(sc2.document)
     es2 = sc2.source_locations[0]
     self.assertIsInstance(es2, sbol3.EntireSequence)
     self.assertNotEqual(es1.identity, es2.identity)
     self.assertTrue(es2.identity.startswith(c2.identity))
     self.assertEqual(es1.sequence, es2.sequence)
     self.assertIsNone(es2.document)
Esempio n. 3
0
 def test_copy_stability(self):
     # Test the stability of naming of objects across copies.
     # See https://github.com/SynBioDex/pySBOL3/issues/231
     #
     # Strategy: create an object with 10+ children of the same
     # type. Add to a document and serialize the document. Load the
     # serialized document. Copy the object to a new document.
     # Serialize the new document. Compare the serializations. If we
     # use sorted ntriples, the serializations should be the same.
     # This will demonstrate that we maintain names properly despite
     # the inherently unordered nature of SBOL.
     sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
     c1 = sbol3.Component('c1', types=[sbol3.SBO_DNA])
     # Create a double-digit number of children to test sort of 10, 11, 1, etc.
     for i in range(12):
         instance_of_uri = f'https://example.com/instance/i{i}'
         c1.features.append(sbol3.SubComponent(instance_of=instance_of_uri))
     doc1 = sbol3.Document()
     doc1.add(c1)
     # Serialize to string
     doc1_string = doc1.write_string(sbol3.SORTED_NTRIPLES)
     self.assertIsNotNone(doc1_string)
     # Load the serialized document into a new document
     tmp_doc = sbol3.Document()
     tmp_doc.read_string(doc1_string, sbol3.SORTED_NTRIPLES)
     # Locate the top level to copy
     tmp_c1 = tmp_doc.find('c1')
     self.assertIsNotNone(tmp_c1)
     self.assertIsInstance(tmp_c1, sbol3.TopLevel)
     # Copy the top level into a new document
     doc2 = sbol3.Document()
     sbol3.copy([tmp_c1], into_document=doc2)
     doc2_string = doc2.write_string(sbol3.SORTED_NTRIPLES)
     # Verify that the serializations are identical
     self.assertEqual(doc1_string, doc2_string)
Esempio n. 4
0
 def test_shacl_closure_with_child_objects(self):
     # See https://github.com/SynBioDex/pySBOL3/issues/348
     # See https://github.com/SynBioDex/pySBOL3/issues/353
     sbol3.set_namespace('https://github.com/SynBioDex/pySBOL3')
     doc = sbol3.Document()
     c_top = sbol3.Component('top', sbol3.SBO_DNA)
     c_middle = sbol3.Component('middle', sbol3.SBO_DNA)
     c_bottom = sbol3.Component('bottom', sbol3.SBO_DNA)
     subc_middle = sbol3.SubComponent(c_middle)
     c_top.features = [subc_middle]
     subc_bottom = sbol3.SubComponent(c_bottom)
     c_middle.features = [subc_bottom]
     subc_bottom_ref = sbol3.ComponentReference(in_child_of=subc_middle, refers_to=subc_bottom)
     c_top.features.append(subc_bottom_ref)
     doc.add(c_top)
     self.assertFalse(len(doc.validate()))
Esempio n. 5
0
 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)
Esempio n. 6
0
    def test_copy_child_objects(self):
        sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
        doc = sbol3.Document()
        root = sbol3.Component('root', sbol3.SBO_DNA)
        sub1 = sbol3.Component('sub1', sbol3.SBO_DNA)
        sub2 = sbol3.Component('sub2', sbol3.SBO_DNA)
        sc1 = sbol3.SubComponent(sub1)
        sc2 = sbol3.SubComponent(sub2)
        root.features.append(sc1)
        root.features.append(sc2)
        doc.add(root)
        doc.add(sub1)
        doc.add(sub2)

        doc2 = sbol3.Document()
        root_copy = root.copy(target_doc=doc2)
        self.assertEqual([sc.identity for sc in root.features],
                         [sc.identity for sc in root_copy.features])
Esempio n. 7
0
 def test_external_instance_of(self):
     # See https://github.com/SynBioDex/pySBOL3/issues/136
     c_uri = 'https://synbiohub.example.org/component1'
     m9_media = 'https://synbiohub.example.org/m9-media'
     e_coli = 'https://synbiohub.example.org/e-coli-DH5-alpha'
     c = sbol3.Component(c_uri, sbol3.SBO_DNA)
     sc1 = sbol3.SubComponent(m9_media)
     sc2 = sbol3.SubComponent(e_coli)
     c.features = [sc1, sc2]
     self.assertEqual(len(c.features), 2)
     doc1 = sbol3.Document()
     doc1.add(c)
     doc2 = sbol3.Document()
     doc2.read_string(doc1.write_string(sbol3.NTRIPLES), sbol3.NTRIPLES)
     c2 = doc2.find(c_uri)
     self.assertIsNotNone(c2)
     self.assertEqual(2, len(c2.features))
     self.assertCountEqual([m9_media, e_coli],
                           [sc.instance_of for sc in c2.features])
Esempio n. 8
0
 def test_shacl_closure_simple(self):
     # This is a very small test case to reproduce the issue at the
     # center of https://github.com/SynBioDex/pySBOL3/issues/348
     sbol3.set_namespace('https://github.com/SynBioDex/pySBOL3')
     other_component = 'https://github.com/SynBioDex/pySBOL3/other_c'
     sc = sbol3.SubComponent(instance_of=other_component)
     c = sbol3.Component('c1', types=[sbol3.SBO_DNA], features=[sc])
     doc = sbol3.Document()
     doc.add(c)
     report = doc.validate()
     self.assertEqual(0, len(report))
Esempio n. 9
0
def add_feature(
        component: sbol3.Component,
        to_add: Union[sbol3.Feature, sbol3.Component]) -> sbol3.Feature:
    """Pass-through adder for adding a Feature to a Component for allowing slightly more compact code.
    Note that unlike ensure_singleton_feature, this allows adding multiple instances

    :param component: Component to add the Feature to
    :param to_add: Feature or Component to be added to system. Components will be wrapped in a SubComponent Feature
    :return: feature added (SubComponent if to_add was a Component)
    """
    if isinstance(to_add, sbol3.Component):
        to_add = sbol3.SubComponent(to_add)
    component.features.append(to_add)
    return to_add
Esempio n. 10
0
 def test_list_wrapping(self):
     # Ensure that at least certain properties handle automatic list
     # wrapping and are typed to do so.
     # See https://github.com/SynBioDex/pySBOL3/issues/301
     sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
     instance_uri = 'https://example.org/instance'
     seq1 = sbol3.Sequence('seq1')
     test_loc = sbol3.EntireSequence(seq1)
     seq2 = sbol3.Sequence('seq2')
     test_source_loc = sbol3.EntireSequence(seq1)
     subcomp1 = sbol3.SubComponent(instance_of=instance_uri,
                                   locations=test_loc,
                                   source_locations=test_source_loc)
     self.assertEqual([test_loc], subcomp1.locations)
     self.assertEqual([test_source_loc], subcomp1.source_locations)
Esempio n. 11
0
def make_combinatorial_derivation(document, display_id, part_lists,
                                  reverse_complements, constraints):
    # Make the combinatorial derivation and its template
    template = sbol3.Component(display_id + "_template", sbol3.SBO_DNA)
    document.add(template)
    cd = sbol3.CombinatorialDerivation(display_id, template)
    cd.strategy = sbol3.SBOL_ENUMERATE
    # for each part, make a SubComponent or LocalSubComponent in the template and link them together in sequence
    template_part_list = []
    for part_list, rc in zip(part_lists, reverse_complements):
        # it's a variable if there are multiple values or if there's a single value that's a combinatorial derivation
        if len(part_list) > 1 or not isinstance(part_list[0], sbol3.Component):
            sub = sbol3.LocalSubComponent({sbol3.SBO_DNA
                                           })  # make a template variable
            sub.name = "Part " + str(len(template_part_list) + 1)
            template.features.append(sub)
            var = sbol3.VariableFeature(cardinality=sbol3.SBOL_ONE,
                                        variable=sub)
            cd.variable_features.append(var)
            # add all of the parts as variables
            for part in part_list:
                if isinstance(part, sbol3.Component): var.variants.append(part)
                elif isinstance(part, sbol3.CombinatorialDerivation):
                    var.variant_derivations.append(part)
                else:
                    raise ValueError(
                        "Don't know how to make library element for " +
                        part.name + ", a " + str(part))
        else:  # otherwise it's a fixed element of the template
            sub = sbol3.SubComponent(part_list[0])
            template.features.append(sub)
        # in either case, orient and order the template elements
        sub.orientation = (sbol3.SBOL_REVERSE_COMPLEMENT
                           if rc else sbol3.SBOL_INLINE)
        if template_part_list:
            template.constraints.append(
                sbol3.Constraint(sbol3.SBOL_MEETS, template_part_list[-1],
                                 sub))
        template_part_list.append(sub)
    # next, add all of the constraints to the template
    #template.constraints = (make_constraint(c.strip(),template_part_list) for c in (constraints.split(',') if constraints else [])) # impacted by pySBOL3 appending
    c_list = (make_constraint(c.strip(), template_part_list)
              for c in (constraints.split(',') if constraints else []))
    for c in c_list:
        template.constraints.append(c)
    # return the completed part
    return cd
Esempio n. 12
0
def make_composite_component(display_id, part_lists, reverse_complements):
    # Make the composite as an engineered region
    composite_part = sbol3.Component(display_id, sbol3.SBO_DNA)
    composite_part.roles.append(sbol3.SO_ENGINEERED_REGION)
    # for each part, make a SubComponent and link them together in sequence
    last_sub = None
    for part_list, rc in zip(part_lists, reverse_complements):
        if not len(part_list) == 1:
            raise ValueError(
                f'Part list should have precisely one element, but is {part_list}'
            )
        sub = sbol3.SubComponent(part_list[0])
        sub.orientation = (sbol3.SBOL_REVERSE_COMPLEMENT
                           if rc else sbol3.SBOL_INLINE)
        composite_part.features.append(sub)
        if last_sub:
            composite_part.constraints.append(
                sbol3.Constraint(sbol3.SBOL_MEETS, last_sub, sub))
        last_sub = sub
    # return the completed part
    return composite_part
Esempio n. 13
0
    def to_sbol(self, sbol_doc: sbol3.Document = None) -> sbol3.Document:
        """Convert the genetic network to SBOL.
        :param sbol_doc: The SBOL document to add the genetic network to.
        """
        if sbol_doc:
            doc=sbol_doc
        else: 
            print('No SBOL Document provided')
            print('Generating a new SBOL Document')
            doc = sbol3.Document()
        products = set()
        geneticnetwork = sbol3.Component('geneticnetwork', sbol3.SBO_DNA)
        geneticnetwork.roles.append(sbol3.SO_ENGINEERED_REGION)
        loica_set = set()
        for op in self.operators:
            # Operator Component
            operator_comp = op.sbol_comp
            operator_sc = sbol3.SubComponent(operator_comp)
            # GeneProduct Outputs Component 
            output_str = ''
            output_scs = []
            if type(op.output) != list:
                outputs = [op.output]
            else: 
                outputs = op.output
            for op_output in outputs:
                output_comp = op_output.sbol_comp
                output_scs.append(sbol3.SubComponent(output_comp))
                output_str += f'_{op_output.name}'
            # TODO output string for policistronic operators
            # TU Component
            if type(op)==Source:
                input_str= 'c'
                tu = sbol3.Component(f'TU_{input_str}_{op}{output_str}', sbol3.SBO_DNA) #generalize to multi input/output TUs
                tu.roles.append(sbol3.SO_ENGINEERED_REGION)
                tu.features = [operator_sc] 
                for sc in output_scs:
                    tu.features.append(sc)
            elif type(op)==Hill2: # type(op.input)==List:
                input_str = ''
                for inp in op.input:
                    input_str += f'_{inp.name}'
                tu = sbol3.Component(f'TU{input_str}_{op}{output_str}', sbol3.SBO_DNA) #generalize to multi input/output TUs
                tu.features = [operator_sc] 
                for sc in output_scs:
                    tu.features.append(sc)
                for inp in op.input:
                    input_comp = inp.sbol_comp
                    if type(input_comp)==sbol3.Component:
                        input_sc = sbol3.SubComponent(input_comp)
                        tu.features.append(input_sc)
                    else:
                        tu.features.append(input_comp)
            else:
                input_str= f'_{op.input.name}'
                tu = sbol3.Component(f'TU{input_str}_{op}{output_str}', sbol3.SBO_DNA) #generalize to multi input/output TUs
                tu.features = [operator_sc] 
                for sc in output_scs:
                    tu.features.append(sc)
                input_comp = op.input.sbol_comp
                if type(input_comp)==sbol3.Component:
                    input_sc = sbol3.SubComponent(input_comp)
                    tu.features.append(input_sc)
                else:
                    tu.features.append(input_comp)                  

            tu.roles.append(sbol3.SO_ENGINEERED_REGION)
            for i in range(len(tu.features)-1):
                constraint = sbol3.Constraint(sbol3.SBOL_PRECEDES, tu.features[i], tu.features[i + 1])
                tu.constraints = [constraint]              
            #tu.constraints = [sbol3.Constraint(sbol3.SBOL_PRECEDES, operator_sc, output_sc)]
            # generate a sequence for the TU assuming assembly by type IIS REsnf both parts will have the fusion sites.
            # compare last 4 bp with thefirst 4 bp of the next part, given the preceds constraint.
            # if they are the same then delete one of them and concatenate the rest.
            # else error or comment TU sequence can not be generated, provide ways to add it.

            # Output GeneProduct Component
            for op_output, sc in zip(outputs, output_scs): #make list of tuples? for output_participation
                if type(op_output)==Regulator:
                    if op_output.type_ == 'PRO':
                        output_gp_comp = sbol3.Component(f'{op_output.name}_protein', sbol3.SBO_PROTEIN)
                        output_gp_comp.roles.append(sbol3.SO_TRANSCRIPTION_FACTOR)               
                    elif op_output.type_ == 'RNA':
                        output_gp_comp = sbol3.Component(f'{op_output.name}_rna', sbol3.SBO_RNA)
                        output_gp_comp.roles.append(sbol3.SO_TRANSCRIPTION_FACTOR)
                    else: 
                        print('Unsupported output molecule type')
                elif type(op_output)==Reporter: # For now just support fluorescent reporters
                    if op_output.type_ == 'PRO':
                        output_gp_comp = sbol3.Component(f'{op_output.name}_protein', sbol3.SBO_PROTEIN)
                        output_gp_comp.roles.append('http://purl.obolibrary.org/obo/NCIT_C37894')
                    elif op_output.type_ == 'RNA':
                        output_gp_comp = sbol3.Component(f'{op_output.name}_rna', sbol3.SBO_RNA)
                        output_gp_comp.roles.append('http://purl.obolibrary.org/obo/NCIT_C37894')  
                    else: 
                            print('Unsupported output molecule type')
                else:
                    print('Unsupported output Type')
                output_gp_sc = sbol3.SubComponent(output_gp_comp)
                tu.features.append(output_gp_sc)
                if op_output not in products:
                    products.add(op_output) 
                    loica_set.add(output_gp_comp)
                # Genetic Production Interaction pf the output
                output_participation = sbol3.Participation(roles=[sbol3.SBO_TEMPLATE], participant=sc)
                gp_participation = sbol3.Participation(roles=[sbol3.SBO_PRODUCT], participant=output_gp_sc)
                production = sbol3.Interaction(types=[sbol3.SBO_GENETIC_PRODUCTION], participations=[output_participation, gp_participation])
                tu.interactions.append(production)
            # obtain TU subcomponents sequences, specially CDS and flanking parts sequences
            # look for ATG on the CDS and upstream part sequences (in the case of MoClo the ATG is in the fusion sites)
            # look for stop codons on frame with the ATG.
            # add translated the sequence between the ATG and the stop codon as protein sequence.
            #protein.sequence = tu.cds.sequence

            # Input Product Component
            if type(op) == Source:
                inputs=[]
            elif type(op) == Hill2: #type(op.input) != List:
                inputs = op.input
            else: inputs = [op.input]
            #inputs_prod_sc = []
            for op_input in inputs:
                if type(op_input)==Regulator:
                    if op_input.type_ == 'PRO':
                        input_prod_comp = sbol3.Component(f'{op_input.name}_protein', sbol3.SBO_PROTEIN)
                        input_prod_comp.roles.append(sbol3.SO_TRANSCRIPTION_FACTOR)               
                    elif op_input.type_ == 'RNA':
                        input_prod_comp = sbol3.Component(f'{op_input.name}_rna', sbol3.SBO_RNA)
                        input_prod_comp.roles.append(sbol3.SO_TRANSCRIPTION_FACTOR)
                    else: 
                        print('Unsupported input molecule type')
                elif type(op_input)==Supplement:
                    input_prod_comp = sbol3.Component(f'{op_input.name}_chemical', sbol3.SBO_SIMPLE_CHEMICAL)
                    input_prod_comp.roles.append(sbol3.SO_TRANSCRIPTION_FACTOR)     
                else:
                    print('Unsupported input Type')
                # adds two times prod comp on the repressilator but necessary for normal circuits
                if op_input not in products:
                    products.add(op_input) 
                    loica_set.add(input_prod_comp)
                
                input_prod_sc = sbol3.SubComponent(input_prod_comp)
                tu.features.append(input_prod_sc)
                #inputs_prod_sc.append(input_prod_sc)
                #how can I not create 2 times the same component?
                if type(op_input)!=Regulator: # if it is a regulator it is already created
                    loica_set.add(input_prod_comp)
                 # Input Interaction
                if type(op)==Hill1 and op.alpha[0]>op.alpha[1]:
                    input_participation = sbol3.Participation(roles=[sbol3.SBO_INHIBITOR], participant=input_prod_sc)
                    op_participation = sbol3.Participation(roles=[sbol3.SBO_INHIBITED], participant=operator_sc)
                    interaction = sbol3.Interaction(types=[sbol3.SBO_INHIBITION], participations=[input_participation, op_participation])
                    tu.interactions.append(interaction)
                elif type(op)==Hill2 and op.alpha[0]== max(op.alpha):
                    input_participation = sbol3.Participation(roles=[sbol3.SBO_INHIBITOR], participant=input_prod_sc)
                    op_participation = sbol3.Participation(roles=[sbol3.SBO_INHIBITED], participant=operator_sc)
                    interaction = sbol3.Interaction(types=[sbol3.SBO_INHIBITION], participations=[input_participation, op_participation])
                    tu.interactions.append(interaction)
                elif type(op)==Receiver:
                    input_participation = sbol3.Participation(roles=[sbol3.SBO_STIMULATOR], participant=input_prod_sc)
                    op_participation = sbol3.Participation(roles=[sbol3.SBO_STIMULATED], participant=operator_sc)
                    interaction = sbol3.Interaction(types=[sbol3.SBO_STIMULATION], participations=[input_participation, op_participation])
                    tu.interactions.append(interaction)
                elif type(op)==Hill1 and op.alpha[0]<op.alpha[1]:
                    input_participation = sbol3.Participation(roles=[sbol3.SBO_STIMULATOR], participant=input_prod_sc)
                    op_participation = sbol3.Participation(roles=[sbol3.SBO_STIMULATED], participant=operator_sc)
                    interaction = sbol3.Interaction(types=[sbol3.SBO_STIMULATION], participations=[input_participation, op_participation])
                    tu.interactions.append(interaction)
                elif type(op)==Source:
                    pass
                else:
                    print('Unsupported operator Type')         
            # Model
            #model_string = str(op.__dict__)
            op_model = sbol3.Model(f'LOICA{input_str}_{op}{output_str}_model', 
                            source='https://github.com/SynBioUC/LOICA/blob/master/loica/operators',
                            language='http://identifiers.org/EDAM:format_3996',
                            framework='http://identifiers.org/SBO:0000062',)
                            #attachments=[model_string])
            doc.add(op_model)
            tu.models.append(op_model)
            doc.add(tu)
            tu_sc = sbol3.SubComponent(tu)
            geneticnetwork.features.append(tu_sc)
        loica_list = list(loica_set)
        doc.add(loica_list) 
        if len(geneticnetwork.features) > 1:
            for i in range(len(geneticnetwork.features)-1):
                geneticnetwork.constraints = [sbol3.Constraint(sbol3.SBOL_PRECEDES, geneticnetwork.features[i], geneticnetwork.features[i+1])]
        else: pass
        doc.add(geneticnetwork)
        return doc
Esempio n. 14
0
def make_composite_part(document, row, composite_parts, linear_products,
                        final_products, config):
    """
    Create a composite part from a row in the composites sheet
    :param document: Document to add parts to
    :param row: Excel row to be processed
    :param composite_parts: collection of parts to add to
    :param linear_products: collection of linear parts to add to
    :param final_products: collection of final parts to add to
    :param config: dictionary of sheet parsing configuration variables
    """
    # Parse material from sheet row
    name = row[config['composite_name_col']].value
    if name is None:
        return  # skip lines without names
    else:
        name = name.strip()  # make sure we're discarding whitespace
    display_id = sbol3.string_to_display_id(name)
    design_notes = (row[config['composite_notes_col']].value
                    if row[config['composite_notes_col']].value else "")
    description = \
        (row[config['composite_description_col']].value if row[config['composite_description_col']].value else "")
    final_product = row[config['composite_final_col']].value  # boolean
    transformed_strain = row[config['composite_strain_col']].value if config[
        'composite_strain_col'] else None
    backbone_or_locus_raw = row[
        config['composite_context_col']].value if config[
            'composite_context_col'] else None
    backbone_or_locus = part_names(
        backbone_or_locus_raw) if backbone_or_locus_raw else []
    constraints = row[config['composite_constraints_col']].value if config[
        'composite_constraints_col'] else None
    reverse_complements = [
        is_RC(spec) for spec in part_specifications(row, config)
    ]
    part_lists = \
        [[partname_to_part(document, name) for name in part_names(spec)] for spec in part_specifications(row, config)]
    combinatorial = any(
        x for x in part_lists
        if len(x) > 1 or isinstance(x[0], sbol3.CombinatorialDerivation))

    # Build the composite
    logging.debug(
        f'Creating {"library" if combinatorial else "composite part"} "{name}"'
    )
    linear_dna_display_id = (f'{display_id}_ins'
                             if backbone_or_locus else display_id)
    if combinatorial:
        composite_part = make_combinatorial_derivation(document,
                                                       linear_dna_display_id,
                                                       part_lists,
                                                       reverse_complements,
                                                       constraints)
    else:
        composite_part = make_composite_component(linear_dna_display_id,
                                                  part_lists,
                                                  reverse_complements)
    composite_part.name = (f'{name} insert' if backbone_or_locus else name)
    composite_part.description = f'{design_notes}\n{description}'.strip()

    # add the component to the appropriate collections
    document.add(composite_part)
    composite_parts.members.append(composite_part.identity)
    if final_product:
        linear_products.members.append(composite_part.identity)

    ###############
    # Consider strain and locus information
    if transformed_strain:
        warnings.warn("Not yet handling strain information: " +
                      transformed_strain)
    if backbone_or_locus:
        # TODO: handle integration locuses as well as plasmid backbones
        backbones = [
            partname_to_part(document, name) for name in backbone_or_locus
        ]
        if any(b is None for b in backbones):
            raise ValueError(
                f'Could not find specified backbone(s) "{backbone_or_locus}"')
        if any(not is_plasmid(b) for b in backbones):
            raise ValueError(
                f'Specified backbones "{backbone_or_locus}" are not all plasmids'
            )
        if combinatorial:
            logging.debug(
                f"Embedding library '{composite_part.name}' in plasmid backbone(s) '{backbone_or_locus}'"
            )
            plasmid = sbol3.Component(f'{display_id}_template', sbol3.SBO_DNA)
            document.add(plasmid)
            part_sub = sbol3.LocalSubComponent([sbol3.SBO_DNA],
                                               name="Inserted Construct")
            plasmid.features.append(part_sub)
            plasmid_cd = sbol3.CombinatorialDerivation(display_id,
                                                       plasmid,
                                                       name=name)
            document.add(plasmid_cd)
            part_var = sbol3.VariableFeature(cardinality=sbol3.SBOL_ONE,
                                             variable=part_sub)
            plasmid_cd.variable_features.append(part_var)
            part_var.variant_derivations.append(composite_part)
            if final_product:
                final_products.members.append(plasmid_cd)
        else:
            if len(backbones) == 1:
                logging.debug(
                    f'Embedding part "{composite_part.name}" in plasmid backbone "{backbone_or_locus}"'
                )
                plasmid = sbol3.Component(display_id, sbol3.SBO_DNA, name=name)
                document.add(plasmid)
                part_sub = sbol3.SubComponent(composite_part)
                plasmid.features.append(part_sub)
                if final_product:
                    final_products.members += {plasmid}
            else:
                logging.debug(
                    f'Embedding part "{composite_part.name}" in plasmid library "{backbone_or_locus}"'
                )
                plasmid = sbol3.Component(f'{display_id}_template',
                                          sbol3.SBO_DNA)
                document.add(plasmid)
                part_sub = sbol3.SubComponent(composite_part)
                plasmid.features.append(part_sub)
                plasmid_cd = sbol3.CombinatorialDerivation(display_id,
                                                           plasmid,
                                                           name=name)
                document.add(plasmid_cd)
                if final_product:
                    final_products.members.append(plasmid_cd)

        if len(backbones) == 1:
            backbone_sub = sbol3.SubComponent(backbones[0])
            plasmid.features.append(backbone_sub)
        else:
            backbone_sub = sbol3.LocalSubComponent([sbol3.SBO_DNA])
            backbone_sub.name = "Vector"
            plasmid.features.append(backbone_sub)
            backbone_var = sbol3.VariableFeature(cardinality=sbol3.SBOL_ONE,
                                                 variable=backbone_sub)
            plasmid_cd.variable_features.append(backbone_var)
            backbone_var.variants += backbones

        plasmid.constraints.append(
            sbol3.Constraint(sbol3.SBOL_MEETS, part_sub, backbone_sub))
        plasmid.constraints.append(
            sbol3.Constraint(sbol3.SBOL_MEETS, backbone_sub, part_sub))
    def subcomponents(self):
        # if type is compdef do one thing, if combdev do another, else error
        if isinstance(self.obj, sbol3.component.Component):
            for sub in self.cell_val:
                sub_part = sbol3.SubComponent(f'{sbol3.get_namespace()}{sub}')
                self.obj.features.append(sub_part)
            # self.obj.assemblePrimaryStructure(self.cell_val)
            # self.obj.compile(assembly_method=None)

        elif isinstance(self.obj, sbol3.combderiv.CombinatorialDerivation):
            comp_list = self.cell_val
            comp_ind = 0
            variant_comps = {}
            for ind, comp in enumerate(comp_list):
                if "," in comp:
                    comp_list[
                        ind] = f'{self.obj.displayId}_subcomponent_{comp_ind}'
                    uri = f'{self.obj.displayId}_subcomponent_{comp_ind}'
                    sub_comp = sbol3.Component(uri, sbol3.SBO_DNA)
                    sub_comp.displayId = f'{self.obj.displayId}_subcomponent_{comp_ind}'
                    self.doc.add(sub_comp)
                    variant_comps[f'subcomponent_{comp_ind}'] = {
                        'object': sub_comp,
                        'variant_list': comp
                    }
                    comp_ind += 1

            # # move this to the object creation section
            # template = sbol2.ComponentDefinition(f'{self.obj.displayId}_template')
            # template.displayId = f'{self.obj.displayId}_template'
            # self.doc.add(template)

            template = self.obj_dict[f'{self.obj.displayId}_template'][
                'object']

            for sub in comp_list:
                name = f'{sbol3.get_namespace()}{sub}'
                name = hf.check_name(name)
                sub_part = sbol3.SubComponent(name)
                template.features.append(sub_part)
            # template.assemblePrimaryStructure(comp_list)
            # template.compile(assembly_method=None)

            self.obj.masterTemplate = template
            for var in variant_comps:
                var_comp = sbol3.VariableFeature(cardinality=sbol3.SBOL_ONE,
                                                 variable=f'var_{var}')
                var_comp.displayId = f'var_{var}'
                var_comp.variable = variant_comps[var]['object']

                var_list = re.split(",", variant_comps[var]['variant_list'])
                var_list = [
                    f'{sbol3.get_namespace()}{x.strip()}' for x in var_list
                ]
                var_comp.variants = var_list
                self.obj.variable_features.append(var_comp)

        else:
            raise KeyError(
                f'The object type "{type(self.obj)}" does not allow subcomponents. (sheet:{self.sheet}, row:{self.sht_row}, col:{self.sht_col})'
            )
Esempio n. 16
0
# RBS
utr1 = sbol3.Component('UTR1', sbol3.SBO_DNA)
utr1.roles = [sbol3.SO_RBS]
utr1.description = 'Your Description Here'

# Create the GFP coding sequence
gfp = sbol3.Component('GFP', sbol3.SBO_DNA)
gfp.roles.append(sbol3.SO_CDS)
gfp.name = 'GFP'
gfp.description = 'GFP Coding Sequence'

# Wrap it together
circuit = sbol3.Component('circuit', sbol3.SBO_DNA)
circuit.roles.append(sbol3.SO_ENGINEERED_REGION)
ptet_sc = sbol3.SubComponent(ptet)
op1_sc = sbol3.SubComponent(op1)
utr1_sc = sbol3.SubComponent(utr1)
gfp_sc = sbol3.SubComponent(gfp)

# circuit.features can be set and appended to like any Python list
circuit.features = [ptet_sc, op1_sc]
circuit.features += [utr1_sc]
circuit.features.append(gfp_sc)

circuit.constraints = [
    sbol3.Constraint(sbol3.SBOL_PRECEDES, ptet_sc, op1_sc),
    sbol3.Constraint(sbol3.SBOL_PRECEDES, op1_sc, utr1_sc),
    sbol3.Constraint(sbol3.SBOL_PRECEDES, utr1_sc, gfp_sc)
]
Esempio n. 17
0
 def test_invalid_create(self):
     # SubComponent requires an `instance_of` argument
     sc = sbol3.SubComponent(None)
     report = sc.validate()
     self.assertIsNotNone(report)
     self.assertEqual(1, len(report.errors))
Esempio n. 18
0
    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