Exemplo n.º 1
0
    def test_system_building(self):
        doc = sbol3.Document()
        sbol3.set_namespace('http://sbolstandard.org/testfiles')

        system = sbol3.Component('system', sbol3.SBO_FUNCTIONAL_ENTITY)
        doc.add(system)
        # make a couple of stand-alone components
        gfp_cds = sbol3.Component('gfp_cds',
                                  sbol3.SBO_DNA,
                                  roles=[tyto.SO.CDS])
        doc.add(gfp_cds)

        # make a functional unit
        expression = add_feature(
            system,
            sbol3.LocalSubComponent([sbol3.SBO_DNA],
                                    roles=[tyto.SO.engineered_region]))
        contains(expression, gfp_cds)
        rbs = contains(
            expression,
            sbol3.LocalSubComponent([sbol3.SBO_DNA],
                                    roles=[tyto.SO.ribosome_entry_site]))
        regulate(rbs, gfp_cds)
        terminator = contains(
            expression,
            sbol3.LocalSubComponent([sbol3.SBO_DNA],
                                    roles=[tyto.SO.terminator]))
        order(gfp_cds, terminator)
        constitutive(expression)
        # link it to a product
        gfp_mut3_ncbi = 'https://www.ncbi.nlm.nih.gov/protein/AAB18957.1'
        gfp = add_feature(
            system, sbol3.ExternallyDefined([sbol3.SBO_PROTEIN],
                                            gfp_mut3_ncbi))
        prod = add_interaction(sbol3.SBO_GENETIC_PRODUCTION,
                               participants={
                                   gfp: sbol3.SBO_PRODUCT,
                                   gfp_cds: sbol3.SBO_TEMPLATE
                               })

        assert contained_components(system) == {system, gfp_cds}
        assert in_role(prod, sbol3.SBO_PRODUCT) == gfp
        assert all_in_role(prod, sbol3.SBO_TEMPLATE) == [
            ensure_singleton_feature(system, gfp_cds)
        ]

        # confirm that the system constructed is exactly as expected
        tmp_out = tempfile.mkstemp(suffix='.nt')[1]
        doc.write(tmp_out, sbol3.SORTED_NTRIPLES)
        test_dir = os.path.dirname(os.path.realpath(__file__))
        comparison_file = os.path.join(test_dir, 'test_files',
                                       'component_construction.nt')
        assert filecmp.cmp(
            tmp_out,
            comparison_file), f'Converted file {tmp_out} is not identical'
Exemplo n.º 2
0
    def test_iadd(self):
        # This is a test for the += operator, which is implemented as __iadd__()
        # When += is invoked the default __iadd__() implementation calls insert()
        # and calls set(). That confuses our auto-numbering of child object
        # identities.
        sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
        doc = sbol3.Document()
        c1 = sbol3.Component('c1', sbol3.SBO_DNA)
        doc.add(c1)
        lsc1 = sbol3.LocalSubComponent([sbol3.SBO_DNA])
        c1.features += [lsc1]
        self.assertEqual('LocalSubComponent1', lsc1.display_id)
        self.assertEqual(posixpath.join(c1.identity, lsc1.display_id),
                         lsc1.identity)
        # TODO: Add checks for document at each step below
        self.assertEqual(doc, lsc1.document)

        lsc2 = sbol3.LocalSubComponent([sbol3.SBO_DNA])
        c1.features += [lsc2]
        # Make sure lsc1 did not get renamed
        self.assertEqual('LocalSubComponent1', lsc1.display_id)
        self.assertEqual(posixpath.join(c1.identity, lsc1.display_id),
                         lsc1.identity)
        self.assertEqual(doc, lsc1.document)
        self.assertEqual('LocalSubComponent2', lsc2.display_id)
        self.assertEqual(posixpath.join(c1.identity, lsc2.display_id),
                         lsc2.identity)
        self.assertEqual(doc, lsc2.document)

        lsc3 = sbol3.LocalSubComponent([sbol3.SBO_DNA])
        lsc4 = sbol3.LocalSubComponent([sbol3.SBO_DNA])
        c1.features += [lsc3, lsc4]
        # Make sure lsc1 did not get renamed
        self.assertEqual('LocalSubComponent1', lsc1.display_id)
        self.assertEqual(posixpath.join(c1.identity, lsc1.display_id),
                         lsc1.identity)
        self.assertEqual(doc, lsc1.document)
        # Make sure lsc2 did not get renamed
        self.assertEqual('LocalSubComponent2', lsc2.display_id)
        self.assertEqual(posixpath.join(c1.identity, lsc2.display_id),
                         lsc2.identity)
        self.assertEqual(doc, lsc2.document)
        self.assertEqual('LocalSubComponent3', lsc3.display_id)
        self.assertEqual(posixpath.join(c1.identity, lsc3.display_id),
                         lsc3.identity)
        self.assertEqual(doc, lsc3.document)
        self.assertEqual('LocalSubComponent4', lsc4.display_id)
        self.assertEqual(posixpath.join(c1.identity, lsc4.display_id),
                         lsc4.identity)
        self.assertEqual(doc, lsc4.document)
