示例#1
0
    def test_expressions(self):
        #############################################
        # set up the document
        print('Setting up document')
        doc = sbol3.Document()
        sbol3.set_namespace('https://bbn.com/scratch/')

        #############################################
        # Create the Expressions
        print('Creating Protocol')

        # expression e1: 60s * duration(a1)
        a1 = paml.Primitive("a1")
        d1 = uml.Duration(observation=uml.DurationObservation(event=[a1]))
        m1 = pamlt.TimeMeasure(expr=sbol3.Measure(60, tyto.OM.second))
        e1 = uml.Expression(symbol="*", is_ordered=False, operand=[m1, d1])
        #doc.add(e1)

        # expression lt1: e1 < e2
        e2 = pamlt.TimeMeasure(expr=sbol3.Measure(120, tyto.OM.second))
        lt1 = uml.Expression(symbol="<", is_ordered=True, operand=[e1, e2])
        #doc.add(lt1)

        # c1: Not(lt1)
        c1 = pamlt.Not(constrained_elements=lt1)
        #  doc.add(c1)

        ########################################
        # Validate and write the document
        print('Validating and writing time')
        v = doc.validate()
        assert not v.errors and not v.warnings, "".join(
            str(e) for e in doc.validate().errors)
示例#2
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')
     source_uri = 'https://example.org/source'
     derived_from_uri = 'https://example.org/derived_from'
     statute_mile = sbol3.OM_NS + 'mile-Statute'
     comp1_type = sbol3.SBO_DNA
     comp1_role = sbol3.SO_PROMOTER
     comp1_seq1 = sbol3.Sequence('seq1')
     comp1_model = sbol3.Model('model1',
                               source=source_uri,
                               language='https://example.org/language',
                               framework='https://example.org/framework')
     comp1_attachment = sbol3.Attachment('att1', source=source_uri)
     comp1_measure = sbol3.Measure(value=26.2, unit=statute_mile)
     comp1_activity = sbol3.Activity('activity1')
     comp1 = sbol3.Component('comp1',
                             types=comp1_type,
                             sequences=comp1_seq1,
                             roles=comp1_role,
                             models=comp1_model,
                             attachments=comp1_attachment,
                             derived_from=derived_from_uri,
                             measures=comp1_measure,
                             generated_by=comp1_activity)
     self.assertEqual([comp1_type], comp1.types)
     self.assertEqual([comp1_seq1.identity], comp1.sequences)
     self.assertEqual([comp1_role], comp1.roles)
     self.assertEqual([comp1_model.identity], comp1.models)
     self.assertEqual([comp1_attachment.identity], comp1.attachments)
     self.assertEqual([derived_from_uri], comp1.derived_from)
     self.assertEqual([comp1_measure], comp1.measures)
     self.assertEqual([comp1_activity.identity], comp1.generated_by)
示例#3
0
 def test_full_constructor(self):
     identity = 'https://github.com/synbiodex/pysbol3/s1'
     elements = 'GCAT'
     encoding = sbol3.IUPAC_DNA_ENCODING
     attachments = ['https://github.com/synbiodex/pysbol3/attachment1']
     name = None
     description = None
     derived_from = ['https://github.com/synbiodex/pysbol3/parent1']
     generated_by = ['https://github.com/synbiodex/pysbol3/tool1']
     m1 = sbol3.Measure(value=2.3, unit='meter')
     measures = [m1]
     s1 = sbol3.Sequence(identity=identity,
                         elements=elements,
                         encoding=encoding,
                         attachments=attachments,
                         name=name,
                         description=description,
                         derived_from=derived_from,
                         generated_by=generated_by,
                         measures=measures)
     self.assertEqual(identity, s1.identity)
     self.assertEqual(elements, s1.elements)
     self.assertEqual(encoding, s1.encoding)
     self.assertEqual(attachments, s1.attachments)
     self.assertEqual(name, s1.name)
     self.assertEqual(description, s1.description)
     self.assertEqual(derived_from, s1.derived_from)
     self.assertEqual(generated_by, s1.generated_by)
     self.assertEqual(measures, s1.measures)
