Ashraful — HTGAA Spring 2026

cover image
Ashraful profile photo

About me

Hi! I’m Ashraful, currently a fourth-year undergraduate student in Plant Biology at the University of Dhaka, Bangladesh. I am passionate about: Plant synthetic biology , Biosecurity & Agentic AI.

Contact info

Homework

Labs

Projects

Subsections of Ashraful — HTGAA Spring 2026

Homework

Weekly homework submissions:

    1. First, describe a biological engineering application or tool you want to develop and why.
      </div>
    </div>
    <div class="card-image">
        <img src="/2026a/md-ashraful-islam/homework/week-01-hw-principles-and-practices/cover-feature.jpeg">
    </div>
    
  • Part 1: Benchling & In-silico Gel Art Make a free account at benchling.com Import the Lambda DNA. Simulate Restriction Enzyme Digestion with the following Enzymes: EcoRI HindIII BamHI KpnI EcoRV SacI SalI
  • Python Script for Opentrons Artwork from opentrons import types import string metadata = { ‘protocolName’: ‘{Ashraful} - Opentrons Art - HTGAA’, ‘author’: ‘Ashraful’, ‘source’: ‘HTGAA 2026’, ‘apiLevel’: ‘2.20’ } Z_VALUE_AGAR = 2.0 POINT_SIZE = 0.75 sfgfp_points = [(-17.6,13.2), (-15.4,13.2), (-13.2,13.2), (-11,13.2), (-8.8,13.2), (11,13.2), (13.2,13.2), (15.4,13.2), (17.6,13.2), (-17.6,11), (-15.4,11), (-11,11), (-8.8,11), (8.8,11), (11,11), (13.2,11), (15.4,11), (17.6,11), (-15.4,8.8), (-13.2,8.8), (-8.8,8.8), (-6.6,8.8), (6.6,8.8), (8.8,8.8), (13.2,8.8), (15.4,8.8), (-13.2,6.6), (-11,6.6), (-6.6,6.6), (-4.4,6.6), (4.4,6.6), (6.6,6.6), (11,6.6), (13.2,6.6), (-11,4.4), (-8.8,4.4), (-4.4,4.4), (-2.2,4.4), (2.2,4.4), (4.4,4.4), (8.8,4.4), (11,4.4), (-8.8,2.2), (-6.6,2.2), (-2.2,2.2), (0,2.2), (2.2,2.2), (6.6,2.2), (8.8,2.2), (-6.6,0), (-4.4,0), (0,0), (4.4,0), (6.6,0), (-4.4,-2.2), (-2.2,-2.2), (0,-2.2), (2.2,-2.2), (4.4,-2.2), (-2.2,-4.4), (0,-4.4), (2.2,-4.4), (-2.2,-6.6), (0,-6.6), (2.2,-6.6), (-2.2,-8.8), (0,-8.8), (2.2,-8.8), (-2.2,-11), (0,-11), (2.2,-11), (-2.2,-13.2), (0,-13.2), (2.2,-13.2), (-11,-15.4), (-8.8,-15.4), (-6.6,-15.4), (-4.4,-15.4), (-2.2,-15.4), (0,-15.4), (2.2,-15.4), (4.4,-15.4), (6.6,-15.4), (8.8,-15.4), (11,-15.4), (13.2,-15.4), (-13.2,-17.6), (-11,-17.6), (-8.8,-17.6), (-6.6,-17.6), (-4.4,-17.6), (-2.2,-17.6), (0,-17.6), (2.2,-17.6), (4.4,-17.6), (6.6,-17.6), (8.8,-17.6), (11,-17.6), (13.2,-17.6), (15.4,-17.6), (-15.4,-19.8), (-13.2,-19.8), (-11,-19.8), (-8.8,-19.8), (-6.6,-19.8), (-4.4,-19.8), (-2.2,-19.8), (0,-19.8), (2.2,-19.8), (4.4,-19.8), (6.6,-19.8), (8.8,-19.8), (11,-19.8), (13.2,-19.8), (15.4,-19.8), (17.6,-19.8)] point_name_pairing = [(“sfgfp”, sfgfp_points)] # Robot deck setup constants TIP_RACK_DECK_SLOT = 9 COLORS_DECK_SLOT = 6 AGAR_DECK_SLOT = 5 PIPETTE_STARTING_TIP_WELL = ‘A1’ # Place the PCR tubes in this order well_colors = { ‘A1’: ‘sfGFP’, ‘A2’: ‘mRFP1’, ‘A3’: ‘mKO2’, ‘A4’: ‘Venus’, ‘A5’: ‘mKate2_TF’, ‘A6’: ‘Azurite’, ‘A7’: ‘mCerulean3’, ‘A8’: ‘mClover3’, ‘A9’: ‘mJuniper’, ‘A10’: ‘mTurquoise2’, ‘A11’: ‘mBanana’, ‘A12’: ‘mPlum’, ‘B1’: ‘Electra2’, ‘B2’: ‘mWasabi’, ‘B3’: ‘mScarlet_I’, ‘B4’: ‘mPapaya’, ‘B5’: ’eqFP578’, ‘B6’: ’tdTomato’, ‘B7’: ‘DsRed’, ‘B8’: ‘mKate2’, ‘B9’: ‘EGFP’, ‘B10’: ‘mRuby2’, ‘B11’: ‘TagBFP’, ‘B12’: ‘mChartreuse_TF’, ‘C1’: ‘mLychee_TF’, ‘C2’: ‘mTagBFP2’, ‘C3’: ‘mEGFP’, ‘C4’: ‘mNeonGreen’, ‘C5’: ‘mAzamiGreen’, ‘C6’: ‘mWatermelon’, ‘C7’: ‘avGFP’, ‘C8’: ‘mCitrine’, ‘C9’: ‘mVenus’, ‘C10’: ‘mCherry’, ‘C11’: ‘mHoneydew’, ‘C12’: ‘TagRFP’, ‘D1’: ‘mTFP1’, ‘D2’: ‘Ultramarine’, ‘D3’: ‘ZsGreen1’, ‘D4’: ‘mMiCy’, ‘D5’: ‘mStayGold2’, ‘D6’: ‘PA_GFP’ } # Mapping for visualization colors VISUALIZATION_COLOR_MAP = { ‘sfGFP’: ‘green’, ‘mRFP1’: ‘red’, ‘mKO2’: ‘orange’, ‘Venus’: ‘yellow’, ‘mKate2_TF’: ‘purple’, ‘Azurite’: ‘blue’, ‘mCerulean3’: ‘cyan’, ‘mClover3’: ’lightgreen’, ‘mJuniper’: ‘darkgreen’, ‘mTurquoise2’: ’teal’, ‘mBanana’: ‘gold’, ‘mPlum’: ‘plum’, ‘Electra2’: ’navy’, ‘mWasabi’: ’lime’, ‘mScarlet_I’: ‘darkred’, ‘mPapaya’: ‘peachpuff’, ’eqFP578’: ‘brown’, ’tdTomato’: ’tomato’, ‘DsRed’: ‘indianred’, ‘mKate2’: ‘darkmagenta’, ‘EGFP’: ‘chartreuse’, ‘mRuby2’: ‘firebrick’, ‘TagBFP’: ‘slateblue’, ‘mChartreuse_TF’: ‘darkseagreen’, ‘mLychee_TF’: ‘palevioletred’, ‘mTagBFP2’: ‘darkblue’, ‘mEGFP’: ’limegreen’, ‘mNeonGreen’: ’lawngreen’, ‘mAzamiGreen’: ‘mediumseagreen’, ‘mWatermelon’: ‘pink’, ‘avGFP’: ‘forestgreen’, ‘mCitrine’: ‘khaki’, ‘mVenus’: ‘olivedrab’, ‘mCherry’: ‘crimson’, ‘mHoneydew’: ‘honeydew’, # This will likely be too light ‘TagRFP’: ‘rosybrown’, ‘mTFP1’: ‘dodgerblue’, ‘Ultramarine’: ‘mediumblue’, ‘ZsGreen1’: ‘springgreen’, ‘mMiCy’: ‘peru’, ‘mStayGold2’: ‘goldenrod’, ‘PA_GFP’: ‘darkgreen’ } volume_used = { ‘sfgfp’: 0 } def update_volume_remaining(current_color, quantity_to_aspirate): rows = string.ascii_uppercase for well, color in list(well_colors.items()): if color == current_color: if (volume_used[current_color] + quantity_to_aspirate) > 250: # Move to next well horizontally by advancing row letter, keeping column number row = well[0] col = well[1:] # Find next row letter next_row = rows[rows.index(row) + 1] next_well = f"{next_row}{col}" del well_colors[well] well_colors[next_well] = current_color volume_used[current_color] = quantity_to_aspirate else: volume_used[current_color] += quantity_to_aspirate break def run(protocol): # Load labware, modules and pipettes protocol.home() # 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]) # Deep Well Plate temperature_plate = protocol.load_labware(’nest_96_wellplate_2ml_deep’, 6, ‘Deep Well Plate’) # Agar Plate agar_plate = protocol.load_labware(‘htgaa_agar_plate’, AGAR_DECK_SLOT, ‘Agar Plate’) agar_plate.set_offset(x=0.00, y=0.00, z=Z_VALUE_AGAR) # Get the top-center of the plate, make sure the plate was calibrated before running this center_location = agar_plate[‘A1’].top() pipette_20ul.starting_tip = tips_20ul.well(PIPETTE_STARTING_TIP_WELL) # Helper function (dispensing) def dispense_and_jog(pipette, volume, location): assert(isinstance(volume, (int, float))) # Go above the location above_location = location.move(types.Point(z=location.point.z + 2)) pipette.move_to(above_location) # Go downwards and dispense pipette.dispense(volume, location) # Go upwards to avoid smearing pipette.move_to(above_location) # Helper function (color location) def location_of_color(color_string): for well,color in well_colors.items(): if color.lower() == color_string.lower(): return temperature_plate[well] raise ValueError(f"No well found with color {color_string}") # Print pattern by iterating over lists for i, (current_color, point_list) in enumerate(point_name_pairing): # Skip the rest of the loop if the list is empty if not point_list: continue # Get the tip for this run, set the bacteria color, and the aspirate bacteria of choice pipette_20ul.pick_up_tip() max_aspirate = int(18 // POINT_SIZE) * POINT_SIZE quantity_to_aspirate = min(len(point_list)*POINT_SIZE, max_aspirate) update_volume_remaining(current_color, quantity_to_aspirate) pipette_20ul.aspirate(quantity_to_aspirate, location_of_color(current_color)) # Iterate over the current points list and dispense them, refilling along the way for i in range(len(point_list)): x, y = point_list[i] adjusted_location = center_location.move(types.Point(x, y)) dispense_and_jog(pipette_20ul, POINT_SIZE, adjusted_location) if pipette_20ul.current_volume == 0 and len(point_list[i+1:]) > 0: quantity_to_aspirate = min(len(point_list[i:])*POINT_SIZE, max_aspirate) update_volume_remaining(current_color, quantity_to_aspirate) pipette_20ul.aspirate(quantity_to_aspirate, location_of_color(current_color)) # Drop tip between each color pipette_20ul.drop_tip() Simulation # Execute Simulation / Visualization protocol = OpentronsMock(well_colors, VISUALIZATION_COLOR_MAP) run(protocol) protocol.visualize() Post-Lab Questions Find and describe a published paper that utilizes the Opentrons or an automation tool to achieve novel biological applications.

