Skip to content

Commit 57a59b6

Browse files
committed
updates for abr1, abr2, abr3, abr4, abr8, reverted abr12
1 parent c83dd09 commit 57a59b6

10 files changed

+652
-369
lines changed

abr-testing/abr_testing/protocols/active_protocols/12_KAPA HyperPlus Library Prep.py

+309-84
Large diffs are not rendered by default.

abr-testing/abr_testing/protocols/active_protocols/2_BMS_PCR_Protocol.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
ThermocyclerContext,
66
TemperatureModuleContext,
77
)
8-
from opentrons.protocol_api import SINGLE, Well
8+
from opentrons.protocol_api import SINGLE, Well, ALL
99
from abr_testing.protocols import helpers
1010
from typing import List, Dict
1111

@@ -206,6 +206,7 @@ def run(ctx: ProtocolContext) -> None:
206206
p50.configure_nozzle_layout(style=SINGLE, start="A1", tip_racks=tiprack_50)
207207
mmx_pic.append(water)
208208
# Empty plates into liquid waste
209+
p50.configure_nozzle_layout(style=ALL, tip_racks=tiprack_50)
209210
helpers.clean_up_plates(p50, [source_plate_1, dest_plate_1], liquid_waste, 50)
210211
# Probe liquid waste
211212
helpers.find_liquid_height_of_all_wells(ctx, p50, [liquid_waste])

abr-testing/abr_testing/protocols/active_protocols/3_Tartrazine Protocol.py

+107-56
Original file line numberDiff line numberDiff line change
@@ -32,110 +32,160 @@ def add_parameters(parameters: ParameterContext) -> None:
3232
minimum=1,
3333
maximum=4,
3434
)
35+
helpers.create_channel_parameter(parameters)
3536

3637

3738
def run(ctx: ProtocolContext) -> None:
3839
"""Protocol."""
40+
# Load parameters
3941
number_of_plates = ctx.params.number_of_plates # type: ignore [attr-defined]
42+
channels = ctx.params.channels # type: ignore [attr-defined]
4043
# Plate Reader
4144
plate_reader: AbsorbanceReaderContext = ctx.load_module(
4245
helpers.abs_mod_str, "A3"
4346
) # type: ignore[assignment]
4447
hs: HeaterShakerContext = ctx.load_module(helpers.hs_str, "A1") # type: ignore[assignment]
4548
hs_adapter = hs.load_adapter("opentrons_universal_flat_adapter")
46-
tube_rack = ctx.load_labware(
47-
"opentrons_10_tuberack_nest_4x50ml_6x15ml_conical", "C2", "Reagent Tube"
48-
)
49-
tartrazine_tube = tube_rack["A1"]
50-
water_tube_1 = tube_rack["A4"]
51-
water_tube_2 = tube_rack["B3"]
52-
sample_plate_1 = ctx.load_labware(
53-
"corning_96_wellplate_360ul_flat", "D1", "Sample Plate 1"
54-
)
55-
sample_plate_2 = ctx.load_labware(
56-
"corning_96_wellplate_360ul_flat", "D2", "Sample Plate 2"
57-
)
58-
sample_plate_3 = ctx.load_labware(
59-
"corning_96_wellplate_360ul_flat", "C1", "Sample Plate 3"
60-
)
61-
sample_plate_4 = ctx.load_labware(
62-
"corning_96_wellplate_360ul_flat", "B1", "Sample Plate 4"
63-
)
64-
65-
sample_plate_list = [sample_plate_1, sample_plate_2, sample_plate_3, sample_plate_4]
66-
tiprack_50_1 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "D3")
67-
tiprack_50_2 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "C3")
68-
tiprack_50_3 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "B3")
69-
tiprack_50_4 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", "B2")
70-
49+
# Load Plates based off of number_of_plates parameter
50+
available_deck_slots = ["D1", "D2", "C1", "B1"]
51+
sample_plate_list = []
52+
for plate_num, slot in zip(range(number_of_plates), available_deck_slots):
53+
plate = ctx.load_labware(
54+
"corning_96_wellplate_360ul_flat", slot, f"Sample Plate {plate_num + 1}"
55+
)
56+
sample_plate_list.append(plate)
57+
available_tip_rack_slots = ["D3", "C3", "B3", "B2"]
58+
# LOAD PIPETTES AND TIP RACKS
59+
# 50 CHANNEL
60+
tip_racks_50 = []
61+
for plate_num, slot_2 in zip(range(number_of_plates), available_tip_rack_slots):
62+
tiprack_50 = ctx.load_labware("opentrons_flex_96_tiprack_50ul", slot_2)
63+
tip_racks_50.append(tiprack_50)
64+
p50 = ctx.load_instrument(f"flex_{channels}_50", "left", tip_racks=tip_racks_50)
65+
# 1000 CHANNEL
7166
tiprack_1000_1 = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "A2")
72-
tip_racks = [tiprack_50_1, tiprack_50_2, tiprack_50_3, tiprack_50_4]
73-
74-
# Pipette
75-
p50 = ctx.load_instrument("flex_1channel_50", "left", tip_racks=tip_racks)
7667
p1000 = ctx.load_instrument(
77-
"flex_1channel_1000", "right", tip_racks=[tiprack_1000_1]
68+
f"flex_{channels}_1000", "right", tip_racks=[tiprack_1000_1]
7869
)
70+
# DETERMINE RESERVOIR BASED OFF # OF PIPETTE CHANNELS
71+
# 1 CHANNEL = TUBE RACK
72+
if p50.active_channels == 1:
73+
reservoir = ctx.load_labware(
74+
"opentrons_10_tuberack_nest_4x50ml_6x15ml_conical", "C2", "Reservoir"
75+
)
76+
water_max_vol = reservoir["A3"].max_volume - 500
77+
reservoir_wells = reservoir.wells()[6:] # Skip first 4 bc they are 15ml
78+
else:
79+
# 8 CHANNEL = 12 WELL RESERVOIR
80+
reservoir = ctx.load_labware("nest_12_reservoir_15ml", "C2", "Reservoir")
81+
water_max_vol = reservoir["A1"].max_volume - 500
82+
reservoir_wells = reservoir.wells()[
83+
1:
84+
] # Skip A1 as it's reserved for tartrazine
85+
86+
# LABEL RESERVOIR WELLS AND DETERMINE NEEDED LIQUID
87+
tartrazine_well = reservoir["A1"]
88+
# NEEDED TARTRAZINE
89+
needed_tartrazine: float = (
90+
float(number_of_plates) * 96.0
91+
) * 10.0 + 1000.0 # loading extra as a safety factor
92+
# NEEDED WATER
93+
needed_water: float = (
94+
float(number_of_plates) * 96.0 * 250
95+
) # loading extra as a safety factor
96+
# CALCULATING NEEDED # OF WATER WELLS
97+
needed_wells = round(needed_water / water_max_vol)
98+
water_wells = []
99+
for i in range(needed_wells + 1):
100+
water_wells.append(reservoir_wells[i])
79101

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

