<Dominik Einfalt> — HTGAA Spring 2026

cover image cover image

About me

Hi, I am Dominik! I am an Vienna-based designer and transmedia artist working at the intersection of technology and nature. My artistic practice revolves around collaborating with living organisms — treating them not just as materials, but as creative partners. In 2024, I founded troost, a design studio dedicated to integrating living materials such as fungi and bacteria with contemporary manufacturing techniques like 3D-printing creating living hybrid design objects.

cover image cover image

Contact info

Homework

Labs

Projects

Subsections of <Dominik Einfalt> — HTGAA Spring 2026

Homework

Weekly homework submissions:

  • Week 1 HW: Principles and Practices

    W̵͈͛ḫ̶͗ą̵̔ṭ̸͌ ̴̩͝c̸̱̊l̶̬̄e̶̡̽a̸̙̚n̵̩͋ ̴̹̌W̷͈̃ả̴̯ẗ̶́ͅè̵͈r̶̲̆ ̵̝͐h̶̲̐ị̶̇ḏ̶͊e̷̼͆s̸̯̎ I would be interested in developing an environmental sensor (such as engineered bacteria) that detects hazardous contaminants like heavy metals (or possibly other pollutants) in water and responds by producing a strong, unpleasant smell. Many forms of modern pollution are dangerous but do not carry clear signs of danger with them. They are invisible, odorless, and difficult to !intuitively! recognize without specialized testing. This creates a disconnect between environmental harm and human perception, where water may appear clean while still being unsafe to consume.

  • Week 2 HW: DNA Read and Write and Edit

    Part 0: Basics of Gel Electrophoresis ✅ Part 1: Benchling & In-silico Gel Art DNA Crawler Part 2: Gel Art - Restriction Digests and Gel Electrophoresis Not possible - sadly I don’t have access to a lab. :/

  • Week 3 HW: Lab Automation

    Part 1: Design some Art This is I think not my final art - i would like to change it for the final submission but i wanted to check out how to write python first and if i manage to implement it. https://opentrons-art.rcdonovan.com/?id=uauqdo374y5jjq1 Part 2: Writing the python code I am not experienced with writing a python code so i had to try around quite a bit but I think I managed - at least the simulation tool gave me some results! :D

Subsections of Homework

Week 1 HW: Principles and Practices

cover image cover image

W̵͈͛ḫ̶͗ą̵̔ṭ̸͌ ̴̩͝c̸̱̊l̶̬̄e̶̡̽a̸̙̚n̵̩͋ ̴̹̌W̷͈̃ả̴̯ẗ̶́ͅè̵͈r̶̲̆ ̵̝͐h̶̲̐ị̶̇ḏ̶͊e̷̼͆s̸̯̎

I would be interested in developing an environmental sensor (such as engineered bacteria) that detects hazardous contaminants like heavy metals (or possibly other pollutants) in water and responds by producing a strong, unpleasant smell. Many forms of modern pollution are dangerous but do not carry clear signs of danger with them. They are invisible, odorless, and difficult to !intuitively! recognize without specialized testing. This creates a disconnect between environmental harm and human perception, where water may appear clean while still being unsafe to consume.

In my idea, I would like to develope a system using engineered bacteria as a living warning interface, with smell as an intuitive signal. When the modified bacteria sense the presence of contaminants like heavy metals, they activate the production of compounds associated (for humans) with decay or spoilage. Instead of explaining risk through data or visual indicators of water quality, the system communicates directly through the sense of smell.

The goal is not to create a precise diagnostic tool, but rather to create an embodied, instinctive response. If the water smells bad, the water is bad!

We have a very power detector implemented in our body. Humans can sense/smell some molecules with a concentration of up to 0.1 ppt. These melocules furthermore get associated them with emotions, body sensations and danger. But recent (mainly human-made) changes to our environment have introduced new harmful components to which our danger-detection-module, aka our nose, has not yet adapted. This project tries to create a tool that makes these otherwise invisible hazards “erfahrbar” (tangible).

By using smell as one of the most immediate and emotionally charged senses, this project tries to reframe synthetic biology as a new tool to make sense of our environment again. We can you organisms so we can communicate with with our surround once again.

(As my background as an artist I would like to create a art-installation with different water veils containing waters of different areas and qualities all looking like drinking water inviting poeple to smell.)

Containment and Control:

Prevent accidental release of genetically engineered bacteria into natural water systems.

