Week 3 HW: Lab Automation

Assignment: Python Script for Opentrons Artwork — DUE BY YOUR LAB TIME!

A Blooming Daisy Flower PINK, PURPLE & BLUE DESIGN! :) image.png image.png

INITIAL DESIGN: image.png image.png

Python documentation

from opentrons import types

metadata = {
    'author': 'Tammy Sisodiya',
    'protocolName': ' HTGAA Dazzling Daisy',
    'description': 'A blooming Daisy flower in Purple, Pink, and Blue.',
    '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'

# UPDATED: Mapping the new lab colors to source wells
well_colors = {
    'A1' : 'Purple',
    'B1' : 'Pink',
    'C1' : 'Blue'
}

def run(protocol):
  # 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_plate = temperature_module.load_labware('opentrons_96_aluminumblock_generic_pcr_strip_200ul', 'Cold Plate')
  color_plate = temperature_plate

  # Agar Plate
  agar_plate = protocol.load_labware('htgaa_agar_plate', AGAR_DECK_SLOT, 'Agar Plate')
  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):
    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):
      assert(isinstance(volume, (int, float)))
      above_location = location.move(types.Point(z=location.point.z + 5))
      pipette.move_to(above_location)
      pipette.dispense(volume, location)
      pipette.move_to(above_location)

