Week 3 HW:Lab Automation

from opentrons import types

metadata = { # see https://docs.opentrons.com/v2/tutorial.html#tutorial-metadata ‘author’: ‘Sebastian Rios’, ‘protocolName’: ‘Say My Name’, ‘description’: ‘I am not in danger, I am the DANGER ‘, ‘source’: ‘HTGAA 2026 Opentrons Lab’, ‘apiLevel’: ‘2.20’ }

##############################################################################

Robot deck setup constants - don’t change these

##############################################################################

TIP_RACK_DECK_SLOT = 9 COLORS_DECK_SLOT = 6 AGAR_DECK_SLOT = 5 PIPETTE_STARTING_TIP_WELL = ‘A1’

well_colors = { ‘A1’ : ‘Red’, ‘B1’ : ‘Green1’, ‘D1’ : ‘Green2’, ‘C1’ : ‘Orange’ }

def run(protocol): ##############################################################################

Load labware, modules and pipettes

##############################################################################

Tips

tips_20ul = protocol.load_labware(‘opentrons_96_tiprack_20ul’, TIP_RACK_DECK_SLOT, ‘Opentrons 20uL Tips’)

Pipettes

pipette_20ul = protocol.load_instrument(“p20_single_gen2”, “right”, [tips_20ul])

Modules

temperature_module = protocol.load_module(’temperature module gen2’, COLORS_DECK_SLOT)

Temperature Module Plate

temperature_plate = temperature_module.load_labware(‘opentrons_96_aluminumblock_generic_pcr_strip_200ul’, ‘Cold Plate’)

Choose where to take the colors from

color_plate = temperature_plate

Agar Plate

agar_plate = protocol.load_labware(‘htgaa_agar_plate’, AGAR_DECK_SLOT, ‘Agar Plate’) ## TA MUST CALIBRATE EACH PLATE!

Get the top-center of the plate, make sure the plate was calibrated before running this

center_location = agar_plate[‘A1’].top()

pipette_20ul.starting_tip = tips_20ul.well(PIPETTE_STARTING_TIP_WELL)

##############################################################################

Patterning

##############################################################################

Helper functions for this lab

pass this e.g. ‘Red’ and get back a Location which can be passed to aspirate()

def location_of_color(color_string): for well,color in well_colors.items(): if color.lower() == color_string.lower(): return color_plate[well] raise ValueError(f"No well found with color {color_string}")

For this lab, instead of calling pipette.dispense(1, loc) use this: dispense_and_detach(pipette, 1, loc)

def dispense_and_detach(pipette, volume, location): """ Move laterally 5mm above the plate (to avoid smearing a drop); then drop down to the plate, dispense, move back up 5mm to detach drop, and stay high to be ready for next lateral move. 5mm because a 4uL drop is 2mm diameter; and a 2deg tilt in the agar pour is >3mm difference across a plate. """ assert(isinstance(volume, (int, float))) above_location = location.move(types.Point(z=location.point.z + 5)) # 5mm above pipette.move_to(above_location) # Go to 5mm above the dispensing location pipette.dispense(volume, location) # Go straight downwards and dispense pipette.move_to(above_location) # Go straight up to detach drop and stay high

###########################################################################

Fluorescent pattern

###########################################################################

sfgfp_points = [(-16.5, 31.9),(-14.3, 31.9),(-12.1, 31.9),(-9.9, 31.9),(-7.7, 31.9),(-5.5, 31.9),(-3.3, 31.9),(-1.1, 31.9),(1.1, 31.9),(3.3, 31.9),(5.5, 31.9),(7.7, 31.9),(9.9, 31.9),(12.1, 31.9),(14.3, 31.9),(16.5, 31.9),(-18.7, 29.7),(-16.5, 29.7),(-14.3, 29.7),(-12.1, 29.7),(-9.9, 29.7),(-7.7, 29.7),(-5.5, 29.7),(-3.3, 29.7),(-1.1, 29.7),(1.1, 29.7),(3.3, 29.7),(5.5, 29.7),(7.7, 29.7),(9.9, 29.7),(12.1, 29.7),(14.3, 29.7),(16.5, 29.7),(-18.7, 27.5),(-16.5, 27.5),(-14.3, 27.5),(-12.1, 27.5),(-9.9, 27.5),(-7.7, 27.5),(-5.5, 27.5),(-3.3, 27.5),(-1.1, 27.5),(1.1, 27.5),(3.3, 27.5),(5.5, 27.5),(7.7, 27.5),(9.9, 27.5),(12.1, 27.5),(14.3, 27.5),(16.5, 27.5),(18.7, 27.5),(-20.9, 25.3),(-18.7, 25.3),(-16.5, 25.3),(-14.3, 25.3),(-12.1, 25.3),(-9.9, 25.3),(-7.7, 25.3),(-5.5, 25.3),(-3.3, 25.3),(-1.1, 25.3),(1.1, 25.3),(3.3, 25.3),(5.5, 25.3),(7.7, 25.3),(9.9, 25.3),(12.1, 25.3),(14.3, 25.3),(16.5, 25.3),(18.7, 25.3),(20.9, 25.3),(-20.9, 23.1),(-18.7, 23.1),(-16.5, 23.1),(-14.3, 23.1),(-12.1, 23.1),(-9.9, 23.1),(-7.7, 23.1),(-5.5, 23.1),(-3.3, 23.1),(-1.1, 23.1),(1.1, 23.1),(3.3, 23.1),(5.5, 23.1),(7.7, 23.1),(9.9, 23.1),(12.1, 23.1),(14.3, 23.1),(16.5, 23.1),(18.7, 23.1),(20.9, 23.1),(-23.1, 20.9),(-20.9, 20.9),(-18.7, 20.9),(-16.5, 20.9),(-14.3, 20.9),(-12.1, 20.9),(-9.9, 20.9),(-7.7, 20.9),(-5.5, 20.9),(-3.3, 20.9),(-1.1, 20.9),(1.1, 20.9),(3.3, 20.9),(5.5, 20.9),(7.7, 20.9),(9.9, 20.9),(12.1, 20.9),(14.3, 20.9),(16.5, 20.9),(18.7, 20.9),(20.9, 20.9),(-34.1, 18.7),(-31.9, 18.7),(-23.1, 18.7),(-20.9, 18.7),(-18.7, 18.7),(-16.5, 18.7),(-14.3, 18.7),(-12.1, 18.7),(-9.9, 18.7),(-7.7, 18.7),(-5.5, 18.7),(-3.3, 18.7),(-1.1, 18.7),(1.1, 18.7),(3.3, 18.7),(5.5, 18.7),(7.7, 18.7),(9.9, 18.7),(12.1, 18.7),(14.3, 18.7),(16.5, 18.7),(18.7, 18.7),(20.9, 18.7),(23.1, 18.7),(34.1, 18.7),(-34.1, 16.5),(-31.9, 16.5),(-29.7, 16.5),(-27.5, 16.5),(-25.3, 16.5),(-23.1, 16.5),(-20.9, 16.5),(-18.7, 16.5),(-16.5, 16.5),(-14.3, 16.5),(-12.1, 16.5),(-9.9, 16.5),(-7.7, 16.5),(-5.5, 16.5),(-3.3, 16.5),(-1.1, 16.5),(1.1, 16.5),(3.3, 16.5),(5.5, 16.5),(7.7, 16.5),(9.9, 16.5),(12.1, 16.5),(14.3, 16.5),(16.5, 16.5),(18.7, 16.5),(20.9, 16.5),(23.1, 16.5),(25.3, 16.5),(27.5, 16.5),(29.7, 16.5),(31.9, 16.5),(34.1, 16.5),(-34.1, 14.3),(-31.9, 14.3),(-29.7, 14.3),(-27.5, 14.3),(-25.3, 14.3),(-23.1, 14.3),(-20.9, 14.3),(-18.7, 14.3),(-16.5, 14.3),(-14.3, 14.3),(-12.1, 14.3),(-9.9, 14.3),(-7.7, 14.3),(-5.5, 14.3),(-3.3, 14.3),(-1.1, 14.3),(1.1, 14.3),(3.3, 14.3),(5.5, 14.3),(7.7, 14.3),(9.9, 14.3),(12.1, 14.3),(14.3, 14.3),(16.5, 14.3),(18.7, 14.3),(20.9, 14.3),(23.1, 14.3),(25.3, 14.3),(27.5, 14.3),(29.7, 14.3),(31.9, 14.3),(34.1, 14.3),(-29.7, 12.1),(-27.5, 12.1),(-25.3, 12.1),(-23.1, 12.1),(-20.9, 12.1),(-18.7, 12.1),(-16.5, 12.1),(-14.3, 12.1),(-12.1, 12.1),(-9.9, 12.1),(-7.7, 12.1),(-5.5, 12.1),(-3.3, 12.1),(-1.1, 12.1),(1.1, 12.1),(3.3, 12.1),(5.5, 12.1),(7.7, 12.1),(9.9, 12.1),(12.1, 12.1),(14.3, 12.1),(16.5, 12.1),(18.7, 12.1),(20.9, 12.1),(23.1, 12.1),(25.3, 12.1),(27.5, 12.1),(29.7, 12.1),(31.9, 12.1),(34.1, 12.1),(-23.1, 9.9),(-20.9, 9.9),(20.9, 9.9),(23.1, 9.9),(-23.1, 7.7),(23.1, 7.7),(-23.1, 5.5),(-20.9, 5.5),(20.9, 5.5),(23.1, 5.5),(-25.3, -5.5),(-23.1, -7.7),(20.9, -7.7),(-23.1, -9.9),(-20.9, -9.9),(20.9, -9.9),(-23.1, -12.1),(20.9, -12.1),(-20.9, -14.3),(20.9, -14.3),(-20.9, -16.5),(-7.7, -16.5),(7.7, -16.5),(20.9, -16.5),(-9.9, -18.7),(9.9, -18.7),(18.7, -18.7),(-18.7, -20.9),(14.3, -20.9),(18.7, -20.9),(-16.5, -23.1),(-12.1, -23.1),(14.3, -23.1),(-14.3, -25.3),(-9.9, -25.3),(12.1, -25.3),(16.5, -25.3),(-12.1, -27.5),(-7.7, -27.5),(-12.1, -29.7),(-9.9, -31.9),(9.9, -31.9),(12.1, -31.9),(-7.7, -34.1),(-5.5, -34.1),(-3.3, -34.1),(5.5, -34.1),(7.7, -34.1),(-1.1, -36.3),(1.1, -36.3),(3.3, -36.3)] # Green1 mwasabi_points = [(-14.3, 9.9),(-12.1, 7.7),(-9.9, 7.7),(-7.7, 7.7),(-5.5, 7.7),(-3.3, 7.7),(-1.1, 7.7),(1.1, 7.7),(3.3, 7.7),(5.5, 7.7),(7.7, 7.7),(9.9, 7.7),(9.9, 5.5),(12.1, 5.5),(-1.1, -1.1),(1.1, -1.1),(-1.1, -3.3),(1.1, -3.3),(-1.1, -5.5),(1.1, -5.5),(-3.3, -7.7),(3.3, -7.7),(-3.3, -9.9),(3.3, -9.9),(-5.5, -12.1),(5.5, -12.1),(-5.5, -14.3),(-3.3, -14.3),(3.3, -14.3),(5.5, -14.3),(-1.1, -16.5),(1.1, -16.5),(-7.7, -18.7),(-5.5, -18.7),(-3.3, -18.7),(3.3, -18.7),(5.5, -18.7),(7.7, -18.7),(-9.9, -20.9),(-7.7, -20.9),(-5.5, -20.9),(-3.3, -20.9),(-1.1, -20.9),(1.1, -20.9),(3.3, -20.9),(5.5, -20.9),(7.7, -20.9),(9.9, -20.9),(-5.5, -25.3),(-3.3, -25.3),(-1.1, -25.3),(1.1, -25.3),(3.3, -25.3),(5.5, -25.3)] # Red azurite_points = [(-25.3, 3.3),(-23.1, 3.3),(-20.9, 3.3),(-18.7, 3.3),(-16.5, 3.3),(-14.3, 3.3),(-12.1, 3.3),(-9.9, 3.3),(-7.7, 3.3),(-5.5, 3.3),(-3.3, 3.3),(-1.1, 3.3),(1.1, 3.3),(3.3, 3.3),(5.5, 3.3),(7.7, 3.3),(9.9, 3.3),(12.1, 3.3),(14.3, 3.3),(16.5, 3.3),(18.7, 3.3),(20.9, 3.3),(23.1, 3.3),(25.3, 3.3),(-25.3, 1.1),(-23.1, 1.1),(-20.9, 1.1),(-18.7, 1.1),(-16.5, 1.1),(-14.3, 1.1),(-12.1, 1.1),(-9.9, 1.1),(-7.7, 1.1),(-5.5, 1.1),(-3.3, 1.1),(-1.1, 1.1),(1.1, 1.1),(3.3, 1.1),(5.5, 1.1),(7.7, 1.1),(9.9, 1.1),(12.1, 1.1),(14.3, 1.1),(16.5, 1.1),(18.7, 1.1),(20.9, 1.1),(23.1, 1.1),(25.3, 1.1),(-27.5, -1.1),(-25.3, -1.1),(-23.1, -1.1),(-20.9, -1.1),(-18.7, -1.1),(-16.5, -1.1),(-14.3, -1.1),(-12.1, -1.1),(-9.9, -1.1),(-7.7, -1.1),(-5.5, -1.1),(-3.3, -1.1),(3.3, -1.1),(5.5, -1.1),(7.7, -1.1),(9.9, -1.1),(12.1, -1.1),(14.3, -1.1),(16.5, -1.1),(18.7, -1.1),(20.9, -1.1),(23.1, -1.1),(-25.3, -3.3),(-23.1, -3.3),(-20.9, -3.3),(-18.7, -3.3),(-16.5, -3.3),(-14.3, -3.3),(-12.1, -3.3),(-9.9, -3.3),(-7.7, -3.3),(-5.5, -3.3),(-3.3, -3.3),(3.3, -3.3),(5.5, -3.3),(7.7, -3.3),(9.9, -3.3),(12.1, -3.3),(14.3, -3.3),(16.5, -3.3),(18.7, -3.3),(20.9, -3.3),(23.1, -3.3),(-23.1, -5.5),(-20.9, -5.5),(-18.7, -5.5),(-16.5, -5.5),(-14.3, -5.5),(-12.1, -5.5),(-9.9, -5.5),(-7.7, -5.5),(-5.5, -5.5),(-3.3, -5.5),(5.5, -5.5),(7.7, -5.5),(9.9, -5.5),(12.1, -5.5),(14.3, -5.5),(16.5, -5.5),(18.7, -5.5),(20.9, -5.5),(-20.9, -7.7),(-18.7, -7.7),(-16.5, -7.7),(-14.3, -7.7),(-12.1, -7.7),(-9.9, -7.7),(-7.7, -7.7),(-5.5, -7.7),(7.7, -7.7),(9.9, -7.7),(12.1, -7.7),(14.3, -7.7),(16.5, -7.7),(18.7, -7.7),(-18.7, -9.9),(-16.5, -9.9),(-14.3, -9.9),(-12.1, -9.9),(-9.9, -9.9),(-7.7, -9.9),(7.7, -9.9),(9.9, -9.9),(12.1, -9.9),(14.3, -9.9),(16.5, -9.9)] # Orange mclover3_points = [(-5.5, -9.9),(-18.7, -18.7),(18.7, -23.1),(16.5, -27.5),(14.3, -29.7)] # Green2

pattern_map = [ (“Green1”, sfgfp_points), (“Red”, mwasabi_points), (“Orange”, azurite_points), (“Green2”, mclover3_points) ]

pipette_20ul.pick_up_tip()

for color_name, points in pattern_map: pipette_20ul.pick_up_tip() for (x_offset, y_offset) in points:

      pipette_20ul.aspirate(1, location_of_color(color_name))

      target_location = center_location.move(
          types.Point(x=x_offset, y=y_offset)
      )

      dispense_and_detach(pipette_20ul, 1, target_location)

pipette_20ul.drop_tip()