Subsections of Homework

Week 1 HW: Principles and Practices

cover image cover image

1. First, describe a biological engineering application or tool you want to develop and why.

I want to develop a plant stress-responsive synthetic gene circuit in a chloroplast-derived cell-free system that detects stress signals like pathogen RNA or heavy metals and produces a visible reporter output. This tool enables rapid, safe prototyping of plant gene circuits and allows assessment of biosecurity risks, such as misfires or misuse, without using live plants. The primary motivation for this project is to build upon and extend the work of the 2021 iGEM Marburg team, leveraging their foundational advances to develop more responsive and secure plant synthetic biology tools.

2. Next, describe one or more governance/policy goals related to ensuring that this application or tool contributes to an “ethical” future, like ensuring non-malfeasance (preventing harm). Break big goals down into two or more specific sub-goals.

Goal: Ensure safe and responsible use of plant stress-responsive synthetic gene circuits.

Sub-goals: Prevent misuse or accidental harm using logic gates, kill switches, and monitoring protocols. Promote constructive applications for crop protection and biosecurity preparedness. Maintain transparency and accountability through documentation and ethical guidelines.

3. Next, describe at least three different potential governance “actions” by considering the four aspects below (Purpose, Design, Assumptions, Risks of Failure & “Success”): 1. Purpose: 2. Design: 3. Assumptions: 4. Risks of Failure & “Success”:

ActionPurposeDesignAssumptionsRisks of Failure & Success
1. Circuit SafeguardsRequire logic gates, kill switches, self-limiting designsResearchers design safeguards; regulators certifySafeguards reliably prevent harmFailure: safeguards bypassed or misconfigured; Success: false sense of security reduces oversight
2. Pre-Deployment Risk AssessmentMandatory biosecurity assessment before field useResearchers submit risk reports; regulators approveRisks can be anticipated and mitigatedFailure: assessments become superficial; Success: bureaucratic compliance slows innovation
3. Incentive-Based Governance & Responsible-Use NormsPromote safe, transparent, and ethical plant synbio useFunders require safety plans, audits, and trainingIncentives motivate responsible behaviorFailure: voluntary uptake limits coverage; Success: norms diffuse unevenly across actors

4. Next, score (from 1-3, with 1 as the best, or n/a) each of your governance actions against your rubric of policy goals. The following is one framework but feel free to make your own:

Does the option:Option 1: Circuit SafeguardsOption 2: Pre-Deployment Risk AssessmentOption 3: Incentive-Based Governance & Responsible-Use Norms
Enhance Biosecurity
• By preventing incidents123
• By helping respond212
Foster Lab Safety
• By preventing incidents122
• By helping respond212
Protect the environment
• By preventing incidents122
• By helping respond213
Other considerations
• Minimizing costs/burdens231
• Feasibility121
• Does not impede research231
• Promote constructive applications221