### YOUR DESIGN DATA ###
  sfgfp_points = [(-4.4, 26.4),(1.1, 26.4),(2.2, 26.4),(3.3, 26.4),(4.4, 26.4),(-6.6, 25.3),(-5.5, 25.3),(-4.4, 25.3),(-3.3, 25.3),(1.1, 25.3),(4.4, 25.3),(-12.1, 24.2),(-11, 24.2),(-9.9, 24.2),(-8.8, 24.2),(-7.7, 24.2),(-6.6, 24.2),(-2.2, 24.2),(0, 24.2),(4.4, 24.2),(-13.2, 23.1),(-12.1, 23.1),(-7.7, 23.1),(-6.6, 23.1),(-2.2, 23.1),(4.4, 23.1),(6.6, 23.1),(7.7, 23.1),(8.8, 23.1),(-13.2, 22),(-7.7, 22),(-6.6, 22),(-2.2, 22),(0, 22),(4.4, 22),(5.5, 22),(6.6, 22),(8.8, 22),(-13.2, 20.9),(-7.7, 20.9),(-2.2, 20.9),(3.3, 20.9),(4.4, 20.9),(9.9, 20.9),(-13.2, 19.8),(-7.7, 19.8),(-2.2, 19.8),(3.3, 19.8),(9.9, 19.8),(-13.2, 18.7),(-2.2, 18.7),(8.8, 18.7),(9.9, 18.7),(-13.2, 17.6),(-2.2, 17.6),(-1.1, 17.6),(8.8, 17.6),(-18.7, 16.5),(-17.6, 16.5),(-16.5, 16.5),(-15.4, 16.5),(-14.3, 16.5),(-12.1, 16.5),(-2.2, 16.5),(7.7, 16.5),(8.8, 16.5),(-20.9, 15.4),(-19.8, 15.4),(-18.7, 15.4),(-14.3, 15.4),(-13.2, 15.4),(-12.1, 15.4),(-2.2, 15.4),(-1.1, 15.4),(7.7, 15.4),(-20.9, 14.3),(-13.2, 14.3),(-12.1, 14.3),(-11, 14.3),(-3.3, 14.3),(-2.2, 14.3),(5.5, 14.3),(6.6, 14.3),(-20.9, 13.2),(-9.9, 13.2),(-8.8, 13.2),(-3.3, 13.2),(4.4, 13.2),(5.5, 13.2),(-20.9, 12.1),(-8.8, 12.1),(-7.7, 12.1),(-3.3, 12.1),(-2.2, 12.1),(2.2, 12.1),(3.3, 12.1),(5.5, 12.1),(6.6, 12.1),(7.7, 12.1),(8.8, 12.1),(9.9, 12.1),(11, 12.1),(-20.9, 11),(-19.8, 11),(-6.6, 11),(-5.5, 11),(-4.4, 11),(0, 11),(1.1, 11),(2.2, 11),(3.3, 11),(4.4, 11),(11, 11),(-19.8, 9.9),(-4.4, 9.9),(-3.3, 9.9),(-2.2, 9.9),(-1.1, 9.9),(0, 9.9),(11, 9.9),(-23.1, 8.8),(-22, 8.8),(-20.9, 8.8),(-19.8, 8.8),(-18.7, 8.8),(-17.6, 8.8),(-5.5, 8.8),(-4.4, 8.8),(-3.3, 8.8),(-2.2, 8.8),(-1.1, 8.8),(0, 8.8),(9.9, 8.8),(11, 8.8),(15.4, 8.8),(16.5, 8.8),(17.6, 8.8),(18.7, 8.8),(19.8, 8.8),(20.9, 8.8),(22, 8.8),(23.1, 8.8),(24.2, 8.8),(-23.1, 7.7),(-3.3, 7.7),(-1.1, 7.7),(0, 7.7),(1.1, 7.7),(2.2, 7.7),(8.8, 7.7),(9.9, 7.7),(14.3, 7.7),(15.4, 7.7),(16.5, 7.7),(20.9, 7.7),(22, 7.7),(24.2, 7.7),(-24.2, 6.6),(-23.1, 6.6),(-5.5, 6.6),(-4.4, 6.6),(-3.3, 6.6),(-2.2, 6.6),(1.1, 6.6),(2.2, 6.6),(7.7, 6.6),(8.8, 6.6),(9.9, 6.6),(11, 6.6),(12.1, 6.6),(13.2, 6.6),(14.3, 6.6),(16.5, 6.6),(19.8, 6.6),(20.9, 6.6),(23.1, 6.6),(-22, 5.5),(-9.9, 5.5),(-7.7, 5.5),(-6.6, 5.5),(-5.5, 5.5),(-4.4, 5.5),(-2.2, 5.5),(3.3, 5.5),(4.4, 5.5),(13.2, 5.5),(16.5, 5.5),(18.7, 5.5),(19.8, 5.5),(23.1, 5.5),(-20.9, 4.4),(-19.8, 4.4),(-18.7, 4.4),(-17.6, 4.4),(-16.5, 4.4),(-15.4, 4.4),(-14.3, 4.4),(-13.2, 4.4),(-12.1, 4.4),(-9.9, 4.4),(-8.8, 4.4),(-7.7, 4.4),(-2.2, 4.4),(4.4, 4.4),(5.5, 4.4),(6.6, 4.4),(13.2, 4.4),(16.5, 4.4),(17.6, 4.4),(18.7, 4.4),(23.1, 4.4),(-12.1, 3.3),(-11, 3.3),(-2.2, 3.3),(5.5, 3.3),(7.7, 3.3),(8.8, 3.3),(9.9, 3.3),(11, 3.3),(12.1, 3.3),(13.2, 3.3),(16.5, 3.3),(17.6, 3.3),(23.1, 3.3),(-13.2, 2.2),(-12.1, 2.2),(-2.2, 2.2),(6.6, 2.2),(9.9, 2.2),(16.5, 2.2),(17.6, 2.2),(18.7, 2.2),(19.8, 2.2),(20.9, 2.2),(22, 2.2),(-14.3, 1.1),(-2.2, 1.1),(7.7, 1.1),(9.9, 1.1),(11, 1.1),(15.4, 1.1),(16.5, 1.1),(22, 1.1),(-15.4, 0),(-14.3, 0),(-2.2, 0),(7.7, 0),(11, 0),(14.3, 0),(15.4, 0),(22, 0),(-15.4, -1.1),(-2.2, -1.1),(3.3, -1.1),(8.8, -1.1),(13.2, -1.1),(14.3, -1.1),(20.9, -1.1),(-15.4, -2.2),(-14.3, -2.2),(-13.2, -2.2),(-12.1, -2.2),(-8.8, -2.2),(-7.7, -2.2),(-6.6, -2.2),(-2.2, -2.2),(3.3, -2.2),(8.8, -2.2),(11, -2.2),(12.1, -2.2),(13.2, -2.2),(20.9, -2.2),(-14.3, -3.3),(-11, -3.3),(-8.8, -3.3),(-7.7, -3.3),(-6.6, -3.3),(-3.3, -3.3),(-2.2, -3.3),(3.3, -3.3),(4.4, -3.3),(8.8, -3.3),(11, -3.3),(19.8, -3.3),(20.9, -3.3),(-13.2, -4.4),(-12.1, -4.4),(-11, -4.4),(-8.8, -4.4),(-3.3, -4.4),(-2.2, -4.4),(4.4, -4.4),(5.5, -4.4),(6.6, -4.4),(7.7, -4.4),(8.8, -4.4),(13.2, -4.4),(19.8, -4.4),(-16.5, -5.5),(-15.4, -5.5),(-14.3, -5.5),(-13.2, -5.5),(-8.8, -5.5),(-4.4, -5.5),(-3.3, -5.5),(-2.2, -5.5),(4.4, -5.5),(14.3, -5.5),(15.4, -5.5),(16.5, -5.5),(18.7, -5.5),(19.8, -5.5),(-19.8, -6.6),(-18.7, -6.6),(-17.6, -6.6),(-16.5, -6.6),(-8.8, -6.6),(-4.4, -6.6),(-1.1, -6.6),(3.3, -6.6),(4.4, -6.6),(17.6, -6.6),(18.7, -6.6),(-23.1, -7.7),(-22, -7.7),(-20.9, -7.7),(-19.8, -7.7),(-17.6, -7.7),(-16.5, -7.7),(-15.4, -7.7),(-8.8, -7.7),(-7.7, -7.7),(-6.6, -7.7),(-5.5, -7.7),(-4.4, -7.7),(-3.3, -7.7),(-2.2, -7.7),(-1.1, -7.7),(0, -7.7),(2.2, -7.7),(3.3, -7.7),(16.5, -7.7),(17.6, -7.7),(-24.2, -8.8),(-23.1, -8.8),(-14.3, -8.8),(-13.2, -8.8),(-8.8, -8.8),(-7.7, -8.8),(-3.3, -8.8),(-2.2, -8.8),(0, -8.8),(1.1, -8.8),(2.2, -8.8),(3.3, -8.8),(5.5, -8.8),(14.3, -8.8),(15.4, -8.8),(16.5, -8.8),(-26.4, -9.9),(-25.3, -9.9),(-24.2, -9.9),(-12.1, -9.9),(-11, -9.9),(-9.9, -9.9),(-8.8, -9.9),(-3.3, -9.9),(0, -9.9),(7.7, -9.9),(8.8, -9.9),(11, -9.9),(12.1, -9.9),(13.2, -9.9),(-27.5, -11),(-26.4, -11),(-25.3, -11),(-24.2, -11),(-23.1, -11),(-22, -11),(-20.9, -11),(-19.8, -11),(-18.7, -11),(-17.6, -11),(-16.5, -11),(-15.4, -11),(-14.3, -11),(-13.2, -11),(-12.1, -11),(-11, -11),(-3.3, -11),(0, -11),(-28.6, -12.1),(-27.5, -12.1),(-19.8, -12.1),(-18.7, -12.1),(-17.6, -12.1),(-15.4, -12.1),(-12.1, -12.1),(-4.4, -12.1),(-3.3, -12.1),(-2.2, -12.1),(0, -12.1),(-28.6, -13.2),(-27.5, -13.2),(-20.9, -13.2),(-19.8, -13.2),(-12.1, -13.2),(-4.4, -13.2),(0, -13.2),(-26.4, -14.3),(-25.3, -14.3),(-13.2, -14.3),(-12.1, -14.3),(-5.5, -14.3),(-2.2, -14.3),(0, -14.3),(-23.1, -15.4),(-20.9, -15.4),(-19.8, -15.4),(-13.2, -15.4),(-8.8, -15.4),(-7.7, -15.4),(-6.6, -15.4),(-1.1, -15.4),(0, -15.4),(-18.7, -16.5),(-16.5, -16.5),(-15.4, -16.5),(-14.3, -16.5),(-13.2, -16.5),(-12.1, -16.5),(-9.9, -16.5),(-8.8, -16.5),(-2.2, -16.5),(0, -16.5),(-2.2, -17.6),(0, -17.6),(0, -18.7),(-1.1, -19.8),(1.1, -19.8),(-1.1, -20.9),(1.1, -20.9),(2.2, -20.9),(0, -22),(3.3, -22),(12.1, -22),(13.2, -22),(14.3, -22),(15.4, -22),(0, -23.1),(4.4, -23.1),(5.5, -23.1),(9.9, -23.1),(11, -23.1),(12.1, -23.1),(13.2, -23.1),(1.1, -24.2),(2.2, -24.2),(5.5, -24.2),(6.6, -24.2),(7.7, -24.2),(8.8, -24.2),(9.9, -24.2),(11, -24.2),(12.1, -24.2),(2.2, -25.3),(3.3, -25.3),(4.4, -25.3),(9.9, -25.3),(11, -25.3),(5.5, -26.4),(6.6, -26.4),(7.7, -26.4),(8.8, -26.4)]
  mrfp1_points = [(-15.4, 12.1),(-14.3, 12.1),(-14.3, 11),(-13.2, 11),(-12.1, 11)]
  mscarlet_i_points = [(-11, 20.9),(-9.9, 20.9),(-11, 19.8),(-9.9, 19.8),(-9.9, 18.7)]
  mko2_points = [(3.3, 18.7),(4.4, 18.7),(5.5, 18.7),(6.6, 18.7),(4.4, 17.6)]
  mjuniper_points = [(6.6, 9.9),(7.7, 9.9),(4.4, 8.8),(5.5, 8.8),(6.6, 8.8),(7.7, 8.8),(-6.6, 2.2),(-9.9, 1.1),(-8.8, 1.1),(-7.7, 1.1),(-6.6, 1.1)]
  electra2_points = [(1.1, 4.4),(1.1, 3.3),(1.1, 2.2),(1.1, 1.1)]

  # 2. UPDATED Design Mapping
  # Purple for the large petals, Pink for highlights, Blue for details.
  layers = [
      ('Purple', sfgfp_points),
      ('Pink', mrfp1_points),
      ('Pink', mscarlet_i_points),
      ('Pink', mko2_points),
      ('Blue', mjuniper_points),
      ('Blue', electra2_points)
  ]

  # 3. Execution Loop
  drop_vol = 1.0

  for color_name, points in layers:
      if not points:
          continue

      source_well = location_of_color(color_name)

      for i in range(0, len(points), 15):
          chunk = points[i:i + 15]
          pipette_20ul.pick_up_tip()

          aspirate_vol = (len(chunk) * drop_vol) + 2.0
          if aspirate_vol > 20.0:
              aspirate_vol = 20.0

          pipette_20ul.aspirate(aspirate_vol, source_well)

          for x, y in chunk:
              if (x**2 + y**2) < 1600:
                  target_point = center_location.point + types.Point(x=x, y=y, z=0)
                  target_loc = types.Location(target_point, None)
                  dispense_and_detach(pipette_20ul, drop_vol, target_loc)

          # Return residual to source well top to avoid contamination
          if pipette_20ul.current_volume > 0:
              pipette_20ul.dispense(pipette_20ul.current_volume, source_well.top())

          pipette_20ul.drop_tip()

