Week 3 – Lab Automation

Opentrons Script from opentrons import types

metadata = { ‘protocolName’: ‘HTGAA Robotic Patterning - Misu Optimized Full’, ‘author’: ‘HTGAA Virtual Exercise’, ‘source’: ‘HTGAA 2022 Modified’, ‘apiLevel’: ‘2.20’ }

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

well_colors = { ‘A1’ : ‘Red’, ‘B1’ : ‘Yellow’, ‘C1’ : ‘Green’, ‘D1’ : ‘Cyan’, ‘E1’ : ‘Blue’ }

def run(protocol):

# -----------------------------
# Speed Optimization
# -----------------------------
protocol.max_speeds.update({
    'X': 300,
    'Y': 300,
    'Z': 80,
    'A': 80
})

# -----------------------------
# Labware
# -----------------------------
tips_20ul = protocol.load_labware('opentrons_96_tiprack_20ul', TIP_RACK_DECK_SLOT)
pipette_20ul = protocol.load_instrument("p20_single_gen2", "right", [tips_20ul])

temperature_module = protocol.load_module('temperature module gen2', COLORS_DECK_SLOT)
temperature_plate = temperature_module.load_labware(
    'opentrons_96_aluminumblock_generic_pcr_strip_200ul'
)

agar_plate = protocol.load_labware('htgaa_agar_plate', AGAR_DECK_SLOT)
center_location = agar_plate['A1'].top()

pipette_20ul.starting_tip = tips_20ul.well(PIPETTE_STARTING_TIP_WELL)

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

def dispense_and_detach_fast(pipette, volume, location):
    near = location.move(types.Point(z=location.point.z + 2))
    pipette.move_to(near)
    pipette.dispense(volume, location)
    pipette.move_to(location.move(types.Point(x=0.8)))
    pipette.move_to(near)

