Beispiel #1
0
 def touch_right(cur_position: Location):
     if touch_tip == "right":
         p10_multi.move_to(cur_position.move(Point(x=2.7, z=-0.75)))
         p10_multi.move_to(cur_position.move(Point(x=-1, z=0.75)))
     else:
         p10_multi.move_to(cur_position.move(Point(x=-2.7, z=-0.75)))
         p10_multi.move_to(cur_position.move(Point(x=1, z=0.75)))
Beispiel #2
0
def run(ctx):

    [transfer_csv] = get_values(  # noqa: F821
        "transfer_csv")

    tiprack20 = [
        ctx.load_labware('opentrons_96_tiprack_20ul', '3', '20µl tiprack')
    ]
    pipettes = [
        ctx.load_instrument('p20_single_gen2', mount, tip_racks=tiprack20)
        for mount in ['right', 'left']
    ]

    # load labware
    transfer_info = [[val.strip().lower() for val in line.split(',')[1:]]
                     for line in transfer_csv.splitlines()
                     if line.split(',')[0].strip()][1:]
    src_a = Location(
        Point(float(transfer_info[0][0]), float(transfer_info[0][1]),
              float(transfer_info[0][2])), None)
    src_b = Location(
        Point(float(transfer_info[1][0]), float(transfer_info[1][1]),
              float(transfer_info[1][2])), None)
    for line in transfer_info[2:]:
        dest = Location(Point(float(line[0]), float(line[1]), float(line[2])),
                        None)
        vol = float(line[3])
        [p.pick_up_tip() for p in pipettes]
        [pip.home() for pip in pipettes]
        for src, p in zip([src_a, src_b], pipettes):
            p.aspirate(vol, src)
            p.home()
            p.dispense(vol, dest)
            p.home()
        [p.drop_tip() for p in pipettes]
def test_move_to_slot():
    slot_position = Location(Point(1, 2, 3), 'deck')
    mock_context = mock.Mock()

    mock_deck = mock.MagicMock(spec=Deck)
    mock_deck.__contains__.return_value = True
    mock_deck.position_for.return_value = slot_position

    mock_context.deck = mock_deck
    pipette_mock = mock.create_autospec(InstrumentContext)

    instruments = {'somePipetteId': pipette_mock}

    params = {
        'pipette': 'somePipetteId',
        'slot': '4',
        'offset': {
            'x': 10,
            'y': 11,
            'z': 12
        },
        'forceDirect': mock.sentinel.force_direct,
        'minimumZHeight': mock.sentinel.minimum_z_height
    }

    _move_to_slot(mock_context, instruments, params)

    assert pipette_mock.mock_calls == [
        mock.call.move_to(Location(Point(11, 13, 15), 'deck'),
                          force_direct=mock.sentinel.force_direct,
                          minimum_z_height=mock.sentinel.minimum_z_height)
    ]
Beispiel #4
0
async def test_max_speeds(loop, monkeypatch, hardware):
    ctx = papi.ProtocolContext(loop)
    ctx.connect(hardware)
    ctx.home()
    mock_move = mock.Mock()
    monkeypatch.setattr(ctx._hw_manager.hardware, 'move_to', mock_move)
    instr = ctx.load_instrument('p10_single', Mount.RIGHT)
    instr.move_to(Location(Point(0, 0, 0), None))
    assert all(
        kwargs['max_speeds'] == {}
        for args, kwargs in mock_move.call_args_list)

    mock_move.reset_mock()
    ctx.max_speeds['x'] = 10
    instr.move_to(Location(Point(0, 0, 1), None))
    assert all(
        kwargs['max_speeds'] == {Axis.X: 10}
        for args, kwargs in mock_move.call_args_list)

    mock_move.reset_mock()
    ctx.max_speeds['x'] = None
    instr.move_to(Location(Point(1, 0, 1), None))
    assert all(
        kwargs['max_speeds'] == {}
        for args, kwargs in mock_move.call_args_list)
