Skip to content

Commit

Permalink
updates for abr1, abr2, abr3, abr4, abr8, reverted abr12
Browse files Browse the repository at this point in the history
  • Loading branch information
rclarke0 committed Dec 6, 2024
1 parent c83dd09 commit 57a59b6
Show file tree
Hide file tree
Showing 10 changed files with 652 additions and 369 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
ThermocyclerContext,
TemperatureModuleContext,
)
from opentrons.protocol_api import SINGLE, Well
from opentrons.protocol_api import SINGLE, Well, ALL
from abr_testing.protocols import helpers
from typing import List, Dict

Expand Down Expand Up @@ -206,6 +206,7 @@ def run(ctx: ProtocolContext) -> None:
p50.configure_nozzle_layout(style=SINGLE, start="A1", tip_racks=tiprack_50)
mmx_pic.append(water)
# Empty plates into liquid waste
p50.configure_nozzle_layout(style=ALL, tip_racks=tiprack_50)
helpers.clean_up_plates(p50, [source_plate_1, dest_plate_1], liquid_waste, 50)
# Probe liquid waste
helpers.find_liquid_height_of_all_wells(ctx, p50, [liquid_waste])
Original file line number Diff line number Diff line change
Expand Up @@ -32,110 +32,160 @@ def add_parameters(parameters: ParameterContext) -> None:
minimum=1,
maximum=4,
)
helpers.create_channel_parameter(parameters)


def run(ctx: ProtocolContext) -> None:
"""Protocol."""
# Load parameters
number_of_plates = ctx.params.number_of_plates # type: ignore [attr-defined]
channels = ctx.params.channels # type: ignore [attr-defined]
# Plate Reader
plate_reader: AbsorbanceReaderContext = ctx.load_module(
helpers.abs_mod_str, "A3"
) # type: ignore[assignment]
hs: HeaterShakerContext = ctx.load_module(helpers.hs_str, "A1") # type: ignore[assignment]
hs_adapter = hs.load_adapter("opentrons_universal_flat_adapter")
tube_rack = ctx.load_labware(
"opentrons_10_tuberack_nest_4x50ml_6x15ml_conical", "C2", "Reagent Tube"
)
tartrazine_tube = tube_rack["A1"]
water_tube_1 = tube_rack["A4"]
water_tube_2 = tube_rack["B3"]
sample_plate_1 = ctx.load_labware(
"corning_96_wellplate_360ul_flat", "D1", "Sample Plate 1"
)
sample_plate_2 = ctx.load_labware(
"corning_96_wellplate_360ul_flat", "D2", "Sample Plate 2"
)
sample_plate_3 = ctx.load_labware(
"corning_96_wellplate_360ul_flat", "C1", "Sample Plate 3"
)
sample_plate_4 = ctx.load_labware(
"corning_96_wellplate_360ul_flat", "B1", "Sample Plate 4"
)

sample_plate_list = [sample_plate_1, sample_plate_2, sample_plate_3, sample_plate_4]
tiprack_50_1 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "D3")
tiprack_50_2 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "C3")
tiprack_50_3 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "B3")
tiprack_50_4 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "B2")

# Load Plates based off of number_of_plates parameter
available_deck_slots = ["D1", "D2", "C1", "B1"]
sample_plate_list = []
for plate_num, slot in zip(range(number_of_plates), available_deck_slots):
plate = ctx.load_labware(
"corning_96_wellplate_360ul_flat", slot, f"Sample Plate {plate_num + 1}"
)
sample_plate_list.append(plate)
available_tip_rack_slots = ["D3", "C3", "B3", "B2"]
# LOAD PIPETTES AND TIP RACKS
# 50 CHANNEL
tip_racks_50 = []
for plate_num, slot_2 in zip(range(number_of_plates), available_tip_rack_slots):
tiprack_50 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", slot_2)
tip_racks_50.append(tiprack_50)
p50 = ctx.load_instrument(f"flex_{channels}_50", "left", tip_racks=tip_racks_50)
# 1000 CHANNEL
tiprack_1000_1 = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "A2")
tip_racks = [tiprack_50_1, tiprack_50_2, tiprack_50_3, tiprack_50_4]

