Steven Ness : Committed Listener, Victoria, BC
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()
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])