Beispiel #5
0
def test_tiprack_list():
    labware_name = 'opentrons_96_tiprack_300ul'
    labware_def = labware.get_labware_definition(labware_name)
    tiprack = labware.Labware(labware_def,
                              Location(Point(0, 0, 0), 'Test Slot'))
    tiprack_2 = labware.Labware(labware_def,
                                Location(Point(0, 0, 0), 'Test Slot'))

    assert labware.select_tiprack_from_list(
        [tiprack], 1) == (tiprack, tiprack['A1'])

    assert labware.select_tiprack_from_list(
        [tiprack], 1, tiprack.wells()[1]) == (tiprack, tiprack['B1'])

    tiprack['C1'].has_tip = False
    assert labware.select_tiprack_from_list(
        [tiprack], 1, tiprack.wells()[2]) == (tiprack, tiprack['D1'])

    tiprack['H12'].has_tip = False
    tiprack_2['A1'].has_tip = False
    assert labware.select_tiprack_from_list(
        [tiprack, tiprack_2], 1, tiprack.wells()[95]) == (
            tiprack_2, tiprack_2['B1'])

    with pytest.raises(labware.OutOfTipsError):
        labware.select_tiprack_from_list(
            [tiprack], 1, tiprack.wells()[95])
Beispiel #6
0
 def _get_move_to_point_loc_by_state(self) -> Location:
     assert self._z_height_reference is not None, \
         "saveOffset has not been called yet"
     pt_id = MOVE_POINT_STATE_MAP[self._current_state]
     coords = self._deck.get_calibration_position(pt_id).position
     loc = Location(Point(*coords), None)
     return loc.move(point=Point(0, 0, self._z_height_reference))
Beispiel #7
0
def test_air_gap():
    m = mock.MagicMock()
    m.pipette_mock = mock.create_autospec(InstrumentContext)
    m.mock_set_flow_rate = mock.MagicMock()

    deck = Location(Point(0, 0, 0), 'deck')
    well_name = 'A2'
    some_labware = labware.Labware(minimalLabwareDef2, deck)
    loaded_labware = {'someLabwareId': some_labware}
    params = {'labware': 'someLabwareId', 'well': well_name}

    params = {'pipette': 'somePipetteId', 'volume': 42,
              'labware': 'someLabwareId', 'well': well_name,
              'offsetFromBottomMm': 12}

    instruments = {'somePipetteId': m.pipette_mock}

    loaded_labware = {'someLabwareId': some_labware}

    with mock.patch(
            'opentrons.protocols.execution.execute_json_v3._set_flow_rate',
            new=m.mock_set_flow_rate):
        _air_gap(instruments, loaded_labware, params)

    # NOTE: air_gap `height` arg is mm from well top,
    # so we expect it to equal offsetFromBottomMm - well depth.
    assert m.mock_calls == [
        mock.call.mock_set_flow_rate(m.pipette_mock, params),
        mock.call.pipette_mock.move_to(
            Location(point=Point(x=19, y=28, z=17.0),
                     labware=some_labware[well_name])),
        mock.call.pipette_mock.air_gap(42, 12 - 40)
    ]
Beispiel #8
0
def test_direct_cp():
    deck = Deck()
    trough = labware.load(trough_name, deck.position_for(1))
    lw1 = labware.load(labware_name, deck.position_for(2))
    # when moving from no origin location to a centered labware we should
    # start in default cp
    from_nothing = plan_moves(Location(Point(50, 50, 50), None),
                              trough.wells()[0].top(), deck)
    check_arc_basic(from_nothing, Location(Point(50, 50, 50), None),
                    trough.wells()[0].top())
    assert from_nothing[0][1] is None
    assert from_nothing[1][1] == CriticalPoint.XY_CENTER
    assert from_nothing[2][1] == CriticalPoint.XY_CENTER
    # when moving from an origin with a centered labware to a dest with a
    # centered labware we should stay in centered the entire time, whether
    # arc
    from_centered_arc = plan_moves(trough.wells()[0].top(),
                                   trough.wells()[1].top(), deck)
    check_arc_basic(from_centered_arc,
                    trough.wells()[0].top(),
                    trough.wells()[1].top())
    assert from_centered_arc[0][1] == CriticalPoint.XY_CENTER
    assert from_centered_arc[1][1] == CriticalPoint.XY_CENTER
    assert from_centered_arc[2][1] == CriticalPoint.XY_CENTER
    # or direct
    from_centered_direct = plan_moves(trough.wells()[0].top(),
                                      trough.wells()[1].bottom(), deck)
    assert from_centered_direct[0][1] == CriticalPoint.XY_CENTER
    # when moving from centered to normal, only the first move should be
    # centered
    to_normal = plan_moves(trough.wells()[0].top(), lw1.wells()[0].top(), deck)
    check_arc_basic(to_normal, trough.wells()[0].top(), lw1.wells()[0].top())
    assert to_normal[0][1] == CriticalPoint.XY_CENTER
    assert to_normal[1][1] is None
    assert to_normal[2][1] is None
