def delay(self, seconds): def _do(): self.plunger.wait(seconds) description = "Delaying {} seconds".format(seconds) self.robot.add_command(Command(do=_do, description=description)) return self
def aspirate(self, volume=None, location=None, rate=1.0): def _do_aspirate(): nonlocal volume nonlocal location if not isinstance(volume, (int, float, complex)): if volume and not location: location = volume volume = self.max_volume - self.current_volume if self.current_volume + volume > self.max_volume: raise RuntimeWarning( 'Pipette cannot hold volume {}' .format(self.current_volume + volume) ) self.position_for_aspirate(location) self.current_volume += volume distance, _ = self.plunge_distance(self.current_volume) destination = self.positions['bottom'] - distance speed = self.speeds['aspirate'] * rate self.plunger.speed(speed) self.plunger.move(destination) description = "Aspirating {0}uL at {1}".format( volume, (humanize_location(location) if location else '<In Place>') ) self.robot.add_command( Command(do=_do_aspirate, description=description)) return self
def dispense(self, volume=None, location=None, rate=1.0): def _do(): nonlocal location nonlocal volume if not isinstance(volume, (int, float, complex)): if volume and not location: location = volume volume = self.current_volume if self.current_volume - volume < 0: volume = self.current_volume if location: self.move_to(location, now=True) if volume: self.current_volume -= volume distance, _ = self.plunge_distance(self.current_volume) destination = self.positions['bottom'] - distance speed = self.speeds['dispense'] * rate self.plunger.speed(speed) self.plunger.move(destination) description = "Dispensing {0}uL at {1}".format( volume, (humanize_location(location) if location else '<In Place>') ) self.robot.add_command(Command(do=_do, description=description)) return self
def move_to(self, location, instrument=None, create_path=True, now=False): placeable, coordinates = containers.unpack_location(location) if instrument: coordinates = instrument.calibrator.convert( placeable, coordinates) else: coordinates += placeable.coordinates(placeable.get_deck()) tallest_z = self._deck.max_dimensions(self._deck)[2][1][2] tallest_z += 10 def _do(): if create_path: self._driver.move_head(z=tallest_z) self._driver.move_head(x=coordinates[0], y=coordinates[1]) self._driver.move_head(z=coordinates[2]) else: self._driver.move_head( x=coordinates[0], y=coordinates[1], z=coordinates[2] ) if now: _do() else: self.add_command(Command(do=_do))
def delay(self, seconds): def _do(): self.mosfet.wait(seconds) description = "Delaying Magbead for {} seconds".format(seconds) self.robot.add_command(Command(do=_do, description=description)) return self
def disengage(self): def _do(): self.mosfet.disengage() description = "Engaging Magbead at mosfet #{}".format(self.mosfet) self.robot.add_command(Command(do=_do, description=description)) return self
def test_command(self): expected = None def _do(): nonlocal expected expected = 'test' description = 'test' command = Command(do=_do, description=description) command() self.assertEquals(expected, command.description)
def blow_out(self, location=None): def _do(): nonlocal location if location: self.move_to(location, now=True) self.plunger.move(self.positions['blow_out']) self.current_volume = 0 description = "Blow_out at {}".format( humanize_location(location) if location else '<In Place>' ) self.robot.add_command(Command(do=_do, description=description)) return self
def drop_tip(self, location=None): def _do(): nonlocal location if location: self.go_to_bottom(location, now=True) self.plunger.move(self.positions['drop_tip']) self.plunger.home() self.current_volume = 0 description = "Drop_tip at {}".format( (humanize_location(location) if location else '<In Place>')) self.robot.add_command(Command(do=_do, description=description)) return self
def home(self, *args, **kwargs): def _do(): if self._driver.calm_down(): if args: return self._driver.home(*args) else: self._driver.home('z') return self._driver.home('x', 'y', 'b', 'a') else: return False if kwargs.get('now'): return _do() else: description = "Homing Robot" self.add_command(Command(do=_do, description=description))
def mix(self, volume=None, location=None, repetitions=3): def _do(): # plunger movements are handled w/ aspirate/dispense # using Command for printing description pass description = "Mixing {0} times with a volume of {1}ul".format( repetitions, str(self.current_volume)) self.robot.add_command(Command(do=_do, description=description)) self.aspirate(location=location, volume=volume) for i in range(repetitions - 1): self.dispense(volume) self.aspirate(volume) self.dispense(volume) return self
def test_macro(self): expected = [] macro = Macro('macro_test') for i in range(3): def _do(): nonlocal expected expected.append('test') command = Command(do=_do) macro.add(command) macro.do() self.assertEquals(expected, ['test', 'test', 'test'])
def touch_tip(self, location=None): def _do(): nonlocal location if location: self.move_to(location, now=True) else: location = self.placeables[-1] self.go_to( (location, location.from_center(x=1, y=0, z=1)), now=True) self.go_to( (location, location.from_center(x=-1, y=0, z=1)), now=True) self.go_to( (location, location.from_center(x=0, y=1, z=1)), now=True) self.go_to( (location, location.from_center(x=0, y=-1, z=1)), now=True) description = 'Touching tip' self.robot.add_command(Command(do=_do, description=description)) return self
def pick_up_tip(self, location=None): def _do(): nonlocal location if location: self.go_to_bottom(location, now=True) # TODO: actual plunge depth for picking up a tip # varies based on the tip # right now it's accounted for via plunge depth # TODO: Need to talk about containers z positioning tip_plunge = 6 # Dip into tip and pull it up for _ in range(3): self.robot.move_head(z=-tip_plunge, mode='relative') self.robot.move_head(z=tip_plunge, mode='relative') self.robot.home('z') description = "Picking up tip from {0}".format( (humanize_location(location) if location else '<In Place>') ) self.robot.add_command(Command(do=_do, description=description)) return self
def commandable(): self.add_command(Command(do=callback))