예제 #1
0
def test_magdeck_labware_props(loop):
    ctx = papi.ProtocolContext(loop)
    # TODO Ian 2019-05-29 load fixtures, not real defs
    labware_name = 'biorad_96_wellplate_200ul_pcr'
    labware_def = json.loads(
        load_shared_data(f'labware/definitions/2/{labware_name}/1.json'))
    ctx._hw_manager.hardware._backend._attached_modules = [('mod0', 'magdeck')]
    mod = ctx.load_module('magdeck', 1)
    assert mod.labware is None
    mod.load_labware(labware_name)
    mod.engage()
    lw_offset = labware_def['parameters']['magneticModuleEngageHeight']
    assert mod._module._driver.plate_height == lw_offset
    mod.disengage()
    mod.engage(offset=2)
    assert mod._module._driver.plate_height == lw_offset + 2
    mod.disengage()
    mod.engage(height=3)
    assert mod._module._driver.plate_height == 3
    mod._geometry.reset_labware()
    labware_name = 'corning_96_wellplate_360ul_flat'
    mod.load_labware(labware_name)
    with pytest.raises(ValueError):
        mod.engage()
    with pytest.raises(ValueError):
        mod.engage(offset=1)
    mod.engage(height=2)
    assert mod._module._driver.plate_height == 2
    mod.engage(height_from_base=2)
    assert mod._module._driver.plate_height == 2 + OFFSET_TO_LABWARE_BOTTOM
예제 #2
0
def _load_v2_module_def(module_model: ModuleModel) -> Dict[str, Any]:
    try:
        return json.loads(
            load_shared_data(
                f'module/definitions/2/{module_model.value}.json'))
    except OSError:
        raise NoSuchModuleError(
            f'Could not find the module {module_model.value}.', module_model)
예제 #3
0
def _load_v1_module_def(module_model: ModuleModel) -> Dict[str, Any]:
    v1names = {
        MagneticModuleModel.MAGNETIC_V1: 'magdeck',
        TemperatureModuleModel.TEMPERATURE_V1: 'tempdeck',
        ThermocyclerModuleModel.THERMOCYCLER_V1: 'thermocycler'
    }
    try:
        name = v1names[module_model]
    except KeyError:
        raise NoSuchModuleError(f'Could not find module {module_model.value}',
                                module_model)
    return json.loads(load_shared_data('module/definitions/1.json'))[name]
예제 #4
0
파일: parse.py 프로젝트: chiloux/opentrons
def validate_json(protocol_json: Dict[Any, Any]) -> int:
    """ Validates a json protocol and returns its schema version """
    # Check if this is actually a labware
    labware_schema_v2 = json.loads(load_shared_data(
        'labware/schemas/2.json').decode('utf-8'))
    try:
        jsonschema.validate(protocol_json, labware_schema_v2)
    except jsonschema.ValidationError:
        pass
    else:
        MODULE_LOG.error("labware uploaded instead of protocol")
        raise RuntimeError(
            'The file you are trying to open is a JSON labware definition, '
            'and therefore can not be opened here. Please try '
            'uploading a JSON protocol file instead.')

    # this is now either a protocol or something corrupt
    version_num = _get_protocol_schema_version(protocol_json)
    if version_num <= 2:
        raise RuntimeError(
            f'JSON protocol version {version_num} is '
            'deprecated. Please upload your protocol into Protocol '
            'Designer and save it to migrate the protocol to a later '
            'version. This error might mean a labware '
            'definition was specified instead of a protocol.')
    if version_num > 4:
        raise RuntimeError(
            f'The protocol you are trying to open is a JSONv{version_num} '
            'protocol and is not supported by your current robot server '
            'version. Please update your OT-2 App and robot server to the '
            'latest version and try again.'
        )
    protocol_schema = _get_schema_for_protocol(version_num)

    # instruct schema how to resolve all $ref's used in protocol schemas
    resolver = jsonschema.RefResolver(
        protocol_schema.get('$id', ''),
        protocol_schema,
        store={
            "opentronsLabwareSchemaV2": labware_schema_v2
        })

    # do the validation
    try:
        jsonschema.validate(protocol_json, protocol_schema, resolver=resolver)
    except jsonschema.ValidationError:
        MODULE_LOG.exception("JSON protocol validation failed")
        raise RuntimeError(
            'This may be a corrupted file or a JSON file that is not an '
            'Opentrons JSON protocol.')
    else:
        return version_num
예제 #5
0
def _get_schema_for_protocol(version_num: int) -> Dict[Any, Any]:
    """ Retrieve the json schema for a protocol schema version
    """
    if version_num > 3:
        raise RuntimeError(f'JSON Protocol version {version_num} is not yet ' +
                           'supported in this version of the API')
    try:
        schema = load_shared_data(f'protocol/schemas/{version_num}.json')
    except FileNotFoundError:
        schema = None  # type: ignore
    if not schema:
        raise RuntimeError(
            'JSON Protocol schema "{}" does not exist'.format(version_num))
    return json.loads(schema.decode('utf-8'))
