I’m doing cell seeding into 384 wellplates with my FLEX and I have a persistent issue with air bubbles when mixing my cell solution, especially after several plates.
Does anyone have any solutions that they like to use for this? I’ve tried blowing out in several places within the protocol and it doesn’t seem to help. It’s a rather bubbly solution of cell media. It’s annoying because sometimes the filter tips clog from too many bubbles
def remove_liquid_loc_list(waste_name,plate_name, volume, pip = channel_96, aspirate_rate = 0.2):
# Get pipetting well destinations
list_pipetting_wells_actual = get_pipetting_wells_A1B1A2B2(plate_name)
protocol.comment(f"Consolidating from plate {plate_name}")
# Remove from each plate (+10 volume to get everything)
for well_name in list_pipetting_wells_actual:
pip.aspirate(volume+10, well_name.bottom(1.2), rate = aspirate_rate)
# Dispense into waste reservoir
waste_loc = waste_name.wells_by_name()["A1"]
pip.dispense(volume*len(list_pipetting_wells_actual),waste_loc.bottom(4),rate=1)
# dip to remove bubbles
pip.blow_out(waste_loc.bottom(10))
pip.move_to(waste_loc.bottom(3))
# blow out to remove liquid gathered from dip
pip.blow_out(waste_loc.bottom(10))
# retract slowly
pip.move_to(waste_loc.top(3),speed=50)
def distribute_cell_volume(source_name,plate_name, volume,mix_rounds=5, mix_volume = 140 , pip = channel_96,dispense_rate = 0.25, aspirate_rate = 0.25):
list_pipetting_wells_actual = get_pipetting_wells_A1B1A2B2(plate_name)
source_loc = source_name.wells_by_name()["A1"]
# if single distribute then mix every time and distirubte one at time, better for more accurate volumes
for well_name in list_pipetting_wells_actual:
if well_name == list_pipetting_wells_actual[0]:
# Mix more for first transfer
mix_intensity = 2
current_mix_rounds = mix_rounds * mix_intensity
else:
# Mix less for second transfer
current_mix_rounds = mix_rounds
# Complex mix, aspirate at bottom, move up, dispense, repeat
#TODO try force-direct later, pipette seems to not move smoothly but move back to the top after each action
for iteration in range(current_mix_rounds):
pip.aspirate(mix_volume, source_loc.bottom(2),rate=1)
pip.dispense(mix_volume,source_loc.bottom(10),rate=1)
pip.blow_out(source_loc.top())
if iteration == current_mix_rounds:
pip.blow_out(source_loc.top())
pip.mix(3,100,source_loc.bottom(2))
pip.blow_out(source_loc.top(-8))
# Aspirate cell volume
channel_96.aspirate(volume, source_loc.bottom(2),rate=aspirate_rate)
# Move slowly to reduce drippage
channel_96.move_to(source_loc.top(1),speed=50)
# Dispense into wellplate
channel_96.dispense(volume,well_name,rate=dispense_rate)
if remove_liquid:
remove_liquid_loc_list(waste_name=waste_trough,plate_name=current_plate, volume=removal_volume)
if cell_addition:
distribute_cell_volume(source_name=liquid_source,plate_name=current_plate, volume=addition_volume)
I can definitely share the above code snippets. I use remove_liquid_loc_list before using the function distribute_cell_volume.
There is some commentary in the protocol of what we would recommend trying (a couple options to test out)!
def distribute_cell_volume(source_name,plate_name, volume,mix_rounds=5, mix_volume = 140 , pip = channel_96,dispense_rate = 0.25, aspirate_rate = 0.25):
list_pipetting_wells_actual = get_pipetting_wells_A1B1A2B2(plate_name)
source_loc = source_name.wells_by_name()[“A1”]
# if single distribute then mix every time and distirubte one at time, better for more accurate volumes
for well_name in list_pipetting_wells_actual:
if well_name == list_pipetting_wells_actual[0]:
# Mix more for first transfer
mix_intensity = 2
current_mix_rounds = mix_rounds * mix_intensity
else:
# Mix less for second transfer
current_mix_rounds = mix_rounds
# Complex mix, aspirate at bottom, move up, dispense, repeat #TODO try force-direct later, pipette seems to not move smoothly but move back to the top after each action
for iteration in range(current_mix_rounds):
pip.aspirate(mix_volume, source_loc.bottom(2),rate=1)
pip.dispense(mix_volume,source_loc.bottom(10),rate=1)
pip.blow_out(source_loc.top())
if iteration == current_mix_rounds:
pip.blow_out(source_loc.top())
####I usually stray away from the mix commmand, As I can see it introduce air bubbles due to the way it moves####
######Could TRY THIS OR THE BELOW#######
for x in range(3):
pip.aspirate(100,source_loc.bottom(2),rate=1)
pip.dispense(100,source_loc.bottom(2),rate=1)
####If you want to continue using the mix command, I would suggest using the following####
pip.aspirate(100,source_loc.bottom(2),rate=1)
pip.dispense(90,source_loc.bottom(2),rate=1)
pip.mix(3,95,source_loc.bottom(2))
pip.dispense(10,source_loc.bottom(2),rate=1) #pip.blow_out(source_loc.top(-8))
# Aspirate cell volume
channel_96.aspirate(volume, source_loc.bottom(2),rate=aspirate_rate)
# Move slowly to reduce drippage
channel_96.move_to(source_loc.top(1),speed=50)
# Dispense into wellplate
channel_96.dispense(volume,well_name,rate=dispense_rate)
if remove_liquid:
remove_liquid_loc_list(waste_name=waste_trough,plate_name=current_plate, volume=removal_volume)
if cell_addition:
distribute_cell_volume(source_name=liquid_source,plate_name=current_plate, volume=addition_volume)
We had similar problems on our OT-2 with air bubbles and dripping.
Here’s some pseudo code from a custom transfer function with manual blow outs and air gaps (after both aspirating and dispensing). It provides more options than the built in transfer function. You might have luck doing a similar manual aspiration on your system.
# Reset the pipette including any previous air gaps
pipette.move_to(source_top)
pipette.dispense()
# Get air for manual blowout
if dispense_blow_out_volume is not None:
pipette.aspirate(dispense_blow_out_volume)
# Aspirate
pipette.move_to(source)
pipette.aspirate(volume)
protocol.delay(aspirate_delay)
# Air gap after aspiration
pipette.move_to(source_top, speed=aspirate_exit_speed)
if aspirate_air_gap_volume is not None:
pipette.air_gap(aspirate_air_gap_volume, height=0)
# Dispense, including blow out
pipette.move_to(destination)
pipette.dispense()
protocol.delay(dispense_delay)
# Air gap after dispensing
pipette.move_to(destination_top, speed=dispense_exit_speed)
if dispense_air_gap_volume is not None:
pipette.air_gap(dispense_air_gap_volume, height=0)
I’ve tried these suggestions and honestly it seems like just using a mix() command without any of the individual aspirate/ dispense commands works the best, because the flex seems incapable of performing multiple aspirate / dispenses without an automatic airgap / blowout between them
Currently just using the standard mix command, retracting the pipette head slowly out of the reservoir, and then dispensing the media directly into the .top(), rate = 1.5 of a 384 wellplate seems to work the best