# Pipette
p50 = ctx.load_instrument("flex_1channel_50", "left", tip_racks=tip_racks)
p1000 = ctx.load_instrument(
"flex_1channel_1000", "right", tip_racks=[tiprack_1000_1]
f"flex_{channels}_1000", "right", tip_racks=[tiprack_1000_1]
)
# DETERMINE RESERVOIR BASED OFF # OF PIPETTE CHANNELS
# 1 CHANNEL = TUBE RACK
if p50.active_channels == 1:
reservoir = ctx.load_labware(
"opentrons_10_tuberack_nest_4x50ml_6x15ml_conical", "C2", "Reservoir"
)
water_max_vol = reservoir["A3"].max_volume - 500
reservoir_wells = reservoir.wells()[6:] # Skip first 4 bc they are 15ml
else:
# 8 CHANNEL = 12 WELL RESERVOIR
reservoir = ctx.load_labware("nest_12_reservoir_15ml", "C2", "Reservoir")
water_max_vol = reservoir["A1"].max_volume - 500
reservoir_wells = reservoir.wells()[
1:
] # Skip A1 as it's reserved for tartrazine

# LABEL RESERVOIR WELLS AND DETERMINE NEEDED LIQUID
tartrazine_well = reservoir["A1"]
# NEEDED TARTRAZINE
needed_tartrazine: float = (
float(number_of_plates) * 96.0
) * 10.0 + 1000.0 # loading extra as a safety factor
# NEEDED WATER
needed_water: float = (
float(number_of_plates) * 96.0 * 250
) # loading extra as a safety factor
# CALCULATING NEEDED # OF WATER WELLS
needed_wells = round(needed_water / water_max_vol)
water_wells = []
for i in range(needed_wells + 1):
water_wells.append(reservoir_wells[i])

def _mix_tartrazine(pipette: InstrumentContext, well_to_probe: Well) -> None:
"""Mix Tartrazine."""
# Mix step is needed to ensure tartrazine does not settle between plates.
pipette.pick_up_tip()
top_of_tartrazine = helpers.find_liquid_height(pipette, well_to_probe)
for i in range(20):
p50.aspirate(1, well_to_probe.bottom(z=1))
p50.dispense(1, well_to_probe.bottom(z=top_of_tartrazine - 2))
p50.dispense(1, well_to_probe.bottom(z=top_of_tartrazine + 1))
pipette.return_tip()

# Probe wells
# LOAD LIQUIDS AND PROBE WELLS
liquid_vols_and_wells: Dict[str, List[Dict[str, Well | List[Well] | float]]] = {
"Tartrazine": [{"well": tartrazine_tube, "volume": 5.0}],
"Water": [{"well": [water_tube_1, water_tube_2], "volume": 45.0}],
"Tartrazine": [{"well": tartrazine_well, "volume": needed_tartrazine}],
"Water": [{"well": water_wells, "volume": water_max_vol}],
}
helpers.find_liquid_height_of_loaded_liquids(ctx, liquid_vols_and_wells, p50)