Exemplo n.º 3
0
def constitutive(target: Union[sbol3.Feature, sbol3.Component], system: Optional[sbol3.Component] = None)\
        -> sbol3.Feature:
    """Add a constitutive promoter regulating the target feature

    :param target: 5' region for promoter to regulate
    :param system: optional explicit statement of system
    :return: newly created constitutive promoter
    """
    # transform implicit arguments into explicit
    system = ensure_singleton_system(system, target)
    target = ensure_singleton_feature(system, target)

    # create a constitutive promoter and use it to regulate the target
    promoter = add_feature(
        system,
        sbol3.LocalSubComponent([sbol3.SBO_DNA],
                                roles=[tyto.SO.constitutive_promoter]))
    regulate(promoter, target)

    # also add the promoter into any containers that hold the target
    # TODO: add lookups for constraints like we have for interactions
    containers = [
        c.subject for c in system.constraints
        if c.restriction == sbol3.SBOL_CONTAINS and c.object == target.identity
    ]
    for c in containers:
        contains(c.lookup(), promoter)

    return promoter
Exemplo n.º 4
0
    def test_features(self):
        # See https://github.com/SynBioDex/pySBOL3/issues/149
        # Note: this example was modified when fixing
        #       https://github.com/SynBioDex/pySBOL3/issues/178
        #       media_variable is unused in the original example so
        #       it has been commented out here

        media_template = sbol3.LocalSubComponent(
            types=[sbol3.SBO_FUNCTIONAL_ENTITY])
        media_template.name = 'media template'

        # variable_uri = 'https://github.com/synbiodex/pysbol3/variable'
        # media_variable = sbol3.VariableFeature(cardinality=sbol3.SBOL_ONE,
        #                                        variable=media_template)
        # media_variable.variable = media_template

        all_sample_templates = [media_template]
        sample_template_uri = 'https://sd2e.org/measurement_template'
        sample_template = sbol3.Component(identity=sample_template_uri,
                                          types=sbol3.SBO_FUNCTIONAL_ENTITY)
        sample_template.name = 'measurement template'
        sample_template.features = all_sample_templates
        self.assertEqual(1, len(sample_template.features))
        self.assertEqual(media_template.identity,
                         sample_template.features[0].identity)
Exemplo n.º 5
0
 def test_clone_bad_rename(self):
     # Tests that the dependent objects have consistent renaming
     namespace = 'https://github.com/synbiodex/pysbol3'
     sbol3.set_namespace(namespace)
     name = 'c1'
     c1 = sbol3.Component(name, types=[sbol3.SBO_DNA])
     lsc1 = sbol3.LocalSubComponent(types=[sbol3.SBO_DNA])
     lsc2 = sbol3.LocalSubComponent(types=[sbol3.SBO_DNA])
     c1.features = [lsc1, lsc2]
     self.assertEqual('LocalSubComponent1', lsc1.display_id)
     self.assertEqual('LocalSubComponent2', lsc2.display_id)
     c1.features.remove(lsc1)
     self.assertListEqual([lsc2], list(c1.features))
     self.assertEqual('LocalSubComponent2', lsc2.display_id)
     self.assertIsNotNone(c1.find('LocalSubComponent2'))
     clone_name = 'c1_prime'
     c1_prime = c1.clone(posixpath.join(namespace, clone_name))
     self.assertIsNotNone(c1_prime.find('LocalSubComponent2'))
