week-03-hw-lab-automation

Bioart Using Opentrons

Goal of learning this lesson and doing the OpenTron automation.

  • Utilizing different tools to automate different lab work using programmed robots.
  • Be able to design, coordinate, code, and print one’s design using OpenTron robots. Design Design

Code

CLICK HERE SEE THE CODE USED

from opentrons import types

metadata = { ‘author’: ‘Kaleab’, ‘protocolName’: ‘ADWA’, ‘description’: ‘ADWA in Amharic and English’, ‘source’: ‘HTGAA 2026 Opentrons Lab’, ‘apiLevel’: ‘2.20’ }

Robot deck setup constants

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

well_colors = { ‘A1’: ‘Red’, # mRFP1 bacteria ‘B1’: ‘Green’, # sfGFP bacteria }

Coordinates for each bacterial color

mRFP1 (Red) points - in mm offset from agar plate center mrfp1_points = [ (-26.4, 17.6), (-28.6, 15.4), (-24.2, 15.4), (30.8, 15.4), (-30.8, 13.2), (-22, 13.2), (-13.2, 13.2), (-11, 13.2), (-8.8, 13.2), (-6.6, 13.2), (-4.4, 13.2), (-2.2, 13.2), (6.6, 13.2), (19.8, 13.2), (28.6, 13.2), (33, 13.2), (-33, 11), (-19.8, 11), (-13.2, 11), (0, 11), (6.6, 11), (13.2, 11), (19.8, 11), (26.4, 11), (35.2, 11), (-35.2, 8.8), (-17.6, 8.8), (-13.2, 8.8), (2.2, 8.8), (6.6, 8.8), (13.2, 8.8), (19.8, 8.8), (24.2, 8.8), (37.4, 8.8), (-35.2, 6.6), (-17.6, 6.6), (-13.2, 6.6), (2.2, 6.6), (6.6, 6.6), (13.2, 6.6), (19.8, 6.6), (24.2, 6.6), (37.4, 6.6), (-35.2, 4.4), (-17.6, 4.4), (-13.2, 4.4), (2.2, 4.4), (6.6, 4.4), (13.2, 4.4), (19.8, 4.4), (24.2, 4.4), (37.4, 4.4), (-35.2, 2.2), (-17.6, 2.2), (-13.2, 2.2), (2.2, 2.2), (6.6, 2.2), (13.2, 2.2), (19.8, 2.2), (24.2, 2.2), (26.4, 2.2), (28.6, 2.2), (30.8, 2.2), (33, 2.2), (35.2, 2.2), (37.4, 2.2), (-35.2, 0), (-33, 0), (-30.8, 0), (-28.6, 0), (-26.4, 0), (-24.2, 0), (-22, 0), (-19.8, 0), (-17.6, 0), (-13.2, 0), (2.2, 0), (6.6, 0), (13.2, 0), (19.8, 0), (24.2, 0), (37.4, 0), (-35.2, -2.2), (-17.6, -2.2), (-13.2, -2.2), (2.2, -2.2), (6.6, -2.2), (13.2, -2.2), (19.8, -2.2), (24.2, -2.2), (37.4, -2.2), (-35.2, -4.4), (-17.6, -4.4), (-13.2, -4.4), (2.2, -4.4), (6.6, -4.4), (13.2, -4.4), (19.8, -4.4), (24.2, -4.4), (37.4, -4.4), (-35.2, -6.6), (-17.6, -6.6), (-13.2, -6.6), (2.2, -6.6), (8.8, -6.6), (13.2, -6.6), (19.8, -6.6), (24.2, -6.6), (37.4, -6.6), (-35.2, -8.8), (-17.6, -8.8), (-13.2, -8.8), (0, -8.8), (11, -8.8), (13.2, -8.8), (15.4, -8.8), (17.6, -8.8), (24.2, -8.8), (37.4, -8.8), (-35.2, -11), (-17.6, -11), (-11, -11), (-8.8, -11), (-6.6, -11), (-4.4, -11), (-2.2, -11) ]

sfGFP (Green) points - in mm offset from agar plate center sfgfp_points = [ (-15.4, 35.2), (-2.2, 35.2), (0, 35.2), (8.8, 35.2), (11, 35.2), (13.2, 35.2), (-17.6, 33), (-2.2, 33), (0, 33), (2.2, 33), (6.6, 33), (11, 33), (15.4, 33), (-17.6, 30.8), (-15.4, 30.8), (-13.2, 30.8), (-11, 30.8), (-8.8, 30.8), (-2.2, 30.8), (0, 30.8), (6.6, 30.8), (11, 30.8), (15.4, 30.8), (-11, 28.6), (-4.4, 28.6), (-2.2, 28.6), (0, 28.6), (2.2, 28.6), (6.6, 28.6), (11, 28.6), (15.4, 28.6), (-13.2, 26.4), (-4.4, 26.4), (2.2, 26.4), (8.8, 26.4), (11, 26.4), (13.2, 26.4), (-15.4, 24.2), (-13.2, 24.2), (-11, 24.2), (-8.8, 24.2), (-4.4, 24.2), (2.2, 24.2), (11, 24.2), (-15.4, 22), (-8.8, 22), (-4.4, 22), (2.2, 22), (11, 22), (-15.4, 19.8), (-8.8, 19.8), (-4.4, 19.8), (2.2, 19.8), (11, 19.8), (-15.4, 17.6), (-8.8, 17.6), (-4.4, 17.6), (2.2, 17.6), (11, 17.6), (-17.6, -15.4), (-15.4, -15.4), (-6.6, -15.4), (-4.4, -15.4), (-2.2, -15.4), (0, -15.4), (8.8, -15.4), (11, -15.4), (13.2, -15.4), (-19.8, -17.6), (-15.4, -17.6), (2.2, -17.6), (6.6, -17.6), (15.4, -17.6), (-15.4, -19.8), (2.2, -19.8), (6.6, -19.8), (15.4, -19.8), (-15.4, -22), (2.2, -22), (6.6, -22), (15.4, -22), (-15.4, -24.2), (-6.6, -24.2), (-4.4, -24.2), (-2.2, -24.2), (0, -24.2), (6.6, -24.2), (15.4, -24.2), (-15.4, -26.4), (2.2, -26.4), (6.6, -26.4), (15.4, -26.4), (-15.4, -28.6), (2.2, -28.6), (6.6, -28.6), (15.4, -28.6), (-19.8, -30.8), (-17.6, -30.8), (-15.4, -30.8), (-13.2, -30.8), (-11, -30.8), (-6.6, -30.8), (-4.4, -30.8), (-2.2, -30.8), (0, -30.8), (2.2, -30.8), (8.8, -30.8), (11, -30.8), (13.2, -30.8) ]

Volume to dispense per dot (uL) DISPENSE_VOLUME = 1

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')

# Get the top-center of the plate (calibration reference point)
center_location = agar_plate['A1'].top()

pipette_20ul.starting_tip = tips_20ul.well(PIPETTE_STARTING_TIP_WELL)

##############################################################################
###   Helper functions
##############################################################################

def location_of_color(color_string):
    """Return the well location for a given color name."""
    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}")

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.
    """
    assert isinstance(volume, (int, float))
    above_location = location.move(types.Point(z=5))
    pipette.move_to(above_location)
    pipette.dispense(volume, location)
    pipette.move_to(above_location)

def stamp_color(color_string, points):
    """
    Aspirate enough liquid to dispense across all points, then visit each
    coordinate and dispense a small dot. Re-aspirate when the tip runs low.

    Args:
        color_string: 'Red' or 'Green'
        points: list of (x, y) tuples in mm offset from plate center
    """
    source_well = location_of_color(color_string)
    max_volume = 18  # stay below 20uL max, leave headroom
    remaining = 0

    pipette_20ul.pick_up_tip()

    for x_offset, y_offset in points:
        # Aspirate a fresh batch if the tip is about to run dry
        if remaining < DISPENSE_VOLUME:
            # How many dots can we fit in one pickup?
            dots_per_fill = int(max_volume // DISPENSE_VOLUME)
            aspirate_vol = min(dots_per_fill * DISPENSE_VOLUME, max_volume)
            pipette_20ul.aspirate(aspirate_vol, source_well)
            remaining = aspirate_vol

        # Build the target location: offset (x, y) from center, at plate surface
        target_location = center_location.move(types.Point(x=x_offset, y=y_offset, z=0))
        dispense_and_detach(pipette_20ul, DISPENSE_VOLUME, target_location)
        remaining -= DISPENSE_VOLUME

    # Drop tip when done with this color
    pipette_20ul.drop_tip()

##############################################################################
###   Patterning — stamp each bacterial strain
##############################################################################

# 1. mRFP1 (Red) — Amharic characters
stamp_color('Red', mrfp1_points)

# 2. sfGFP (Green) — English / additional characters
stamp_color('Green', sfgfp_points)

Printed Design Printed Design