# -----------------------------
# FULL MISU Coordinate List
# -----------------------------
mturquoise2_points = [

(-4.5, 15.5),(-4.5, 14.5),(-3.5, 14.5),(-2.5, 14.5),(-3.5, 13.5),(-2.5, 13.5), (-1.5, 13.5),(-0.5, 13.5),(-3.5, 12.5),(-2.5, 12.5),(-1.5, 12.5),(-0.5, 12.5), (-3.5, 11.5),(-2.5, 11.5),(-1.5, 11.5),(-0.5, 11.5),(-3.5, 10.5),(-2.5, 10.5), (-1.5, 10.5),(-0.5, 10.5),(-3.5, 9.5),(-2.5, 9.5),(-1.5, 9.5),(-0.5, 9.5), (5.5, 9.5),(6.5, 9.5),(7.5, 9.5),(-3.5, 8.5),(-2.5, 8.5),(-1.5, 8.5), (5.5, 8.5),(6.5, 8.5),(7.5, 8.5),(8.5, 8.5),(-3.5, 7.5),(-2.5, 7.5), (-1.5, 7.5),(4.5, 7.5),(5.5, 7.5),(6.5, 7.5),(7.5, 7.5),(8.5, 7.5), (-3.5, 6.5),(-2.5, 6.5),(-1.5, 6.5),(4.5, 6.5),(5.5, 6.5),(6.5, 6.5), (7.5, 6.5),(-3.5, 5.5),(-2.5, 5.5),(-1.5, 5.5),(3.5, 5.5),(4.5, 5.5), (5.5, 5.5),(-7.5, 4.5),(-6.5, 4.5),(-3.5, 4.5),(-2.5, 4.5),(-1.5, 4.5), (2.5, 4.5),(3.5, 4.5),(4.5, 4.5),(-10.5, 3.5),(-9.5, 3.5),(-8.5, 3.5), (-7.5, 3.5),(-6.5, 3.5),(-5.5, 3.5),(-3.5, 3.5),(-2.5, 3.5),(-1.5, 3.5), (1.5, 3.5),(2.5, 3.5),(3.5, 3.5),(-13.5, 2.5),(-12.5, 2.5),(-11.5, 2.5), (-10.5, 2.5),(-9.5, 2.5),(-7.5, 2.5),(-6.5, 2.5),(-5.5, 2.5),(-3.5, 2.5), (-2.5, 2.5),(-1.5, 2.5),(-0.5, 2.5),(0.5, 2.5),(1.5, 2.5), (-14.5, 1.5),(-13.5, 1.5),(-12.5, 1.5),(-8.5, 1.5),(-7.5, 1.5), (-6.5, 1.5),(-3.5, 1.5),(-2.5, 1.5),(-1.5, 1.5),(0.5, 1.5),(1.5, 1.5), (-13.5, 0.5),(-9.5, 0.5),(-8.5, 0.5),(-7.5, 0.5),(-6.5, 0.5), (-3.5, 0.5),(-2.5, 0.5),(-1.5, 0.5),(0.5, 0.5),(1.5, 0.5),(2.5, 0.5), (-10.5, -0.5),(-9.5, -0.5),(-8.5, -0.5),(-7.5, -0.5),(-3.5, -0.5), (-2.5, -0.5),(-1.5, -0.5),(2.5, -0.5),(3.5, -0.5),(4.5, -0.5), (-10.5, -1.5),(-9.5, -1.5),(-8.5, -1.5),(-3.5, -1.5),(-2.5, -1.5), (-1.5, -1.5),(3.5, -1.5),(4.5, -1.5),(-11.5, -2.5),(-10.5, -2.5), (-9.5, -2.5),(-3.5, -2.5),(-2.5, -2.5),(-1.5, -2.5),(4.5, -2.5), (5.5, -2.5),(-11.5, -3.5),(-10.5, -3.5),(-9.5, -3.5),(-3.5, -3.5), (-2.5, -3.5),(-1.5, -3.5),(4.5, -3.5),(5.5, -3.5),(6.5, -3.5),(7.5, -3.5), (-12.5, -4.5),(-11.5, -4.5),(-3.5, -4.5),(-2.5, -4.5),(-1.5, -4.5), (5.5, -4.5),(6.5, -4.5),(7.5, -4.5),(8.5, -4.5),(-13.5, -5.5), (-12.5, -5.5),(-11.5, -5.5),(-3.5, -5.5),(-2.5, -5.5),(-1.5, -5.5), (5.5, -5.5),(6.5, -5.5),(7.5, -5.5),(8.5, -5.5),(9.5, -5.5), (-14.5, -6.5),(-13.5, -6.5),(-3.5, -6.5),(-2.5, -6.5),(-1.5, -6.5), (6.5, -6.5),(7.5, -6.5),(8.5, -6.5),(9.5, -6.5),(10.5, -6.5), (11.5, -6.5),(-14.5, -7.5),(-3.5, -7.5),(-2.5, -7.5),(-1.5, -7.5), (-0.5, -7.5),(6.5, -7.5),(7.5, -7.5),(8.5, -7.5),(9.5, -7.5), (10.5, -7.5),(11.5, -7.5),(12.5, -7.5),(13.5, -7.5),(-15.5, -8.5), (-3.5, -8.5),(-2.5, -8.5),(-1.5, -8.5),(-0.5, -8.5),(7.5, -8.5), (8.5, -8.5),(9.5, -8.5),(10.5, -8.5),(11.5, -8.5),(12.5, -8.5), (13.5, -8.5),(14.5, -8.5),(-3.5, -9.5),(-2.5, -9.5),(-1.5, -9.5), (-0.5, -9.5),(-5.5, -10.5),(-4.5, -10.5),(-3.5, -10.5),(-2.5, -10.5), (-1.5, -10.5),(-0.5, -10.5),(-4.5, -11.5),(-3.5, -11.5),(-2.5, -11.5), (-1.5, -11.5),(-0.5, -11.5),(-4.5, -12.5),(-3.5, -12.5),(-2.5, -12.5), (-1.5, -12.5),(-3.5, -13.5),(-2.5, -13.5),(-1.5, -13.5), (-3.5, -14.5),(-2.5, -14.5),(-2.5, -15.5) ]

# -----------------------------
# Printing
# -----------------------------
pipette_20ul.pick_up_tip()

volume_per_drop = 1
max_batch_volume = 18
drops_per_batch = int(max_batch_volume / volume_per_drop)

total_points = len(mturquoise2_points)
index = 0

while index < total_points:

    batch = mturquoise2_points[index:index + drops_per_batch]

    pipette_20ul.aspirate(
        len(batch) * volume_per_drop,
        location_of_color('Cyan')
    )

    for x_offset, y_offset in batch:
        dispense_location = center_location.move(
            types.Point(x=x_offset, y=y_offset)
        )
        dispense_and_detach_fast(
            pipette_20ul,
            volume_per_drop,
            dispense_location
        )

    index += drops_per_batch

pipette_20ul.drop_tip()