Week 03 HW: Lab Automation

WEEK 3 — LAB AUTOMATION

LAB PROTOCOL

1. Review of Materials

First, I reviewed the available documentation on HTGAA (LAB–Week 3 – Opentrons Art). Key information required to prepare the design was found at the beginning of the Google Colab notebook, including technical constraints and recommended parameters for droplet spacing and volume.


Figure 1. Lab protocol.


2. Design Generation

I generated the artistic design using the GUI available at:
https://opentrons-art.rcdonovan.com

Initially, I had questions regarding droplet size and spacing between points. The Google Colab notebook provided specific recommendations about these parameters.

Before identifying these constraints, I created a version of the design with reduced spacing between points to increase visual detail. However, decreasing the distance between droplets increased the risk of unintended merging during robotic dispensing. After reviewing the guidelines, I adjusted the design to comply with the recommended 3.5 mm spacing.


Figure 2. Drops 2.2 mm.

Figure 3. Drops 3.5 mm. Both figures in https://rc/donovan.com/gel-art

From Donovan’s platform, I downloaded the coordinate sets to be used in the Python script. The coordinates were grouped by color and already respected the recommended spacing (3.5 mm).

Figure 4. Coordinates.

The design was registered on the platform under the following ID:
https://opentrons-art.rcdonovan.com/?id=w8392ofgw0pexpu


Figure 5. Art design.

3. Script Development and Simulation

I opened the HTGAA26 Opentrons Colab notebook and created a personal copy to develop the script. The notebook included reference examples from previous students, which were useful to understand how coordinate-based dispensing is implemented on agar plates.

The script was written in Python. Since the laboratory setup provides only two available colors for execution, I adapted the original design as follows:

After completing the implementation, I executed the simulation within the Opentrons environment. The simulation ran successfully without errors, confirming correct tip usage, aspiration logic, and coordinate positioning.


Figure 6. Simulation result.

Figure 7. Art design.

Here, the script (sent to Leon and Martina on time, no receive the picture back):

from opentrons import types

metadata = {    # see https://docs.opentrons.com/v2/tutorial.html#tutorial-metadata
    'author': 'María José Pérez Crespo',
    'protocolName': 'Peacock',
    'description': 'Print peacock using two colors: green 1 µL, green 1.2 µL, red 1 µL',
    '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_20ul = protocol.load_labware(
      'opentrons_96_tiprack_20ul',
      TIP_RACK_DECK_SLOT,
      'Opentrons 20uL Tips'
  )

  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',
      'Cold Plate'
  )

  color_plate = temperature_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)


  ##############################################################################
  ###   Definición de puntos
  ##############################################################################

  sfgfp_points = [...]
  mrfp1_points = [...]
  electra2_points = [...]

  ##############################################################################
  ###   Centrado automático
  ##############################################################################

  all_points = sfgfp_points + mrfp1_points + electra2_points

  min_x = min(pt[0] for pt in all_points)
  max_x = max(pt[0] for pt in all_points)
  min_y = min(pt[1] for pt in all_points)
  max_y = max(pt[1] for pt in all_points)

  offset_x = (min_x + max_x) / 2
  offset_y = (min_y + max_y) / 2


  ##############################################################################
  ###   Green (new tip)
  ##############################################################################

  green_loc = location_of_color('Green')
  pipette_20ul.pick_up_tip()

  remaining_total_volume = len(sfgfp_points) * 1.0 + len(electra2_points) * 1.2
  current_volume = 0.0

  for point in sfgfp_points:
      vol = 1.0
      if current_volume < vol:
          load_volume = min(20, remaining_total_volume)
          pipette_20ul.aspirate(load_volume, green_loc)
          current_volume += load_volume

      x_mm, y_mm = point
      target_location = center_location.move(
          types.Point(x=x_mm - offset_x, y=y_mm - offset_y, z=0)
      )

      dispense_and_detach(pipette_20ul, vol, target_location)

      current_volume -= vol
      remaining_total_volume -= vol


  for point in electra2_points:
      vol = 1.2
      if current_volume < vol:
          load_volume = min(20, remaining_total_volume)
          pipette_20ul.aspirate(load_volume, green_loc)
          current_volume += load_volume

      x_mm, y_mm = point
      target_location = center_location.move(
          types.Point(x=x_mm - offset_x, y=y_mm - offset_y, z=0)
      )

      dispense_and_detach(pipette_20ul, vol, target_location)

      current_volume -= vol
      remaining_total_volume -= vol


  pipette_20ul.drop_tip()


  ##############################################################################
  ###   RED color (New tip)
  ##############################################################################

  red_loc = location_of_color('Red')
  pipette_20ul.pick_up_tip()

  remaining_total_volume = len(mrfp1_points) * 1.0
  current_volume = 0.0

  for point in mrfp1_points:
      vol = 1.0
      if current_volume < vol:
          load_volume = min(20, remaining_total_volume)
          pipette_20ul.aspirate(load_volume, red_loc)
          current_volume += load_volume

      x_mm, y_mm = point
      target_location = center_location.move(
          types.Point(x=x_mm - offset_x, y=y_mm - offset_y, z=0)
      )

      dispense_and_detach(pipette_20ul, vol, target_location)

      current_volume -= vol
      remaining_total_volume -= vol


  pipette_20ul.drop_tip()

4. Use of AI Assistance

Artificial intelligence tools were used to support the development of the script. The structural logic was based on the provided examples in the notebook, particularly Example 7 (Microbial Earth), which clarified how grouped coordinates are iterated and dispensed.

AI assistance was used to:

The questions posed were specific and focused on resolving implementation details. AI was used as a technical support tool rather than as a replacement for understanding the protocol logic.


5. Robot Scheduling

I already booked Friday 27, 14.00


Figure 7¡8. Booking,.

Figure 9. Booking in Opentrons Art Slots - SynBio USFQ Node.

6. Submission

The Python script was submitted via the corresponding Google Form, and confirmation was received.


Figure 10. Confirmation.

Figure 11. Google form sent.

The script was shared using the following link:

https://colab.research.google.com/drive/15lHDPfQqFryL9ydvX3P-SeppB7QAd0d8?usp=sharing


Figure 12. Google colab.


Post Lab Questions


1. Find and describe a published paper that utilizes the Opentrons or an automation tool to achieve novel biological applications.

Rosini, E., Battaglia, C., Miani, D., Molinari, F., Arrigoni, F., Piarulli, U., … & Pollegioni, L. (2025). Valuable compounds from pollutants: converting PET into enantiopure alanine. ACS Catalysis, 15(21), 17829-17843.

In this study, the Opentrons OT-2 automated pipetting system was used to perform a colorimetric assay with PSP dye, which allows measurement of pH changes associated with terephthalic acid (TPA) production during PET depolymerization. The automation enabled rapid and consistent processing of multiple samples, improving the reproducibility and efficiency of depolymerizing enzyme screening.

FINAL PROJECT IDEAS

No ideas already.