5. Last, drawing upon this scoring, describe which governance option, or combination of options, you would prioritize, and why. Outline any trade-offs you considered as well as assumptions and uncertainties.

Based on the scoring, I prioritize a combined approach led by Option 1 (Circuit Safeguards) and Option 3 (Incentive-Based Governance & Responsible-Use Norms), with Option 2 (Pre-Deployment Risk Assessment) applied selectively to higher-risk projects. Circuit safeguards are most effective at preventing incidents by embedding safety directly into design, while incentive-based governance best preserves feasibility, equity, and research freedom. Risk assessments are valuable for response and preparedness, but can impose high burdens if universally required. Key trade-offs involve balancing prevention with flexibility. Ethical concerns include overreliance on technical fixes and inequitable access; tiered governance and ongoing safety education help address these risks.

Assignment (Week 2 Lecture Prep)

Homework Questions from Professor Jacobson:

  1. Nature’s machinery for copying DNA is called polymerase. What is the error rate of polymerase? How does this compare to the length of the human genome. How does biology deal with that discrepancy?

    The error rate of the polymerase is 1 in 10⁶ bases. The human genome is approximately 3 × 10⁹ base pairs long. Therefore, when compared to the length of the human genome, this error rate corresponds to about 3 × 10³ errors per genome. Biology deals with this discrepency by proofreading, mismatch repair (MMR) system, & redundancy and selection.

  2. How many different ways are there to code (DNA nucleotide code) for an average human protein? In practice what are some of the reasons that all of these different codes don’t work to code for the protein of interest?

The number of different DNA sequences (theoretical): ~3⁴⁰⁰ ≈ 10¹⁹⁰ for a 400-amino-acid protein. Many DNA sequences don’t work in practice due to codon usage bias, mRNA structure, protein folding dynamics, regulatory elements, and mutation robustness/cellular context.

Homework Questions from Dr. LeProust:

  1. What’s the most commonly used method for oligo synthesis currently?

    Phosphoramidite (solid‑phase) chemistry.

  2. Why is it difficult to make oligos longer than 200nt via direct synthesis?

