Pipette Intro#
This example notebook will show you how to do simple liquid handling with an OT-2 tool. It assumes you know a little bit about the laboratory automation deck and installing labware.
Before Starting:#
Clear any existing items off the bed of your machine!
A lab automation deck and pipette should be installed on your machine
[ ]:
### Import modules and connect to the machine
from science_jubilee.Machine import Machine
from science_jubilee.tools.Pipette import Pipette
from science_jubilee.labware.Labware import Labware
[ ]:
m = Machine(address='192.168.1.2') # connect to the machine
[ ]:
# m.home_all() # if you need to, uncomment this line to home the machine
[ ]:
deck = m.load_deck('POSE-calibrated-deck') # load in your deck calibration
Labware Preparation#
Now we need to load all labware both physically and digitally .
Digitally: we’ll load the
labware
we want to use and indicate whichslot
each is assigned toPhysically: install the labware onto the deck of your Jubilee
For this example, we’ll use the following labware:
A Tiprack that is suitable for the pipette you are using to transfer your liquids. We’ll use an OpenTrons tiprack.
A Sample Labware that will be used to collect samples. We’ll use a 96 well plate.
A Stock Labware that will host your stock liquids. We’ll use a 6-well plate.
A trash to collect used tips. We’ll use a petri dish.
If you’d like, you can fill your stock labware (the 6 well plate) wells A1, A2, and A3 with water. You’re welcome to add water color/etc as well, or just leave them empty to do a dry run.
[ ]:
# -------------- Labware ------------------
# You might have EITHER a P300 or P1000 pipette and associated tiprack on your machine.
# uncomment the relevent line for your machine!
# tiprack = m.load_labware('opentrons_96_tiprack_300ul', 0) # Uncomment if you have a P300 pipette, otherwise delete!
# tiprack = m.load_labware('opentrons_96_tiprack_1000ul', 0) # Uncomment if you have a P100 pipette, otherwise delete!
trash = m.load_labware('generic_petri_dish_100ml', 1) # Petri dish in slot 1, used as trash
samples = m.load_labware('falcon_96_wellplate_360ul_flat', 2) # 96 well plate in slot 2
stocks = m.load_labware('scienfocus_6_wellplate_15900ul', 3) # 6 well plate in slot 3
[ ]:
m.move_to(z=150) # Drop the bed down to create space to physically load your labware
Before moving on, you should physically install these labware on your machine! It’s always good to double check that you’ve put the correct labware into the correct slot; the tool can crash into labware if your digital setup differs from your physical one.
Tool Setup#
To use your tool, you’ll need to set a tool_index
and a tool_name
. These should be the same as the ones defined in your machine’s config.g
file that appear in the Duet Web Control panel.
You will also import a configuration file for your pipette. If you’re using a P300 pipette, use the P300_config
; if you have a P1000 pipette, use P1000_config
!
[ ]:
# You can check what tools are configured at what indices
m.configured_tools
[ ]:
pipette_index = 3 # change this number to match the tool number for the pipette on your machine!
pipette_config = "P300_config" # change this to P300_config for a P300 pipette, P1000_config for a P1000 pipette
pipette_name = "Pipette" # No need to change this
[ ]:
pipette = Pipette.from_config(pipette_index, pipette_name, pipette_config)
m.load_tool(pipette)
Now we can associate a tiprack
and a trash
with the pipette to pickup and dispense tips
[ ]:
pipette.add_tiprack(tiprack)
pipette.trash = trash[0] # the petri dish is a single well, so we set the 'well' as the trash
We can now pickup our tool!
[ ]:
m.pickup_tool(pipette)
Moving Liquids#
Now, that our tool is active, we can choose start moving liquids around. In the following cells, we will:
pickup a tip
aspirate a certain volume ( in \(\mu\) L) from a source reservoir/well
dispense it into a destination well
return the tip ( if we want to reuse it) OR drop the tip in the trash
[ ]:
# By default, we'll pickup the first tip in the tiprack
# Make sure your tiprack is loaded up with tips!
pipette.pickup_tip()
The aspirate command will move to a given well and then aspirate a specified volume of liquid from a well. The command will automatically move in the Z direction to make sure that it doesn’t collide with any installed labware. Note that if you send move
commands manually (via code or via Duet Web Control), you can still collide with labware!
We also specify the height to aspirate from using bottom(z_offset)
, where we supply a distance in mm from the bottom of the well. This is used to account for any slight errors in the calibration process.
[ ]:
# Now we'll pick up some liquid from our stock plate
# Th aspirate command will automatically move in Z and then to the specified well
pipette.aspirate(250, stocks['A1'].bottom(3)) # (volume in microliters, well to aspirate from)
# .bottom(3) indicates to aspirate from 3 mm above the bottom of the well
The dispense command will move to a given well and then dispence a specified volume of liquid into a well. The command will automatically move in the Z direction to make sure that it doesn’t collide with any installed labware. Note that if you send move
commands manually (via code or via Duet Web Control), you can still collide with labware!
We also specify the height to dispense from using .top(z_offset)
, where we supply a distance in mm from the top of the well. This is used to account for any slight errors in the calibration process.
[ ]:
# Nowd dispense into our samples plate
pipette.dispense(250, samples['A1'].top(-1)) # (volume in microliters, well to dispense to)
# .top(-1) indicates to dispense from just 1mm into top of the well
Once we are done, we can either return the tip to the tip rack, or drop it into the trash
[ ]:
# if you're just using water, you probably want to return the tip to the tip rack
# if you wanted to trash the tip, you could instead use pipette.drop_tip()
pipette.return_tip()
Tranfser Function#
Above, we used pickup_tip
, aspirate
, dispense
, and return_tip
to manually move our liquid. In general, we won’t actually use these more atomic commands. Instead, we can instead use transfer()
which will take care of everything at once, including tracking tips and moving liquids.
In out transfer function, we can specify some additional details, such as:
blowout: Should we push an extra amount of air through the pipette tip to make sure that any remaining droplets are expelled? True or False, False by default
mix_after: Should we mix after dispensing liquid? This is done by aspirating and dispensing the liquid. You can specify a (volume in microliters, number of times to mix)
new_tip: Sets the tip strategy for the transfer. Possible settings include:
‘always’: Trash the tip after every transfer and get a new one
‘once’: Return the tip back to the tip rack after use
‘never’: Don’t pick up a tip; to use this strategy, you need to pickup a tip manually with
pickup_tip
[ ]:
# This function will pick up a tip, then transer liquid!
pipette.transfer(
vol = 250, # volume to transer in microliters
source_well = stocks['A1'].bottom(3), # source well to transer from
destination_well = samples['A2'].top(-1), # destination well to transfer to
blowout = True, # blowout after dispensing
mix_after = (200, 3), # mix after dispensing (vol in microliters, # times to mix)
new_tip = 'once' # return the tip after use
)
You can also provide a list of volumes and source_wells to make things a bit easier. The index of volumes and source_wells are 1:1.
[ ]:
volumes = [50, 100, 50] # transfer 50 microliters, then 100, then 50
stocks = [
stocks['A1'].bottom(3), # transfer from stock wells A1, then A2, then A3
stocks['A2'].bottom(3),
stocks['A3'].bottom(3)
]
destination = samples['A3'].top(-1) # move all samples into sample well A3
pipette.transfer(
vol = volumes,
source_well = stocks,
destination_well = destination,
blowout = True,
new_tip = 'once',
mix_after = (200, 3)
)