Post-Lab Questions — DUE BY START OF FEB 24 LECTURE

  1. I found a paper which utilises Opentrons-2 liquid handling to mix and set up protein crystallization plates using Hen Egg White Lysozyme (HEWL) as a Model System and validation of the robot’s capabilities and Periplasmic Protein (which is used as a framework/scaffold for large batches of similarly structured crystals). Protein crystallization aids in 3D structural determination of proteins using X-ray crystallography. If we know the protein-protein interactions and protein function details, we can use this to drive the design, modelling and optimization of new drugs which fit in the protein’s active site. The paper showed how researchers automated the 24-well sitting drop plates setup for these two specific proteins for protein crystallization, and compared to manual human pipetting of plates, the Opentrons robot decreased manual labour, increased reliability of pipetting, but potentially decreased variability across plates from person to person (DeRoo et al., 2025).

2) Write a description about what you intend to do with automation tools for your final project. You may include example pseudocode, Python scripts, 3D printed holders, a plan for how to use Ginkgo Nebula, and more. You may reference this week’s recitation slide deck for lab automation details.

For my idea 1: The Opentrons protocol can be used in a 96-well plate to mix different PETase enzyme mutants / variations of this enzyme with 5 different plastic types.

A random idea I thought of initially as a small side project as part of my original idea 1: Measure PETase degradation rate