•	Use of  containment strategies (e.g.kill switches that trigger if bacteria leave controlled environments).
•	Physical containment measures 
•	Regulatory oversight requiring testing in controlled environments before any field use!

Human and Ecological Safety:

Ensure that the compounds produced for smell signaling do not harm humans, animals, or microbes.

•	Risk assessment of any volatile compounds released.
•	Limits on concentration and exposure levels.
•	Monitoring for unintended ecological impacts (e.g., affecting local microbial communities or wildlife).

Transparency and Public Trust:

Ensure communities understand the presence and purpose of engineered bacteria in their environment.

•	Public disclosure of where, when, and why bacteria are used.
•	Clear labeling of water systems using the technology.
•	Education campaigns about benefits, risks, and safe interaction
cover image cover image

_̸̙͐͑̀́͐̀͠_̸͉̖͊̐̂͛͊̊͋͛͝_̴̧̨̞̖͎̞̆̀͑͝_̷̭̼͇̻̹̣͙̏̀͌_̵̣͉̘͖̦̺̣̼̔̎͗̉̓̚̚_̶͈̮̟͙̾̋̾̈_̶̣̮̟͍̬̣͉͖̒̓̋͆̚_̶͓̀̓_̶̨̥̗̥̭̯̖̐͊͝ͅ_̷̛͓̪̬̗̬̣̣̻̤͑̈̽̓́͝_̴̙͑̏͑̑̂̍_̴͚̥̾̃͗̈́̈̿̎͂_̷̰̦̟̹̩͍́_̸̥͕̏́̽̍̚ͅ_̸̲̬̬̩͑̋̈̆͝_̸̨̰̦̝̺̥͑̈́̌̕_̸̺̭̟̟͈̼̑́̋_̸̺͚̜̣̪̱̳̊̉̃̆͊͌̽͗͝_̴̻̘̲̬̓͋͗͐̊ͅ_̸͙̿̒̌͐͛_̷͎̝̝̮̬̘͆̀_̶̗̪̣͍̞́̒̀̽_̷̨͕̘̥̻͎̬̗̲̃̑̄͌̽̌͘͠_̴̥͆͛́̀̒_̵̡̥͈̺̩̫̊̾̐̒̒́̈̕͘_̶͓̤̮̲̰̳̑̋̆̂̈́̓͌̅͝_̵̛͖̤̿̇͑̓͘͝ͅ_̸̡͎͕͍̳̤̭͖̆̾̈́̿̎͊̕ͅ_̷̛̰̻̌͆͗̍̆͝͠_̷̙̱̯͑̑͒͑̓̽͌̆̚_̷̛̦̾̊̆̓̐̏́_̵̤̣̏̀̄̅͝͝_̸͈̰̹̝̭͔͖̓́̂̃͝_̸̨͓̯̖̜̳͊͜_̷̡̙̰͕̤̠̦̋͜_̵̧̳̬͍͇̱̟̓̋̾̏̈́̾́̚_̸͉͍̭̾͌͊͑̃̋͠_̴̬̪͛̀͆̂̓͠_̷͉̬̺̂́̅̚_̵͙̙̦̑̏͋͗_̶̹͈̼̮̯̾̈̽̀̇̅̿̀̉_̷̡̘͍͓͈͂͛̅͊͐̀͐̒͜͜͜͝_̵̮̰̱͈̖͍̲̼̉̈́̎͗̐_̸̰̠̪͕͊͝_̴̢͖̦̥̖̗̇̐̉̋_̸̢̞̻̣̜͑

Purpose

Currently, water contamination by hazardous substances such as heavy metals is primarily detected through technical, invisible methods: chemical test kits, laboratory analysis, sensors, and regulatory monitoring. These systems are effective but require infrastructure, expertise, time, and most importantly trust in abstract data. For everyday users, contaminated water frequently remains sensory-neutral. It smells, looks and tastes clean while still being unsafe. This project proposes a shift from data-driven warning systems to sensory communication. By engineering bacteria that recognize specific contaminants in water and respond by producing a strong, unpleasant odor, the system acts as a living warning interface. Rather than explaining risk through numbers, labels, or visual indicators, it communicates danger through smell. The proposed change is not to replace existing testing infrastructure, but to add an direct, embodied layer of perception that reconnects environmental risk with human intuition.

Design

Biological Design

