Example #1
0
    def blow_out(self, location=None, enqueue=True):
        """
        Force any remaining liquid to dispense, by moving
        this pipette's plunger to the calibrated `blow_out` position

        Notes
        -----
        If no `location` is passed, the pipette will blow_out
        from it's current position.

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the blow_out.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(axis='a', max_volume=200)
        >>> p200.aspirate(50).dispense().blow_out() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        def _setup():
            nonlocal location
            self.current_volume = 0
            self._associate_placeable(location)

        def _do():
            nonlocal location
            self.move_to(location, strategy='arc', enqueue=False)
            self.motor.move(self._get_plunger_position('blow_out'))

        _description = "Blow_out at {}".format(
            humanize_location(location) if location else '<In Place>'
        )
        self.create_command(
            do=_do,
            setup=_setup,
            description=_description,
            enqueue=enqueue)
        return self
Example #2
0
    def blow_out(self, location=None, enqueue=True):
        """
        Force any remaining liquid to dispense, by moving
        this pipette's plunger to the calibrated `blow_out` position

        Notes
        -----
        If no `location` is passed, the pipette will blow_out
        from it's current position.

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the blow_out.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(axis='a', max_volume=200)
        >>> p200.aspirate(50).dispense().blow_out() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        def _setup():
            nonlocal location
            self.current_volume = 0
            self._associate_placeable(location)

        def _do():
            nonlocal location
            self.move_to(location, strategy='arc', enqueue=False)
            self.motor.move(self._get_plunger_position('blow_out'))

        _description = "Blow_out at {}".format(
            humanize_location(location) if location else '<In Place>')
        self.create_command(do=_do,
                            setup=_setup,
                            description=_description,
                            enqueue=enqueue)
        return self
Example #3
0
    def blow_out(self, location=None):
        """
        Force any remaining liquid to dispense, by moving
        this pipette's plunger to the calibrated `blow_out` position

        Notes
        -----
        If no `location` is passed, the pipette will blow_out
        from it's current position.

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the blow_out.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(name='p200', axis='a', max_volume=200)
        >>> p200.aspirate(50).dispense().blow_out() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """

        _description = "Blowing out {}".format(
            'at ' + humanize_location(location) if location else '')
        self.robot.add_command(_description)

        self.move_to(location, strategy='arc')
        self.motor.move(self._get_plunger_position('blow_out'))
        self.current_volume = 0
        return self
Example #4
0
    def drop_tip(self, location=None, home_after=True):
        """
        Drop the pipette's current tip

        Notes
        -----
        If no location is passed, the pipette defaults to its `trash_container`
        (see :any:`Pipette`)

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the drop_tip.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> robot.reset() # doctest: +ELLIPSIS
        <opentrons.robot.robot.Robot object at ...>
        >>> tiprack = containers.load('tiprack-200ul', 'A1')
        >>> trash = containers.load('point', 'A1')
        >>> p200 = instruments.Pipette(axis='a', trash_container=trash)
        >>> p200.pick_up_tip(tiprack[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # drops the tip in the trash
        >>> p200.drop_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.pick_up_tip(tiprack[1]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # drops the tip back at its tip rack
        >>> p200.drop_tip(tiprack[1]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """

        if not location and self.trash_container:
            location = self.trash_container

        if isinstance(location, Placeable):
            # give space for the drop-tip mechanism
            location = location.bottom(self._drop_tip_offset)

        _description = "Drop_tip {}".format(
            ('at ' + humanize_location(location) if location else ''))
        self.robot.add_command(_description)

        if location:
            self.move_to(location, strategy='arc')

        self.motor.move(self._get_plunger_position('drop_tip'))
        if home_after:
            self.motor.home()

        self.motor.move(self._get_plunger_position('bottom'))

        self.current_volume = 0
        self.current_tip(None)
        return self