示例#4
0
def _getUMLInterval(interval, intervalType, units=tyto.OM.second):
    if isinstance(interval, list) and len(interval) == 2:
        min = interval[0]
        max = interval[1]
    elif isinstance(interval, int) or isinstance(interval, float):
        min = interval
        max = interval
    else:
        raise MalformedInterval(
            f"Cannot constrain time point with interval: {interval}")

    uml_interval = intervalType(min=uml.TimeExpression(expr=pamlt.TimeMeasure(
        expr=sbol3.Measure(min, units))),
                                max=uml.TimeExpression(expr=pamlt.TimeMeasure(
                                    expr=sbol3.Measure(max, units))))
    return uml_interval
示例#5
0
 def test_measures_initial_value(self):
     # See https://github.com/SynBioDex/pySBOL3/issues/301
     sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
     metre = 'http://www.ontology-of-units-of-measure.org/resource/om-2/metre'
     one_metre = sbol3.Measure(1, unit=metre)
     two_metres = sbol3.Measure(2, unit=metre)
     # Test passing a list of measures
     c1 = sbol3.Component('c1',
                          types=[sbol3.SBO_DNA],
                          measures=[one_metre, two_metres])
     self.assertListEqual([one_metre, two_metres], list(c1.measures))
     # test passing a singleton measure
     three_metres = sbol3.Measure(3, unit=metre)
     c2 = sbol3.Component('c2',
                          types=[sbol3.SBO_DNA],
                          measures=three_metres)
     self.assertListEqual([three_metres], list(c2.measures))
示例#6
0
def provision_ludox(protocol: paml.Protocol, plate, ludox) -> None:
    c_ludox = protocol.primitive_step('PlateCoordinates',
                                      source=plate.output_pin('samples'),
                                      coordinates='A2:D2')
    protocol.primitive_step('Provision',
                            resource=ludox,
                            destination=c_ludox.output_pin('samples'),
                            amount=sbol3.Measure(100, tyto.OM.microliter))
示例#7
0
def provision_h2o(protocol: paml.Protocol, plate, ddh2o) -> None:
    c_ddh2o = protocol.primitive_step('PlateCoordinates',
                                      source=plate.output_pin('samples'),
                                      coordinates='A1:D1')
    protocol.primitive_step('Provision',
                            resource=ddh2o,
                            destination=c_ddh2o.output_pin('samples'),
                            amount=sbol3.Measure(100, tyto.OM.microliter))
示例#8
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')
     unit_uri = 'http://www.ontology-of-units-of-measure.org/resource/om-2/gramPerLitre'
     # SBO:0000612 is from the SBOL 3.0.1 specification.
     test_type = 'https://identifiers.org/SBO:0000612'
     measure1 = sbol3.Measure(value=1.0, unit=unit_uri, types=test_type)
     self.assertEqual([test_type], measure1.types)
