def test_all_pipette_models_can_transfer(): from opentrons.config import pipette_config models = [ 'p10_single', 'p10_multi', 'p50_single', 'p50_multi', 'p300_single', 'p300_multi', 'p1000_single' ] for m in models: robot.reset() v1 = m + '_v1' v13 = m + '_v1.3' left = instruments._create_pipette_from_config( config=pipette_config.load(v1), mount='left', name=v1) right = instruments._create_pipette_from_config( config=pipette_config.load(v13), mount='right', name=v13) left.tip_attached = True right.tip_attached = True left.aspirate().dispense() right.aspirate().dispense()
def test_pipette_version_1_0_and_1_3_extended_travel(): models = [ 'p10_single', 'p10_multi', 'p50_single', 'p50_multi', 'p300_single', 'p300_multi', 'p1000_single' ] for m in models: robot.reset() v1 = m + '_v1' v13 = m + '_v1.3' left = instruments._create_pipette_from_config( config=pipette_config.load(v1), mount='left', name=v1) right = instruments._create_pipette_from_config( config=pipette_config.load(v13), mount='right', name=v13) # the difference between v1 and v1.3 is that the plunger's travel # distance extended, allowing greater ranges for aspirate/dispense # and blow-out. Test that all v1.3 pipette have larger travel thant v1 left_poses = left.plunger_positions left_diff = left_poses['top'] - left_poses['blow_out'] right_poses = right.plunger_positions right_diff = right_poses['top'] - right_poses['blow_out'] assert right_diff > left_diff
def set_current_mount(attached_pipettes): """ Choose the pipette in which to execute commands. If there is no pipette, or it is uncommissioned, the pipette is not mounted. :attached_pipettes attached_pipettes: Information obtained from the current pipettes attached to the robot. This looks like the following: :dict with keys 'left' and 'right' and a model string for each mount, or 'uncommissioned' if no model string available :return: The selected pipette """ global session left = attached_pipettes.get('left') right = attached_pipettes.get('right') left_pipette = None right_pipette = None pipette = None model = None if left['model'] in pipette_config.configs: pip_config = pipette_config.load(left['model']) left_pipette = instruments._create_pipette_from_config( mount='left', config=pip_config) if right['model'] in pipette_config.configs: pip_config = pipette_config.load(right['model']) right_pipette = instruments._create_pipette_from_config( mount='right', config=pip_config) if right_pipette and right_pipette.channels == 1: session.current_mount = 'A' pipette = right_pipette model = right['model'] elif left_pipette and left_pipette.channels == 1: session.current_mount = 'Z' pipette = left_pipette model = left['model'] else: if right_pipette: session.current_mount = 'A' pipette = right_pipette model = right['model'] elif left_pipette: session.current_mount = 'Z' pipette = left_pipette model = left['model'] return {'pipette': pipette, 'model': model}
def test_shake_during_pick_up(monkeypatch): robot.reset() pip = instruments._create_pipette_from_config( config=pipette_config.load('p1000_single_v2.0'), mount='left', name='p1000_single_v2.0') tiprack = containers_load(robot, 'opentrons_96_tiprack_1000ul', '1') shake_tips_pick_up = mock.Mock( side_effect=pip._shake_off_tips_pick_up) monkeypatch.setattr(pip, '_shake_off_tips_pick_up', shake_tips_pick_up) # Test double shake for after pick up tips pip.pick_up_tip(tiprack[0]) assert shake_tips_pick_up.call_count == 2 actual_calls = [] def mock_jog(pose_tree, axis, distance): actual_calls.append((axis, distance)) monkeypatch.setattr(pip, '_jog', mock_jog) # Test shake in both x and y shake_tips_pick_up() expected_calls = [('x', -0.3), ('x', 0.6), ('x', -0.3), ('y', -0.3), ('y', 0.6), ('y', -0.3), ('z', 20)] assert actual_calls == expected_calls pip.tip_attached = False
def test_shake_during_drop(monkeypatch): robot.reset() pip = instruments._create_pipette_from_config( config=pipette_config.load('p1000_single_v2.0'), mount='left', name='p1000_single_v2.0') tiprack = containers_load(robot, 'opentrons_96_tiprack_1000ul', '1') shake_tips_drop = mock.Mock( side_effect=pip._shake_off_tips_drop) monkeypatch.setattr(pip, '_shake_off_tips_drop', shake_tips_drop) # Test single shake for after pick up tips pip.tip_attached = True pip.drop_tip(tiprack.wells(0)) assert shake_tips_drop.call_count == 1 actual_calls = [] def jog_side_effect(pose_tree, axis, distance): actual_calls.append((axis, distance)) jog = mock.Mock(side_effect=jog_side_effect) monkeypatch.setattr(pip, '_jog', jog) # Test shake only in x, with no location passed, shake distance is 2.25 shake_tips_drop() expected_calls = [('x', -2.25), ('x', 4.5), ('x', -2.25), ('z', 20)] assert actual_calls == expected_calls # Test drop tip shake at a well with diameter above upper limit (2.25 mm) tiprack.wells(0).properties['width'] = 2.3*4 actual_calls.clear() shake_tips_drop(tiprack.wells(0)) expected_calls = [('x', -2.25), ('x', 4.5), ('x', -2.25), ('z', 20)] assert actual_calls == expected_calls # Test drop tip shake at a well with diameter between upper limit # and lower limit (1.00 - 2.25 mm) tiprack.wells(0).properties['width'] = 2*4 actual_calls.clear() shake_tips_drop(tiprack.wells(0)) expected_calls = [('x', -2), ('x', 4), ('x', -2), ('z', 20)] assert actual_calls == expected_calls # Test drop tip shake at a well with diameter below lower limit (1.00 mm) tiprack.wells(0).properties['width'] = 0.9*4 actual_calls.clear() shake_tips_drop(tiprack.wells(0)) expected_calls = [('x', -1), ('x', 2), ('x', -1), ('z', 20)] assert actual_calls == expected_calls pip.tip_attached = False
def load_pipettes(protocol_data): pipettes = protocol_data.get('pipettes', {}) pipettes_by_id = {} for pipette_id, props in pipettes.items(): model = props.get('model') mount = props.get('mount') config = pipette_config.load(model) pipettes_by_id[pipette_id] = instruments._create_pipette_from_config( config=config, mount=mount) return pipettes_by_id
def test_pipette_models_reach_max_volume(): for model in pipette_config.config_models: config = pipette_config.load(model) robot.reset() pipette = instruments._create_pipette_from_config(config=config, mount='right', name=model) pipette.tip_attached = True pipette.aspirate(pipette.max_volume) pos = pose_tracker.absolute(robot.poses, pipette.instrument_actuator) assert pos[0] < pipette.plunger_positions['top']
def _fetch_or_create_pipette(mount, model=None): existing_pipettes = robot.get_instruments() pipette = None for existing_mount, existing_pipette in existing_pipettes: if existing_mount == mount: pipette = existing_pipette if pipette is None: if model is None: pipette = instruments.Pipette(mount=mount) else: config = pipette_config.load(model) pipette = instruments._create_pipette_from_config(config=config, mount=mount) return pipette
def _fetch_or_create_pipette(robot, mount, model=None): existing_pipettes = robot.get_instruments() pipette = None should_remove = True for existing_mount, existing_pipette in existing_pipettes: if existing_mount == mount: pipette = existing_pipette should_remove = False if pipette is None: if model is None: pipette = instruments.Pipette( mount=mount, max_volume=1000, ul_per_mm=1000) else: config = pipette_config.load(model) pipette = instruments._create_pipette_from_config( config=config, mount=mount, name=model) return pipette, should_remove