Skip to content

Commit 372655f

Browse files
authored
adds Pipette.air_gap(vol, height) (#154)
* adds Pipette.air_gap(vol, height) * adds tests
1 parent 6759f1f commit 372655f

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

opentrons/instruments/pipette.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,10 @@ def _do():
385385
self.motor.speed(speed)
386386
self.motor.move(destination)
387387

388+
# if volume is specified as 0uL, then do nothing
389+
if volume is 0:
390+
return self
391+
388392
_description = "Aspirating {0}uL at {1}".format(
389393
volume,
390394
(humanize_location(location) if location else '<In Place>')
@@ -497,6 +501,10 @@ def _do():
497501
self.motor.speed(speed)
498502
self.motor.move(destination)
499503

504+
# if volume is specified as 0uL, then do nothing
505+
if volume is 0:
506+
return self
507+
500508
_description = "Dispensing {0}uL at {1}".format(
501509
volume,
502510
(humanize_location(location) if location else '<In Place>')
@@ -775,6 +783,70 @@ def _do():
775783

776784
return self
777785

786+
# QUEUEABLE
787+
def air_gap(self, volume=None, height=None, enqueue=True):
788+
"""
789+
Pull air into the :any:`Pipette` current tip
790+
791+
Notes
792+
-----
793+
If no `location` is passed, the pipette will touch_tip
794+
from it's current position.
795+
796+
Parameters
797+
----------
798+
volume : number
799+
The amount in uL to aspirate air into the tube.
800+
(Default will use all remaining volume in tip)
801+
802+
height : number
803+
The number of millimiters to move above the current Placeable
804+
to perform and air-gap aspirate
805+
(Default will be 10mm above current Placeable)
806+
807+
Returns
808+
-------
809+
810+
This instance of :class:`Pipette`.
811+
812+
Examples
813+
--------
814+
..
815+
>>> p200 = instruments.Pipette(axis='a', max_volume=200)
816+
>>> p200.aspirate(50, plate[0]) # doctest: +ELLIPSIS
817+
<opentrons.instruments.pipette.Pipette object at ...>
818+
>>> p200.air_gap(50) # doctest: +ELLIPSIS
819+
<opentrons.instruments.pipette.Pipette object at ...>
820+
"""
821+
822+
def _setup():
823+
pass
824+
825+
def _do():
826+
pass
827+
828+
# if volumes is specified as 0uL, do nothing
829+
if volume is 0:
830+
return self
831+
832+
_description = 'Air gap'
833+
self.create_command(
834+
do=_do,
835+
setup=_setup,
836+
description=_description,
837+
enqueue=enqueue)
838+
839+
if height is None:
840+
height = 20
841+
842+
location = self.previous_placeable.top(height)
843+
# "move_to" separate from aspirate command
844+
# so "_position_for_aspirate" isn't executed
845+
self.move_to(location, enqueue=enqueue)
846+
self.aspirate(volume, enqueue=enqueue)
847+
848+
return self
849+
778850
# QUEUEABLE
779851
def return_tip(self, enqueue=True):
780852
"""

tests/opentrons/labware/test_pipette.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,31 @@ def test_mix(self):
529529
]
530530
)
531531

532+
def test_air_gap(self):
533+
self.p200.aspirate(50, self.plate[0])
534+
self.p200.air_gap()
535+
self.assertEquals(self.p200.current_volume, 200)
536+
537+
self.p200.dispense()
538+
self.p200.aspirate(50, self.plate[1])
539+
self.p200.air_gap(10)
540+
self.assertEquals(self.p200.current_volume, 60)
541+
542+
self.p200.dispense()
543+
self.p200.aspirate(50, self.plate[2])
544+
self.p200.air_gap(10, 10)
545+
self.assertEquals(self.p200.current_volume, 60)
546+
547+
self.p200.dispense()
548+
self.p200.aspirate(50, self.plate[2])
549+
self.p200.air_gap(0)
550+
self.assertEquals(self.p200.current_volume, 50)
551+
552+
def test_pipette_home(self):
553+
self.p200.motor.home = mock.Mock()
554+
self.p200.home()
555+
self.assertEquals(len(self.robot.commands()), 1)
556+
532557
def test_mix_with_named_args(self):
533558
self.p200.current_volume = 100
534559
self.p200.aspirate = mock.Mock()

0 commit comments

Comments
 (0)