示例#9
0
    def test_create_protocol(self):
        protocol: paml.Protocol
        doc: sbol3.Document
        logger = logging.getLogger("LUDOX_protocol")
        logger.setLevel(logging.INFO)
        protocol, doc = protocol_def.ludox_protocol()

        ########################################
        # Validate and write the document

        agent = sbol3.Agent("test_agent")

        # Execute the protocol
        # In order to get repeatable timings, we use ordinal time in the test
        # where each timepoint is one second after the previous time point
        ee = ExecutionEngine(use_ordinal_time=True)
        parameter_values = [
            paml.ParameterValue(
                parameter=protocol.get_input("wavelength"),
                value=uml.LiteralIdentified(
                    value=sbol3.Measure(100, tyto.OM.nanometer)))
        ]
        execution = ee.execute(protocol,
                               agent,
                               id="test_execution",
                               parameter_values=parameter_values)

        # Get the SampleData objects and attach values
        # get_data() returns a dict of output parameter ids to SampleData objects
        dataset = execution.get_data()

        for k, v in dataset.data_vars.items():
            for dimension in v.dims:
                new_data = [8] * len(dataset[k].data)
                dataset.update({k: (dimension, new_data)})

        execution.set_data(dataset)

        print('Validating and writing protocol')
        v = doc.validate()
        assert len(v) == 0, "".join(f'\n {e}' for e in v)

        temp_name = os.path.join(tempfile.gettempdir(),
                                 'igem_ludox_data_test.nt')
        doc.write(temp_name, sbol3.SORTED_NTRIPLES)
        print(f'Wrote file as {temp_name}')

        comparison_file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'testfiles',
            'igem_ludox_data_test.nt')
        # doc.write(comparison_file, sbol3.SORTED_NTRIPLES)
        print(f'Comparing against {comparison_file}')
        assert filecmp.cmp(temp_name,
                           comparison_file), "Files are not identical"
        print('File identical with test file')
示例#10
0
 def test_create(self):
     unit = 'https://sbolstandard.org/examples/millimolePerLitre'
     value = 0.1
     types = ['https://identifiers.org/SBO:0000196',
              'https://identifiers.org/SBO:0000197']
     measure = sbol3.Measure(value, unit)
     measure.types = types
     self.assertIsNotNone(measure)
     self.assertIsInstance(measure, sbol3.Measure)
     self.assertEqual(value, measure.value)
     self.assertCountEqual(types, measure.types)
     self.assertEqual(unit, measure.unit)
示例#11
0
 def test_singleton_property_update_identity(self):
     sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
     tl = sbol3.CustomTopLevel(
         'foo', 'http://synbio.bbn.com/opil#MeasurementValue')
     tl.measure = sbol3.OwnedObject(tl,
                                    'http://synbio.bbn.com/opil#measure', 0,
                                    1)
     m = sbol3.Measure(10, 'liters')
     tl.measure = m
     expected = posixpath.join(tl.identity, 'Measure1')
     self.assertIsNotNone(tl.measure.identity)
     self.assertEqual(expected, tl.measure.identity)
示例#12
0
    def test_parse_class_name(self):
        sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
        # Test parsing with # delimiter in type URI
        c = sbol3.Component('c', sbol3.SBO_DNA)
        class_name = parse_class_name(c.type_uri)
        self.assertEqual(class_name, 'Component')

        # Test parsing with # delimiter in type URI
        m = sbol3.Measure(0, 'dollars')
        class_name = parse_class_name(m.type_uri)
        self.assertEqual(class_name, 'Measure')

        # Test failure with invalid type URI
        with self.assertRaises(ValueError):
            parse_class_name('Component')
示例#13
0
def ludox_protocol() -> Tuple[paml.Protocol, Document]:
    #############################################
    # set up the document
    doc: Document = prepare_document()

    #############################################
    # Import the primitive libraries
    import_paml_libraries()

    #############################################
    # Create the protocol
    protocol: paml.Protocol = create_protocol()
    doc.add(protocol)

    # create the materials to be provisioned
    ddh2o = create_h2o()
    doc.add(ddh2o)

    ludox = create_ludox()
    doc.add(ludox)

    # add an optional parameter for specifying the wavelength
    wavelength_param = protocol.input_value('wavelength',
                                            sbol3.OM_MEASURE,
                                            optional=True,
                                            default_value=sbol3.Measure(
                                                600, tyto.OM.nanometer))

    # actual steps of the protocol
    # get a plate
    plate = create_plate(protocol)

    # put ludox and water in selected wells
    provision_h2o(protocol, plate, ddh2o)
    provision_ludox(protocol, plate, ludox)

    # measure the absorbance
    measure = measure_absorbance(protocol, plate, wavelength_param)

    output = protocol.designate_output('absorbance', sbol3.OM_MEASURE,
                                       measure.output_pin('measurements'))
    protocol.order(protocol.get_last_step(), output)
    return protocol, doc