I would like to check for stable PETase variants, by using Ginkgo Nebula to design a library of between 50-100 PETase mutants, specifically targeting the W159H/S238F double mutation which has been shown to improve stabilisation and binding affinity to PET in Ideonella sakaiensis PETase (Austin et al., 2018).

The steps I will take to get them sequenced and produced by the foundry: 1) ensuring codon optimisation for the DNA sequence variants and 2) get 96-well plates or expression ready plasmids.

I will hope to develop 3D printed lab equipment, such as a PETase film clamping insert, which will allow PETase films to not float and keep films submerged, so the Opentrons pipette will deposit the enzyme directly on the surface.

I would then like to automate the measurement of how fast PETase degrades plastic - optimising the conditions for PETase activity, as it is dependent on temperature, pH and NaCl concentration. We can use a multiplexed bioreactor array with precise control over pH, temperature, oxygen transfer, and nutrient feeding in its chambers, to allow lots of parallel experiments (cell cultures) to be conducted all at the same time. I would like to use hardware such as Arduino / ESP32 to administer 4–8 small vials, each with its own heating element and pH probe. We use a loop to keep the pH continuous: When PETase breaks down PET into its monomers; terephthalic acid and ethylene glycol, the pH will become more acidic. The automation system will measure how much alkalinity like adding NaOH it has to pump in to neutralize the acid. The quantity of the alkaline base added will become a substitute for the plastic degradation rate, producing an output of a graph.