Per‑cycle inefficiencies and side reactions cause the full‑length fraction to fall rapidly with length.

  1. Why can’t you make a 2000bp gene via direct oligo synthesis?

The cumulative yield of full‑length product becomes essentially zero; chemical synthesis is not scalable to kilobase lengths.

Homework Question from George Church:

  1. What are the 10 essential amino acids in all animals and how does this affect your view of the “Lysine Contingency”?

Ten amino acids commonly treated as essential for animals: Lysine; Methionine; Tryptophan; Threonine; Valine; Isoleucine; Leucine; Arginine; Histidine; Phenylalanine. Lysine auxotrophy is a useful mitigation but not a reliable sole safeguard —it can be rescued by environmental lysine, cross‑feeding, or genetic escape, so treat it as one layer in a multi‑layered containment strategy.

(For completing the second part of the homework (Week 2 preparation), I verified my answers and summarized the lecture slides to clarify specific points, using ChatGPT as a support tool.)

Week 2 HW: DNA Read, Write and Edit

Part 1: Benchling & In-silico Gel Art

  1. Make a free account at benchling.com
  2. Import the Lambda DNA.

search search import import import import

  1. Simulate Restriction Enzyme Digestion with the following Enzymes: EcoRI HindIII BamHI KpnI EcoRV SacI SalI digest digest digest digest virtual digest virtual digest

  2. Create a pattern/image in the style of Paul Vanouse’s Latent Figure Protocol artworks. pattern pattern

Part 3: DNA Design Challenge

The sequence of the peotein is:

MSNKKQSNRLTEQHKLSQGVIGIFGDYAKAHDLAVGEVSKLVKKALSNEYPQLSFRYRDSIKKTEINEALKKIDPDLGGTLFVSNSSIKPDGGIVEVKDDYGEWRVVLVAEAKHQGKDIINIRNGLLVGKRGDQDLMAAGNAIERSHKNISEIANFMLSESHFPYVLFLEGSNFLTENISITRPDGRVVNLEYNSGILNRLDRLTAANYGMPINSNLCINKFVNHKDKSIMLQAASIYTQGDGREWDSKIMFEIMFDISTTSLRVLGRDLFEQLTSK
reverse translate reverse translate

The reverse translated sequence is:

atgagcaacaaaaaacagagcaaccgcctgaccgaacagcataaactgagccagggcgtg
attggcatttttggcgattatgcgaaagcgcatgatctggcggtgggcgaagtgagcaaa
ctggtgaaaaaagcgctgagcaacgaatatccgcagctgagctttcgctatcgcgatagc
attaaaaaaaccgaaattaacgaagcgctgaaaaaaattgatccggatctgggcggcacc
ctgtttgtgagcaacagcagcattaaaccggatggcggcattgtggaagtgaaagatgat
tatggcgaatggcgcgtggtgctggtggcggaagcgaaacatcagggcaaagatattatt
aacattcgcaacggcctgctggtgggcaaacgcggcgatcaggatctgatggcggcgggc
aacgcgattgaacgcagccataaaaacattagcgaaattgcgaactttatgctgagcgaa
agccattttccgtatgtgctgtttctggaaggcagcaactttctgaccgaaaacattagc
attacccgcccggatggccgcgtggtgaacctggaatataacagcggcattctgaaccgc
ctggatcgcctgaccgcggcgaactatggcatgccgattaacagcaacctgtgcattaac
aaatttgtgaaccataaagataaaagcattatgctgcaggcggcgagcatttatacccag
ggcgatggccgcgaatgggatagcaaaattatgtttgaaattatgtttgatattagcacc
accagcctgcgcgtgctgggccgcgatctgtttgaacagctgaccagcaaa

Codon Optimization codon_optimization codon_optimization codon_optimization_ result codon_optimization_ result

Week 3 HW: Lab Automation

cover image cover image

Python Script for Opentrons Artwork

from opentrons import types

import string

metadata = {
    'protocolName': '{Ashraful} - Opentrons Art - HTGAA',
    'author': 'Ashraful',
    'source': 'HTGAA 2026',
    'apiLevel': '2.20'
}

Z_VALUE_AGAR = 2.0
POINT_SIZE = 0.75