•	Engineered bacteria capable of sensing specific contaminants 
(e.g. heavy metals, toxins, or microbial byproducts)
•	Genetic circuits linking detection to the production of unpleasant odor compounds
•	Built-in containment strategies 
(e.g. kill switches, nutrient dependency, physical encapsulation)

Technical & Contextual Design

•	Deployment in controlled environments 
(testing vessels, installations, water interfaces rather than open ecosystems)
•	Clear sensory thresholds so the smell is noticeable but not harmful
•	Systems for safe disposal of contaminated bacterial material

Actors Involved

•	Researchers design, test, and validate the sensing and odor-response mechanisms
•	Manufacturers produce the engineered bacteria under controlled conditions
•	Users (e.g. communities, institutions, artists) 
opt in to using the system as a warning tool
•	Organizations and regulators approve use cases, set safety standards, 
and oversee containment and disposal
•	Funders (academic, public, or artistic) support development, testing, and evaluation

Participation must be opt-in, and use would require approval by biosafety and ethics committees.

Assumptions

This project relies on several assumptions that may be incorrect:

•	That it is even possible to engineer such a bacteria 
(I am an artist and don’t have any experience with synthetic biology)
•	That containment systems will fully prevent unintended environmental release
•	That smell is universally interpreted as a warning signal 
(cultural differences may alter perception)
•	That bacteria can be engineered to respond specifically 
enough without too many false positives
•	That odor production can be strong, stable, and controllable across different environments
•	That users will trust sensory feedback over invisible data, 
or understand it as a warning rather than contamination itself

Risks of Failure & Success

Risks of Failure

•	False alarms could cause unnecessary panic or water avoidance
•	Odor production may be too weak, inconsistent, or overwhelming
•	Bacteria could die or mutate, reducing reliability
•	Containment failure could lead to environmental or regulatory concerns

Risks of Success

•	Smell-based warnings could stigmatize certain water sources or communities
•	The technology could be misused to intentionally create fear or disruption
•	Sensory warning systems might be adopted without adequate regulation due to their simplicity

_̸̙͐͑̀́͐̀͠_̸͉̖͊̐̂͛͊̊͋͛͝_̴̧̨̞̖͎̞̆̀͑͝_̷̭̼͇̻̹̣͙̏̀͌_̵̣͉̘͖̦̺̣̼̔̎͗̉̓̚̚_̶͈̮̟͙̾̋̾̈_̶̣̮̟͍̬̣͉͖̒̓̋͆̚_̶͓̀̓_̶̨̥̗̥̭̯̖̐͊͝ͅ_̷̛͓̪̬̗̬̣̣̻̤͑̈̽̓́͝_̴̙͑̏͑̑̂̍_̴͚̥̾̃͗̈́̈̿̎͂_̷̰̦̟̹̩͍́_̸̥͕̏́̽̍̚ͅ_̸̲̬̬̩͑̋̈̆͝_̸̨̰̦̝̺̥͑̈́̌̕_̸̺̭̟̟͈̼̑́̋_̸̺͚̜̣̪̱̳̊̉̃̆͊͌̽͗͝_̴̻̘̲̬̓͋͗͐̊ͅ_̸͙̿̒̌͐͛_̷͎̝̝̮̬̘͆̀_̶̗̪̣͍̞́̒̀̽_̷̨͕̘̥̻͎̬̗̲̃̑̄͌̽̌͘͠_̴̥͆͛́̀̒_̵̡̥͈̺̩̫̊̾̐̒̒́̈̕͘_̶͓̤̮̲̰̳̑̋̆̂̈́̓͌̅͝_̵̛͖̤̿̇͑̓͘͝ͅ_̸̡͎͕͍̳̤̭͖̆̾̈́̿̎͊̕ͅ_̷̛̰̻̌͆͗̍̆͝͠_̷̙̱̯͑̑͒͑̓̽͌̆̚_̷̛̦̾̊̆̓̐̏́_̵̤̣̏̀̄̅͝͝_̸͈̰̹̝̭͔͖̓́̂̃͝_̸̨͓̯̖̜̳͊͜_̷̡̙̰͕̤̠̦̋͜_̵̧̳̬͍͇̱̟̓̋̾̏̈́̾́̚_̸͉͍̭̾͌͊͑̃̋͠_̴̬̪͛̀͆̂̓͠_̷͉̬̺̂́̅̚_̵͙̙̦̑̏͋͗_̶̹͈̼̮̯̾̈̽̀̇̅̿̀̉_̷̡̘͍͓͈͂͛̅͊͐̀͐̒͜͜͜͝_̵̮̰̱͈̖͍̲̼̉̈́̎͗̐_̸̰̠̪͕͊͝_̴̢͖̦̥̖̗̇̐̉̋_̸̢̞̻̣̜͑

