def setUp(self): self.robot = Robot() self.robot.connect() self.trash = containers_load(self.robot, 'point', 'A1', 'trash') self.tiprack = containers_load(self.robot, 'tiprack-200ul', 'B2', 'p200-rack') self.trough = containers_load(self.robot, 'trough-12row', 'B2', 'trough') self.plate = containers_load(self.robot, '96-flat', 'A2', 'magbead') self.p200 = pipette.Pipette( self.robot, name="p200", trash_container=self.trash, tip_racks=[self.tiprack], min_volume=10, # These are variable axis="b", channels=1) self.p1000 = pipette.Pipette( self.robot, name="p1000", trash_container=self.trash, tip_racks=[self.tiprack], min_volume=100, # These are variable axis="a", channels=1)
def setUp(self): Robot.reset_for_tests() self.robot = Robot.get_instance() self.robot.connect() self.trash = containers.load('point', 'A1', 'trash') self.tiprack = containers.load('tiprack-200ul', 'B2', 'p200-rack') self.trough = containers.load('trough-12row', 'B2', 'trough') self.plate = containers.load('96-flat', 'A2', 'magbead') self.p200 = instruments.Pipette( name="p200", trash_container=self.trash, tip_racks=[self.tiprack], min_volume=10, # These are variable axis="b", channels=1 ) self.p1000 = instruments.Pipette( name="p1000", trash_container=self.trash, tip_racks=[self.tiprack], min_volume=100, # These are variable axis="a", channels=1 )
def setUp(self): Robot.reset_for_tests() self.trash_box = containers.load('trash-box', 'A1') self.wheaton_vial_rack = containers.load('wheaton_vial_rack', 'A2') self.tube_rack_80well = containers.load('tube-rack-80well', 'A3') self.T75_flask = containers.load('T75-flask', 'B1') self.T25_flask = containers.load('T25-flask', 'B2')
def setUp(self): Robot.reset_for_tests() self.robot = Robot.get_instance() self.robot.connect() self.trash = containers.load('point', 'A1', 'trash') self.tiprack = containers.load('tiprack-200ul', 'B2', 'p200-rack') self.trough = containers.load('trough-12row', 'B2', 'trough') self.plate = containers.load('96-flat', 'A2', 'magbead') self.p200 = instruments.Pipette( name="p200", trash_container=self.trash, tip_racks=[self.tiprack], min_volume=10, # These are variable axis="b", channels=1) self.p1000 = instruments.Pipette( name="p1000", trash_container=self.trash, tip_racks=[self.tiprack], min_volume=100, # These are variable axis="a", channels=1)
def exit(): # stop any active threads exit_threads.set() # stop detached run thread Robot.get_instance().stop() # stops attached run thread func = request.environ.get('werkzeug.server.shutdown') if func is None: sys.exit() func() return 'Server shutting down...'
def test_all(self): failures = [] for protocol_path, protocol_dict in self.get_protocols(): Robot.reset_for_tests() try: jpp = JSONProtocolProcessor(protocol_dict) jpp.process() except Exception as e: failures.append((protocol_path, e, jpp.errors)) if failures: print('The following protocols failed to parse') for path, exc, reason in failures: print("[{}]. Reason: {}".format(path, exc)) assert False
class StateTestCase(unittest.TestCase): def setUp(self): self.robot = Robot() self.robot.home() self.trash = containers_load(self.robot, 'point', 'A1') self.tiprack1 = containers_load(self.robot, 'tiprack-10ul', 'B2') self.tiprack2 = containers_load(self.robot, 'tiprack-10ul', 'B3') self.plate = containers_load(self.robot, '96-flat', 'A2') self.p200 = pipette.Pipette( self.robot, trash_container=self.trash, tip_racks=[self.tiprack1, self.tiprack2], max_volume=200, min_volume=10, # These are variable axis="a", channels=1) self.p200.aspirate(100, self.plate[0]).dispense() def test_initial_state(self): s = state.get_state(self.robot) expected = [{ 'axis': 'a', 'blow_out': 12.0101, 'bottom': 10.0101, 'calibrated': False, 'channels': 1, 'drop_tip': 14.0101, 'label': 'Pipette', 'max_volume': 200, 'placeables': [{ 'calibrated': False, 'label': '96-flat', 'slot': 'A2', 'type': '96-flat' }], 'top': 0.0101 }] self.assertEqual(s, expected)
class ProtocolTestCase(unittest.TestCase): def setUp(self): self.robot = Robot() def test_protocol_container_setup(self): plate = containers_load(self.robot, '96-flat', '1', 'myPlate') tiprack = containers_load(self.robot, 'tiprack-10ul', '5') containers_list = self.robot.get_containers() self.assertEqual(len(containers_list), 3) self.assertEqual(self.robot._deck['1']['myPlate'], plate) self.assertEqual(self.robot._deck['5']['tiprack-10ul'], tiprack) self.assertTrue(plate in containers_list) self.assertTrue(tiprack in containers_list) def test_protocol_head(self): trash = containers_load(self.robot, 'point', '1', 'myTrash') tiprack = containers_load(self.robot, 'tiprack-10ul', '5') p200 = pipette.Pipette( self.robot, name='myPipette', trash_container=trash, tip_racks=[tiprack], min_volume=10, # These are variable mount='left', channels=1) instruments_list = self.robot.get_instruments() self.assertEqual(instruments_list[0], ('left', p200)) instruments_list = self.robot.get_instruments('myPipette') self.assertEqual(instruments_list[0], ('left', p200)) def test_deck_setup(self): deck = self.robot.deck pip = pipette.Pipette(self.robot, mount='left') # Check that the fixed trash has loaded on to the pipette trash = pip.trash_container tiprack = containers_load(self.robot, 'tiprack-10ul', '5') self.assertTrue(isinstance(tiprack, Container)) self.assertTrue(isinstance(deck, Deck)) # Check that well location is the same on the robot as the pipette self.assertEqual(self.robot._deck['12']['tall-fixed-trash'][0], trash) self.assertTrue(deck.has_container(tiprack))
class CalibrationTest(unittest.TestCase): def setUp(self): self.robot = Robot() self.robot.connect() self.trash = containers_load(self.robot, 'point', 'A1', 'trash') self.tiprack = containers_load(self.robot, 'tiprack-200ul', 'B2', 'p200-rack') self.trough = containers_load(self.robot, 'trough-12row', 'B2', 'trough') self.plate = containers_load(self.robot, '96-flat', 'A2', 'magbead') self.p200 = pipette.Pipette( self.robot, name="p200", trash_container=self.trash, tip_racks=[self.tiprack], min_volume=10, # These are variable axis="b", channels=1) self.p1000 = pipette.Pipette( self.robot, name="p1000", trash_container=self.trash, tip_racks=[self.tiprack], min_volume=100, # These are variable axis="a", channels=1) def test_load_json(self): json_file_path = os.path.join(os.path.dirname(__file__), 'pipette_calibrations.json') pipette_calibration = json.load(open(json_file_path)) import_calibration_file(json_file_path, self.robot) my_calibrator = self.robot._instruments['B'].calibrator res = my_calibrator.convert(self.robot._deck['A1']['trash'], self.robot._deck['A1']['trash'].center()) expected_coordinates = [] for axis in 'xyz': expected_coordinates.append( pipette_calibration['b']['theContainers']['trash'][axis]) expected_coordinates = tuple(expected_coordinates) self.assertEqual(res, self.robot.flip_coordinates(expected_coordinates))
class MagbeadTest(unittest.TestCase): def setUp(self): self.robot = Robot() options = { 'limit_switches': False } self.robot.connect(options=options) self.robot.home() self.plate = containers_load(self.robot, '96-flat', 'A2') self.magbead = magbead.Magbead( self.robot, mosfet=0, container=self.plate ) self.robot._driver.set_mosfet = mock.Mock() self.robot._driver.wait = mock.Mock() def tearDown(self): del self.robot def test_magbead_engage(self): self.magbead.engage() calls = self.robot._driver.set_mosfet.mock_calls expected = [mock.call(0, True)] self.assertEquals(calls, expected) def test_magbead_disengage(self): self.magbead.engage() self.magbead.disengage() calls = self.robot._driver.set_mosfet.mock_calls expected = [mock.call(0, True), mock.call(0, False)] self.assertEquals(calls, expected) def test_magbead_delay(self): self.magbead.engage() self.magbead.delay(2) self.magbead.disengage() self.magbead.delay(minutes=2) calls = self.robot._driver.set_mosfet.mock_calls expected = [mock.call(0, True), mock.call(0, False)] self.assertEquals(calls, expected) calls = self.robot._driver.wait.mock_calls expected = [mock.call(2), mock.call(120)] self.assertEquals(calls, expected)
def setUp(self): self.robot = Robot() options = { 'limit_switches': False } self.robot.connect(options=options) self.robot.home() self.plate = containers_load(self.robot, '96-flat', 'A2') self.magbead = magbead.Magbead( self.robot, mosfet=0, container=self.plate ) self.robot._driver.set_mosfet = mock.Mock() self.robot._driver.wait = mock.Mock()
def setUp(self): self.robot = Robot.reset_for_tests() myport = self.robot.VIRTUAL_SMOOTHIE_PORT self.robot.connect(port=myport) self.robot.home() self.trash = containers.load('point', 'A1') self.tiprack1 = containers.load('tiprack-10ul', 'B2') self.tiprack2 = containers.load('tiprack-10ul', 'B3') self.plate = containers.load('96-flat', 'A2') self.p200 = instruments.Pipette( trash_container=self.trash, tip_racks=[self.tiprack1, self.tiprack2], max_volume=200, min_volume=10, # These are variable axis="b", channels=1 ) self.p200.reset() self.p200.calibrate_plunger(top=0, bottom=10, blow_out=12, drop_tip=13) self.robot.home(enqueue=False) _, _, starting_z = self.robot._driver.get_head_position()['current']
def _detached_progress(): robot = Robot.get_instance() while not exit_threads.is_set(): res = robot._driver.smoothie_player.progress(timeout=20) if not res.get('file'): return percentage = '{}%'.format(round(res.get('percentage', 0) * 100, 2)) def _seconds_to_string(sec): hours = int(sec / (60 * 60)) hours = str(hours) if hours > 9 else '0{}'.format(hours) minutes = int(sec / 60) % 60 minutes = str(minutes) if minutes > 9 else '0{}'.format(minutes) seconds = sec % 60 seconds = str(seconds) if seconds > 9 else '0{}'.format(seconds) return (hours, minutes, seconds) h, m, s = _seconds_to_string(res.get('elapsed_time')) progress_data = 'Protocol {} Complete - Elapsed Time {}:{}:{}'.format( percentage, h, m, s) if res.get('estimated_time'): h, m, s = _seconds_to_string(res.get('estimated_time')) progress_data += ' - Estimated Time Left {}:{}:{}'.format(h, m, s) d = { 'caller': 'ui', 'mode': 'live', 'name': 'command-run', 'command_description': progress_data } notify(d)
def test_containers_create(self): import os import json from opentrons import Robot container_name = 'plate_for_testing_containers_create' containers.create(name=container_name, grid=(8, 12), spacing=(9, 9), diameter=4, depth=8, volume=1000) p = containers.load(container_name, 'A1') self.assertEquals(len(p), 96) self.assertEquals(len(p.rows), 12) self.assertEquals(len(p.cols), 8) self.assertEquals(p.get_parent(), Robot.get_instance().deck['A1']) self.assertEquals(p['C3'], p[18]) self.assertEquals(p['C3'].max_volume(), 1000) for i, w in enumerate(p): self.assertEquals(w, p[i]) # remove the file if we only created it for this test should_delete = False with open(environment.get_path('CONTAINERS_FILE')) as f: created_containers = json.load(f) del created_containers['containers'][p.get_name()] if not len(created_containers['containers'].keys()): should_delete = True if should_delete: os.remove(environment.get_path('CONTAINERS_FILE'))
def _get_all_pipettes(): robot = Robot.get_instance() pipette_list = [] for _, p in robot.get_instruments(): if isinstance(p, instruments.Pipette): pipette_list.append(p) return sorted(pipette_list, key=lambda p: p.name.lower())
def _run_detached(): try: robot = Robot.get_instance() p = player.SmoothiePlayer_2_0_0() d = {'caller': 'ui', 'mode': 'live', 'name': 'command-run'} d.update({'command_description': 'Simulating, please wait...'}) notify(d) robot.smoothie_drivers['simulate'].record_start(p) robot.simulate() robot.smoothie_drivers['simulate'].record_stop() d.update( {'command_description': 'Saving file to robot, please wait...'}) notify(d) robot._driver.play(p) d.update({ 'command_description': 'Protocol running, unplug USB at any time.' }) notify(d) d.update( {'command_description': 'To stop, unplug USB and power robot OFF'}) notify(d) _detached_progress() except Exception as e: emit_notifications([str(e)], 'danger') socketio.emit('event', {'name': 'run-finished'})
def test_all(self): failures = [] for protocol_path, protocol_dict in self.get_protocols(): Robot.reset_for_tests() try: jpp = JSONProtocolProcessor(protocol_dict) jpp.process() except Exception as e: failures.append( (protocol_path, e, jpp.errors) ) if failures: print('The following protocols failed to parse') for path, exc, reason in failures: print("[{}]. Reason: {}".format(path, exc)) assert False
def _run_commands(should_home_first=True): robot = Robot.get_instance() start_time = time.time() api_response = {'errors': [], 'warnings': []} try: robot.resume() robot.run(caller='ui') if len(robot._commands) == 0: error = \ "This protocol does not contain any commands for the robot." api_response['errors'] = [error] except Exception as e: api_response['errors'] = [str(e)] api_response['warnings'] = robot.get_warnings() or [] api_response['name'] = 'run exited' end_time = time.time() emit_notifications(api_response['warnings'], 'warning') emit_notifications(api_response['errors'], 'danger') seconds = end_time - start_time minutes, seconds = divmod(seconds, 60) hours, minutes = divmod(minutes, 60) run_time = "%d:%02d:%02d" % (hours, minutes, seconds) result = "Run complete in {}".format(run_time) emit_notifications([result], 'success') socketio.emit('event', {'name': 'run-finished'})
def update_step_list(): global current_protocol_step_list robot = Robot.get_instance() if current_protocol_step_list is None: create_step_list() try: for step in current_protocol_step_list: t_axis = str(step['axis']).upper() instrument = robot._instruments[t_axis] step.update({ 'top': instrument.positions['top'], 'bottom': instrument.positions['bottom'], 'blow_out': instrument.positions['blow_out'], 'drop_tip': instrument.positions['drop_tip'], 'max_volume': instrument.max_volume, 'calibrated': _check_if_instrument_calibrated(instrument) }) for placeable_step in step['placeables']: c = _get_container_from_step(placeable_step) if c: placeable_step.update( {'calibrated': _check_if_calibrated(instrument, c)}) except Exception as e: emit_notifications([str(e)], 'danger') return current_protocol_step_list
def setUp(self): self.robot = Robot.reset_for_tests() myport = self.robot.VIRTUAL_SMOOTHIE_PORT self.robot.connect(port=myport) self.robot.home() self.trash = containers.load('point', 'A1') self.tiprack1 = containers.load('tiprack-10ul', 'B2') self.tiprack2 = containers.load('tiprack-10ul', 'B3') self.plate = containers.load('96-flat', 'A2') self.p200 = instruments.Pipette( trash_container=self.trash, tip_racks=[self.tiprack1, self.tiprack2], max_volume=200, min_volume=10, # These are variable axis="b", channels=1) self.p200.reset() self.p200.calibrate_plunger(top=0, bottom=10, blow_out=12, drop_tip=13) self.robot.home(enqueue=False) _, _, starting_z = self.robot._driver.get_head_position()['current']
def setUp(self): self.robot = Robot() self.robot.connect() self.plate = containers_load(self.robot, '96-flat', 'A1', 'plate') self.p200 = pipette.Pipette(self.robot, name="p200", axis="b") self.p200.delete_calibration_data() well = self.plate[0] pos = well.from_center(x=0, y=0, z=0, reference=self.plate) self.location = (self.plate, pos) well_deck_coordinates = well.center(well.get_deck()) dest = well_deck_coordinates + Vector(1, 2, 3) self.robot.move_head(x=dest['x'], y=dest['y'], z=dest['z']) self.p200.calibrate_position(self.location)
class ProtocolTestCase(unittest.TestCase): def setUp(self): self.robot = Robot() def test_protocol_container_setup(self): plate = containers_load(self.robot, '96-flat', 'A1', 'myPlate') tiprack = containers_load(self.robot, 'tiprack-10ul', 'B2') containers_list = self.robot.containers().values() self.assertEqual(len(containers_list), 2) self.assertEqual(self.robot._deck['A1']['myPlate'], plate) self.assertEqual(self.robot._deck['B2']['tiprack-10ul'], tiprack) self.assertTrue(plate in containers_list) self.assertTrue(tiprack in containers_list) def test_protocol_head(self): trash = containers_load(self.robot, 'point', 'A1', 'myTrash') tiprack = containers_load(self.robot, 'tiprack-10ul', 'B2') p200 = pipette.Pipette( self.robot, name='myPipette', trash_container=trash, tip_racks=[tiprack], min_volume=10, # These are variable axis="b", channels=1) instruments_list = self.robot.get_instruments() self.assertEqual(instruments_list[0], ('B', p200)) instruments_list = self.robot.get_instruments('myPipette') self.assertEqual(instruments_list[0], ('B', p200)) def test_deck_setup(self): deck = self.robot.deck trash = containers_load(self.robot, 'point', 'A1', 'myTrash') tiprack = containers_load(self.robot, 'tiprack-10ul', 'B2') self.assertTrue(isinstance(tiprack, Container)) self.assertTrue(isinstance(deck, Deck)) self.assertTrue(deck.has_container(trash)) self.assertTrue(deck.has_container(tiprack))
def setUp(self): Robot.reset_for_tests() self.robot = Robot.get_instance() self.robot.connect() self.plate = containers.load('96-flat', 'A1', 'plate') self.p200 = instruments.Pipette(name="p200", axis="b") self.p200.delete_calibration_data() well = self.plate[0] pos = well.from_center(x=0, y=0, z=0, reference=self.plate) self.location = (self.plate, pos) well_deck_coordinates = well.center(well.get_deck()) dest = well_deck_coordinates + Vector(1, 2, 3) self.robot.move_head(x=dest['x'], y=dest['y'], z=dest['z']) self.p200.calibrate_position(self.location)
def get_unallocated_slot(self): """ :return: str name of a slot without any children (first occurence) """ robot = Robot.get_instance() for slot in robot._deck.get_children_list(): if not slot.has_children(): return slot.get_name() raise JSONProcessorRuntimeError( 'Unable to find any unallocated slots in robot deck')
def setUp(self): self.robot = Robot() self.robot.home() self.trash = containers_load(self.robot, 'point', 'A1') self.tiprack1 = containers_load(self.robot, 'tiprack-10ul', 'B2') self.tiprack2 = containers_load(self.robot, 'tiprack-10ul', 'B3') self.plate = containers_load(self.robot, '96-flat', 'A2') self.p200 = pipette.Pipette( self.robot, trash_container=self.trash, tip_racks=[self.tiprack1, self.tiprack2], max_volume=200, min_volume=10, # These are variable axis="a", channels=1) self.p200.aspirate(100, self.plate[0]).dispense()
def setUp(self): self.robot = Robot() self.trash_box = containers_load(self.robot, 'trash-box', 'A1') self.wheaton_vial_rack = containers_load( self.robot, 'wheaton_vial_rack', 'A2' ) self.tube_rack_80well = containers_load( self.robot, 'tube-rack-80well', 'A3' ) self.T75_flask = containers_load(self.robot, 'T75-flask', 'B1') self.T25_flask = containers_load(self.robot, 'T25-flask', 'B2')
def drop_tip(): robot = Robot.get_instance() try: axis = request.json.get("axis") instrument = robot._instruments[axis.upper()] instrument.return_tip(enqueue=False) except Exception as e: emit_notifications([str(e)], 'danger') return flask.jsonify({'status': 'error', 'data': str(e)}) return flask.jsonify({'status': 'success', 'data': ''})
def setUp(self): self.robot = Robot() # set this to True if testing with a robot connected # testing while connected allows the response handlers # and serial handshakes to be tested options = { 'firmware': 'edge-1c222d9NOMSD', 'limit_switches': True, 'config': { 'alpha_steps_per_mm': 80.0, 'beta_steps_per_mm': 80.0 } } self.robot.disconnect() self.robot.connect(options=options) self.motor = self.robot._driver
def get_unallocated_slot(self): """ :return: str name of a slot without any children (first occurence) """ robot = Robot.get_instance() for slot in robot._deck.get_children_list(): if not slot.has_children(): return slot.get_name() raise JSONProcessorRuntimeError( 'Unable to find any unallocated slots in robot deck' )
def _get_all_containers(): """ Returns all containers currently on the deck """ all_containers = list() robot = Robot.get_instance() for slot in robot._deck: if slot.has_children(): all_containers += slot.get_children_list() return _sort_containers(all_containers)
def setUp(self): self.robot = Robot.reset_for_tests() options = {'limit_switches': False} self.robot.connect(options=options) self.robot.home() self.plate = containers.load('96-flat', 'A2') self.magbead = instruments.Magbead(mosfet=0, container=self.plate) self.robot._driver.set_mosfet = mock.Mock() self.robot._driver.wait = mock.Mock()
def setUp(self): self.robot = Robot.reset_for_tests() options = { 'limit_switches': False } self.robot.connect(options=options) self.robot.home() self.plate = containers.load('96-flat', 'A2') self.magbead = instruments.Magbead(mosfet=0, container=self.plate) self.robot._driver.set_mosfet = mock.Mock() self.robot._driver.wait = mock.Mock()
def setup_robot(): robot = Robot() for port in list_of_ports: trycon(robot, port) if (robot.is_simulating()): print("no connection made") else: robot.home() robot._driver.speeds['z'] = 1200 for (axis, pipette) in robot.get_instruments(): pipette.load_persisted_data() try: yield robot finally: robot.disconnect()
def disconnectRobot(): status = 'success' data = None robot = Robot.get_instance() try: robot.disconnect() emit_notifications(["Successfully disconnected"], 'info') except Exception as e: status = 'error' data = str(e) emit_notifications([data], 'danger') return flask.jsonify({'status': status, 'data': data})
def test_remove_child(self): robot = Robot.get_instance() robot.reset() slot = 'B1' plate = containers.load('96-flat', slot, 'plate') self.assertEquals(len(robot.containers()), 1) plate.get_parent().remove_child(plate.get_name()) self.assertEquals(len(robot.containers()), 0) plate = containers.load('96-flat', slot, 'plate') self.assertEquals(len(robot.containers()), 1) robot.deck[slot].remove_child(plate.get_name()) self.assertEquals(len(robot.containers()), 0)
def setUp(self): self.robot = Robot.get_instance() # set this to True if testing with a robot connected # testing while connected allows the response handlers # and serial handshakes to be tested self.motor = self.robot._driver options = {"limit_switches": True, "config": {"alpha_steps_per_mm": 80.0, "beat_steps_per_mm": 80.0}} myport = self.robot.VIRTUAL_SMOOTHIE_PORT self.robot.disconnect() success = self.robot.connect(port=myport, options=options) self.assertTrue(success)
def create_command(self, do, setup=None, description=None, enqueue=True): """ Creates an instance of Command to be appended to the :any:`Robot` run queue. Parameters ---------- do : callable The method to execute on the robot. This usually includes moving an instrument's motors, or the robot head setup : callable The method to execute just before `do()`, which includes updating the instrument's state description : str Human-readable description of the action taking place enqueue : bool If set to `True` (default), the method will be appended to the robots list of commands for executing during :any:`run` or :any:`simulate`. If set to `False`, the method will skip the command queue and execute immediately Examples -------- .. >>> instrument = Instrument() >>> def setup(): >>> print('hello') >>> def do(): >>> print(' world') >>> description = 'printing "hello world"' >>> instrument.create_command(do, setup, description) hello >>> robot.simulate() hello world >>> instrument.create_command(do, setup, description, enqueue=False) hello world """ command = Command(do=do, setup=setup, description=description) if enqueue: Robot().add_command(command) else: command()
def load(container_name, slot, label=None): """ Examples -------- >>> from opentrons import containers >>> containers.load('96-flat', 'A1') <Deck>/<Slot A1>/<Container 96-flat> >>> containers.load('96-flat', 'A2', 'plate') <Deck>/<Slot A2>/<Container plate> >>> containers.load('non-existent-type', 'A2') # doctest: +ELLIPSIS Exception: Container type "non-existent-type" not found in file ... """ from opentrons import Robot if not label: label = container_name protocol = Robot.get_instance() return protocol.add_container(container_name, slot, label)
def setUp(self): Robot.reset_for_tests() self.robot = Robot.get_instance() self.robot.connect() self.protocol = None
class RobotSerializationTestCase(unittest.TestCase): def setUp(self): Robot.reset_for_tests() self.robot = Robot() def test_serializing_and_deserializing_unconfigured_robot(self): robot_as_bytes = dill.dumps(self.robot) self.assertIsInstance(robot_as_bytes, bytes) dill.loads(robot_as_bytes) def test_serializing_configured_robot(self): plate = containers.load('96-flat', 'A1') p200 = instruments.Pipette(axis='b', max_volume=200) for well in plate: p200.aspirate(well).delay(5).dispense(well) original_robot_cmd_cnts = len(self.robot._commands) robot_as_bytes = dill.dumps(self.robot) self.assertIsInstance(robot_as_bytes, bytes) deserialized_robot = dill.loads(robot_as_bytes) deserialized_robot_cmd_cnts = len(deserialized_robot._commands) self.assertEqual(deserialized_robot_cmd_cnts, original_robot_cmd_cnts) original_robot_instruments = self.robot.get_instruments() deserialized_robot_instruments = self.robot.get_instruments() self.assertEqual( len(original_robot_instruments), len(deserialized_robot_instruments), ) self.assertEqual( original_robot_instruments[0][0], deserialized_robot_instruments[0][0], ) def test_serializing_configured_robot_with_2_instruments(self): plate = containers.load('96-flat', 'A1') trash = containers.load('point', 'A2') tiprack = containers.load('tiprack-200ul', 'A3') p200 = instruments.Pipette( axis='b', tip_racks=[tiprack], trash_container=trash, max_volume=200 ) p100 = instruments.Pipette( axis='a', channels=8, tip_racks=[tiprack], trash_container=trash, max_volume=100 ) self.make_commands(p200, plate, p100, plate) original_robot_cmds_txt = self.robot.commands() original_robot_cmd_cnts = len(self.robot._commands) robot_as_bytes = dill.dumps(self.robot) self.assertIsInstance(robot_as_bytes, bytes) deserialized_robot = dill.loads(robot_as_bytes) deserialized_robot_cmd_cnts = len(deserialized_robot._commands) # Check commands are unmarshalled self.assertEqual(deserialized_robot_cmd_cnts, original_robot_cmd_cnts) # Check instruments are unmarshalled original_robot_instruments = self.robot.get_instruments() deserialized_robot_instruments = self.robot.get_instruments() self.assertEqual( len(original_robot_instruments), len(deserialized_robot_instruments), ) self.assertEqual( original_robot_instruments[0][0], deserialized_robot_instruments[0][0], ) # Set deserialized robot as the global robot and attempt to # reconstruct the same commands again Singleton._instances[Robot] = deserialized_robot deserialized_robot._commands = [] r2_p200 = deserialized_robot_instruments[0][1] r2_p100 = deserialized_robot_instruments[1][1] self.make_commands(r2_p200, plate, r2_p100, plate) self.assertEqual( original_robot_cmd_cnts, len(deserialized_robot._commands) ) self.assertListEqual( original_robot_cmds_txt, deserialized_robot.commands() ) def make_commands(self, inst1, inst1_plate, inst2, inst2_plate): for well in inst1_plate: inst1.aspirate(well).delay(5).dispense(well) for row in inst2_plate.rows[::-1]: inst2.aspirate(row).delay(5).dispense(row)
def setUp(self): Robot.reset_for_tests() self.plate = containers.load("96-flat", "A2")
import os from opentrons import containers from opentrons.labware import instruments from opentrons import Robot from opentrons.drivers.motor import CNCDriver from helpers.calibration import import_json_calibration robot = Robot.get_instance() robot._driver = CNCDriver() plate = containers.load("96-flat", "A2", "magbead") trash = containers.load("point", "A1", "trash") tiprack = containers.load("tiprack-200ul", "B2", "p200-rack") # tipracks need a Well height equal to the tip length for tip in tiprack: tip.properties["height"] = 80 p200 = instruments.Pipette( name="p200", trash_container=trash, tip_racks=[tiprack], max_volume=200, min_volume=0.1, # These are variable axis="b", channels=1, )
def protocol(self): robot = Robot.get_instance() robot.get_serial_ports_list() robot.connect() robot.home() tiprack = containers.load( 'tiprack-200ul', # container type 'A1', # slot 'tiprack' # user-defined name ) plate = containers.load( '96-flat', 'B1', 'plate' ) trash = containers.load( 'point', 'C2', 'trash' ) trough = containers.load( 'trough-12row', 'B2', 'trough' ) p200 = instruments.Pipette( name="p200", trash_container=trash, tip_racks=[tiprack], max_volume=200, min_volume=0.5, axis="b", channels=1 ) calibration_data = """ { "b": { "blowout": 28.0, "bottom": 26.0, "droptip": 32.0, "resting": 0, "theContainers": { "plate": { "rel_x": 181.696, "rel_y": 0.700999999999965, "rel_z": 9.600999999999999, "x": 202.195, "y": 370.304, "z": 125.7 }, "tiprack": { "rel_x": 0.0, "rel_y": 0.0, "rel_z": 0.0, "x": 20.499, "y": 369.603, "z": 116.099 }, "trough": { "rel_x": 0.0, "rel_y": 0.0, "rel_z": 0.0, "x": 20.499, "y": 269.603, "z": 116.099 }, "trash": { "rel_x": 212.701, "rel_y": -200.801, "rel_z": -58.399, "x": 233.2, "y": 171.305, "z": 57.7 } }, "tip_rack_origin": "tiprack", "tip_racks": [ { "container": "tiprack" } ], "top": 13.0, "trash_container": { "container": "trash" }, "volume": 200 } } """ import_calibration_json(calibration_data, robot, True) robot.clear_commands() # distribute p200.pick_up_tip(tiprack[0]) p200.aspirate(96 * 2, trough[0]) for i in range(96): p200.dispense(2, plate[i]).touch_tip() p200.drop_tip(tiprack[0]) p200.pick_up_tip(tiprack[1]) for i in range(96): p200.aspirate(2, plate[95 - i]) p200.dispense(trough[0]) p200.drop_tip(tiprack[1])
def setUp(self): Robot.reset_for_tests() self.robot = Robot.get_instance()
def setUp(self): Robot.reset_for_tests() self.robot = Robot()