For my idea 2: Protein MPNN generated phage tail sequences will be stored in Benchling and annotated, top 5 highly ranked phage tail sequences will be run into Nebula’s codon optimisation tool for bacteria. To test engineered phages against non target and target bacteria, I’d use a phage spotting assay, for which I’d utilise Opentrons protocol to automate this.

For my idea 3: Creating a GFP-based cancer mutation biosensor, I will use Benchling to create the genetic construct (GFP-antibody fragment/nanobody fusion, promoter, linker sequences), Ginkgo Nebula to codon optimise and synthesise the sequence and an Opentrons protocol which will automate the 96-well plate fluorescence assay, which I will use mutant and non-mutant KRAS genes for exposing to the GFP biosensor.

Final Project Ideas — DUE BY START OF FEB 24 LECTURE

BTS: Inspirations, content and why I chose these 3 project ideas?

My inspiration for the first idea, the PETase substrate specificity in silico project idea was to understand how different plastics apart from PET could be degraded by the enzyme, and how inducing mutations in the stabilisation sites of the enzyme may increase binding affinity for the plastic. Generally, I am very interested in the topic of bioremediation for plastic pollution, which is widespread.

My inspiration for the second idea, was that phages use receptor binding proteins to bind to bacteria, and as they have a limited host range due to the high receptor specificity for specific bacterial organelles, we can engineer the receptor binding loops in the RBP region with swapping similar genes between phages, and through insertions, mutations and recombining genes to change binding affinity to different bacterial surface proteins and broaden host phage range.

My inspiration for the third idea was brought about my initial meeting at at Lifefabs using phytoplanktons as water quality biosensors joined with the idea of learning at the BioBootcamp and in HTGAA classes of GFP as glowing if mutations are detected which would be a biological readout of an active molecular detector to prevent the development of cancer downstream.

References

DeRoo, J. B., Jones, A. A., Slaughter, C. K., Ahr, T. W., Stroup, S. M., Thompson, G. B., & Snow, C. D. (2025). Automation of protein crystallization scaleup via Opentrons-2 liquid handling. SLAS Technology, 32, 100268. https://doi.org/10.1016/j.slast.2025.100268

Austin, H. P., Allen, M. D., Donohoe, B. S., Rorrer, N. A., Kearns, F. L., Silveira, R. L., Pollard, B. C., Dominick, G., Duman, R., El Omari, K., Mykhaylyk, V., Wagner, A., Michener, W. E., Amore, A., Skaf, M. S., Crowley, M. F., Thorne, A. W., Johnson, C. W., Woodcock, H. L., … Beckham, G. T. (2018). Characterization and engineering of a plastic-degrading aromatic polyesterase. Proceedings of the National Academy of Sciences, 115(19). https://doi.org/10.1073/pnas.1718804115