cover image cover image

Prioritized Governance Options

The highest priority should be given to Organizations and regulatory bodies as the primary actors for response, particularly in the areas of biosecurity and environmental protection. Because this project involves engineered organisms clear institutional oversight is essential. Regulatory and ethics organizations are best positioned to establish safety standards, define acceptable use cases, and respond to unintended consequences such as misuse, misinterpretation, or containment failure.

At the same time, Researchers should play a central role in monitoring, as they are most capable of evaluating long-term biological behavior and possible ?kill-switches?(I don’t know excactly how and if they are possible). Research institutions are also critical for containment strategies and for openly communicating limitations and uncertainties of the system.

cover image cover image

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?

Polymerase error rate: ~1 error per 10⁶ base pairs Human genome size: ~3.2 × 10⁹ base pairs (3.2 Gbp)

This would result in ~3,200 errors per genome replication which would be too many! To deal with it biology work with Error Correcting Polymerase, which lowers the error rate to ~10⁹.

2

The average Average Human Protein is made out of ~ 1036 bp.

With an average of around 3 bp per codon ≈ 333–345 amino acids. Number of DNA sequences≈3^345 different ways.

Changing a codon to a synonymous one often results in a non-functional or misfolded protein.

Homework Questions from Dr. LeProust:

1

The most commonly used method for oligonucleotide synthesis today is solid-phase phosphoramidite synthesis. Typically controlled-pore glass (CPG), carried out in a standard automated 96-well format.

2

Every cycle has an yield less than 100%. The error rate occurs with each synthesis cycle and accumulates exponentially over successive cycles.

3

The error rate ist still at around 1:2000 nt and it scale exponentially! There would be too many errors! :D

Homework Question from George Church:

1

Histidine (H) Isoleucine (I) Leucine (L) Lysine (K) Methionine (M) Phenylalanine (F) Threonine (T) Selenocysteine (U) Tryptophan (W) Valine (V)

It’s possible to engineer organisms that require supplemental lysine to survive. If lysine isn’t supplied, the organism cannot grow. For microbes, lysine dependency can act as a containment mechanism, but only under strict conditions:

•	The environment must lack lysine.
•	Cross-feeding from other organisms must be prevented.
•	Alternative biosynthesis pathways must not evolve.

Week 2 HW: DNA Read and Write and Edit

Part 0: Basics of Gel Electrophoresis

Part 1: Benchling & In-silico Gel Art

DNA Crawler

cover image cover image

Part 2: Gel Art - Restriction Digests and Gel Electrophoresis

Not possible - sadly I don’t have access to a lab. :/

Part 3: DNA Design Challenge

I chose MerR, a metal-responsive transcriptional regulator, because it directly senses toxic heavy metals (such as mercury) and converts that detection into a clear genetic on/off signal. This fits to my idea developed for HW1, where it’s all about detecting heavy metals in water.

cover image cover image

MerR Amino Acid Sequence

sp|P22853|MERR_BACCE Mercuric resistance operon regulatory protein OS=Bacillus cereus OX=1396 GN=merR1 PE=1 SV=1 MKFRIGELADKCGVNKETIRYYERLGLIPEPERTEKGYRMYSQQTVDRLHFIKRMQELGF TLNEIDKLLGVVDRDEAKCRDMYDFTILKIEDIQRKIEDLKRIERMLMDLKERCPENKDI YECPIIETLMKK

MerR DNA Sequence

ATGATGAAAT TTCGTATTGG TGAATTAGCT GATAAATGTG GTGTTAATAA AGAAACTATT CGTTATTATG AACGTTTAGG TTTAATTCCT GAACCTGAAC GTACTGAAAA AGGTTATCGT ATGTATTCTC AACAAACTGT TGATCGTTTA CATTTTATTA AACGTATGCA AGAATTAGGT TTTACTTTAA ATGAAATTGA TAAATTATTA GGTGTTGTTG ATCGTGATGA AGCTAAATGT CGTGATATGT ATGATTTTAC TATTTTAAAA ATTGAAGATA TTCAACGTAA AATTGAAGAT TTAAAACGTA TTGAACGTAT GTTAATGGAT TTAAAAGAAC GTTGTCCTGA AAATAAAGAT ATTTATGAAT GTCCTATTAT TGAAACTTTA ATGAAAAAAT AA