sfgfp_points = [(-17.6,13.2), (-15.4,13.2), (-13.2,13.2), (-11,13.2), (-8.8,13.2), (11,13.2), (13.2,13.2), (15.4,13.2), (17.6,13.2), (-17.6,11), (-15.4,11), (-11,11), (-8.8,11), (8.8,11), (11,11), (13.2,11), (15.4,11), (17.6,11), (-15.4,8.8), (-13.2,8.8), (-8.8,8.8), (-6.6,8.8), (6.6,8.8), (8.8,8.8), (13.2,8.8), (15.4,8.8), (-13.2,6.6), (-11,6.6), (-6.6,6.6), (-4.4,6.6), (4.4,6.6), (6.6,6.6), (11,6.6), (13.2,6.6), (-11,4.4), (-8.8,4.4), (-4.4,4.4), (-2.2,4.4), (2.2,4.4), (4.4,4.4), (8.8,4.4), (11,4.4), (-8.8,2.2), (-6.6,2.2), (-2.2,2.2), (0,2.2), (2.2,2.2), (6.6,2.2), (8.8,2.2), (-6.6,0), (-4.4,0), (0,0), (4.4,0), (6.6,0), (-4.4,-2.2), (-2.2,-2.2), (0,-2.2), (2.2,-2.2), (4.4,-2.2), (-2.2,-4.4), (0,-4.4), (2.2,-4.4), (-2.2,-6.6), (0,-6.6), (2.2,-6.6), (-2.2,-8.8), (0,-8.8), (2.2,-8.8), (-2.2,-11), (0,-11), (2.2,-11), (-2.2,-13.2), (0,-13.2), (2.2,-13.2), (-11,-15.4), (-8.8,-15.4), (-6.6,-15.4), (-4.4,-15.4), (-2.2,-15.4), (0,-15.4), (2.2,-15.4), (4.4,-15.4), (6.6,-15.4), (8.8,-15.4), (11,-15.4), (13.2,-15.4), (-13.2,-17.6), (-11,-17.6), (-8.8,-17.6), (-6.6,-17.6), (-4.4,-17.6), (-2.2,-17.6), (0,-17.6), (2.2,-17.6), (4.4,-17.6), (6.6,-17.6), (8.8,-17.6), (11,-17.6), (13.2,-17.6), (15.4,-17.6), (-15.4,-19.8), (-13.2,-19.8), (-11,-19.8), (-8.8,-19.8), (-6.6,-19.8), (-4.4,-19.8), (-2.2,-19.8), (0,-19.8), (2.2,-19.8), (4.4,-19.8), (6.6,-19.8), (8.8,-19.8), (11,-19.8), (13.2,-19.8), (15.4,-19.8), (17.6,-19.8)]

point_name_pairing = [("sfgfp", sfgfp_points)]

# Robot deck setup constants
TIP_RACK_DECK_SLOT = 9
COLORS_DECK_SLOT = 6
AGAR_DECK_SLOT = 5
PIPETTE_STARTING_TIP_WELL = 'A1'

# Place the PCR tubes in this order
well_colors = {
    'A1': 'sfGFP',
    'A2': 'mRFP1',
    'A3': 'mKO2',
    'A4': 'Venus',
    'A5': 'mKate2_TF',
    'A6': 'Azurite',
    'A7': 'mCerulean3',
    'A8': 'mClover3',
    'A9': 'mJuniper',
    'A10': 'mTurquoise2',
    'A11': 'mBanana',
    'A12': 'mPlum',
    'B1': 'Electra2',
    'B2': 'mWasabi',
    'B3': 'mScarlet_I',
    'B4': 'mPapaya',
    'B5': 'eqFP578',
    'B6': 'tdTomato',
    'B7': 'DsRed',
    'B8': 'mKate2',
    'B9': 'EGFP',
    'B10': 'mRuby2',
    'B11': 'TagBFP',
    'B12': 'mChartreuse_TF',
    'C1': 'mLychee_TF',
    'C2': 'mTagBFP2',
    'C3': 'mEGFP',
    'C4': 'mNeonGreen',
    'C5': 'mAzamiGreen',
    'C6': 'mWatermelon',
    'C7': 'avGFP',
    'C8': 'mCitrine',
    'C9': 'mVenus',
    'C10': 'mCherry',
    'C11': 'mHoneydew',
    'C12': 'TagRFP',
    'D1': 'mTFP1',
    'D2': 'Ultramarine',
    'D3': 'ZsGreen1',
    'D4': 'mMiCy',
    'D5': 'mStayGold2',
    'D6': 'PA_GFP'
}