示例#14
0
 def test_round_trip2(self):
     # See https://github.com/SynBioDex/pySBOL3/issues/159
     sbol3.set_namespace('https://github.com/synbiodex/pysbol3')
     doc1 = sbol3.Document()
     comp1 = sbol3.Component('comp1', sbol3.SBO_DNA)
     doc1.add(comp1)
     cd1 = sbol3.CombinatorialDerivation('cd1', comp1)
     self.assertEqual(comp1.identity, cd1.template)
     doc1.add(cd1)
     vf1 = sbol3.VariableFeature(cardinality=sbol3.SBOL_ONE,
                                 variable=sbol3.PYSBOL3_MISSING)
     hour = 'https://identifiers.org/ncit:C25529'
     m1 = sbol3.Measure(32, hour)
     vf1.variant_measures.append(m1)
     cd1.variable_features.append(vf1)
     self.assertTrue(vf1.identity.startswith(cd1.identity))
     # Ensure that Measure m1 is valid. The bug tested here was that it
     # had been assigned an invalid displayId.
     report = m1.validate()
     self.assertEqual(0, len(report.errors))
def sum_measures(measure_list):
    """Add a list of measures and return a fresh measure
    Note: requires that all have the same unit and types

    Parameters
    ----------
    measure_list of SBOL Measure objects

    Returns
    -------
    New Measure object with the sum of input measure amounts
    """
    prototype = measure_list[0]
    if not all(m.types == prototype.types and m.unit == prototype.unit
               for m in measure_list):
        raise ValueError(
            f'Can only merge measures with identical units and types: {([m.value, m.unit, m.types] for m in measure_list)}'
        )
    total = sum(m.value for m in measure_list)
    return sbol3.Measure(value=total,
                         unit=prototype.unit,
                         types=prototype.types)
示例#16
0
    def _run_execution(self, doc, specializations):

        protocol = doc.find(
            "https://bbn.com/scratch/iGEM_LUDOX_OD_calibration_2018")

        #############################################
        # Execution Configuration
        ee = ExecutionEngine(specializations=specializations)
        agent = sbol3.Agent("test_agent")
        parameter_values = [
            paml.ParameterValue(
                parameter=protocol.get_input("wavelength"),
                value=uml.LiteralIdentified(
                    value=sbol3.Measure(100, tyto.OM.nanometer)))
        ]

        #############################################
        # Execute Protocol and Convert
        execution = ee.execute(protocol,
                               agent,
                               id="test_execution",
                               parameter_values=parameter_values)
示例#17
0
    def test_execute_protocol(self):
        #############################################
        # set up the document
        print('Setting up document')
        doc = sbol3.Document()
        sbol3.set_namespace('https://bbn.com/scratch/')

        protocol_file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), "testfiles",
            "igem_ludox_test.nt")
        doc.read(protocol_file, 'nt')

        protocol = doc.find(
            "https://bbn.com/scratch/iGEM_LUDOX_OD_calibration_2018")
        agent = sbol3.Agent("test_agent")

        # print('Importing libraries')
        # paml.import_library('liquid_handling')
        # print('... Imported liquid handling')

        ee = ExecutionEngine()
        parameter_values = [
            paml.ParameterValue(parameter=protocol.get_input("wavelength"),
                                value=sbol3.Measure(100, tyto.OM.nanometer))
        ]
        execution = ee.execute(protocol,
                               agent,
                               id="test_execution",
                               parameter_values=parameter_values)

        #dot = execution.to_dot()
        #dot.render(f'{protocol.name}.gv')
        #dot.view()  # uncomment to see it on your own screen

        ########################################
        # Validate and write the document
        print('Validating and writing protocol')
        v = doc.validate()
        assert len(v) == 0, "".join(f'\n {e}' for e in v)