MerR Optimized Sequence

ATGAAGTTCCGGATTGGCGAGTTGGCTGATAAATGCGGCGTGAACAAGGAGACAATCCGATACTACGAGCGTCTGGGTCTGATACCGGAGCCGGAGCGGACTGAGAAGGGATACCGGATGTATTCCCAACAAACCGTGGACCGCCTGCACTTCATAAAGCGTATGCAAGAACTGGGGTTCACGCTCAACGAAATCGACAAACTGTTGGGTGTGGTTGATCGCGACGAAGCAAAATGTCGTGACATGTATGACTTCACGATACTTAAGATAGAGGACATTCAGCGCAAGATTGAGGATCTGAAGAGAATCGAAAGAATGTTGATGGACCTCAAGGAGCGGTGCCCAGAGAACAAGGACATCTACGAGTGTCCGATTATCGAAACGCTGATGAAGAAG

3.4. You have a sequence! Now what?

There are different ways how to get the proteins. There is cell -dependent and a cell-free option.

In a cell-dependent system, the gene, in my case the MerR-gene is inserted into a plasmid along with a promoter. When this DNA is introduced into a host cell (I optimized my sequence for the E.coli bacteria), the cell should be able to read the inserted DNA sequence and reproduce it.

Part 4: Prepare a Twist DNA Synthesis Order

What DNA would you want to sequence (e.g., read) and why?

I would want to sequence DNA from water samples. By reading this DNA I could try identify genes related to pollution tolerance or resistance (for example, heavy-metal resistance genes??). This information could help reveal hidden environmental stressors and contamination.

I would choose the second-generation, because i would have to sequence lots and lots of DNA in a fast way.

Input:

Extracted environmental DNA (eDNA) from water samples

Essential preparation steps:

  • DNA extraction from water (often after filtration)
  • Fragmentation of DNA into short pieces
  • Adapter ligation to both ends of fragments
  • PCR amplification to enrich adapter-ligated DNA

Essential sequencing steps and base calling

  • DNA fragments bind to the flow cell surface
  • Clusters of identical DNA fragments are generated (bridge amplification)
  • Fluorescently labeled nucleotides are added one base at a time
  • A camera records the emitted fluorescence after each incorporation
  • The color signals are converted into DNA bases (A, T, C, G) through base calling

Output

  • Short DNA sequences
  • Output files containing the DNA sequence
  • These reads can be analyzed to identify species, genes, and indicators of environmental contamination

DNA Write

I would want to synthesize a genetic sensor circuit for environmental heavy-metal detection working in bacteria.

Specifically, I would synthesize a DNA construct containing the merR gene and its metal-responsive promoter, coupled to a odor-producing reporter gene.

  • The MerR protein acts as a sensor: when a toxic metal is present, MerR changes conformation and activates transcription from its target promoter.

  • This promoter would then drive expression of genes that produce a strong smell.

Rather than synthesizing a whole genome, I would focus on a modular genetic circuit, including:

  • metal-sensing regulatory gene (merR),
  • metal-responsive promoter,
  • reporter module encoding enzymes that generate a bad odor.

This approach allows the circuit to be easily tested, tuned, and reused in different bacterial hosts.

Array-based oligonucleotide synthesis (phosphoramidite chemistry) is ideal because it allows many DNA sequences to be synthesized in parallel and relatively low cost. This is well suited for building modular genetic circuits (promoters, genes, regulatory elements) and rapidly iterating on designs.

Essential steps of the DNA synthesis method

  • Digital design of the DNA sequence (e.g. merR, promoter, reporter genes)
  • Chemical synthesis of short DNA on a silicon chip
  • Collection of synthesized oligos from the chip
  • Assembly of oligos into longer DNA fragments
  • Sequence verification before use

DNA Edit

I would want to edit the DNA of bacteria to enhance environmental sensing, specifically by modifying genes involved in heavy-metal detection and response. For example, I could edit the promoter or coding sequence of the merR gene to increase sensitivity to toxic metals, or introduce regulatory sequences that trigger production of a strong, unpleasant odor when contamination is detected.

