예제 #1
0
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))
예제 #2
0
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)
예제 #3
0
class OpenTronsTest(unittest.TestCase):
    def setUp(self):
        global reset_time
        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': 'v1.0.5',
            '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 test_is_simulating(self):
        self.assertTrue(self.motor.is_simulating())

    def test_reset(self):
        self.motor.reset()
        self.assertFalse(self.motor.is_connected())

    def test_write_with_lost_connection(self):
        self.motor.connection.serial_port.close()

        def _temp():
            return True

        old_method = getattr(self.motor, 'is_connected')
        setattr(self.motor, 'is_connected', _temp)

        self.assertTrue(self.motor.is_connected())
        self.assertRaises(RuntimeError, self.motor.calm_down)

        setattr(self.motor, 'is_connected', old_method)

    def test_version_compatible(self):
        self.motor.versions_compatible()

        kwargs = {
            'options': {
                'firmware': 'v2.0.0',
                'config': {
                    'version': 'v3.1.2',
                    'ot_version': 'hoodie'
                }
            }
        }
        self.assertRaises(RuntimeError, self.robot.connect, **kwargs)

    def test_invalid_coordinate_system(self):
        self.assertRaises(ValueError, self.motor.set_coordinate_system, 'andy')

    def test_message_timeout(self):
        self.robot._driver.connection.flush_input()
        self.assertRaises(RuntimeWarning, self.motor.readline_from_serial, 0.1)

    def test_set_plunger_speed(self):
        self.motor.set_plunger_speed(400, 'a')
        self.assertRaises(ValueError, self.motor.set_plunger_speed, 400, 'x')

    def test_set_speed(self):
        self.motor.set_speed(4000)
        self.assertEquals(self.motor.speeds['x'], 4000)
        self.assertEquals(self.motor.speeds['y'], 4000)

        self.motor.set_speed(3000, z=2000, a=700, b=600)
        self.assertEquals(self.motor.speeds['x'], 3000)
        self.assertEquals(self.motor.speeds['y'], 3000)
        self.assertEquals(self.motor.speeds['z'], 2000)
        self.assertEquals(self.motor.speeds['a'], 700)
        self.assertEquals(self.motor.speeds['b'], 600)

    def test_get_connected_port(self):
        res = self.motor.get_connected_port()
        self.assertEquals(res, drivers.VIRTUAL_SMOOTHIE_PORT)
        self.motor.disconnect()
        res = self.motor.get_connected_port()
        self.assertEquals(res, 'Virtual Smoothie')
        self.assertFalse(self.motor.is_connected())

    def test_get_dimensions(self):
        self.motor.ot_version = None
        res = self.motor.get_dimensions()
        self.assertEquals(res, Vector(400.00, 400.00, 100.00))

    def test_pause_resume(self):
        self.motor.home()

        self.motor.pause()

        def _move_head():
            self.motor.move_head(x=100, y=0, z=0)

        thread = Thread(target=_move_head)
        thread.start()

        self.motor.resume()
        thread.join()

        coords = self.motor.get_head_position()
        expected_coords = {'target': (100, 0, 0), 'current': (100, 0, 0)}
        self.assertDictEqual(coords, expected_coords)

    def test_stop(self):
        self.motor.home()

        self.motor.pause()

        def _move_head():
            self.assertRaises(RuntimeWarning, self.motor.move_head, **{
                'x': 100,
                'y': 0,
                'z': 0
            })

        thread = Thread(target=_move_head)
        thread.start()

        self.motor.stop()

        thread.join()

        coords = self.motor.get_head_position()
        expected_coords = {'target': (0, 400, 100), 'current': (0, 400, 100)}
        self.assertDictEqual(coords, expected_coords)

        self.motor.move_head(x=100, y=0, z=0)
        coords = self.motor.get_head_position()
        expected_coords = {'target': (100, 0, 0), 'current': (100, 0, 0)}
        self.assertDictEqual(coords, expected_coords)

    def test_halt(self):
        self.motor.home()

        self.motor.pause()

        def _move_head():
            self.assertRaises(RuntimeWarning, self.motor.move_head, **{
                'x': 100,
                'y': 0,
                'z': 0
            })

        thread = Thread(target=_move_head)
        thread.start()

        self.motor.halt()

        thread.join()

        coords = self.motor.get_head_position()
        expected_coords = {'target': (0, 400, 100), 'current': (0, 400, 100)}
        self.assertDictEqual(coords, expected_coords)

        self.motor.move_head(x=100, y=0, z=0)
        coords = self.motor.get_head_position()
        expected_coords = {'target': (100, 0, 0), 'current': (100, 0, 0)}
        self.assertDictEqual(coords, expected_coords)

    def test_get_position(self):
        self.motor.home()
        self.motor.ot_version = None
        self.motor.move_head(x=100)
        coords = self.motor.get_head_position()
        expected_coords = {
            'target': (100, 400, 100),
            'current': (100, 400, 100)
        }
        self.assertDictEqual(coords, expected_coords)

    def test_home(self):

        self.motor.home('x', 'y')
        pos = self.motor.get_head_position()['current']
        self.assertEquals(pos['x'], 0)

        self.motor.home('ba')
        pos = self.motor.get_plunger_positions()['current']
        self.assertEquals(pos['a'], 0)
        self.assertEquals(pos['b'], 0)

    def test_limit_hit_exception(self):
        self.motor.home()
        try:
            self.motor.move_head(x=-100)
            self.motor.wait_for_arrival()
        except RuntimeWarning as e:
            self.assertEqual(
                str(RuntimeWarning('Robot Error: limit switch hit')), str(e))

        self.motor.home()

    def test_move(self):
        self.motor.ot_version = None
        for axis in 'xyz':
            self.motor.move(**{axis: 30})
            pos = self.motor.get_head_position()['current']
            self.assertEquals(pos[axis], 30)

        for axis in 'ab':
            self.motor.move(**{axis: 30})
            pos = self.motor.get_plunger_positions()['current']
            self.assertEquals(pos[axis], 30)

    def test_send_command(self):
        res = self.motor.send_command('G0 X1 Y1 Z1')
        self.assertEquals(res, 'ok')
        if self.motor.firmware_version != 'v1.0.5':
            self.assertEquals(self.motor.readline_from_serial(), 'ok')
        pos = self.motor.get_head_position()['current']
        self.assertEquals(pos['x'], 1)
        self.assertEquals(pos['y'], 399)
        self.assertEquals(pos['z'], 99)

    def test_send_command_with_kwargs(self):
        res = self.motor.send_command('G0', X=1, Y=2, Z=3)
        self.assertEquals(res, 'ok')
        if self.motor.firmware_version != 'v1.0.5':
            self.assertEquals(self.motor.readline_from_serial(), 'ok')
        pos = self.motor.get_head_position()['current']
        self.assertEquals(pos['x'], 1)
        self.assertEquals(pos['y'], 398)
        self.assertEquals(pos['z'], 97)

    def test_wait(self):
        # do not use Virtual Smoothie for this test
        old_method = getattr(self.motor.connection, 'device')

        def _temp():
            return int()

        setattr(self.motor.connection, 'device', _temp)

        start_time = time.time()
        self.motor.wait(1.234)
        end_time = time.time()
        self.assertAlmostEquals(end_time - start_time, 1.234, places=1)

        start_time = time.time()
        self.motor.wait(1.0)
        end_time = time.time()
        self.assertAlmostEquals(end_time - start_time, 1.0, places=1)

        setattr(self.motor.connection, 'device', old_method)

    def test_wait_for_arrival(self):
        self.motor.home()
        self.motor.move_head(x=200, y=200)
        self.motor.move_head(z=30)
        self.motor.wait_for_arrival()

        old_coords = dict(self.motor.connection.serial_port.coordinates)
        vs = self.motor.connection.serial_port
        for ax in vs.coordinates['target'].keys():
            vs.coordinates['target'][ax] += 10
        self.assertRaises(RuntimeError, self.motor.wait_for_arrival)
        vs.coordinates = old_coords

    def test_move_relative(self):
        self.motor.home()
        self.motor.move_head(x=100, y=100, z=100)
        self.motor.move_head(x=0, mode='relative')
        self.motor.move_head(x=100, mode='absolute')

    def test_calibrate_steps_per_mm(self):
        self.motor.home()
        self.motor.set_steps_per_mm('x', 80.0)
        self.motor.set_steps_per_mm('y', 80.0)
        self.motor.set_steps_per_mm('z', 400)
        self.motor.move_head(x=200, y=200)

        self.motor.calibrate_steps_per_mm('x', 200, 198)
        self.motor.calibrate_steps_per_mm('y', 200, 202)
        self.motor.calibrate_steps_per_mm('z', 100, 101)

        new_x_steps = self.motor.get_steps_per_mm('x')
        new_y_steps = self.motor.get_steps_per_mm('y')
        new_z_steps = self.motor.get_steps_per_mm('z')

        exptected_x = round((200 / 198) * 80.0, 2)
        exptected_y = round((200 / 202) * 80.0, 2)
        exptected_z = round((100 / 101) * 400, 2)

        self.assertEqual(exptected_x, new_x_steps)
        self.assertEqual(exptected_y, new_y_steps)
        self.assertEqual(exptected_z, new_z_steps)

        self.assertRaises(ValueError, self.motor.get_steps_per_mm, 'd')
        self.assertRaises(ValueError, self.motor.set_steps_per_mm, 'd', 80.0)

        self.motor.set_steps_per_mm('x', 80.0)
        self.motor.set_steps_per_mm('y', 80.0)
        self.motor.set_steps_per_mm('z', 400)

    def test_get_endstop_switches(self):
        res = self.motor.get_endstop_switches()
        expected = {'x': False, 'y': False, 'z': False, 'a': False, 'b': False}
        self.assertEquals(res, expected)
        try:
            self.motor.move_head(x=-100)
            self.motor.move_head(x=-101)
        except Exception:
            pass
        res = self.motor.get_endstop_switches()
        expected = {'x': True, 'y': False, 'z': False, 'a': False, 'b': False}
        self.assertEquals(res, expected)

    def test_set_mosfet(self):
        res = self.motor.set_mosfet(0, True)
        self.assertTrue(res)

        res = self.motor.set_mosfet(5, False)
        self.assertTrue(res)

        self.assertRaises(IndexError, self.motor.set_mosfet, 6, True)

    def test_power_on_off(self):
        self.motor.power_on()

        self.motor.power_off()

        assert True