예제 #6
0
 def __init__(self):
     super().__init__()
     row_offset = 90.5
     col_offset = 132.5
     for idx in range(1, 13):
         self.data[idx] = None
     self._positions = {
         idx + 1: types.Point((idx % 3) * col_offset, idx // 3 * row_offset,
                              0)
         for idx in range(12)
     }
     self._highest_z = 0.0
     # TODO: support deck loadName as a param
     def_path = 'deck/definitions/2/ot2_standard.json'
     self._definition = json.loads(load_shared_data(def_path))
예제 #7
0
파일: parse.py 프로젝트: pablo-vs/opentrons
def _get_schema_for_protocol(version_num: int) -> Dict[Any, Any]:
    """ Retrieve the json schema for a protocol schema version
    """
    # TODO(IL, 2020/03/05): use $otSharedSchema, but maybe wait until
    # deprecating v1/v2 JSON protocols?
    if version_num > 4:
        raise RuntimeError(f'JSON Protocol version {version_num} is not yet ' +
                           'supported in this version of the API')
    try:
        schema = load_shared_data(f'protocol/schemas/{version_num}.json')
    except FileNotFoundError:
        schema = None  # type: ignore
    if not schema:
        raise RuntimeError(
            'JSON Protocol schema "{}" does not exist'.format(version_num))
    return json.loads(schema.decode('utf-8'))
예제 #8
0
def test_module_load_v1(v1_module_name):
    module_defs = json.loads(load_shared_data('module/definitions/1.json'))
    model = module_geometry.resolve_module_model(v1_module_name)
    mod = module_geometry.load_module(model, Location(Point(0, 0, 0), 'test'))
    mod_def = module_defs[v1_module_name]
    offset = Point(mod_def['labwareOffset']['x'],
                   mod_def['labwareOffset']['y'],
                   mod_def['labwareOffset']['z'])
    high_z = mod_def['dimensions']['bareOverallHeight']
    assert mod.highest_z == high_z
    assert mod.location.point == offset
    mod = module_geometry.load_module(model, Location(Point(1, 2, 3), 'test'))
    assert mod.highest_z == high_z + 3
    assert mod.location.point == (offset + Point(1, 2, 3))
    mod2 = module_geometry.load_module_from_definition(
        module_defs[v1_module_name], Location(Point(3, 2, 1), 'test2'))
    assert mod2.highest_z == high_z + 1
    assert mod2.location.point == (offset + Point(3, 2, 1))
예제 #9
0
def test_module_load():
    module_names = ['tempdeck', 'magdeck']
    module_defs = json.loads(load_shared_data('module/definitions/1.json'))
    for name in module_names:
        mod = labware.load_module(name, Location(Point(0, 0, 0), 'test'))
        mod_def = module_defs[name]
        offset = Point(mod_def['labwareOffset']['x'],
                       mod_def['labwareOffset']['y'],
                       mod_def['labwareOffset']['z'])
        high_z = mod_def['dimensions']['bareOverallHeight']
        assert mod.highest_z == high_z
        assert mod.location.point == offset
        mod = labware.load_module(name, Location(Point(1, 2, 3), 'test'))
        assert mod.highest_z == high_z + 3
        assert mod.location.point == (offset + Point(1, 2, 3))
        mod2 = labware.load_module_from_definition(
            mod_def, Location(Point(3, 2, 1), 'test2'))
        assert mod2.highest_z == high_z + 1
        assert mod2.location.point == (offset + Point(3, 2, 1))
예제 #10
0
def load_module_from_definition(
    definition: Dict[str, Any],
    parent: Location,
    api_level: APIVersion = None,
    configuration: GenericConfiguration = ThermocyclerConfiguration.FULL
) -> ModuleGeometry:
    """
    Return a :py:class:`ModuleGeometry` object from a specified definition
    matching the v1 module definition schema

    :param definition: A dict representing the full module definition adhering
                       to the v1 module schema
    :param parent: A :py:class:`.Location` representing the location where
                   the front and left most point of the outside of the module
                   is (often the front-left corner of a slot on the deck).
    :param APIVersion api_level: the API version to set for the loaded
                                 :py:class:`ModuleGeometry` instance. The
                                 :py:class:`ModuleGeometry` will
                                 conform to this level. If not specified,
                                 defaults to :py:attr:`.MAX_SUPPORTED_VERSION`.
    """
    api_level = api_level or MAX_SUPPORTED_VERSION
    schema = definition.get("$otSharedSchema")
    if not schema:
        # v1 definitions don't have schema versions
        return _load_from_v1(definition, parent, api_level)
    if schema == 'module/schemas/2':
        schema_doc = json.loads(load_shared_data("module/schemas/2.json"))
        try:
            jsonschema.validate(definition, schema_doc)
        except jsonschema.ValidationError:
            log.exception("Failed to validate module def schema")
            raise RuntimeError('The specified module definition is not valid.')
        return _load_from_v2(definition, parent, api_level, configuration)
    elif isinstance(schema, str):
        maybe_schema = re.match('^module/schemas/([0-9]+)$', schema)
        if maybe_schema:
            raise RuntimeError(
                f"Module definitions of schema version {maybe_schema.group(1)}"
                " are not supported in this robot software release.")
    log.error(f"Bad module definition (schema specifier {schema})")
    raise RuntimeError('The specified module definition is not valid.')
