from opentrons import types
metadata = { # see https://docs.opentrons.com/v2/tutorial.html#tutorial-metadata
'author': 'Heather Qian',
'protocolName': 'Opentrons Flower',
'description': 'Makes a red and green flower',
'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' : 'Green',
'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
###
### YOUR CODE HERE to create your design
###
# Center
pipette_20ul.pick_up_tip()
pipette_20ul.aspirate(18, location_of_color("Green"))
cursor = center_location.move(types.Point(x=-4, y=15))
for i in range(9):
dispense_and_detach(pipette_20ul, 3, cursor)
if i != 8:
cursor = cursor.move(types.Point(x=4))
if i % 3 == 2 and i != 8:
cursor = cursor.move(types.Point(x=-12, y=-4))
if i == 5:
pipette_20ul.aspirate(9, location_of_color("Green"))
pipette_20ul.drop_tip()
# Right petal
pipette_20ul.pick_up_tip()
pipette_20ul.aspirate(18, location_of_color("Red"))
cursor = cursor.move(types.Point(x=4))
for i in range(6):
dispense_and_detach(pipette_20ul, 3, cursor)
cursor = cursor.move(types.Point(y=4))
if i % 3 == 2:
cursor = cursor.move(types.Point(x=4, y=-12))
pipette_20ul.aspirate(3, location_of_color("Red"))
cursor = cursor.move(types.Point(y=4))
dispense_and_detach(pipette_20ul, 3, cursor)
# Top petal
pipette_20ul.aspirate(18, location_of_color("Red"))
cursor = cursor.move(types.Point(x=-12, y=8))
for i in range(6):
dispense_and_detach(pipette_20ul, 3, cursor)
cursor = cursor.move(types.Point(x=-4))
if i % 3 == 2:
cursor = cursor.move(types.Point(x=12, y=4))
pipette_20ul.aspirate(3, location_of_color("Red"))
cursor = cursor.move(types.Point(x=-4))
dispense_and_detach(pipette_20ul, 3, cursor)
# Left petal
pipette_20ul.aspirate(18, location_of_color("Red"))
cursor = cursor.move(types.Point(x=-8, y=-12))
for i in range(6):
dispense_and_detach(pipette_20ul, 3, cursor)
cursor = cursor.move(types.Point(y=-4))
if i % 3 == 2:
cursor = cursor.move(types.Point(x=-4, y=12))
pipette_20ul.aspirate(3, location_of_color("Red"))
cursor = cursor.move(types.Point(y=-4))
dispense_and_detach(pipette_20ul, 3, cursor)
# Bottom petal
pipette_20ul.aspirate(18, location_of_color("Red"))
cursor = cursor.move(types.Point(x=12, y=-8))
for i in range(6):
dispense_and_detach(pipette_20ul, 3, cursor)
cursor = cursor.move(types.Point(x=4))
if i % 3 == 2:
cursor = cursor.move(types.Point(x=-12, y=-4))
pipette_20ul.aspirate(3, location_of_color("Red"))
cursor = cursor.move(types.Point(x=4))
dispense_and_detach(pipette_20ul, 3, cursor)
pipette_20ul.drop_tip()
# Stem
pipette_20ul.pick_up_tip()
pipette_20ul.aspirate(18, location_of_color("Green"))
for i in range(6):
cursor = cursor.move(types.Point(y=-4))
dispense_and_detach(pipette_20ul, 3, cursor)
# Right leaf
pipette_20ul.aspirate(15, location_of_color("Green"))
cursor = cursor.move(types.Point(x=4, y=8))
for i in range(5):
dispense_and_detach(pipette_20ul, 3, cursor)
if i % 2 == 0:
cursor = cursor.move(types.Point(y=4))
else:
cursor = cursor.move(types.Point(x=4))
# Left leaf
pipette_20ul.aspirate(15, location_of_color("Green"))
cursor = cursor.move(types.Point(x=-16, y=-12))
for i in range(5):
dispense_and_detach(pipette_20ul, 3, cursor)
if i % 2 == 0:
cursor = cursor.move(types.Point(y=4))
else:
cursor = cursor.move(types.Point(x=-4))
pipette_20ul.drop_tip()