def test_select_next_tip():
    labware_name = 'opentrons_96_tiprack_300ul'
    labware_def = labware.get_labware_definition(labware_name)
    tiprack = labware.Labware(labware_def,
                              Location(Point(0, 0, 0), 'Test Slot'))
    well_list = tiprack.wells()

    next_one = tiprack.next_tip()
    assert next_one == well_list[0]
    next_five = tiprack.next_tip(5)
    assert next_five == well_list[0]
    next_eight = tiprack.next_tip(8)
    assert next_eight == well_list[0]
    next_nine = tiprack.next_tip(9)
    assert next_nine is None

    # A1 tip only has been used
    tiprack.use_tips(well_list[0])

    next_one = tiprack.next_tip()
    assert next_one == well_list[1]
    next_five = tiprack.next_tip(5)
    assert next_five == well_list[1]
    next_eight = tiprack.next_tip(8)
    assert next_eight == well_list[8]

    # 2nd column has also been used
    tiprack.use_tips(well_list[8], num_channels=8)

    next_one = tiprack.next_tip()
    assert next_one == well_list[1]
    next_five = tiprack.next_tip(5)
    assert next_five == well_list[1]
    next_eight = tiprack.next_tip(8)
    assert next_eight == well_list[16]

    # Bottom 4 tips of 1rd column are also used
    tiprack.use_tips(well_list[4], num_channels=4)

    next_one = tiprack.next_tip()
    assert next_one == well_list[1]
    next_three = tiprack.next_tip(3)
    assert next_three == well_list[1]
    next_five = tiprack.next_tip(5)
    assert next_five == well_list[16]
    next_eight = tiprack.next_tip(8)
    assert next_eight == well_list[16]

    # you can reuse tips infinitely on api level 2.2
    tiprack.use_tips(well_list[0])
    tiprack.use_tips(well_list[0])

    # you can't on api level 2.1 or previous
    early_tr = labware.Labware(labware_def,
                               Location(Point(0, 0, 0), 'Test Slot'),
                               api_level=APIVersion(2, 1))
    early_tr.use_tips(well_list[0])
    with pytest.raises(AssertionError):
        early_tr.use_tips(well_list[0])
Beispiel #10
0
def test_get_location_with_offset():
    deck = Location(Point(0, 0, 0), 'deck')
    some_labware = labware.Labware(minimalLabwareDef2, deck)
    loaded_labware = {'someLabwareId': some_labware}
    params = {'offsetFromBottomMm': 3,
              'labware': 'someLabwareId', 'well': 'A2'}
    result = _get_location_with_offset(loaded_labware, params)
    assert result == Location(Point(19, 28, 8), some_labware['A2'])
Beispiel #11
0
def test_bottom():
    slot = Location(Point(7, 8, 9), 1)
    well_name = 'rectangular_well_json'
    has_tip = False
    well = labware.Well(test_data[well_name], slot, well_name, has_tip)
    well_data = test_data[well_name]
    expected_x = well_data['x'] + slot.point.x
    expected_y = well_data['y'] + slot.point.y
    expected_z = well_data['z'] + slot.point.z
    assert well.bottom() == Location(Point(expected_x, expected_y, expected_z),
                                     well)
Beispiel #12
0
def test_top():
    slot = Location(Point(4, 5, 6), 1)
    well_name = 'circular_well_json'
    has_tip = False
    well = labware.Well(test_data[well_name], slot, well_name, has_tip)
    well_data = test_data[well_name]
    expected_x = well_data['x'] + slot.point.x
    expected_y = well_data['y'] + slot.point.y
    expected_z = well_data['z'] + well_data['depth'] + slot.point.z
    assert well.top() == Location(Point(expected_x, expected_y, expected_z),
                                  well)
Beispiel #13
0
 async def move_to_tip_rack(self):
     # point safely above target tip well in tip rack
     pt_above_well = self._tip_rack.wells()[0].top().point + \
         MOVE_TO_TIP_RACK_SAFETY_BUFFER
     if self._tip_origin_pt is not None:
         # use jogged to x and y offsets only if returning tip to rack
         await self._move(Location(Point(self._tip_origin_pt.x,
                                         self._tip_origin_pt.y,
                                         pt_above_well.z),
                                   None))
     else:
         await self._move(Location(pt_above_well, None))
