Steven Ness : Committed Listener, Victoria, BC

Part 1

For this assigment, I modified the code for drawing an image by Dominika Wawrzyniak to make my own image drawing routine. I also used command line tools to generate the image, hopefully this should make it easier to reproduce.

I started by creating the image .csv file. For this I used Imagemagick on Linux and ran the following command to convert the image to text format:

convert marilyn-monroe-6.jpg -negate -resize 40x40 -threshold 50% -flip marilyn.txt

This command does a number of things at once. First, it inverts the image so that the colonies that are growing will make the black agar clear and turn this negative image into a positive image. It will then resize it to 40x40 pixels, a size that for this particular image of Andy Warhol’s Marilyn Monroe looked somewhat recognizable at this size. The “-threshold 50%” command turns the image from grayscale into black and white with a threshold of 50%, this value can be adjusted to find a pleasing value for your image. Another image I tried needed a threshold of 80% to be recognizable. Finally the “-flip” command flips the image, thus making the python code simpler.

I then converted this file into csv format:

tail -n +2 marilyn.txt | grep -v "(0," | cut -f 1 -d ":" > marilyn.csv

This command outputs a value for every pixel that does not have a value of exactly “0” and puts it into a CSV file of the format that Dominika used.

I then modified Dominika’s code to make it more concise:

def run(protocol):
  tips_20ul = protocol.load_labware('opentrons_96_tiprack_20ul', 1, 'Opentrons 20uL Tips')
  temperature_module = protocol.load_module('temperature module gen2', 2)
  source_plate = temperature_module.load_labware('opentrons_96_aluminumblock_generic_pcr_strip_200ul', label='Source Plate')
  agar_plate = protocol.load_labware('htgaa_agar_plate', 3, 'Agar Plate')
  pipette_20ul = protocol.load_instrument("p20_single_gen2", "right", tip_racks=[tips_20ul])

  pipette_20ul.starting_tip = tips_20ul.well('A1')
  center_location = agar_plate['A1'].top()

  size = 30 # Size in mm, designed to fit on 85mm agar plate
  vol = 20 # Volume to aspirate

  # Calculate image
  url = '<https://raw.githubusercontent.com/sness23/test-htgaa-mock/main/marilyn.csv>'
  data = pd.read_csv(url)
  data.columns = ["x", "y"]
  x = data['x']
  y = data['y']
  x_shift = x-((np.amin(x) + np.amax(x)/2))
  y_shift = y-((np.amin(y) + np.amax(y)/2))
  radius = np.sqrt(np.square(x_shift) + np.square(y_shift));
  x_trans = size/np.amax(radius)*x_shift;
  y_trans = size/np.amax(radius)*y_shift;
  center_location = agar_plate['A1'].top()
  cell_well = source_plate['A1']

  pipette_20ul.pick_up_tip()

  for i in range(len(x_trans)):
    pipette_20ul.aspirate(vol, cell_well)
    adjusted_location = center_location.move(types.Point(x_trans[i], y_trans[i]))
    pipette_20ul.dispense(vol, adjusted_location)
    hover_location = adjusted_location.move(types.Point(z = 2))
    pipette_20ul.move_to(hover_location)

  pipette_20ul.drop_tip()

Part 2

For this part, I wrote code to transfer liquid from a Nest 15ml well that we 3D printed at our makerspace to a 96 well tray, transfering each column in the Nest to the corresponding column in the 96 well tray:

def run(protocol: protocol_api.ProtocolContext):
    plate = protocol.load_labware('corning_96_wellplate_360ul_flat', 1)
    nest = protocol.load_labware('nest_12_reservoir_15ml',2)
    tiprack = protocol.load_labware('opentrons_96_tiprack_300ul', 3)
    p300 = protocol.load_instrument('p300_single', 'right', tip_racks=[tiprack])

    rows = ['A','B','C','D','E','F','G','H']
    cols = range(1,12)

    for row in rows:
        for col in cols:
            dest = row + str(col)
            p300.transfer(100, nest.wells()[col], plate[dest])