Example #5
0
    def pick_up_tip(self, location=None, presses=3):
        """
        Pick up a tip for the Pipette to run liquid-handling commands with

        Notes
        -----
        A tip can be manually set by passing a `location`. If no location
        is passed, the Pipette will pick up the next available tip in
        it's `tip_racks` list (see :any:`Pipette`)

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the pick_up_tip.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> robot.reset() # doctest: +ELLIPSIS
        <opentrons.robot.robot.Robot object at ...>
        >>> tiprack = containers.load('tiprack-200ul', 'A1')
        >>> p200 = instruments.Pipette(axis='a', tip_racks=[tiprack])
        >>> p200.pick_up_tip(tiprack[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.return_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # `pick_up_tip` will automatically go to tiprack[1]
        >>> p200.pick_up_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.return_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """

        if not location:
            location = self.get_next_tip()
        self.current_tip(None)
        if location:
            placeable, _ = unpack_location(location)
            self.current_tip(placeable)

        if isinstance(location, Placeable):
            location = location.bottom()

        _description = "Picking up tip {0}".format(
            ('from ' +
             humanize_location(location) if location else ''))  # NOQA
        self.robot.add_command(_description)

        presses = (1 if not helpers.is_number(presses) else presses)

        self.motor.move(self._get_plunger_position('bottom'))
        self.current_volume = 0

        if location:
            self.move_to(location, strategy='arc')

        tip_plunge = 6
        for i in range(int(presses) - 1):
            self.robot.move_head(z=tip_plunge, mode='relative')
            self.robot.move_head(z=-tip_plunge, mode='relative')
        return self