89-
# Probe wells
112+
# LOAD LIQUIDS AND PROBE WELLS
90113
liquid_vols_and_wells: Dict[str, List[Dict[str, Well | List[Well] | float]]] = {
91-
"Tartrazine": [{"well": tartrazine_tube, "volume": 5.0}],
92-
"Water": [{"well": [water_tube_1, water_tube_2], "volume": 45.0}],
114+
"Tartrazine": [{"well": tartrazine_well, "volume": needed_tartrazine}],
115+
"Water": [{"well": water_wells, "volume": water_max_vol}],
93116
}
94117
helpers.find_liquid_height_of_loaded_liquids(ctx, liquid_vols_and_wells, p50)
95-
118+
tip_count = 1 * p50.active_channels # number of 50 ul tip uses.
119+
p50.reset_tipracks()
96120
i = 0
97121
all_percent_error_dict = {}
98122
cv_dict = {}
99-
vol = 0.0
100-
tip_count = 0
123+
vol = 0.0 # counter to track available water volume
124+
water_tip_count = 0 * p1000.active_channels # number of 1000 ul tip uses
125+
well_num = 0 # index of well being used for water
101126
for sample_plate in sample_plate_list[:number_of_plates]:
102-
_mix_tartrazine(p50, tartrazine_tube)
103-
tip_count += 1
104-
deck_locations = ["D1", "D2", "C1", "B1"]
105-
p1000.pick_up_tip()
106-
for well in sample_plate.wells():
107-
if vol < 45000:
108-
tube_of_choice = water_tube_1
127+
return_location = sample_plate.parent
128+
# Mix Tartrazine to ensure no settling as occurred
129+
_mix_tartrazine(p50, tartrazine_well)
130+
tip_count += 1 * p50.active_channels
131+
# Determine list of wells to probe
132+
if p50.active_channels == 1:
133+
well_list = sample_plate.wells()
134+
elif p50.active_channels == 8:
135+
well_list = sample_plate.rows()[0]
136+
for well in well_list:
137+
p1000.pick_up_tip()
138+
# Determine which water well to aspirate from.
139+
if vol < water_max_vol - 6000:
140+
well_of_choice = water_wells[well_num]
109141
else:
110-
tube_of_choice = water_tube_2
142+
well_num += 1
143+
well_of_choice = water_wells[well_num]
144+
vol = 0.0
111145
p50.pick_up_tip()
112-
p1000.aspirate(190, tube_of_choice)
146+
p1000.aspirate(190, well_of_choice)
113147
p1000.air_gap(10)
114-
p1000.dispense(5, well.top())
148+
p1000.dispense(10, well.top())
115149
p1000.dispense(190, well)
116-
vol += 190
117-
height = helpers.find_liquid_height(p50, tartrazine_tube)
118-
p50.aspirate(10, tartrazine_tube.bottom(z=height), rate=0.15)
150+
# Two blow outs ensures water is completely removed from pipette
151+
p1000.blow_out(well.top())
152+
ctx.delay(minutes=0.1)
153+
p1000.blow_out(well.top())
154+
vol += 190 * p1000.active_channels
155+
# Probe to find liquid height of tartrazine to ensure correct amount is aspirated
156+
height = helpers.find_liquid_height(p50, tartrazine_well)
157+
p50.aspirate(10, tartrazine_well.bottom(z=height), rate=0.15)
119158
p50.air_gap(5)
120159
p50.dispense(5, well.top())
121160
p50.dispense(10, well.bottom(z=0.5), rate=0.15)
122161
p50.blow_out()
162+
ctx.delay(minutes=0.1)
163+
p50.blow_out()
123164
p50.return_tip()
124-
tip_count += 1
125-
if tip_count >= (96 * 4):
165+
tip_count += p50.active_channels
166+
if tip_count >= (96 * len(tip_racks_50)):
126167
p50.reset_tipracks()
127-
p1000.return_tip()
168+
tip_count = 0
169+
p1000.return_tip()
170+
water_tip_count += p1000.active_channels
171+
if water_tip_count >= 96:
172+
p1000.reset_tipracks()
173+
water_tip_count = 0
174+
# Move labware to heater shaker to be mixed
128175
helpers.move_labware_to_hs(ctx, sample_plate, hs, hs_adapter)
129176
helpers.set_hs_speed(ctx, hs, 1500, 2.0, True)
130177
hs.open_labware_latch()
178+
# Initialize plate reader
131179
plate_reader.close_lid()
132180
plate_reader.initialize("single", [450])
133181
plate_reader.open_lid()
182+
# Move sample plate into plate reader
134183
ctx.move_labware(sample_plate, plate_reader, use_gripper=True)
135184
sample_plate_name = "sample plate_" + str(i + 1)
136185
csv_string = sample_plate_name + "_" + str(datetime.now())
137186
plate_reader.close_lid()
138187
result = plate_reader.read(csv_string)
188+
# Calculate CV and % error of expected value.
139189
for wavelength in result:
140190
dict_of_wells = result[wavelength]
141191
readings_and_wells = dict_of_wells.items()
@@ -163,12 +213,13 @@ def _mix_tartrazine(pipette: InstrumentContext, well_to_probe: Well) -> None:
163213
"SD": standard_deviation,
164214
"Avg Percent Error": avg_percent_error,
165215
}
166-
ctx.comment(f"------plate {sample_plate}. {cv_dict[sample_plate_name]}------")
216+
# Move Plate back to original location
167217
all_percent_error_dict[sample_plate_name] = percent_error_dict
168218
plate_reader.open_lid()
169-
ctx.move_labware(sample_plate, deck_locations[i], use_gripper=True)
219+
ctx.comment(f"------plate {sample_plate}. {cv_dict[sample_plate_name]}------")
220+
ctx.move_labware(sample_plate, return_location, use_gripper=True)
170221
i += 1
171222
# Print percent error dictionary
172223
ctx.comment("Percent Error: " + str(all_percent_error_dict))
173224
# Print cv dictionary
174-
ctx.comment("Plate Reader result: " + str(cv_dict))
225+
ctx.comment("Plate Reader Result: " + str(cv_dict))

0 commit comments

Comments
 (0)