# Mapping for visualization colors
VISUALIZATION_COLOR_MAP = {
    'sfGFP': 'green',
    'mRFP1': 'red',
    'mKO2': 'orange',
    'Venus': 'yellow',
    'mKate2_TF': 'purple',
    'Azurite': 'blue',
    'mCerulean3': 'cyan',
    'mClover3': 'lightgreen',
    'mJuniper': 'darkgreen',
    'mTurquoise2': 'teal',
    'mBanana': 'gold',
    'mPlum': 'plum',
    'Electra2': 'navy',
    'mWasabi': 'lime',
    'mScarlet_I': 'darkred',
    'mPapaya': 'peachpuff',
    'eqFP578': 'brown',
    'tdTomato': 'tomato',
    'DsRed': 'indianred',
    'mKate2': 'darkmagenta',
    'EGFP': 'chartreuse',
    'mRuby2': 'firebrick',
    'TagBFP': 'slateblue',
    'mChartreuse_TF': 'darkseagreen',
    'mLychee_TF': 'palevioletred',
    'mTagBFP2': 'darkblue',
    'mEGFP': 'limegreen',
    'mNeonGreen': 'lawngreen',
    'mAzamiGreen': 'mediumseagreen',
    'mWatermelon': 'pink',
    'avGFP': 'forestgreen',
    'mCitrine': 'khaki',
    'mVenus': 'olivedrab',
    'mCherry': 'crimson',
    'mHoneydew': 'honeydew', # This will likely be too light
    'TagRFP': 'rosybrown',
    'mTFP1': 'dodgerblue',
    'Ultramarine': 'mediumblue',
    'ZsGreen1': 'springgreen',
    'mMiCy': 'peru',
    'mStayGold2': 'goldenrod',
    'PA_GFP': 'darkgreen'
}

volume_used = {
    'sfgfp': 0
}

def update_volume_remaining(current_color, quantity_to_aspirate):
    rows = string.ascii_uppercase
    for well, color in list(well_colors.items()):
        if color == current_color:
            if (volume_used[current_color] + quantity_to_aspirate) > 250:
                # Move to next well horizontally by advancing row letter, keeping column number
                row = well[0]
                col = well[1:]

                # Find next row letter
                next_row = rows[rows.index(row) + 1]
                next_well = f"{next_row}{col}"

                del well_colors[well]
                well_colors[next_well] = current_color
                volume_used[current_color] = quantity_to_aspirate
            else:
                volume_used[current_color] += quantity_to_aspirate
            break

