Ejemplo n.º 1
0
def test_gen2_module_transforms():
    deck = Deck()
    tmod = module_geometry.load_module(
        module_geometry.TemperatureModuleModel.TEMPERATURE_V2,
        deck.position_for('1'), MAX_SUPPORTED_VERSION)
    assert tmod.labware_offset == Point(-1.45, -0.15, 80.09)
    tmod2 = module_geometry.load_module(
        module_geometry.TemperatureModuleModel.TEMPERATURE_V2,
        deck.position_for('3'), MAX_SUPPORTED_VERSION)
    assert tmod2.labware_offset == Point(1.15, -0.15, 80.09)

    mmod = module_geometry.load_module(
        module_geometry.MagneticModuleModel.MAGNETIC_V2,
        deck.position_for('1'), MAX_SUPPORTED_VERSION)
    assert mmod.labware_offset == Point(-1.175, -0.125, 82.25)
    mmod2 = module_geometry.load_module(
        module_geometry.MagneticModuleModel.MAGNETIC_V2,
        deck.position_for('3'), MAX_SUPPORTED_VERSION)
    assert mmod2.labware_offset == Point(1.425, -0.125, 82.25)
Ejemplo n.º 2
0
def test_highest_z():
    deck = Deck()
    fixed_trash = deck.get_fixed_trash()
    assert deck.highest_z == fixed_trash.highest_z
    tall_lw = labware.load(tall_lw_name, deck.position_for(1))
    deck[1] = tall_lw
    assert deck.highest_z == pytest.approx(tall_lw.wells()[0].top().point.z)
    del deck[1]
    assert deck.highest_z == fixed_trash.highest_z
    mod = module_geometry.load_module(
        module_geometry.TemperatureModuleModel.TEMPERATURE_V1,
        deck.position_for(8))
    deck[8] = mod
    assert deck.highest_z == mod.highest_z
    lw = labware.load(labware_name, mod.location)
    mod.add_labware(lw)
    deck.recalculate_high_z()
    assert deck.highest_z == mod.highest_z
Ejemplo n.º 3
0
def test_first_parent():
    deck = Deck()
    trough = labware.load(trough_name, deck.position_for(1))
    assert first_parent(trough) == '1'
    assert first_parent(trough['A2']) == '1'
    assert first_parent(None) is None
    assert first_parent('6') == '6'
    mod = module_geometry.load_module(
        module_geometry.TemperatureModuleModel.TEMPERATURE_V2,
        deck.position_for('6'), MAX_SUPPORTED_VERSION)
    mod_trough = mod.add_labware(labware.load(trough_name, mod.location))
    assert first_parent(mod_trough['A5']) == '6'
    assert first_parent(mod_trough) == '6'
    assert first_parent(mod) == '6'

    mod_trough._parent = mod_trough
    with pytest.raises(RuntimeError):
        # make sure we catch cycles
        first_parent(mod_trough)
Ejemplo n.º 4
0
def test_slot_collisions():
    d = Deck()
    mod_slot = '7'
    mod = module_geometry.load_module(
        module_geometry.ThermocyclerModuleModel.THERMOCYCLER_V1,
        d.position_for(mod_slot))
    d[mod_slot] = mod
    with pytest.raises(ValueError):
        d['7'] = 'not this time boyo'
    with pytest.raises(ValueError):
        d['8'] = 'nor this time boyo'
    with pytest.raises(ValueError):
        d['10'] = 'or even this time boyo'
    with pytest.raises(ValueError):
        d['11'] = 'def not this time though'

    lw_slot = '4'
    lw = labware.load(labware_name, d.position_for(lw_slot))
    d[lw_slot] = lw

    assert lw_slot in d
Ejemplo n.º 5
0
def test_should_dodge():
    deck = Deck()
    # with no tc loaded, doesn't matter what the positions are
    assert not should_dodge_thermocycler(deck, deck.position_for(4),
                                         deck.position_for(9))
    deck[7] = module_geometry.load_module(
        module_geometry.ThermocyclerModuleModel.THERMOCYCLER_V1,
        deck.position_for(7))
    # with a tc loaded, some positions should require dodging
    assert should_dodge_thermocycler(deck, deck.position_for(12),
                                     deck.position_for(1))
    assert should_dodge_thermocycler(deck, deck.position_for(9),
                                     deck.position_for(4))
    # but ones that weren't explicitly marked shouldn't
    assert not should_dodge_thermocycler(deck, deck.position_for(1),
                                         deck.position_for(2))
    # including a situation where we might have some messed up locations
    # with no parent
    assert not should_dodge_thermocycler(
        deck,
        deck.position_for(1)._replace(labware=None), deck.position_for(12))