Beispiel #14
0
def test_get_location_with_offset_fixed_trash():
    deck = Location(Point(0, 0, 0), 'deck')
    trash_labware_def = deepcopy(minimalLabwareDef2)
    trash_labware_def['parameters']['quirks'] = ["fixedTrash"]
    trash_labware = labware.Labware(trash_labware_def, deck)

    loaded_labware = {'someLabwareId': trash_labware}
    params = {'offsetFromBottomMm': 3,
              'labware': 'someLabwareId', 'well': 'A1'}

    result = _get_location_with_offset(loaded_labware, params)

    assert result == Location(Point(10, 28, 45), trash_labware['A1'])
def test_get_parent_identifier():
    labware_name = 'corning_96_wellplate_360ul_flat'
    labware_def = labware.get_labware_definition(labware_name)
    lw = labware.Labware(labware_def, Location(Point(0, 0, 0), 'Test Slot'))
    # slots have no parent identifier
    assert labware._get_parent_identifier(lw) == ''
    # modules do
    mmg = ModuleGeometry('my magdeck',
                         MagneticModuleModel.MAGNETIC_V1,
                         ModuleType.MAGNETIC,
                         Point(0, 0, 0), 10, 10, Location(Point(1, 2, 3), '3'),
                         APIVersion(2, 4))
    lw = labware.Labware(labware_def, mmg.location)
    assert labware._get_parent_identifier(lw)\
        == MagneticModuleModel.MAGNETIC_V1.value
Beispiel #16
0
def test_tip_tracking_init():
    labware_name = 'opentrons_96_tiprack_300ul'
    labware_def = labware.get_labware_definition(labware_name)
    tiprack = labware.Labware(labware_def,
                              Location(Point(0, 0, 0), 'Test Slot'))
    assert tiprack.is_tiprack
    for well in tiprack.wells():
        assert well.has_tip

    labware_name = 'corning_96_wellplate_360ul_flat'
    labware_def = labware.get_labware_definition(labware_name)
    lw = labware.Labware(labware_def, Location(Point(0, 0, 0), 'Test Slot'))
    assert not lw.is_tiprack
    for well in lw.wells():
        assert not well.has_tip
Beispiel #17
0
def test_well_parent():
    labware_name = 'corning_96_wellplate_360ul_flat'
    labware_def = labware.get_labware_definition(labware_name)
    lw = labware.Labware(labware_def, Location(Point(0, 0, 0), 'Test Slot'))
    parent = Location(Point(7, 8, 9), lw)
    well_name = 'circular_well_json'
    has_tip = True
    well = labware.Well(test_data[well_name], parent, well_name, has_tip)
    assert well.parent is lw
    assert well.top().labware is well
    assert well.top().labware.parent is lw
    assert well.bottom().labware is well
    assert well.bottom().labware.parent is lw
    assert well.center().labware is well
    assert well.center().labware.parent is lw
def test_labware_init():
    deck = Location(Point(0, 0, 0), 'deck')
    fake_labware = labware.Labware(minimalLabwareDef, deck)
    ordering = [well for col in minimalLabwareDef['ordering'] for well in col]
    assert fake_labware._ordering == ordering
    assert fake_labware._well_definition == minimalLabwareDef['wells']
    assert fake_labware._offset == Point(x=10, y=10, z=5)
Beispiel #19
0
def test_load_calibration(monkeypatch, clear_calibration):

    calibration_point = None

    def mock_set_calibration(self, delta):
        nonlocal calibration_point
        calibration_point = delta

    monkeypatch.setattr(labware.Labware, 'set_calibration',
                        mock_set_calibration)

    monkeypatch.setattr(labware, '_hash_labware_def', mock_hash_labware)

    test_labware = labware.Labware(minimalLabwareDef,
                                   Location(Point(0, 0, 0), 'deck'))

    test_offset = Point(1, 1, 1)
    test_tip_length = 31.7

    labware.save_calibration(test_labware, test_offset)
    labware.save_tip_length(test_labware, test_tip_length)

    # Set without saving to show that load will update with previously saved
    # data
    test_labware.set_calibration(Point(0, 0, 0))
    test_labware.tip_length = 46.8

    labware.load_calibration(test_labware)
    assert calibration_point == test_offset
    assert test_labware.tip_length == test_tip_length