class CrudCalibrationsTestCase(unittest.TestCase):
    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)

    def test_save_load_calibration_data(self):

        self.p200 = pipette.Pipette(self.robot, name="p200-diff", axis="b")
        self.assertDictEqual(self.p200.calibration_data, {})

        self.p200 = pipette.Pipette(self.robot, name="p200", axis="a")
        self.p200.delete_calibration_data()
        self.assertDictEqual(self.p200.calibration_data, {})

        self.p200 = pipette.Pipette(self.robot, name="p200", axis="b")

        expected_delta = {'delta': (1.0, 2.0, 3.0), 'type': '96-flat'}

        self.assertTrue('A1' in self.p200.calibration_data)
        actual = self.p200.calibration_data['A1']['children']
        self.assertTrue('plate' in actual)
        actual = self.p200.calibration_data['A1']['children']['plate']
        self.assertEquals(expected_delta, actual)

    def test_delete_calibrations_data(self):

        self.p200 = pipette.Pipette(self.robot, name="p200", axis="b")

        expected_delta = {'delta': (1.0, 2.0, 3.0), 'type': '96-flat'}

        self.assertTrue('A1' in self.p200.calibration_data)
        actual = self.p200.calibration_data['A1']['children']
        self.assertTrue('plate' in actual)
        actual = self.p200.calibration_data['A1']['children']['plate']
        self.assertEquals(expected_delta, actual)

        self.p200.delete_calibration_data()
        self.assertDictEqual(self.p200.calibration_data, {})

        self.p200 = pipette.Pipette(self.robot, name="p200", axis="b")
        self.assertDictEqual(self.p200.calibration_data, {})
        self.assertDictEqual(
            self.p200.positions, {
                'top': 0.0101,
                'bottom': 10.0101,
                'blow_out': 12.0101,
                'drop_tip': 14.0101
            })

    def test_delete_old_calibration_file(self):
        def test_file(file_name):
            calib_dir = environment.get_path('CALIBRATIONS_DIR')
            shutil.copyfile(os.path.join(os.path.dirname(__file__), file_name),
                            os.path.join(calib_dir, 'calibrations.json'))

            instrument.Instrument()._read_calibrations()

            file = os.path.join(calib_dir, 'calibrations.json')
            with open(file) as f:
                calib_object = json.load(f)
                self.assertEquals(calib_object['version'], 1)

        test_file('data/calibrations.json')
        test_file('data/invalid_json.json')