-
Notifications
You must be signed in to change notification settings - Fork 180
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'edge' into pd_refactor-toolbox-layouts
- Loading branch information
Showing
47 changed files
with
1,341 additions
and
469 deletions.
There are no files selected for viewing
429 changes: 88 additions & 341 deletions
429
abr-testing/abr_testing/protocols/active_protocols/12_KAPA HyperPlus Library Prep.py
Large diffs are not rendered by default.
Oops, something went wrong.
351 changes: 351 additions & 0 deletions
351
abr-testing/abr_testing/protocols/active_protocols/6_Omega_HDQ_DNA_Cells-Flex_96_channel.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,351 @@ | ||
"""Omega Bio-tek Mag-Bind Blood & Tissue DNA HDQ - Bacteria.""" | ||
from typing import List, Dict | ||
from abr_testing.protocols import helpers | ||
from opentrons.protocol_api import ( | ||
ProtocolContext, | ||
ParameterContext, | ||
Well, | ||
InstrumentContext, | ||
) | ||
from opentrons.protocol_api.module_contexts import ( | ||
HeaterShakerContext, | ||
MagneticBlockContext, | ||
TemperatureModuleContext, | ||
) | ||
from opentrons import types | ||
import numpy as np | ||
|
||
metadata = { | ||
"author": "Zach Galluzzo <[email protected]>", | ||
"protocolName": "Omega Bio-tek Mag-Bind Blood & Tissue DNA HDQ - Bacteria", | ||
} | ||
|
||
requirements = { | ||
"robotType": "Flex", | ||
"apiLevel": "2.21", | ||
} | ||
|
||
|
||
def add_parameters(parameters: ParameterContext) -> None: | ||
"""Parameters.""" | ||
helpers.create_dot_bottom_parameter(parameters) | ||
|
||
|
||
# Start protocol | ||
def run(ctx: ProtocolContext) -> None: | ||
"""Protocol.""" | ||
dot_bottom = ctx.params.dot_bottom # type: ignore[attr-defined] | ||
|
||
dry_run = False | ||
tip_mixing = False | ||
|
||
wash_vol = 600.0 | ||
AL_vol = 230.0 | ||
bind_vol = 320.0 | ||
sample_vol = 180.0 | ||
elution_vol = 100.0 | ||
|
||
# Same for all HDQ Extractions | ||
deepwell_type = "nest_96_wellplate_2ml_deep" | ||
if not dry_run: | ||
settling_time = 2.0 | ||
num_washes = 3 | ||
if dry_run: | ||
settling_time = 0.5 | ||
num_washes = 1 | ||
bead_vol = PK_vol = 20.0 | ||
inc_temp = 55.0 | ||
AL_total_vol = AL_vol + PK_vol | ||
binding_buffer_vol = bead_vol + bind_vol | ||
starting_vol = AL_total_vol + sample_vol | ||
|
||
h_s: HeaterShakerContext = ctx.load_module(helpers.hs_str, "D1") # type: ignore[assignment] | ||
sample_plate, h_s_adapter = helpers.load_hs_adapter_and_labware( | ||
deepwell_type, h_s, "Sample Plate" | ||
) | ||
h_s.close_labware_latch() | ||
samples_m = sample_plate.wells()[0] | ||
|
||
# NOTE: MAG BLOCK will be on slot 6 | ||
|
||
temp: TemperatureModuleContext = ctx.load_module( | ||
helpers.temp_str, "A3" | ||
) # type: ignore[assignment] | ||
elutionplate, tempblock = helpers.load_temp_adapter_and_labware( | ||
"armadillo_96_wellplate_200ul_pcr_full_skirt", temp, "Elution Plate/Reservoir" | ||
) | ||
|
||
magblock: MagneticBlockContext = ctx.load_module( | ||
"magneticBlockV1", "C1" | ||
) # type: ignore[assignment] | ||
liquid_waste = ctx.load_labware("nest_1_reservoir_195ml", "B3", "Liquid Waste") | ||
waste = liquid_waste.wells()[0].top() | ||
|
||
lysis_reservoir = ctx.load_labware(deepwell_type, "D2", "Lysis reservoir") | ||
lysis_res = lysis_reservoir.wells()[0] | ||
bind_reservoir = ctx.load_labware( | ||
deepwell_type, "C2", "Beads and binding reservoir" | ||
) | ||
bind_res = bind_reservoir.wells()[0] | ||
wash1_reservoir = ctx.load_labware(deepwell_type, "C3", "Wash 1 reservoir") | ||
wash1_res = wash1_reservoir.wells()[0] | ||
wash2_reservoir = ctx.load_labware(deepwell_type, "B1", "Wash 2 reservoir") | ||
wash2_res = wash2_reservoir.wells()[0] | ||
elution_res = elutionplate.wells()[0] | ||
# Load Pipette and tip racks | ||
# Load tips | ||
tiprack_1 = ctx.load_labware( | ||
"opentrons_flex_96_tiprack_1000ul", | ||
"A1", | ||
adapter="opentrons_flex_96_tiprack_adapter", | ||
) | ||
tips = tiprack_1.wells()[0] | ||
|
||
tiprack_2 = ctx.load_labware( | ||
"opentrons_flex_96_tiprack_1000ul", | ||
"A2", | ||
adapter="opentrons_flex_96_tiprack_adapter", | ||
) | ||
tips1 = tiprack_2.wells()[0] | ||
# load 96 channel pipette | ||
pip: InstrumentContext = ctx.load_instrument( | ||
"flex_96channel_1000", mount="left", tip_racks=[tiprack_1, tiprack_2] | ||
) | ||
# Load Liquids and probe | ||
liquid_vols_and_wells: Dict[str, List[Dict[str, Well | List[Well] | float]]] = { | ||
"Lysis Buffer": [{"well": lysis_reservoir.wells(), "volume": AL_vol + 92.0}], | ||
"PK Buffer": [{"well": lysis_reservoir.wells(), "volume": PK_vol + 8.0}], | ||
"Binding Buffer": [{"well": bind_reservoir.wells(), "volume": bind_vol + 91.5}], | ||
"Magnetic Beads": [{"well": bind_reservoir.wells(), "volume": bead_vol + 8.5}], | ||
"Wash 1 and 2 Buffer": [ | ||
{"well": wash1_reservoir.wells(), "volume": (wash_vol * 2.0) + 100.0} | ||
], | ||
"Wash 3 Buffer": [ | ||
{"well": wash2_reservoir.wells(), "volume": wash_vol + 100.0} | ||
], | ||
"Elution Buffer": [{"well": elutionplate.wells(), "volume": elution_vol + 5}], | ||
"Samples": [{"well": sample_plate.wells(), "volume": sample_vol}], | ||
} | ||
|
||
helpers.find_liquid_height_of_loaded_liquids(ctx, liquid_vols_and_wells, pip) | ||
|
||
pip.flow_rate.aspirate = 50 | ||
pip.flow_rate.dispense = 150 | ||
pip.flow_rate.blow_out = 300 | ||
|
||
def resuspend_pellet(vol: float, plate: Well, reps: int = 3) -> None: | ||
"""Re-suspend pellets.""" | ||
pip.flow_rate.aspirate = 200 | ||
pip.flow_rate.dispense = 300 | ||
|
||
loc1 = plate.bottom().move(types.Point(x=1, y=0, z=1)) | ||
loc2 = plate.bottom().move(types.Point(x=0.75, y=0.75, z=1)) | ||
loc3 = plate.bottom().move(types.Point(x=0, y=1, z=1)) | ||
loc4 = plate.bottom().move(types.Point(x=-0.75, y=0.75, z=1)) | ||
loc5 = plate.bottom().move(types.Point(x=-1, y=0, z=1)) | ||
loc6 = plate.bottom().move(types.Point(x=-0.75, y=0 - 0.75, z=1)) | ||
loc7 = plate.bottom().move(types.Point(x=0, y=-1, z=1)) | ||
loc8 = plate.bottom().move(types.Point(x=0.75, y=-0.75, z=1)) | ||
|
||
if vol > 1000: | ||
vol = 1000 | ||
|
||
mixvol = vol * 0.9 | ||
|
||
for _ in range(reps): | ||
pip.aspirate(mixvol, loc1) | ||
pip.dispense(mixvol, loc1) | ||
pip.aspirate(mixvol, loc2) | ||
pip.dispense(mixvol, loc2) | ||
pip.aspirate(mixvol, loc3) | ||
pip.dispense(mixvol, loc3) | ||
pip.aspirate(mixvol, loc4) | ||
pip.dispense(mixvol, loc4) | ||
pip.aspirate(mixvol, loc5) | ||
pip.dispense(mixvol, loc5) | ||
pip.aspirate(mixvol, loc6) | ||
pip.dispense(mixvol, loc6) | ||
pip.aspirate(mixvol, loc7) | ||
pip.dispense(mixvol, loc7) | ||
pip.aspirate(mixvol, loc8) | ||
pip.dispense(mixvol, loc8) | ||
if _ == reps - 1: | ||
pip.flow_rate.aspirate = 50 | ||
pip.flow_rate.dispense = 30 | ||
pip.aspirate(mixvol, loc8) | ||
pip.dispense(mixvol, loc8) | ||
|
||
pip.flow_rate.aspirate = 150 | ||
pip.flow_rate.dispense = 200 | ||
|
||
def bead_mix(vol: float, plate: Well, reps: int = 5) -> None: | ||
"""Bead mix.""" | ||
pip.flow_rate.aspirate = 200 | ||
pip.flow_rate.dispense = 300 | ||
|
||
loc1 = plate.bottom().move(types.Point(x=0, y=0, z=1)) | ||
loc2 = plate.bottom().move(types.Point(x=0, y=0, z=8)) | ||
loc3 = plate.bottom().move(types.Point(x=0, y=0, z=16)) | ||
loc4 = plate.bottom().move(types.Point(x=0, y=0, z=24)) | ||
|
||
if vol > 1000: | ||
vol = 1000 | ||
|
||
mixvol = vol * 0.9 | ||
|
||
for _ in range(reps): | ||
pip.aspirate(mixvol, loc1) | ||
pip.dispense(mixvol, loc1) | ||
pip.aspirate(mixvol, loc1) | ||
pip.dispense(mixvol, loc2) | ||
pip.aspirate(mixvol, loc1) | ||
pip.dispense(mixvol, loc3) | ||
pip.aspirate(mixvol, loc1) | ||
pip.dispense(mixvol, loc4) | ||
if _ == reps - 1: | ||
pip.flow_rate.aspirate = 50 | ||
pip.flow_rate.dispense = 30 | ||
pip.aspirate(mixvol, loc1) | ||
pip.dispense(mixvol, loc1) | ||
|
||
pip.flow_rate.aspirate = 150 | ||
pip.flow_rate.dispense = 200 | ||
|
||
# Start Protocol | ||
temp.set_temperature(inc_temp) | ||
# Transfer and mix lysis | ||
pip.pick_up_tip(tips) | ||
pip.aspirate(AL_total_vol, lysis_res) | ||
pip.dispense(AL_total_vol, samples_m) | ||
resuspend_pellet(400, samples_m, reps=4 if not dry_run else 1) | ||
if not tip_mixing: | ||
pip.return_tip() | ||
|
||
# Mix, then heat | ||
ctx.comment("Lysis Mixing") | ||
helpers.set_hs_speed(ctx, h_s, 1800, 10, False) | ||
if not dry_run: | ||
h_s.set_and_wait_for_temperature(55) | ||
ctx.delay( | ||
minutes=10 if not dry_run else 0.25, | ||
msg="Please allow another 10 minutes of 55C incubation to complete lysis.", | ||
) | ||
h_s.deactivate_shaker() | ||
|
||
# Transfer and mix bind&beads | ||
pip.pick_up_tip(tips) | ||
bead_mix(binding_buffer_vol, bind_res, reps=4 if not dry_run else 1) | ||
pip.aspirate(binding_buffer_vol, bind_res) | ||
pip.dispense(binding_buffer_vol, samples_m) | ||
bead_mix(binding_buffer_vol + starting_vol, samples_m, reps=4 if not dry_run else 1) | ||
if not tip_mixing: | ||
pip.return_tip() | ||
pip.home() | ||
|
||
# Shake for binding incubation | ||
ctx.comment("Binding incubation") | ||
helpers.set_hs_speed(ctx, h_s, 1800, 10, True) | ||
|
||
# Transfer plate to magnet | ||
helpers.move_labware_from_hs_to_destination(ctx, sample_plate, h_s, magblock) | ||
|
||
ctx.delay( | ||
minutes=settling_time, | ||
msg="Please wait " + str(settling_time) + " minute(s) for beads to pellet.", | ||
) | ||
|
||
# Remove Supernatant and move off magnet | ||
pip.pick_up_tip(tips) | ||
pip.aspirate(1000, samples_m.bottom(dot_bottom)) | ||
pip.dispense(1000, waste) | ||
if starting_vol + binding_buffer_vol > 1000: | ||
pip.aspirate(1000, samples_m.bottom(dot_bottom)) | ||
pip.dispense(1000, waste) | ||
pip.return_tip() | ||
|
||
# Transfer plate from magnet to H/S | ||
helpers.move_labware_to_hs(ctx, sample_plate, h_s, h_s_adapter) | ||
|
||
# Washes | ||
for i in range(num_washes if not dry_run else 1): | ||
if i == 0 or i == 1: | ||
wash_res = wash1_res | ||
else: | ||
wash_res = wash2_res | ||
|
||
pip.pick_up_tip(tips) | ||
pip.aspirate(wash_vol, wash_res) | ||
pip.dispense(wash_vol, samples_m) | ||
if not tip_mixing: | ||
pip.return_tip() | ||
helpers.set_hs_speed(ctx, h_s, 1800, 5, True) | ||
|
||
# Transfer plate to magnet | ||
helpers.move_labware_from_hs_to_destination(ctx, sample_plate, h_s, magblock) | ||
|
||
ctx.delay( | ||
minutes=settling_time, | ||
msg="Please wait " + str(settling_time) + " minute(s) for beads to pellet.", | ||
) | ||
|
||
# Remove Supernatant and move off magnet | ||
pip.pick_up_tip(tips) | ||
pip.aspirate(1000, samples_m.bottom(dot_bottom)) | ||
pip.dispense(1000, bind_res.top()) | ||
if wash_vol > 1000: | ||
pip.aspirate(1000, samples_m.bottom(dot_bottom)) | ||
pip.dispense(1000, bind_res.top()) | ||
pip.return_tip() | ||
|
||
# Transfer plate from magnet to H/S | ||
helpers.move_labware_to_hs(ctx, sample_plate, h_s, h_s_adapter) | ||
|
||
# Dry beads | ||
if dry_run: | ||
drybeads = 0.5 | ||
else: | ||
drybeads = 10 | ||
# Number of minutes you want to dry for | ||
for beaddry in np.arange(drybeads, 0, -0.5): | ||
ctx.delay( | ||
minutes=0.5, | ||
msg="There are " + str(beaddry) + " minutes left in the drying step.", | ||
) | ||
|
||
# Elution | ||
pip.pick_up_tip(tips1) | ||
pip.aspirate(elution_vol, elution_res) | ||
pip.dispense(elution_vol, samples_m) | ||
resuspend_pellet(elution_vol, samples_m, reps=3 if not dry_run else 1) | ||
if not tip_mixing: | ||
pip.return_tip() | ||
pip.home() | ||
|
||
helpers.set_hs_speed(ctx, h_s, 2000, 5, True) | ||
|
||
# Transfer plate to magnet | ||
helpers.move_labware_from_hs_to_destination(ctx, sample_plate, h_s, magblock) | ||
|
||
ctx.delay( | ||
minutes=settling_time, | ||
msg="Please wait " + str(settling_time) + " minute(s) for beads to pellet.", | ||
) | ||
|
||
pip.pick_up_tip(tips1) | ||
pip.aspirate(elution_vol, samples_m) | ||
pip.dispense(elution_vol, elutionplate.wells()[0]) | ||
pip.return_tip() | ||
|
||
pip.home() | ||
pip.reset_tipracks() | ||
|
||
# Empty Plates | ||
pip.pick_up_tip() | ||
pip.aspirate(1000, samples_m) | ||
pip.dispense(1000, liquid_waste["A1"].top()) | ||
pip.aspirate(1000, wash1_res) | ||
pip.dispense(1000, liquid_waste["A1"].top()) | ||
pip.aspirate(1000, wash2_res) | ||
pip.dispense(1000, liquid_waste["A1"].top()) | ||
pip.return_tip() | ||
helpers.find_liquid_height_of_all_wells(ctx, pip, [liquid_waste["A1"]]) |
Oops, something went wrong.