Beispiel #20
0
def test_build_edges():
    lw_def = get_labware_definition('corning_96_wellplate_360ul_flat')
    test_lw = Labware(lw_def, Location(Point(0, 0, 0), None))
    off = Point(0, 0, 1.0)
    deck = Deck()
    old_correct_edges = [
        test_lw['A1']._from_center_cartesian(x=1.0, y=0, z=1) + off,
        test_lw['A1']._from_center_cartesian(x=-1.0, y=0, z=1) + off,
        test_lw['A1']._from_center_cartesian(x=0, y=1.0, z=1) + off,
        test_lw['A1']._from_center_cartesian(x=0, y=-1.0, z=1) + off,
    ]
    res = build_edges(
        test_lw['A1'], 1.0, Mount.RIGHT, deck, version=APIVersion(2, 2))
    assert res == old_correct_edges

    new_correct_edges = [
        test_lw['A1']._from_center_cartesian(x=1.0, y=0, z=1) + off,
        test_lw['A1']._from_center_cartesian(x=-1.0, y=0, z=1) + off,
        test_lw['A1']._from_center_cartesian(x=0, y=0, z=1) + off,
        test_lw['A1']._from_center_cartesian(x=0, y=1.0, z=1) + off,
        test_lw['A1']._from_center_cartesian(x=0, y=-1.0, z=1) + off,
    ]
    res2 = build_edges(
        test_lw['A1'], 1.0, Mount.RIGHT, deck, version=APIVersion(2, 4))
    assert res2 == new_correct_edges
def test_module_load_v2(module_model):
    mod = module_geometry.load_module(
        module_model, Location(Point(0, 0, 0), '3'))
    mod_def = module_geometry._load_module_definition(MAX_SUPPORTED_VERSION,
                                                      module_model)
    high_z = mod_def['dimensions']['bareOverallHeight']
    assert mod.highest_z == high_z
Beispiel #22
0
    def __init__(self, definition: dict, parent: Location) -> None:
        """
        Create a Module for tracking the position of a module.

        Note that modules do not currently have a concept of calibration apart
        from calibration of labware on top of the module. The practical result
        of this is that if the module parent :py:class:`.Location` is
        incorrect, then acorrect calibration of one labware on the deck would
        be incorrect on the module, and vice-versa. Currently, the way around
        this would be to correct the :py:class:`.Location` so that the
        calibrated labware is targeted accurately in both positions.

        :param definition: A dict containing all the data required to define
                           the geometry of the module.
        :type definition: dict
        :param parent: A location representing location of the front left of
                       the outside of the module (usually the front-left corner
                       of a slot on the deck).
        :type parent: :py:class:`.Location`
        """
        self._parent = parent
        self._display_name = "{} on {}".format(definition["displayName"],
                                               str(parent.labware))
        self._load_name = definition["loadName"]
        self._offset = Point(definition["labwareOffset"]["x"],
                             definition["labwareOffset"]["y"],
                             definition["labwareOffset"]["z"])
        self._height = definition["dimensions"]["bareOverallHeight"]\
            + self._parent.point.z
        self._over_labware = definition["dimensions"]["overLabwareHeight"]
        self._labware: Optional[Labware] = None
        self._location = Location(point=self._offset + self._parent.point,
                                  labware=self)
def test_touch_tip():
    location = Location(Point(1, 2, 3), 'deck')
    well = labware.Well(
        {
            'shape': 'circular',
            'depth': 40,
            'totalLiquidVolume': 100,
            'diameter': 30,
            'x': 40,
            'y': 50,
            'z': 3
        },
        parent=Location(Point(10, 20, 30), 1),
        has_tip=False,
        display_name='some well',
        api_level=MAX_SUPPORTED_VERSION)

    pipette_mock = mock.create_autospec(InstrumentContext, name='pipette_mock')
    mock_get_location_with_offset = mock.MagicMock(
        return_value=location, name='mock_get_location_with_offset')
    mock_get_well = mock.MagicMock(return_value=well, name='mock_get_well')
    mock_set_flow_rate = mock.MagicMock(name='mock_set_flow_rate')

    params = {
        'pipette': 'somePipetteId',
        'labware': 'someLabwareId',
        'well': 'someWell'
    }
    instruments = {'somePipetteId': pipette_mock}

    with mock.patch(
            'opentrons.protocol_api.execute_v3._get_location_with_offset',
            new=mock_get_location_with_offset):
        with mock.patch('opentrons.protocol_api.execute_v3._get_well',
                        new=mock_get_well):
            with mock.patch('opentrons.protocol_api.execute_v3._set_flow_rate',
                            new=mock_set_flow_rate):
                _touch_tip(instruments, mock.sentinel.loaded_labware, params)

    # note: for this fn, order of calls doesn't matter b/c
    # we don't have stateful stuff like flow_rate
    mock_get_location_with_offset.assert_called_once_with(
        mock.sentinel.loaded_labware, params)
    mock_get_well.assert_called_once_with(mock.sentinel.loaded_labware, params)
    assert pipette_mock.mock_calls == [
        mock.call.touch_tip(well, v_offset=-70.0)
    ]