Exemplo n.º 6
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')
     test_type = sbol3.SBO_DNA
     seq = sbol3.Sequence('seq1')
     test_loc = sbol3.EntireSequence(seq)
     lsc = sbol3.LocalSubComponent(types=test_type, locations=test_loc)
     self.assertEqual([test_type], lsc.types)
     self.assertEqual([test_loc], lsc.locations)
Exemplo n.º 7
0
 def test_remove_from_document_identified(self):
     # Test removing a non-TopLevel from the document. This should
     # not give an error
     sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
     doc = sbol3.Document()
     # This should quietly succeed because the string is not in the
     # document
     doc.remove_object('foo')
     lsc = sbol3.LocalSubComponent(types=[sbol3.SBO_DNA])
     # This should also quietly succeed because the local subcomponent
     # is also not in the document
     doc.remove_object(lsc)
Exemplo n.º 8
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
Exemplo n.º 9
0
 def test_set_document(self):
     # Ensure that document is set on child objects
     # See https://github.com/SynBioDex/pySBOL3/issues/176
     sbol3.set_namespace('https://bioprotocols.org/paml/primitives/')
     doc = sbol3.Document()
     c = sbol3.Component("scratch", sbol3.SBO_DNA)
     doc.add(c)
     lsc = sbol3.LocalSubComponent([sbol3.SBO_DNA])
     self.assertIsNone(lsc.document)
     c.features.append(lsc)
     self.assertIsNotNone(lsc.document)
     interaction = sbol3.Interaction([sbol3.SBO_DEGRADATION])
     c.interactions.append(interaction)
     self.assertEqual(doc, interaction.document)
     p = sbol3.Participation([sbol3.SBO_REACTANT], lsc)
     interaction.participations.append(p)
     self.assertEqual(doc, p.document)
     resolved_lsc = p.participant.lookup()
     self.assertEqual(lsc, resolved_lsc)
     self.assertEqual(lsc.identity, resolved_lsc.identity)
Exemplo n.º 10
0
 def test_compose_then_set_document(self):
     # Ensure that document is set on child objects
     # See https://github.com/SynBioDex/pySBOL3/issues/230
     sbol3.set_namespace('https://bioprotocols.org/paml/primitives/')
     c = sbol3.Component("scratch", sbol3.SBO_DNA)
     lsc = sbol3.LocalSubComponent([sbol3.SBO_DNA])
     self.assertIsNone(lsc.document)
     c.features.append(lsc)
     doc = sbol3.Document()
     doc.add(c)
     self.assertIsNotNone(lsc.document)
     self.assertEqual(doc, lsc.document)
     interaction = sbol3.Interaction([sbol3.SBO_DEGRADATION])
     p = sbol3.Participation([sbol3.SBO_REACTANT], lsc)
     interaction.participations.append(p)
     c.interactions.append(interaction)
     # Now that we've composed the objects, add them to the parent.
     # This should assign the document to all the objects in the hierarchy
     # See https://github.com/SynBioDex/pySBOL3/issues/230
     self.assertEqual(doc, interaction.document)
     self.assertEqual(doc, p.document)
     resolved_lsc = p.participant.lookup()
     self.assertEqual(lsc, resolved_lsc)
     self.assertEqual(lsc.identity, resolved_lsc.identity)
Exemplo n.º 11
0
 def test_validation(self):
     types = []
     lsc = sbol3.LocalSubComponent(types)
     report = lsc.validate()
     self.assertIsNotNone(report)
     self.assertEqual(1, len(report.errors))
Exemplo n.º 12
0
 def test_create(self):
     types = [sbol3.SBO_DNA]
     lsc = sbol3.LocalSubComponent(types)
     self.assertIsNotNone(lsc)
     self.assertEqual(types, lsc.types)
     self.assertEqual([], lsc.locations)
Exemplo n.º 13
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))