tip_count = 1 * p50.active_channels # number of 50 ul tip uses.
p50.reset_tipracks()
i = 0
all_percent_error_dict = {}
cv_dict = {}
vol = 0.0
tip_count = 0
vol = 0.0 # counter to track available water volume
water_tip_count = 0 * p1000.active_channels # number of 1000 ul tip uses
well_num = 0 # index of well being used for water
for sample_plate in sample_plate_list[:number_of_plates]:
_mix_tartrazine(p50, tartrazine_tube)
tip_count += 1
deck_locations = ["D1", "D2", "C1", "B1"]
p1000.pick_up_tip()
for well in sample_plate.wells():
if vol < 45000:
tube_of_choice = water_tube_1
return_location = sample_plate.parent
# Mix Tartrazine to ensure no settling as occurred
_mix_tartrazine(p50, tartrazine_well)
tip_count += 1 * p50.active_channels
# Determine list of wells to probe
if p50.active_channels == 1:
well_list = sample_plate.wells()
elif p50.active_channels == 8:
well_list = sample_plate.rows()[0]
for well in well_list:
p1000.pick_up_tip()
# Determine which water well to aspirate from.
if vol < water_max_vol - 6000:
well_of_choice = water_wells[well_num]
else:
tube_of_choice = water_tube_2
well_num += 1
well_of_choice = water_wells[well_num]
vol = 0.0
p50.pick_up_tip()
p1000.aspirate(190, tube_of_choice)
p1000.aspirate(190, well_of_choice)
p1000.air_gap(10)
p1000.dispense(5, well.top())
p1000.dispense(10, well.top())
p1000.dispense(190, well)
vol += 190
height = helpers.find_liquid_height(p50, tartrazine_tube)
p50.aspirate(10, tartrazine_tube.bottom(z=height), rate=0.15)
# Two blow outs ensures water is completely removed from pipette
p1000.blow_out(well.top())
ctx.delay(minutes=0.1)
p1000.blow_out(well.top())
vol += 190 * p1000.active_channels
# Probe to find liquid height of tartrazine to ensure correct amount is aspirated
height = helpers.find_liquid_height(p50, tartrazine_well)
p50.aspirate(10, tartrazine_well.bottom(z=height), rate=0.15)
p50.air_gap(5)
p50.dispense(5, well.top())
p50.dispense(10, well.bottom(z=0.5), rate=0.15)
p50.blow_out()
ctx.delay(minutes=0.1)
p50.blow_out()
p50.return_tip()
tip_count += 1
if tip_count >= (96 * 4):
tip_count += p50.active_channels
if tip_count >= (96 * len(tip_racks_50)):
p50.reset_tipracks()
p1000.return_tip()
tip_count = 0
p1000.return_tip()
water_tip_count += p1000.active_channels
if water_tip_count >= 96:
p1000.reset_tipracks()
water_tip_count = 0
# Move labware to heater shaker to be mixed
helpers.move_labware_to_hs(ctx, sample_plate, hs, hs_adapter)
helpers.set_hs_speed(ctx, hs, 1500, 2.0, True)
hs.open_labware_latch()
# Initialize plate reader
plate_reader.close_lid()
plate_reader.initialize("single", [450])
plate_reader.open_lid()
# Move sample plate into plate reader
ctx.move_labware(sample_plate, plate_reader, use_gripper=True)
sample_plate_name = "sample plate_" + str(i + 1)
csv_string = sample_plate_name + "_" + str(datetime.now())
plate_reader.close_lid()
result = plate_reader.read(csv_string)
# Calculate CV and % error of expected value.
for wavelength in result:
dict_of_wells = result[wavelength]
readings_and_wells = dict_of_wells.items()
Expand Down Expand Up @@ -163,12 +213,13 @@ def _mix_tartrazine(pipette: InstrumentContext, well_to_probe: Well) -> None:
"SD": standard_deviation,
"Avg Percent Error": avg_percent_error,
}
ctx.comment(f"------plate {sample_plate}. {cv_dict[sample_plate_name]}------")
# Move Plate back to original location
all_percent_error_dict[sample_plate_name] = percent_error_dict
plate_reader.open_lid()
ctx.move_labware(sample_plate, deck_locations[i], use_gripper=True)
ctx.comment(f"------plate {sample_plate}. {cv_dict[sample_plate_name]}------")
ctx.move_labware(sample_plate, return_location, use_gripper=True)
i += 1
# Print percent error dictionary
ctx.comment("Percent Error: " + str(all_percent_error_dict))
# Print cv dictionary
ctx.comment("Plate Reader result: " + str(cv_dict))
ctx.comment("Plate Reader Result: " + str(cv_dict))
Loading

0 comments on commit 57a59b6

Please sign in to comment.