Beispiel #24
0
def test_uris():
    details = ('opentrons', 'opentrons_96_tiprack_300ul', '1')
    uri = 'opentrons/opentrons_96_tiprack_300ul/1'
    assert labware.uri_from_details(*details) == uri
    defn = labware.get_labware_definition(details[1], details[0], details[2])
    assert labware.uri_from_definition(defn) == uri
    lw = labware.Labware(defn, Location(Point(0, 0, 0), 'Test Slot'))
    assert lw.uri == uri
Beispiel #25
0
 async def _return_first_tip(self):
     first_pip = self._get_pipette_by_rank(PipetteRank.first)
     assert first_pip, \
         'cannot drop tip on first mount, pipette not present'
     state_name = CalibrationCheckState.preparingFirstPipette
     loc = Location(getattr(self._moves, state_name).position, None)
     await self._move(first_pip.mount, loc)
     await self._drop_tip(first_pip.mount)
Beispiel #26
0
 async def _return_second_tip(self):
     second_pip = self._get_pipette_by_rank(PipetteRank.second)
     assert second_pip, \
         'cannot drop tip on second mount, pipette not present'
     state_name = CalibrationCheckState.preparingSecondPipette
     loc = Location(getattr(self._moves, state_name).position, None)
     await self._move(second_pip.mount, loc)
     await self._drop_tip(second_pip.mount)
Beispiel #27
0
 async def _move_second_pipette(self):
     second_pip = self._get_pipette_by_rank(PipetteRank.second)
     assert second_pip, \
         'cannot move pipette on second mount, pipette not present'
     loc_to_move = Location(
         getattr(self._moves, self.current_state_name).position, None)
     if self.current_state_name ==\
             CalibrationCheckState.joggingSecondPipetteToPointOne:
         saved_height =\
             self._saved_points[getattr(CalibrationCheckState,
                                        'comparingSecondPipetteHeight')]
         z_point = \
             saved_height + self._initial_z_offset - HEIGHT_SAFETY_BUFFER
         updated_point = loc_to_move.point + z_point._replace(x=0.0, y=0.0)
         loc_to_move = Location(updated_point, None)
     await self._move(second_pip.mount, loc_to_move)
     await self._register_point_second_pipette()
def test_get_well():
    deck = Location(Point(0, 0, 0), 'deck')
    well_name = 'A2'
    some_labware = labware.Labware(minimalLabwareDef2, deck)
    loaded_labware = {'someLabwareId': some_labware}
    params = {'labware': 'someLabwareId', 'well': well_name}
    result = _get_well(loaded_labware, params)
    assert result == some_labware[well_name]
Beispiel #29
0
 async def move_to_deck(self):
     deck_pt = self._deck.get_slot_center(JOG_TO_DECK_SLOT)
     ydim = self._deck.get_slot_definition(
         JOG_TO_DECK_SLOT)['boundingBox']['yDimension']
     new_pt = deck_pt - Point(0, (ydim/2), deck_pt.z) + \
         MOVE_TO_DECK_SAFETY_BUFFER
     to_loc = Location(new_pt, None)
     await self._move(to_loc)
Beispiel #30
0
 def center(self) -> Location:
     """
     :return: a Point corresponding to the absolute position of the center
     of the well relative to the deck (with the front-left corner of slot 1
     as (0,0,0))
     """
     top = self.top()
     center_z = top.point.z - (self._depth / 2.0)
     return Location(Point(x=top.point.x, y=top.point.y, z=center_z), self)