The reason for these edits is to create a living environmental sensor that makes heavy metals/hazardous matter in water into an percieviable warning. By fine-tuning bacterial DNA in this way, we can make environmental risks tangible to humans through smell, bridging the gap between invisible pollution and instinctive human perception.

Beyond bacteria, similar editing could be applied to plants or other organisms used in biosensing, to increase their ability to indicate pollution or environmental stress without harming the organism or the ecosystem.

CRISPR

For editing bacterial DNA in my environmental sensor project, I would use CRISPR-Cas9 genome editing because it is precise, efficient, and widely used in bacteria.

CRISPR-Cas9 works as a programmable molecular scissor: a Cas9 nuclease is guided by a short RNA sequence (sgRNA) to a specific DNA target. Cas9 introduces a double-stranded break at the target site. The cell’s repair machinery afterwards fixes the break and giving the possibilty to introduce DNA.

Essential steps

  • Design the guide RNA (sgRNA) to target the DNA sequence I want to edit
  • Assemble the CRISPR-Cas9 system (Cas9 + sgRNA) on a plasmid or deliver as RNA/protein complex
  • Provide a repair template if precise edits are needed (for HDR)
  • Introduce the system into the host cells (e.g., bacteria via transformation or electroporation)
  • Allow cells to repair the DNA break, producing the desired edit
  • Screen and verify edited cells using sequencing

Limitations

  • Efficiency: HDR-based edits can be less efficient than NHEJ
  • Precision: Off-target cuts may occur if sgRNA binds similar sequences
  • Cell-dependence: Requires competent host cells capable of repairing DNA breaks
  • Size limitations: Very large DNA insertions can be more challenging

Week 3 HW: Lab Automation

Part 1: Design some Art

This is I think not my final art - i would like to change it for the final submission but i wanted to check out how to write python first and if i manage to implement it.

cover image cover image

https://opentrons-art.rcdonovan.com/?id=uauqdo374y5jjq1

Part 2: Writing the python code

I am not experienced with writing a python code so i had to try around quite a bit but I think I managed - at least the simulation tool gave me some results! :D

https://colab.research.google.com/drive/1I2iWDn4lVa5APjPBOefBhoj4b07UhK3X#scrollTo=pczDLwsq64mk&line=2&uniqifier=1

import subprocess, sys
subprocess.check_call([sys.executable, "-m", "pip", "install", "numpy", "pandas"])
import numpy as np
import pandas as pd

from opentrons import types

metadata = {    # see https://docs.opentrons.com/v2/tutorial.html#tutorial-metadata
    'author': 'Dominik Einfalt',
    'protocolName': 'HTGAA Opentrons Lab',
    'description': 'PetriPlant - Image on petri dish',
    '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 = 'B1'

well_colors = {
    'A1' : 'Red',
    'B1' : 'Green',
    'C1' : 'Orange'
}


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

  # 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 Module Plate
  temperature_plate = temperature_module.load_labware('opentrons_96_aluminumblock_generic_pcr_strip_200ul',
                                                      'Cold Plate')
  # Choose where to take the colors from
  color_plate = temperature_plate

  # Agar Plate
  agar_plate = protocol.load_labware('htgaa_agar_plate', AGAR_DECK_SLOT, 'Agar Plate')  ## TA MUST CALIBRATE EACH PLATE!
  # 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)

  ##############################################################################
  ###   Patterning
  ##############################################################################

  ###
  ### Helper functions for this lab
  ###

  # pass this e.g. 'Red' and get back a Location which can be passed to aspirate()
  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}")

  # For this lab, instead of calling pipette.dispense(1, loc) use this: dispense_and_detach(pipette, 1, loc)
  def dispense_and_detach(pipette, volume, location):
      """
      Move laterally 5mm above the plate (to avoid smearing a drop); then drop down to the plate,
      dispense, move back up 5mm to detach drop, and stay high to be ready for next lateral move.
      5mm because a 4uL drop is 2mm diameter; and a 2deg tilt in the agar pour is >3mm difference across a plate.
      """
      assert(isinstance(volume, (int, float)))
      above_location = location.move(types.Point(z=location.point.z + 5))  # 5mm above
      pipette.move_to(above_location)       # Go to 5mm above the dispensing location
      pipette.dispense(volume, location)    # Go straight downwards and dispense
      pipette.move_to(above_location)       # Go straight up to detach drop and stay high

  ###
  ### YOUR CODE HERE to create your design
  ###

   #Coordinates of my Design
  url = 'https://edit.htgaa.org/2026a-dominik-einfalt/webpages/raw/branch/main/content/homework/IMG/points_Petriplant.csv'
  world_coord = pd.read_csv(url)
  data = world_coord
  data.columns = ["x", "y"]


  x_value = data['x']
  y_value = data['y']

  #Change to location of green
  cell_well = color_plate['B1']


  # Aspirate
  pipette_20ul.pick_up_tip()

  for i in range(len(x_value)):
    if i%20 == 0:
      # pick up more every 20 uL, but only as much as we're going to need!
      pipette_20ul.aspirate(min(20, len(x_value)-i), cell_well)

    adjusted_location = center_location.move(types.Point(x_value[i], y_value[i]))
    pipette_20ul.dispense(1, adjusted_location)
    hover_location = adjusted_location.move(types.Point(z = 2))
    pipette_20ul.move_to(hover_location)

  pipette_20ul.drop_tip()

  # Don't forget to end with a drop_tip()