示例#18
0
# Inputs: collection of samples, pbs_source
samples = split_and_measure.add_input(
    name='samples',
    description='Samples to measure',
    type='http://bioprotocols.org/paml#LocatedSamples')
pbs_source = split_and_measure.add_input(
    name='pbs',
    description='Source for PBS',
    type='http://bioprotocols.org/paml#LocatedSamples')

# subprotocol steps
s_p = split_and_measure.execute_primitive('Dispense',
                                          source=pbs_source,
                                          destination=od_plate,
                                          amount=sbol3.Measure(
                                              90, tyto.OM.microliter))
split_and_measure.add_flow(split_and_measure.initial(),
                           s_p)  # dispensing OD can be a first action
s_u = split_and_measure.execute_primitive('Unseal', location=samples)
split_and_measure.add_flow(
    split_and_measure.initial(),
    s_u)  # unsealing the growth plate can be a first action
s_t = split_and_measure.execute_primitive(
    'TransferInto',
    source=samples,
    destination=s_p.output_pin('samples'),
    amount=sbol3.Measure(10, tyto.OM.microliter),
    mixCycles=sbol3.Measure(10, tyto.OM.number))
split_and_measure.add_flow(
    s_u, s_t)  # transfer can't happen until growth plate is unsealed
示例#19
0
# actual steps of the protocol
# get a plate space for building
build_wells = protocol.primitive_step('DuplicateCollection',
                                      source=dna_build_layout)

# put DNA into the selected wells following the build plan
protocol.primitive_step('TransferByMap',
                        source=dna_sources,
                        destination=build_wells.output_pin('samples'),
                        plan=dna_build_layout)

# put buffer, assembly mix, and water into build wells too
protocol.primitive_step('Provision',
                        resource=gg_buf,
                        destination=build_wells.output_pin('samples'),
                        amount=sbol3.Measure(2, tyto.OM.microliter))
protocol.primitive_step('Provision',
                        resource=gg_mix,
                        destination=build_wells.output_pin('samples'),
                        amount=sbol3.Measure(1, tyto.OM.microliter))
protocol.primitive_step('Provision',
                        resource=nf_h2o,
                        destination=build_wells.output_pin('samples'),
                        amount=sbol3.Measure(15, tyto.OM.microliter))

# seal and spin to mix
protocol.primitive_step(
    'Seal', location=build_wells.output_pin('samples'))  # TODO: add type