예제 #11
0
def test_module_load_labware(loop):
    ctx = papi.ProtocolContext(loop)
    labware_name = 'corning_96_wellplate_360ul_flat'
    # TODO Ian 2019-05-29 load fixtures, not real defs
    labware_def = json.loads(
        load_shared_data(f'labware/definitions/2/{labware_name}/1.json'))
    ctx._hw_manager.hardware._backend._attached_modules = [
        ('mod0', 'tempdeck')]
    mod = ctx.load_module('Temperature Module', 1)
    assert mod.labware is None
    lw = mod.load_labware(labware_name)
    lw_offset = Point(labware_def['cornerOffsetFromSlot']['x'],
                      labware_def['cornerOffsetFromSlot']['y'],
                      labware_def['cornerOffsetFromSlot']['z'])
    assert lw._offset == lw_offset + mod._geometry.location.point
    assert lw.name == labware_name
    # Test load with old name
    mod2 = ctx.load_module('tempdeck', 2)
    lw2 = mod2.load_labware(labware_name)
    assert lw2._offset == lw_offset + mod2._geometry.location.point
예제 #12
0
def verify_definition(contents: Union[AnyStr, LabwareDefinition])\
        -> LabwareDefinition:
    """ Verify that an input string is a labware definition and return it.

    If the definition is invalid, an exception is raised; otherwise parse the
    json and return the valid definition.

    :raises json.JsonDecodeError: If the definition is not valid json
    :raises jsonschema.ValidationError: If the definition is not valid.
    :returns: The parsed definition
    """
    schema_body = load_shared_data('labware/schemas/2.json').decode('utf-8')
    labware_schema_v2 = json.loads(schema_body)

    if isinstance(contents, dict):
        to_return = contents
        jsonschema.validate(to_return, labware_schema_v2)

    else:
        to_return = json.loads(contents)
        jsonschema.validate(to_return, labware_schema_v2)
    return to_return
예제 #13
0
def test_magdeck_gen1_labware_props(loop):
    ctx = papi.ProtocolContext(loop)
    # TODO Ian 2019-05-29 load fixtures, not real defs
    labware_name = 'biorad_96_wellplate_200ul_pcr'
    labware_def = json.loads(
        load_shared_data(f'labware/definitions/2/{labware_name}/1.json'))
    mod = ctx.load_module('magdeck', 1)
    assert mod.labware is None
    mod.engage(height=45)
    assert mod._module.current_height == 45
    with pytest.raises(ValueError):
        mod.engage(height=45.1)  # max engage height for gen1 is 45 mm
    mod.load_labware(labware_name)
    mod.engage()
    lw_offset = labware_def['parameters']['magneticModuleEngageHeight']
    assert mod._module._driver.plate_height == lw_offset
    mod.disengage()
    mod.engage(offset=2)
    assert mod._module._driver.plate_height == lw_offset + 2
    mod.disengage()
    mod.engage(height=3)
    assert mod._module._driver.plate_height == 3
    mod._geometry.reset_labware()
    labware_name = 'corning_96_wellplate_360ul_flat'
    mod.load_labware(labware_name)
    with pytest.raises(ValueError):
        mod.engage()
    with pytest.raises(ValueError):
        mod.engage(offset=1)
    mod.engage(height=2)
    assert mod._module._driver.plate_height == 2
    mod.engage(height=0)
    assert mod._module._driver.plate_height == 0
    mod.engage(height_from_base=2)
    assert mod._module._driver.plate_height == 2 +\
        OFFSET_TO_LABWARE_BOTTOM[mod._module.model()]
예제 #14
0
def name_config() -> Dict[str, Any]:
    """ Load the per-pipette-name config file from within the wheel """
    return json.loads(
        load_shared_data('pipette/definitions/pipetteNameSpecs.json') or '{}')
예제 #15
0
 def dummy_load(labware_name, namespace=None, version=None):
     # TODO: Ian 2019-05-30 use fixtures not real defs
     labware_def = json.loads(
         load_shared_data(f'labware/definitions/2/{labware_name}/1.json'))
     return labware_def
예제 #16
0
import json
from unittest.mock import patch
from numpy import isclose

import pytest
from opentrons import types

from opentrons.config import pipette_config, feature_flags as ff, CONFIG
from opentrons.system.shared_data import load_shared_data

defs = json.loads(
    load_shared_data("pipette/definitions/pipetteModelSpecs.json"))


def check_sequences_close(first, second):
    """
    Check two ul/mm sequences are the same (replaces pytest.approx nested )
    """
    assert len(first) == len(second)
    for f, s in zip(first, second):
        assert f == pytest.approx(s)


@pytest.mark.parametrize('pipette_model', [
    c for c in pipette_config.config_models
    if not (c.startswith('p1000') or c.startswith('p300_multi')
            or c.endswith('1.5') or c.endswith('1.6') or 'v2' in c)
])
def test_versioned_aspiration(pipette_model, monkeypatch):

    monkeypatch.setattr(ff, 'use_old_aspiration_functions', lambda: True)