def run(protocol):
    # Load labware, modules and pipettes
    protocol.home()

    # 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])

    # Deep Well Plate
    temperature_plate = protocol.load_labware('nest_96_wellplate_2ml_deep', 6, 'Deep Well Plate')

    # Agar Plate
    agar_plate = protocol.load_labware('htgaa_agar_plate', AGAR_DECK_SLOT, 'Agar Plate')
    agar_plate.set_offset(x=0.00, y=0.00, z=Z_VALUE_AGAR)

    # Get the top-center of the plate, make sure the plate was calibrated before running this
    center_location = agar_plate['A1'].top()

    pipette_20ul.starting_tip = tips_20ul.well(PIPETTE_STARTING_TIP_WELL)

    # Helper function (dispensing)
    def dispense_and_jog(pipette, volume, location):
        assert(isinstance(volume, (int, float)))
        # Go above the location
        above_location = location.move(types.Point(z=location.point.z + 2))
        pipette.move_to(above_location)
        # Go downwards and dispense
        pipette.dispense(volume, location)
        # Go upwards to avoid smearing
        pipette.move_to(above_location)

    # Helper function (color location)
    def location_of_color(color_string):
        for well,color in well_colors.items():
            if color.lower() == color_string.lower():
                return temperature_plate[well]
        raise ValueError(f"No well found with color {color_string}")

    # Print pattern by iterating over lists
    for i, (current_color, point_list) in enumerate(point_name_pairing):
        # Skip the rest of the loop if the list is empty
        if not point_list:
            continue

        # Get the tip for this run, set the bacteria color, and the aspirate bacteria of choice
        pipette_20ul.pick_up_tip()
        max_aspirate = int(18 // POINT_SIZE) * POINT_SIZE
        quantity_to_aspirate = min(len(point_list)*POINT_SIZE, max_aspirate)
        update_volume_remaining(current_color, quantity_to_aspirate)
        pipette_20ul.aspirate(quantity_to_aspirate, location_of_color(current_color))

        # Iterate over the current points list and dispense them, refilling along the way
        for i in range(len(point_list)):
            x, y = point_list[i]
            adjusted_location = center_location.move(types.Point(x, y))

            dispense_and_jog(pipette_20ul, POINT_SIZE, adjusted_location)

            if pipette_20ul.current_volume == 0 and len(point_list[i+1:]) > 0:
                quantity_to_aspirate = min(len(point_list[i:])*POINT_SIZE, max_aspirate)
                update_volume_remaining(current_color, quantity_to_aspirate)
                pipette_20ul.aspirate(quantity_to_aspirate, location_of_color(current_color))

        # Drop tip between each color
        pipette_20ul.drop_tip()

Simulation

# Execute Simulation / Visualization
protocol = OpentronsMock(well_colors, VISUALIZATION_COLOR_MAP)
run(protocol)
protocol.visualize()
Artwork Image Artwork Image

Post-Lab Questions

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

paper title paper title paper workflow paper workflow

In the paper “An open-source, automated, and cost-effective platform for COVID-19 diagnosis and rapid portable genomic surveillance using nanopore sequencing” published in Scientific Reports, the researchers integrated a robotic liquid-handling system (Tecan Freedom EVO) to automate the MAVRICS RNA extraction workflow in a 96-well format. The robot performed magnetic bead–based RNA extraction, washing, and transfer steps with optimized pipetting and contamination-control measures, allowing high-throughput and reproducible processing of clinical samples. The automated extraction was then combined with in-house qRT-PCR diagnostics and the portable NIRVANA nanopore sequencing system for variant tracking. This automation significantly reduced human error and cross-contamination, increased testing capacity (up to thousands of samples per day), and enabled scalable, low-cost pandemic response—highlighting the importance of robotic tools in biosecurity, diagnostics, and rapid outbreak surveillance.

  1. 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.

Automated Workflow for Screening EcoRI Constructs in Cell-Free System

1. Echo – DNA Transfer  
Transfer codon-optimized EcoRI DNA constructs into designated wells with high precision.

2. Bravo – Master Mix Addition  
Add CFPS master mix containing buffers and cofactors uniformly to all wells.

3. Multiflo – Start Reaction  
Dispense cell-free lysate into each well to initiate protein synthesis.

4. PlateLoc – Seal Plate  
Seal the plate to prevent evaporation and contamination during incubation.

5. Inheco – Incubation  
Maintain optimal temperature (e.g., 37°C) for EcoRI protein expression.

6. XPeel – Remove Seal  
Open the plate safely to prepare for downstream reactions or measurements.

7. PHERAstar – Measure Output  
Quantify EcoRI activity on fluorescent DNA substrates to compare construct performance.

Week 4 HW: Protein Design Part 1

Week 5 HW: Protein Design Part 2

Week 6 HW: Genetic Circuits Part 1

Week 7 HW: Genetic Circuits Part 2

Subsections of Labs

Week 1 Lab: Pipetting

cover image cover image

Week 2 Lab: DNA Gel Art

Week 3 Lab: Opentrons Art

Week 4 Lab: Protein Design Part 1

Week 5 Lab: Protein Design Part 2

Week 6 Lab: Gibson Assembly

Week 7 Lab: Neuromorphic Circuits

Subsections of Projects

Individual Final Project

cover image cover image

Group Final Project

cover image cover image