protocol.primitive_step(
    'Spin',
    acceleration=sbol3.Measure(
示例#20
0
    def test_create_protocol(self):
        protocol: paml.Protocol
        doc: sbol3.Document
        logger = logging.getLogger("transfer_map_protocol")
        logger.setLevel(logging.INFO)
        protocol, doc = initialize_protocol()

        # The aliquots will be the coordinates of the SampleArray and SampleMap objects
        num_aliquots = 4
        aliquot_ids = list(range(num_aliquots))

        # Make Components for the contents of the SampleArray
        reagent1 = sbol3.Component(
            'ddH2Oa', 'https://identifiers.org/pubchem.substance:24901740')
        reagent2 = sbol3.Component(
            'ddH2Ob', 'https://identifiers.org/pubchem.substance:24901740')
        reagents = [reagent1, reagent2]

        # TODO ContainerSpec without parameters will refer to a logical container of unspecified size and geometry
        source_spec = paml.ContainerSpec(name='abstractPlateRequirement1')
        target_spec = paml.ContainerSpec(name='abstractPlateRequirement2')

        # Arbitrary volume to use in specifying the reagents in the container.
        default_volume = sbol3.Measure(600, tyto.OM.microliter)

        # Creating the source SampleArray involves the following steps:
        # 1. Calling the EmptyContainer primitive with a defined specifcation
        # 2. Creating the SampleArray and referencing the specification.
        #    (SBOLFactory needs the specification to have an identity, which only
        #     happens in step 1.)
        # 3. Remove the EmptyContainer InputPin for "sample_array"
        # 4. Create a ValuePin for "sample_array" and add it to the input of the EmptyContainer call.
        #    (This is a place where we can map a SampleArray to a container)

        # 1.
        create_source = protocol.primitive_step('EmptyContainer',
                                                specification=source_spec)

        # 2.
        # The SampleArray is a 2D |aliquot| x |reagent| array, where values are volumes.
        # The aliquot dimension uses aliquot_ids (specified above) as coordinates.
        # The reagent dimension uses reagents (specified above) as coordinates.
        #
        # Results in the DataArray representing contents:
        #
        # <xarray.DataArray (aliquot: 4, contents: 2)>
        # array([[600., 600.],
        #        [600., 600.],
        #        [600., 600.],
        #        [600., 600.]])
        # Coordinates:
        #   * aliquot   (aliquot) int64 0 1 2 3
        #   * contents  (contents) <U30 'https://bbn.com/scratch/ddH2Oa' 'https://bbn.c...
        source_array = paml.SampleArray(
            name="source",
            container_type=source_spec,
            contents=json.dumps(
                xr.DataArray(
                    [[default_volume.value for reagent in reagents]
                     for id in aliquot_ids],
                    dims=("aliquot", "contents"),
                    coords={
                        "aliquot": aliquot_ids,
                        "contents": [r.identity for r in reagents]
                    }).to_dict()))
        # 3.
        sample_array_parameter = create_source.pin_parameter("sample_array")
        [old_input
         ] = [x for x in create_source.inputs if x.name == "sample_array"]
        create_source.inputs.remove(old_input)

        # 4.
        create_source.inputs.append(
            uml.ValuePin(
                name="sample_array",
                is_ordered=sample_array_parameter.property_value.is_ordered,
                is_unique=sample_array_parameter.property_value.is_unique,
                value=uml.literal(source_array)))

        # Similar to the source_array, above, we specify an analogous target_array
        # 1.
        create_target = protocol.primitive_step('EmptyContainer',
                                                specification=target_spec)

        # 2.
        target_array = paml.SampleArray(
            name="target",
            container_type=target_spec,
            contents=json.dumps(
                xr.DataArray(
                    [[0.0 for reagent in reagents] for id in aliquot_ids],
                    dims=("aliquot", "contents"),
                    coords={
                        "aliquot": aliquot_ids,
                        "contents": [r.identity for r in reagents]
                    }).to_dict()))

        # 3.
        sample_array_parameter = create_target.pin_parameter("sample_array")
        [old_input
         ] = [x for x in create_target.inputs if x.name == "sample_array"]
        create_target.inputs.remove(old_input)

        # 4.
        create_target.inputs.append(
            uml.ValuePin(
                name="sample_array",
                is_ordered=sample_array_parameter.property_value.is_ordered,
                is_unique=sample_array_parameter.property_value.is_unique,
                value=uml.literal(target_array)))

        # plan_mapping is a 4D array of volumes for transfers:
        #    (source_array, source_aliquot) --volume--> (target_array, target_aliquot)
        #
        # The plan_mapping from above is a single source_array and single target_array:
        #
        # <xarray.DataArray (source_array: 1, source_aliquot: 4, target_array: 1,
        #                    target_aliquot: 4)>
        # array([[[[10., 10., 10., 10.]],

        #         [[10., 10., 10., 10.]],

        #         [[10., 10., 10., 10.]],

        #         [[10., 10., 10., 10.]]]])
        # Coordinates:
        #   * source_array    (source_array) <U6 'source'
        #   * source_aliquot  (source_aliquot) int64 0 1 2 3
        #   * target_array    (target_array) <U6 'target'
        #   * target_aliquot  (target_aliquot) int64 0 1 2 3

        plan_mapping = json.dumps(
            xr.DataArray(
                [[[[10.0 for target_aliquot in aliquot_ids]
                   for target_array in [target_array.name]]
                  for source_aliquot in aliquot_ids]
                 for source_array in [source_array.name]],
                dims=(
                    "source_array",
                    "source_aliquot",
                    "target_array",
                    "target_aliquot",
                ),
                coords={
                    "source_array": [source_array.name],
                    "source_aliquot": aliquot_ids,
                    "target_array": [target_array.name],
                    "target_aliquot": aliquot_ids
                }).to_dict())

        # The SampleMap specifies the sources and targets, along with the mappings.
        plan = paml.SampleMap(sources=[source_array],
                              targets=[target_array],
                              values=plan_mapping)

        # The outputs of the create_source and create_target calls will be identical
        # to the source_array and target_array.  They will not be on the output pin
        # until execution, but the SampleMap needs to reference them.
        transfer_by_map = protocol.primitive_step(
            'TransferByMap',
            source=create_source.output_pin('samples'),
            destination=create_target.output_pin('samples'),
            plan=plan)

        ########################################
        # Validate and write the document

        agent = sbol3.Agent("test_agent")

        # Execute the protocol
        # In order to get repeatable timings, we use ordinal time in the test
        # where each timepoint is one second after the previous time point
        ee = ExecutionEngine(use_ordinal_time=True)
        parameter_values = [
            # paml.ParameterValue(parameter=protocol.get_input("wavelength"),
            #                     value=uml.LiteralIdentified(value=sbol3.Measure(100, tyto.OM.nanometer)))
        ]
        execution = ee.execute(protocol,
                               agent,
                               id="test_execution",
                               parameter_values=parameter_values)

        print('Validating and writing protocol')
        v = doc.validate()
        assert len(v) == 0, "".join(f'\n {e}' for e in v)

        temp_name = os.path.join(tempfile.gettempdir(),
                                 'igem_ludox_data_test.nt')
        doc.write(temp_name, sbol3.SORTED_NTRIPLES)
        print(f'Wrote file as {temp_name}')

        comparison_file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'testfiles',
            'sample_map_test.nt')
        doc.write(comparison_file, sbol3.SORTED_NTRIPLES)
        print(f'Comparing against {comparison_file}')
        assert filecmp.cmp(temp_name,
                           comparison_file), "Files are not identical"
        print('File identical with test file')
示例#21
0
    def test_create_timed_protocol(self):
        #############################################
        # set up the document
        print('Setting up document')
        doc = sbol3.Document()
        sbol3.set_namespace('https://bbn.com/scratch/')

        #############################################
        # Import the primitive libraries
        print('Importing libraries')
        paml.import_library('liquid_handling')
        print('... Imported liquid handling')
        paml.import_library('plate_handling')
        print('... Imported plate handling')
        paml.import_library('spectrophotometry')
        print('... Imported spectrophotometry')
        paml.import_library('sample_arrays')
        print('... Imported sample arrays')

        #############################################
        # Create the protocol
        print('Creating protocol')
        protocol = paml.Protocol('iGEM_LUDOX_OD_calibration_2018')
        protocol.name = "iGEM 2018 LUDOX OD calibration protocol"
        protocol.description = '''
        With this protocol you will use LUDOX CL-X (a 45% colloidal silica suspension) as a single point reference to
        obtain a conversion factor to transform absorbance (OD600) data from your plate reader into a comparable
        OD600 measurement as would be obtained in a spectrophotometer. This conversion is necessary because plate
        reader measurements of absorbance are volume dependent; the depth of the fluid in the well defines the path
        length of the light passing through the sample, which can vary slightly from well to well. In a standard
        spectrophotometer, the path length is fixed and is defined by the width of the cuvette, which is constant.
        Therefore this conversion calculation can transform OD600 measurements from a plate reader (i.e. absorbance
        at 600 nm, the basic output of most instruments) into comparable OD600 measurements. The LUDOX solution
        is only weakly scattering and so will give a low absorbance value.
                '''
        doc.add(protocol)

        # create the materials to be provisioned
        ddh2o = sbol3.Component(
            'ddH2O', 'https://identifiers.org/pubchem.substance:24901740')
        ddh2o.name = 'Water, sterile-filtered, BioReagent, suitable for cell culture'  # TODO get via tyto
        doc.add(ddh2o)

        ludox = sbol3.Component(
            'LUDOX', 'https://identifiers.org/pubchem.substance:24866361')
        ludox.name = 'LUDOX(R) CL-X colloidal silica, 45 wt. % suspension in H2O'
        doc.add(ludox)

        # actual steps of the protocol
        # get a plate
        plate = protocol.primitive_step(
            'EmptyContainer',
            specification=tyto.NCIT.get_uri_by_term(
                'Microplate'))  # replace with container ontology

        # put ludox and water in selected wells
        c_ddh2o = protocol.primitive_step('PlateCoordinates',
                                          source=plate,
                                          coordinates='A1:D1')
        provision_ludox = protocol.primitive_step(
            'Provision',
            resource=ludox,
            destination=c_ddh2o.output_pin('samples'),
            amount=sbol3.Measure(100, tyto.OM.microliter))

        c_ludox = protocol.primitive_step('PlateCoordinates',
                                          source=plate,
                                          coordinates='A2:D2')
        provision_ddh2o = protocol.primitive_step(
            'Provision',
            resource=ddh2o,
            destination=c_ludox.output_pin('samples'),
            amount=sbol3.Measure(100, tyto.OM.microliter))

        # measure the absorbance
        c_measure = protocol.primitive_step('PlateCoordinates',
                                            source=plate,
                                            coordinates='A1:D2')
        measure = protocol.primitive_step('MeasureAbsorbance',
                                          samples=c_measure,
                                          wavelength=sbol3.Measure(
                                              600, tyto.OM.nanometer))

        protocol.add_output('absorbance', measure.output_pin('measurements'))

        # Set protocol timepoints

        # protocol starts at time 0
        protocol_start_time = pamlt.startTime(protocol, 0, units=tyto.OM.hour)
        provision_ludox_duration = pamlt.duration(provision_ludox,
                                                  60,
                                                  units=tyto.OM.second)
        provision_ddh2o_duration = pamlt.duration(provision_ddh2o,
                                                  60,
                                                  units=tyto.OM.second)
        execute_measurement_duration = pamlt.duration(measure,
                                                      60,
                                                      units=tyto.OM.minute)
        ludox_before_ddh2o_constraint = pamlt.precedes(provision_ludox,
                                                       [10, 15],
                                                       provision_ddh2o,
                                                       units=tyto.OM.hour)

        time_constraints = pamlt.TimeConstraints(
            "ludox_protocol_constraints",
            constraints=[
                pamlt.And([
                    protocol_start_time, provision_ludox_duration,
                    provision_ddh2o_duration, execute_measurement_duration,
                    ludox_before_ddh2o_constraint
                ])
            ],
            protocols=[protocol])

        doc.add(time_constraints)

        ########################################
        # Validate and write the document
        print('Validating and writing protocol')
        v = doc.validate()
        assert not v.errors and not v.warnings, "".join(
            str(e) for e in doc.validate().errors)

        # assert check_doc(doc) # Is the protocol consistent?
        # assert get_minimum_duration(doc)  # What is the minimum duration for each protocol in doc

        temp_name = os.path.join(tempfile.gettempdir(),
                                 'igem_ludox_time_test.nt')
        doc.write(temp_name, sbol3.SORTED_NTRIPLES)
        print(f'Wrote file as {temp_name}')

        comparison_file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'testfiles',
            'igem_ludox_time_test.nt')
        # doc.write(comparison_file, sbol3.SORTED_NTRIPLES)
        print(f'Comparing against {comparison_file}')
        assert filecmp.cmp(temp_name,
                           comparison_file), "Files are not identical"
        print('File identical with test file')