cover image cover image

https://colab.research.google.com/drive/1ah0k5Q00aQBtg8QPGjdbyycOvA5HUMBm#scrollTo=pczDLwsq4mk&line=158&uniqifier=1

cover image cover image
from opentrons import types
import math

metadata = {    # see https://docs.opentrons.com/v2/tutorial.html#tutorial-metadata
    'author': '',
    'protocolName': '',
    'description': '',
    '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
  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 Module Plate
  temperature_plate = temperature_module.load_labware('opentrons_96_aluminumblock_generic_pcr_strip_200ul',
                                                      'Cold Plate')
  # Choose where to take the colors from
  color_plate = temperature_plate

  # Agar Plate
  agar_plate = protocol.load_labware('htgaa_agar_plate', AGAR_DECK_SLOT, 'Agar Plate')  ## TA MUST CALIBRATE EACH PLATE!
  # 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)

  ##############################################################################
  ###   Patterning
  ##############################################################################

  ###
  ### Helper functions for this lab
  ###

  # pass this e.g. 'Red' and get back a Location which can be passed to aspirate()
  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}")

  # For this lab, instead of calling pipette.dispense(1, loc) use this: dispense_and_detach(pipette, 1, loc)
  def dispense_and_detach(pipette, volume, location):
      """
      Move laterally 5mm above the plate (to avoid smearing a drop); then drop down to the plate,
      dispense, move back up 5mm to detach drop, and stay high to be ready for next lateral move.
      5mm because a 4uL drop is 2mm diameter; and a 2deg tilt in the agar pour is >3mm difference across a plate.
      """
      assert(isinstance(volume, (int, float)))
      above_location = location.move(types.Point(z=location.point.z + 5))  # 5mm above
      pipette.move_to(above_location)       # Go to 5mm above the dispensing location
      pipette.dispense(volume, location)    # Go straight downwards and dispense
      pipette.move_to(above_location)       # Go straight up to detach drop and stay high

  ###
  ### YOUR CODE HERE to create your design
  ###


  startY = 34
  # halfStartY = int(startY/2)
  halfStartY = 17

  cursor = center_location.move(types.Point(x=-halfStartY, y = startY))

  triangle_radius = 15  # mm from center to each corner