Example #6
0
    def dispense(self, volume=None, location=None, rate=1.0):
        """
        Dispense a volume of liquid (in microliters/uL) using this pipette

        Notes
        -----
        If no `location` is passed, the pipette will dispense
        from it's current position. If no `volume` is passed,
        `dispense` will default to it's `current_volume`

        Parameters
        ----------
        volume : int or float
            The number of microliters to dispense
            (Default: self.current_volume)
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the dispense.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`
        rate : float
            Set plunger speed for this dispense, where
            speed = rate * dispense_speed (see :meth:`set_speed`)

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(name='p200', axis='a', max_volume=200)
        >>> # fill the pipette with liquid (200uL)
        >>> p200.aspirate(plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 50uL to a Well
        >>> p200.dispense(50, plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 50uL to the center of a well
        >>> relative_vector = plate[1].center()
        >>> p200.dispense(50, (plate[1], relative_vector)) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 20uL in place, at half the speed
        >>> p200.dispense(20, rate=0.5) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense the pipette's remaining volume (80uL) to a Well
        >>> p200.dispense(plate[2]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        if not helpers.is_number(volume):
            if volume and not location:
                location = volume
            volume = self.current_volume

        # Ensure we don't dispense more than the current volume
        volume = min(self.current_volume, volume)

        # if volume is specified as 0uL, then do nothing
        if volume == 0:
            return self

        _description = "Dispensing {0} {1}".format(
            volume,
            ('at ' + humanize_location(location) if location else ''))  # NOQA
        self.robot.add_command(_description)

        self.move_to(location, strategy='arc')  # position robot above location

        # TODO(ahmed): revisit this
        distance = self._plunge_distance(self.current_volume - volume)
        bottom = self._get_plunger_position('bottom')
        destination = bottom - distance
        speed = self.speeds['dispense'] * rate

        self.motor.speed(speed)
        self.motor.move(destination)
        self.current_volume -= volume  # update after actual dispense
        return self
Example #7
0
    def aspirate(self, volume=None, location=None, rate=1.0):
        """
        Aspirate a volume of liquid (in microliters/uL) using this pipette

        Notes
        -----
        If no `location` is passed, the pipette will aspirate
        from it's current position. If no `volume` is passed,
        `aspirate` will default to it's `max_volume`

        Parameters
        ----------
        volume : int or float
            The number of microliters to aspirate (Default: self.max_volume)

        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the aspirate.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        rate : float
            Set plunger speed for this aspirate, where
            speed = rate * aspirate_speed (see :meth:`set_speed`)

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(
        ...     name='p200', axis='a', max_volume=200)

        >>> # aspirate 50uL from a Well
        >>> p200.aspirate(50, plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate 50uL from the center of a well
        >>> p200.aspirate(50, plate[1].bottom()) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate 20uL in place, twice as fast
        >>> p200.aspirate(20, rate=2.0) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate the pipette's remaining volume (80uL) from a Well
        >>> p200.aspirate(plate[2]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """

        # Note: volume positional argument may not be passed. if it isn't then
        # assume the first positional argument is the location
        if not helpers.is_number(volume):
            if volume and not location:
                location = volume
            volume = self.max_volume - self.current_volume

        # if volume is specified as 0uL, then do nothing
        if volume == 0:
            return self

        if self.current_volume + volume > self.max_volume:
            raise RuntimeWarning(
                'Pipette with max volume of {0} cannot hold volume {1}'.format(
                    self.max_volume, self.current_volume + volume))

        distance = self._plunge_distance(self.current_volume + volume)
        bottom = self._get_plunger_position('bottom')
        destination = bottom - distance
        speed = self.speeds['aspirate'] * rate

        _description = "Aspirating {0} {1}".format(
            volume,
            ('at ' + humanize_location(location) if location else ''))  # NOQA
        self.robot.add_command(_description)

        self._position_for_aspirate(location)
        self.motor.speed(speed)
        self.motor.move(destination)
        self.current_volume += volume  # update after actual aspirate
        return self
Example #8
0
    def drop_tip(self, location=None, enqueue=True):
        """
        Drop the pipette's current tip

        Notes
        -----
        If no location is passed, the pipette defaults to its `trash_container`
        (see :any:`Pipette`)

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the drop_tip.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> robot.reset() # doctest: +ELLIPSIS
        <opentrons.robot.robot.Robot object at ...>
        >>> tiprack = containers.load('tiprack-200ul', 'A1')
        >>> trash = containers.load('point', 'A1')
        >>> p200 = instruments.Pipette(axis='a', trash_container=trash)
        >>> p200.pick_up_tip(tiprack[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # drops the tip in the trash
        >>> p200.drop_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.pick_up_tip(tiprack[1]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # drops the tip back at its tip rack
        >>> p200.drop_tip(tiprack[1]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        def _setup():
            nonlocal location
            if not location and self.trash_container:
                location = self.trash_container

            if isinstance(location, Placeable):
                # give space for the drop-tip mechanism
                location = location.bottom(self._drop_tip_offset)

            self._associate_placeable(location)
            self.current_tip_home_well = None

            self.current_volume = 0

        def _do():
            nonlocal location

            if location:
                self.move_to(location, strategy='arc', enqueue=False)

            self.motor.move(self._get_plunger_position('drop_tip'))
            self.motor.home()

            self.motor.move(self._get_plunger_position('bottom'))

        _description = "Drop_tip at {}".format(
            (humanize_location(location) if location else '<In Place>')
        )

        self.create_command(
            do=_do,
            setup=_setup,
            description=_description,
            enqueue=enqueue)
        return self
Example #9
0
    def pick_up_tip(self, location=None, enqueue=True):
        """
        Pick up a tip for the Pipette to run liquid-handling commands with

        Notes
        -----
        A tip can be manually set by passing a `location`. If no location
        is passed, the Pipette will pick up the next available tip in
        it's `tip_racks` list (see :any:`Pipette`)

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the pick_up_tip.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> robot.reset() # doctest: +ELLIPSIS
        <opentrons.robot.robot.Robot object at ...>
        >>> tiprack = containers.load('tiprack-200ul', 'A1')
        >>> p200 = instruments.Pipette(axis='a', tip_racks=[tiprack])
        >>> p200.pick_up_tip(tiprack[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.return_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # `pick_up_tip` will automatically go to tiprack[1]
        >>> p200.pick_up_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.return_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        def _setup():
            nonlocal location
            if not location:
                if self.has_tip_rack():
                    # TODO: raise warning/exception if looped back to first tip
                    location = next(self.tip_rack_iter)
                else:
                    self.robot.add_warning(
                        'pick_up_tip called with no reference to a tip')

            self.current_tip_home_well = None
            if location:
                placeable, _ = containers.unpack_location(location)
                self.current_tip_home_well = placeable

            if isinstance(location, Placeable):
                location = location.bottom()

            self._associate_placeable(location)

            self.current_volume = 0

        def _do():
            nonlocal location

            if location:
                self.move_to(location, strategy='arc', enqueue=False)

            tip_plunge = 6

            self.robot.move_head(z=tip_plunge, mode='relative')
            self.robot.move_head(z=-tip_plunge - 1, mode='relative')
            self.robot.move_head(z=tip_plunge + 1, mode='relative')
            self.robot.move_head(z=-tip_plunge, mode='relative')

        _description = "Picking up tip from {0}".format(
            (humanize_location(location) if location else '<In Place>')
        )
        self.create_command(
            do=_do,
            setup=_setup,
            description=_description,
            enqueue=enqueue)
        return self
Example #10
0
    def dispense(self,
                 volume=None,
                 location=None,
                 rate=1.0,
                 enqueue=True):
        """
        Dispense a volume of liquid (in microliters/uL) using this pipette

        Notes
        -----
        If no `location` is passed, the pipette will dispense
        from it's current position. If no `volume` is passed,
        `dispense` will default to it's `current_volume`

        Parameters
        ----------
        volume : int or float
            The number of microliters to dispense
            (Default: self.current_volume)
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the dispense.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`
        rate : float
            Set plunger speed for this dispense, where
            speed = rate * dispense_speed (see :meth:`set_speed`)

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(axis='a', max_volume=200)
        >>> # fill the pipette with liquid (200uL)
        >>> p200.aspirate(plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 50uL to a Well
        >>> p200.dispense(50, plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 50uL to the center of a well
        >>> relative_vector = plate[1].center()
        >>> p200.dispense(50, (plate[1], relative_vector)) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 20uL in place, at half the speed
        >>> p200.dispense(20, rate=0.5) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense the pipette's remaining volume (80uL) to a Well
        >>> p200.dispense(plate[2]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        def _setup():
            nonlocal location
            nonlocal volume
            nonlocal rate

            if not isinstance(volume, (int, float, complex)):
                if volume and not location:
                    location = volume
                volume = self.current_volume

            if not volume or (self.current_volume - volume < 0):
                volume = self.current_volume

            if isinstance(location, Placeable):
                location = location.bottom(1)

            self.current_volume -= volume

            self._associate_placeable(location)

        def _do():
            nonlocal location
            nonlocal volume
            nonlocal rate

            self.move_to(location, strategy='arc', enqueue=False)

            distance = self._plunge_distance(self.current_volume)
            bottom = self._get_plunger_position('bottom')
            destination = bottom - distance

            speed = self.speeds['dispense'] * rate

            self.motor.speed(speed)
            self.motor.move(destination)

        _description = "Dispensing {0}uL at {1}".format(
            volume,
            (humanize_location(location) if location else '<In Place>')
        )
        self.create_command(
            do=_do,
            setup=_setup,
            description=_description,
            enqueue=enqueue)
        return self
Example #11
0
    def aspirate(self,
                 volume=None,
                 location=None,
                 rate=1.0,
                 enqueue=True):
        """
        Aspirate a volume of liquid (in microliters/uL) using this pipette

        Notes
        -----
        If no `location` is passed, the pipette will aspirate
        from it's current position. If no `volume` is passed,
        `aspirate` will default to it's `max_volume`

        Parameters
        ----------
        volume : int or float
            The number of microliters to aspirate (Default: self.max_volume)

        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the aspirate.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        rate : float
            Set plunger speed for this aspirate, where
            speed = rate * aspirate_speed (see :meth:`set_speed`)

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(axis='a', max_volume=200)

        >>> # aspirate 50uL from a Well
        >>> p200.aspirate(50, plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate 50uL from the center of a well
        >>> relative_vector = plate[1].center()
        >>> p200.aspirate(50, (plate[1], relative_vector)) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate 20uL in place, twice as fast
        >>> p200.aspirate(20, rate=2.0) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate the pipette's remaining volume (80uL) from a Well
        >>> p200.aspirate(plate[2]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """

        # set True if volume before this aspirate was 0uL
        plunger_empty = False

        def _setup():
            nonlocal volume
            nonlocal location
            nonlocal rate
            nonlocal plunger_empty
            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 ({0}) cannot hold volume {1}'
                    .format(
                        self.max_volume,
                        self.current_volume + volume)
                )

            if self.current_volume == 0:
                plunger_empty = True
            self.current_volume += volume

            self._associate_placeable(location)

        def _do():
            nonlocal volume
            nonlocal location
            nonlocal rate
            nonlocal plunger_empty
            distance = self._plunge_distance(self.current_volume)
            bottom = self._get_plunger_position('bottom')
            destination = bottom - distance

            speed = self.speeds['aspirate'] * rate

            self._position_for_aspirate(location, plunger_empty)

            self.motor.speed(speed)
            self.motor.move(destination)

        _description = "Aspirating {0}uL at {1}".format(
            volume,
            (humanize_location(location) if location else '<In Place>')
        )
        self.create_command(
            do=_do,
            setup=_setup,
            description=_description,
            enqueue=enqueue)

        return self
Example #12
0
    def drop_tip(self, location=None, enqueue=True):
        """
        Drop the pipette's current tip

        Notes
        -----
        If no location is passed, the pipette defaults to its `trash_container`
        (see :any:`Pipette`)

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the drop_tip.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> robot.reset() # doctest: +ELLIPSIS
        <opentrons.robot.robot.Robot object at ...>
        >>> tiprack = containers.load('tiprack-200ul', 'A1')
        >>> trash = containers.load('point', 'A1')
        >>> p200 = instruments.Pipette(axis='a', trash_container=trash)
        >>> p200.pick_up_tip(tiprack[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # drops the tip in the trash
        >>> p200.drop_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.pick_up_tip(tiprack[1]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # drops the tip back at its tip rack
        >>> p200.drop_tip(tiprack[1]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        def _setup():
            nonlocal location
            if not location and self.trash_container:
                location = self.trash_container

            if isinstance(location, Placeable):
                # give space for the drop-tip mechanism
                location = location.bottom(self._drop_tip_offset)

            self._associate_placeable(location)
            self.current_tip_home_well = None

            self.current_volume = 0

        def _do():
            nonlocal location

            if location:
                self.move_to(location, strategy='arc', enqueue=False)

            self.motor.move(self._get_plunger_position('drop_tip'))
            self.motor.home()

            self.motor.move(self._get_plunger_position('bottom'))

        _description = "Drop_tip at {}".format(
            (humanize_location(location) if location else '<In Place>'))

        self.create_command(do=_do,
                            setup=_setup,
                            description=_description,
                            enqueue=enqueue)
        return self
Example #13
0
    def pick_up_tip(self, location=None, enqueue=True):
        """
        Pick up a tip for the Pipette to run liquid-handling commands with

        Notes
        -----
        A tip can be manually set by passing a `location`. If no location
        is passed, the Pipette will pick up the next available tip in
        it's `tip_racks` list (see :any:`Pipette`)

        Parameters
        ----------
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the pick_up_tip.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> robot.reset() # doctest: +ELLIPSIS
        <opentrons.robot.robot.Robot object at ...>
        >>> tiprack = containers.load('tiprack-200ul', 'A1')
        >>> p200 = instruments.Pipette(axis='a', tip_racks=[tiprack])
        >>> p200.pick_up_tip(tiprack[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.return_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> # `pick_up_tip` will automatically go to tiprack[1]
        >>> p200.pick_up_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        >>> p200.return_tip() # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        def _setup():
            nonlocal location
            if not location:
                if self.has_tip_rack():
                    # TODO: raise warning/exception if looped back to first tip
                    location = next(self.tip_rack_iter)
                else:
                    self.robot.add_warning(
                        'pick_up_tip called with no reference to a tip')

            self.current_tip_home_well = None
            if location:
                placeable, _ = containers.unpack_location(location)
                self.current_tip_home_well = placeable

            if isinstance(location, Placeable):
                location = location.bottom()

            self._associate_placeable(location)

            self.current_volume = 0

        def _do():
            nonlocal location

            if location:
                self.move_to(location, strategy='arc', enqueue=False)

            tip_plunge = 6

            self.robot.move_head(z=tip_plunge, mode='relative')
            self.robot.move_head(z=-tip_plunge - 1, mode='relative')
            self.robot.move_head(z=tip_plunge + 1, mode='relative')
            self.robot.move_head(z=-tip_plunge, mode='relative')

        _description = "Picking up tip from {0}".format(
            (humanize_location(location) if location else '<In Place>'))
        self.create_command(do=_do,
                            setup=_setup,
                            description=_description,
                            enqueue=enqueue)
        return self
Example #14
0
    def dispense(self, volume=None, location=None, rate=1.0, enqueue=True):
        """
        Dispense a volume of liquid (in microliters/uL) using this pipette

        Notes
        -----
        If no `location` is passed, the pipette will dispense
        from it's current position. If no `volume` is passed,
        `dispense` will default to it's `current_volume`

        Parameters
        ----------
        volume : int or float
            The number of microliters to dispense
            (Default: self.current_volume)
        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the dispense.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`
        rate : float
            Set plunger speed for this dispense, where
            speed = rate * dispense_speed (see :meth:`set_speed`)

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(axis='a', max_volume=200)
        >>> # fill the pipette with liquid (200uL)
        >>> p200.aspirate(plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 50uL to a Well
        >>> p200.dispense(50, plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 50uL to the center of a well
        >>> relative_vector = plate[1].center()
        >>> p200.dispense(50, (plate[1], relative_vector)) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense 20uL in place, at half the speed
        >>> p200.dispense(20, rate=0.5) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # dispense the pipette's remaining volume (80uL) to a Well
        >>> p200.dispense(plate[2]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """
        def _setup():
            nonlocal location
            nonlocal volume
            nonlocal rate

            if not isinstance(volume, (int, float, complex)):
                if volume and not location:
                    location = volume
                volume = self.current_volume

            if not volume or (self.current_volume - volume < 0):
                volume = self.current_volume

            if isinstance(location, Placeable):
                location = location.bottom(1)

            self.current_volume -= volume

            self._associate_placeable(location)

        def _do():
            nonlocal location
            nonlocal volume
            nonlocal rate

            self.move_to(location, strategy='arc', enqueue=False)

            distance = self._plunge_distance(self.current_volume)
            bottom = self._get_plunger_position('bottom')
            destination = bottom - distance

            speed = self.speeds['dispense'] * rate

            self.motor.speed(speed)
            self.motor.move(destination)

        _description = "Dispensing {0}uL at {1}".format(
            volume,
            (humanize_location(location) if location else '<In Place>'))
        self.create_command(do=_do,
                            setup=_setup,
                            description=_description,
                            enqueue=enqueue)
        return self
Example #15
0
    def aspirate(self, volume=None, location=None, rate=1.0, enqueue=True):
        """
        Aspirate a volume of liquid (in microliters/uL) using this pipette

        Notes
        -----
        If no `location` is passed, the pipette will aspirate
        from it's current position. If no `volume` is passed,
        `aspirate` will default to it's `max_volume`

        Parameters
        ----------
        volume : int or float
            The number of microliters to aspirate (Default: self.max_volume)

        location : :any:`Placeable` or tuple(:any:`Placeable`, :any:`Vector`)
            The :any:`Placeable` (:any:`Well`) to perform the aspirate.
            Can also be a tuple with first item :any:`Placeable`,
            second item relative :any:`Vector`

        rate : float
            Set plunger speed for this aspirate, where
            speed = rate * aspirate_speed (see :meth:`set_speed`)

        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

        Returns
        -------

        This instance of :class:`Pipette`.

        Examples
        --------
        ..
        >>> p200 = instruments.Pipette(axis='a', max_volume=200)

        >>> # aspirate 50uL from a Well
        >>> p200.aspirate(50, plate[0]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate 50uL from the center of a well
        >>> relative_vector = plate[1].center()
        >>> p200.aspirate(50, (plate[1], relative_vector)) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate 20uL in place, twice as fast
        >>> p200.aspirate(20, rate=2.0) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>

        >>> # aspirate the pipette's remaining volume (80uL) from a Well
        >>> p200.aspirate(plate[2]) # doctest: +ELLIPSIS
        <opentrons.instruments.pipette.Pipette object at ...>
        """

        # set True if volume before this aspirate was 0uL
        plunger_empty = False

        def _setup():
            nonlocal volume
            nonlocal location
            nonlocal rate
            nonlocal plunger_empty
            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 ({0}) cannot hold volume {1}'.format(
                        self.max_volume, self.current_volume + volume))

            if self.current_volume == 0:
                plunger_empty = True
            self.current_volume += volume

            self._associate_placeable(location)

        def _do():
            nonlocal volume
            nonlocal location
            nonlocal rate
            nonlocal plunger_empty
            distance = self._plunge_distance(self.current_volume)
            bottom = self._get_plunger_position('bottom')
            destination = bottom - distance

            speed = self.speeds['aspirate'] * rate

            self._position_for_aspirate(location, plunger_empty)

            self.motor.speed(speed)
            self.motor.move(destination)

        _description = "Aspirating {0}uL at {1}".format(
            volume,
            (humanize_location(location) if location else '<In Place>'))
        self.create_command(do=_do,
                            setup=_setup,
                            description=_description,
                            enqueue=enqueue)

        return self