Ejemplo n.º 6
0
def test_slot_names():
    slots_by_int = list(range(1, 13))
    slots_by_str = [str(idx) for idx in slots_by_int]
    for method in (slots_by_int, slots_by_str):
        d = Deck()
        for idx, slot in enumerate(method):
            lw = labware.load(labware_name, d.position_for(slot))
            assert slot in d
            d[slot] = lw
            with pytest.raises(ValueError):
                d[slot] = 'not this time boyo'
            del d[slot]
            assert slot in d
            assert d[slot] is None
            mod = module_geometry.load_module(
                module_geometry.TemperatureModuleModel.TEMPERATURE_V1,
                d.position_for(slot))
            d[slot] = mod
            assert mod == d[slot]

    assert 'hasasdaia' not in d
    with pytest.raises(ValueError):
        d['ahgoasia'] = 'nope'
Ejemplo n.º 7
0
    def load_module(self,
                    module_name: str,
                    location: Optional[types.DeckLocation] = None,
                    configuration: str = None) -> ModuleTypes:
        """ Load a module onto the deck given its name.

        This is the function to call to use a module in your protocol, like
        :py:meth:`load_instrument` is the method to call to use an instrument
        in your protocol. It returns the created and initialized module
        context, which will be a different class depending on the kind of
        module loaded.

        A map of deck positions to loaded modules can be accessed later
        using :py:attr:`loaded_modules`.

        :param str module_name: The name or model of the module.
        :param location: The location of the module. This is usually the
                         name or number of the slot on the deck where you
                         will be placing the module. Some modules, like
                         the Thermocycler, are only valid in one deck
                         location. You do not have to specify a location
                         when loading a Thermocycler - it will always be
                         in Slot 7.
        :param configuration: Used to specify the slot configuration of
                              the Thermocycler. Only Valid in Python API
                              Version 2.4 and later. If you wish to use
                              the non-full plate configuration, you must
                              pass in the key word value `semi`
        :type location: str or int or None
        :returns ModuleContext: The loaded and initialized
                                :py:class:`ModuleContext`.
        """
        resolved_model = resolve_module_model(module_name)
        resolved_type = resolve_module_type(resolved_model)
        resolved_location = self._deck_layout.resolve_module_location(
            resolved_type, location)
        if self._api_version < APIVersion(2, 4) and configuration:
            raise APIVersionError(
                f'You have specified API {self._api_version}, but you are'
                'using thermocycler parameters only available in 2.4')

        geometry = load_module(
            resolved_model, self._deck_layout.position_for(resolved_location),
            self._api_version, configuration)

        hc_mod_instance = None
        mod_class = {
            ModuleType.MAGNETIC: MagneticModuleContext,
            ModuleType.TEMPERATURE: TemperatureModuleContext,
            ModuleType.THERMOCYCLER: ThermocyclerContext
        }[resolved_type]
        for mod in self._hw_manager.hardware.attached_modules:
            if models_compatible(module_model_from_string(mod.model()),
                                 resolved_model):
                hc_mod_instance = SynchronousAdapter(mod)
                break

        if self.is_simulating() and hc_mod_instance is None:
            mod_type = {
                ModuleType.MAGNETIC: modules.magdeck.MagDeck,
                ModuleType.TEMPERATURE: modules.tempdeck.TempDeck,
                ModuleType.THERMOCYCLER: modules.thermocycler.Thermocycler
            }[resolved_type]
            hc_mod_instance = SynchronousAdapter(
                mod_type(port='',
                         simulating=True,
                         loop=self._hw_manager.hardware.loop,
                         execution_manager=ExecutionManager(
                             loop=self._hw_manager.hardware.loop),
                         sim_model=resolved_model.value))
            hc_mod_instance._connect()
        if hc_mod_instance:
            mod_ctx = mod_class(self, hc_mod_instance, geometry,
                                self.api_version, self._loop)
        else:
            raise RuntimeError(
                f'Could not find specified module: {module_name}')
        self._modules.add(mod_ctx)
        self._deck_layout[resolved_location] = geometry
        return mod_ctx