# Equilateral triangle centered at (0,0)
  corners = [
    (0, triangle_radius),  # top corner
    (-triangle_radius * math.sin(math.pi/3),
     -triangle_radius / 2),  # bottom left
    (triangle_radius * math.sin(math.pi/3),
     -triangle_radius / 2)   # bottom right
    ]

  rows = 10
  spacing = 3.5

  points = []

  # Calculate offset to center the y-coordinates of the generated points
  total_height = (rows - 1) * spacing
  y_offset = total_height / 2

  for row in range(rows):
    for col in range(row + 1):
        x = (col - row/2) * spacing
        y = row * spacing - y_offset  # Adjust y to center the triangle vertically

        points.append((x, y))

  def barycentric_weights(px, py, c1, c2, c3):
    x1,y1 = c1
    x2,y2 = c2
    x3,y3 = c3

    det = (y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3)

    w1 = ((y2 - y3)*(px - x3) + (x3 - x2)*(py - y3)) / det
    w2 = ((y3 - y1)*(px - x3) + (x1 - x3)*(py - y3)) / det
    w3 = 1 - w1 - w2

    return w1, w2, w3

  total_volume = 3  # µL per dot

  red_well = color_plate['A1']
  green_well = color_plate['B1']
  orange_well = color_plate['C1']

  # Max volume the pipette can hold in one go
  pipette_max_vol = pipette_20ul.max_volume # This is 20uL for p20_single_gen2

  # Helper function to perform aspirate/multi-dispense/refill
  def perform_multi_dispense_for_color(pipette, color_source_well, all_dispense_tasks):
    if not all_dispense_tasks:
        return # Nothing to dispense

    pipette.pick_up_tip()
    current_volume_in_pipette = 0

    for i, (vol_to_dispense, loc_to_dispense) in enumerate(all_dispense_tasks):
      if current_volume_in_pipette < vol_to_dispense:
        # Calculate how much volume is still needed for the *remaining* dispenses
        remaining_needed = sum(task[0] for task in all_dispense_tasks[i:])

        # Calculate space available in pipette
        space_in_pipette = pipette_max_vol - current_volume_in_pipette

        # Aspirate the minimum of space available, and what is actually needed for remaining tasks
        amount_to_aspirate = min(space_in_pipette, remaining_needed)

        # Make sure we don't try to aspirate 0 or negative volume
        if amount_to_aspirate > 0:
          pipette.aspirate(amount_to_aspirate, color_source_well)
          current_volume_in_pipette += amount_to_aspirate

      dispense_and_detach(pipette, vol_to_dispense, loc_to_dispense)
      current_volume_in_pipette -= vol_to_dispense

    pipette.drop_tip()


  # =========================
  # RED PASS
  # =========================
  red_dispense_tasks = []
  for (x, y) in points:
    w1, w2, w3 = barycentric_weights(x, y, corners[0], corners[1], corners[2])
    red_vol = total_volume * w1
    if red_vol > 0:
      dispense_location = center_location.move(
          types.Point(x=x, y=y)
      )
      red_dispense_tasks.append((red_vol, dispense_location))

  perform_multi_dispense_for_color(pipette_20ul, red_well, red_dispense_tasks)


  # =========================
  # GREEN PASS
  # =========================
  green_dispense_tasks = []
  for (x, y) in points:
    w1, w2, w3 = barycentric_weights(x, y, corners[0], corners[1], corners[2])
    green_vol = total_volume * w2
    if green_vol > 0:
      dispense_location = center_location.move(
          types.Point(x=x, y=y)
      )
      green_dispense_tasks.append((green_vol, dispense_location))

  perform_multi_dispense_for_color(pipette_20ul, green_well, green_dispense_tasks)


  # =========================
  # ORANGE PASS
  # =========================
  orange_dispense_tasks = []
  for (x, y) in points:
    w1, w2, w3 = barycentric_weights(x, y, corners[0], corners[1], corners[2])
    orange_vol = total_volume * w3
    if orange_vol > 0:
      dispense_location = center_location.move(
          types.Point(x=x, y=y)
      )
      orange_dispense_tasks.append((orange_vol, dispense_location))

  perform_multi_dispense_for_color(pipette_20ul, orange_well, orange_dispense_tasks)

https://opentrons-art.rcdonovan.com/?id=uauqdo374y5jjq1

cover image cover imagecover image cover imagecover image cover image

Find and describe

AssemblyTron: flexible automation of DNA assembly with Opentrons OT-2 lab robots

The paper presents AssemblyTron, an open‑source software that automates DNA assembly on the Opentrons OT‑2 robot. It translates design outputs from tools like j5 into pipetting protocols, supporting PCR setup, Golden Gate assembly, and other DNA assembly methods. It showed high accuracy, reproduciblity and is comparable to manual assembly, but much faster and easier. This work demonstrates a low-cost, accessible approach to automating complex synthetic biology workflows, reducing human error and increasing throughput.

Write a description

Automated Dose–Response Mapping of Pollutant Detection

My project could use the Opentrons OT-2 to automate the dose–response analysis of heavy metal pollutants. The robot could perform automated serial dilutions to establish a concentration gradient of metals (e.g., lead, copper, or mercury) across a 96-well plate. It then handles the standardized inoculation of engineered bacteria, which are designed to produce an odor in response to specific contaminants. This automated setup allows for the rapid generation of quantitative dose–response maps, precisely linking pollutant levels to bacterial output while minimizing human error and increasing throughput.

Subsections of Labs

Week 1 Lab: Pipetting

cover image cover image

Subsections of Projects

Individual Final Project

cover image cover image

Group Final Project

cover image cover image