<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>johnowhitaker.dev</title>
<link>https://johnowhitaker.dev/</link>
<atom:link href="https://johnowhitaker.dev/index.xml" rel="self" type="application/rss+xml"/>
<description></description>
<generator>quarto-1.10.1</generator>
<lastBuildDate>Thu, 02 Apr 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>AGGG (Airsoft Gun Gene Gun) Part 2 - Hints of Success?</title>
  <link>https://johnowhitaker.dev/mini-hw-projects/asgg2.html</link>
  <description><![CDATA[ 




<p>In a <a href="https://johnowhitaker.dev/mini-hw-projects/airsoft-gene-gun.html">previous post</a>, I pointed out that a gene gun (fancy, $XXXXX) and a cheap airsoft gun share a lot in common. Now that I <a href="https://johnowhitaker.dev/posts/dnaq.html">have DNA</a>, it was time to pew pew - and it looks like maybe we got some transformations! I’ll explain what I’ve tried, what I found, what I’m thinking, and what I hope to try next.</p>
<section id="the-method" class="level2">
<h2 class="anchored" data-anchor-id="the-method">The Method</h2>
<p>I take a small amount (10uL) of a slurry of diatomaceous earth (DE), add some (10uL, 50mM) calcium chloride and some (~1ug, in ~2uL) plasmid DNA and place it on a piece of parafilm stretched over a 3D-printed tube. I dry it in a filtered stream of air, then the tube adapts to the end of my cheap airsoft pistol, and I fire it at a leaf from a few cm distance.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/asgg_bullet_prep.jpg" class="img-fluid figure-img"></p>
<figcaption>‘Bullet’ prep with slurries of graphite powder and DE waiting to dry</figcaption>
</figure>
</div>
<p>The DNA I have codes for the ‘RUBY’ reporter, which expresses a red pigment. I extracted the DNA from bacteria carrying this plasmid which I got from <a href="https://atinygreencell.com/products/pcambia2300-rubygreen">Sebastian’s Biotech Bazaar</a>. I used <a href="https://bioland-sci.com/products/plasmid-miniprep-ii-kit-50-preps?pr_prod_strat=e5_desc&amp;pr_rec_id=821821b3f&amp;pr_rec_pid=8042713055421&amp;pr_ref_pid=8042712826045&amp;pr_seq=uniform">this miniprep kit</a> to purify out the plasmid DNA.</p>
</section>
<section id="findings" class="level2">
<h2 class="anchored" data-anchor-id="findings">Findings</h2>
<p>I shot some tobacco leaves, some duckweed, a slice of carrot and some onion… In the leaves, around the spots shot with DNA (but not the controls) there are some, well, reddish bits that show up after a few days! And after lots of squinting at them I’ve convinced myself that at least some of these are cells expressing RUBY :)</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/maybe_ruby.png" class="img-fluid figure-img"></p>
<figcaption>Possible RUBY expression - reddish cells/spots</figcaption>
</figure>
</div>
<p>My gallery is filled with blurry attempts to capture this, and none make it as obvious as I’d like. For example, there are also plenty of cases where, around an impact point where a clump of DE has hit, there’ll be some orange-ish crud welling up. Around most impacts (and all that I saw in the no-DNA controls) this stuff is pale white. Could this be RUBY too, expressed in some damaged cell(s) and being included in whatever is happening around the hole? Plus there are random red things just around the place - bits of fiber, random flakes - here’s a gallery of things I was more sceptical of:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/maybe_not_ruby.png" class="img-fluid figure-img"></p>
<figcaption>Other things that might random fluff, browning, or other junk</figcaption>
</figure>
</div>
<p>The almost magenta dots in the carrot are apparently pretty much what <a href="(https://academic.oup.com/hr/article/10/4/uhad024/7036638)">RUBY looks like in carrot</a>, that was a YOLO shot with some leftover stuff, I’ll do some follow-on ones with carrot callus that I have growing and hopefully get a clearer signal. But in general it was much harder looking for red/orange reporter in orange carrot tissue!</p>
<p>I didn’t see anything in the onion I shot. Nor did I see anything in onion that I tried my micro-needle idea on. But then, RUBY doesn’t work everywhere - for example <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC12787607/">this paper documents it being a poor marker in coconut</a> (also a good ref for optimization strat once I can easily bombard and measure.)</p>
<p>For comparison: I’ve also been trying transformation with agrobacterium, which gives a much more macro result - here are some duckweed fronds expressing RUBY to various degrees:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/dwe_tfm.jpg" class="img-fluid figure-img"></p>
<figcaption>RUBY expression at various levels in duckweed transformed with agrobacterium</figcaption>
</figure>
</div>
</section>
<section id="thoughts-what-didnt-work-what-next" class="level2">
<h2 class="anchored" data-anchor-id="thoughts-what-didnt-work-what-next">Thoughts, What didn’t work, What Next</h2>
<p>What didn’t work:</p>
<ul>
<li>Using graphite as the carrier (I wanted something more visible than the DE, so I sanded some graphite rod to get powder, but I didn’t ever see transformation using it)</li>
<li>Using my tungsten micro-needles seemed to kill leaf cells, and when I tried them more gently on onion I didn’t see any transformation</li>
<li>Bombarding duckweed was tricky (it tended to fly away in the blast) and I didn’t see any transformation of its tiny cells.</li>
</ul>
<p>I <em>think</em> the red spots are enough to indicate that we’ve gone from 0 to 1. From here, we can optimise - playing with</p>
<ul>
<li>DNA, carrier and buffer amounts</li>
<li>Nozzle diameter and geometry (I already switched to a converging-diverging nozzle which seems to give a much nicer shot). <a href="https://www.nature.com/articles/s41467-025-60761-x">Ref for flow guiding barrel design (just found)</a></li>
<li>Shot distance</li>
<li>etc.</li>
</ul>
<p>But I’m not happy with RUBY as a readout - too hard to see and measure. I’d love to use a flourescent reporter, but after months of trying I wasn’t able to get my hands on some. I have a construct with a fluorescent reporter ready to go for another project, which I’ll be ordering soon, for about $500… Once I get that I’m hoping we’ll be able to easily quantify how well a given shot does, and start optimizing everything. I wish individuals could order plasmids from addgene! Anyway.</p>
<p>Once you have some transformed cells, you can try to grow them out in tissue culture, optionally with something like herbicide resistance to select for the trasnformed ones. I’m hoping we can find a visual-selection-only flow since I don’t want to me making herbicide resistant plants or having other people work with them.</p>
<p>My dream is to work out a path for people who haven’t done this before, and don’t have the tools to do assembly and cloning, to still order a construct with their own protein/design, and get it into a plant, all as easily as possible. Wish me luck :)</p>


</section>

 ]]></description>
  <category>mini-hw-projects</category>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/mini-hw-projects/asgg2.html</guid>
  <pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate>
  <media:content url="https://johnowhitaker.dev/mini-hw-projects/images/ruby_closeup.png" medium="image" type="image/png" height="139" width="144"/>
</item>
<item>
  <title>DNA quantification with a visible light spectrometer</title>
  <link>https://johnowhitaker.dev/posts/dnaq.html</link>
  <description><![CDATA[ 




<p>In microbio, a common procedure is a ‘miniprep’, where plasmid DNA is extracted from bacteria (often e. coli, which is good at making lots of copies) for insertion into some other organism. I’ve done a few, but had no good way to know if they worked! Typical approaches look at absorption at 260nm, and I don’t have a UV spectrometer. In this post I’ll show my trick for getting around this problem to estimate DNA concentration with my existing cobbled-together visible light spectrometer.</p>
<p>The key trick is to mix a small amount of the DNA sample with a dye that binds to DNA and fluoresces when illuminated with visible light. I used SeeGreen <a href="https://www.minipcr.com/product/seegreen-nucleic-acid-gel-stain/">stain</a> - I prepared a dilution with 2uL of stain in 20ml water, and then mix 1uL of DNA into 100uL of the diluted stain. A blue LED shines down into the sample. I use some yellow film to block most of this blue light from reaching the camera in the spectrometer, and instead look at the intensity of the green fluorescence emitted by the dye. The more DNA there is, the more dye binds and fluoresces, so this gives us a way to estimate DNA concentration.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/posts/images/dnaq1.png" class="img-fluid figure-img"></p>
<figcaption>Illuminating the sample with a blue LED</figcaption>
</figure>
</div>
<p>We also need a reference with known concentration. I used some spare plasmid I had on hand to make a 500ng/uL reference (well, I had to add 5uL of 100ng/uL DNA to the diluted stain, but close enough). And then as a baseline I made several vials to which no DNA was added. Here are the results, looking at a sample from my most recent miniprep and comparing to the standard and the two baseline samples:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/posts/images/dnaq2.png" class="img-fluid figure-img"></p>
<figcaption>Comparing spectra</figcaption>
</figure>
</div>
<p>Code is <a href="https://gist.github.com/johnowhitaker/3aa41553b027c29d307766fcc06a79cf">here</a> for the curious. Since the exact figures you’ll get vary depending on choices like the bounding box used in the image, I did some quick bootstrapping to give a range of values, picking a final estimate of 687 ng/µL (90% CI: 507–845).</p>
<p><img src="https://johnowhitaker.dev/posts/images/dnaq3.png" class="img-fluid"></p>
<p>Note, the confidence interval there only accounts for the variability of the image analysis. There could be additional variation from bad light sealing in the spectrometer, volume measurement errors, the fact that my reference sample was from a few uL of old DNA in a tube that had been shaken up, etc etc. I suspect the reference might be more like 300 ng/µL than 500, for example, which would knock the estimate down to around 400 ng/µL. Still, the miniprep kit targets 30-50ug total in 100uL elution, and I did try to stack the odds in my favour, so the estimate is in the right ballpark.</p>
<p>Importantly, the estimate is not 0, which is what I was really worried about :) If I wanted more precision, I’d do repeat estimates, average over multiple exposures, and make up more known reference samples. But for what I want, this is more than good enough to move on to the next steps of my project. Although I will want to do a gel to assess the quality of the DNA too - once I get my hands on a DNA ladder. At the moment we know there is DNA, but not how much is plasmid vs genomic junk that might have made it through :)</p>
<p>Anyway, that’s all, see you in the next one.</p>



 ]]></description>
  <category>bio</category>
  <category>mini-hw-projects</category>
  <guid>https://johnowhitaker.dev/posts/dnaq.html</guid>
  <pubDate>Thu, 19 Mar 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Spectral Shifts with Pyoverdine pH</title>
  <link>https://johnowhitaker.dev/mini-hw-projects/spectrometer.html</link>
  <description><![CDATA[ 




<p>Since my <a href="https://johnowhitaker.dev/posts/putida.html">previous post</a> I’ve continued tinkering with the flourescent pyoverdine produced by pseudomonas putida. I made some really pure stuff with solid phase extraction using activated charcoal (no luck getting access to LC-MS sadly) and also just extracted a bunch for further experiments. In todays post: what happens when you shift pH. Spoiler, fun color changes :) The first test:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/pyoverdine_fl.png" class="img-fluid figure-img"></p>
<figcaption>Image lightly edited in an attempt to capture + emphasize what it looks like IRL</figcaption>
</figure>
</div>
<p>I’d noticed some older colonies shift to green, and green/yellow rather than blue when some stained my hands a while ago. So I started adding things to it to see what would happen. Citric acid and Vitamin C both shifted it to whitish, almost pink (at least in comparison to the normal color). Some strongly basic NaOH shifted it to green. To get a better picture of this, I made a spectrometer using a diffraction grating and a raspbery pi camera in a box. I calibrated it with a few laser pointers - by looking at the pixel values in one area of the image, we get a rough view of the spectrum (my slit is a fairly wide cut in some cardboard, nothing fancy here).</p>
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/spec_calib.png" class="img-fluid"></p>
<p>Putting some pyoverdine extract in ethanol in three vials, and adding some citric acid to one and NaOH to another, we get the following spectra:</p>
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/spec_p.png" class="img-fluid"></p>
<p>To me, this indicates that there might be two different flourescent compounds in the extract! More to investigate, I bought a tube to try my own LC to see if I can separate them.</p>
<p>A few more pics:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/spec_cad.png" class="img-fluid figure-img"></p>
<figcaption>While cardboard and gaffer tape would work fine, I did print a nice enclosure and some holders to make this spectrometer useful for future work</figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/pyoverdine_plates.png" class="img-fluid figure-img"></p>
<figcaption>One plate had e. coli growing before Pseudomonas putida took over</figcaption>
</figure>
</div>
<p>PS: <a href="https://gist.github.com/johnowhitaker/d9e8d41fa5c215dfd16b7c94f651ef3f">Code for the plots etc</a></p>



 ]]></description>
  <category>mini-hw-projects</category>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/mini-hw-projects/spectrometer.html</guid>
  <pubDate>Fri, 27 Feb 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>The Idea Is The Software</title>
  <link>https://johnowhitaker.dev/essays/distributables.html</link>
  <description><![CDATA[ 




<p>Here’s a device that only does X. Here’s a binary you can run that does X. Here’s code that you can compile and run that does X. Here’s an X SAAS. Here’s a prompt that creates code that does X. “Did you know computers can do X?”. [Half-baked musings on software incoming].</p>
<p>There’s always been a gap between ‘works on my machine’ and software that other people can easily use. So, if I coded up something that worked for me, it was a bit of a burden to polish that into something that others can use. You need to solve for different operating systems, you can’t have a hard-coded “~/johnos_projects” path, there are requirements… Plus there is some education you feel obligated to do, for potential users who might not know what <code>pip</code> is or something.</p>
<p>With LLMs getting good, new ideas around this are beginning to float about. What if we just shared, like, a really good prompt? Everyone could have their agent build their own bespoke version. Karpathy found a nice example of this being used as an extensibility mechanism for a project recently, where the repo includes prompts to tell LLMs how to add functionality:</p>
<blockquote class="blockquote">
<p>I also love their approach to configurability - it’s not done via config files it’s done via skills! For example, /add-telegram instructs your AI agent how to modify the actual code to integrate Telegram. I haven’t come across this yet and it slightly blew my mind earlier today as a new, AI-enabled approach to preventing config mess and if-then-else monsters. Basically - the implied new meta is to write the most maximally forkable repo and then have skills that fork it into any desired more exotic configuration.</p>
</blockquote>
<p>This weekend it really hit home to me how far this goes for some things: at the end of the day, all I need to share is that something is <strong>possible</strong> - the implementation is left as an exercise for the reader, but that is no longer a gatekeeping, elitist move! The specific example was my <a href="https://johnowhitaker.dev/mini-hw-projects/tachometer.html">quick and dirty strobe tachometer</a>. It’s a microcontroller, that lets you pulse an LED at different rates. When the flash speed matches the rotation speed of something, it looks like it’s standing still. Nothing fancy. Historically, if I wanted others to re-create this, I’d need to share:</p>
<ul>
<li>An exact parts list</li>
<li>A wiring diagram</li>
<li>The code</li>
<li>Installation instructions (how to install the Arduino IDE, how to connect your device)</li>
<li>Tips for connecting to the board (serial ports on Windows are a nightmare, for example)</li>
</ul>
<p>And odds are, a reader who wanted to re-create it won’t have the exact parts on hand. For e.g.&nbsp;the board I used is an ancient NodeMCU ESP8266 dev board from the hackerspace junk bin - but there is no reason to use that specifically.</p>
<p>Contrast to today. The thing I share is the <strong>idea</strong>: flash a light with a microcontroller to estimate speed. You can use a transistor to push more current through the LED if you want it bright. Ask your agent to use the arduino-cli to handle the programming etc.</p>
<p>I’m somewhat confident that many could replicate this project, and it won’t matter if they use an STM32 or a Raspberry Pi Pico or an ESP32. It won’t matter if they have the same display as me (I can’t even remember the model number, and did not tell codex - it figured it out anyway!). If they have different transistors on hand, I’m confident the model can tell them how to wire them up. In other words, the “source code” for this project is simply the notion that one can do such a thing - and all the tedious embedded engineering work is just an implementation detail that can be handled by an LLM.</p>
<p>In some ways this is the ‘LLMs are lossy compilers’ take that has been around for ages, but the point of this essay is me coming to terms with this now that the scope of tasks for which they are ~reliable is growing. There are lots of apps I’ve built for myself that would be a pain to release, since I’d need payments to cover inference costs, bla bla bla. It is somewhat freeing to think that maybe sharing a screenshot of the core idea is enough!</p>
<p>Of course, we’re still far from this working for all software. But it’s interesting to think how far you could push this, especially with OS building blocks. “Combine ThreeJS with [this mapping lib] and [that data API] to visualize cycle traffic in your city”. That’s a lot easier and more fun to type in and run than those old magazine code listings :) The future is going to be interesting!</p>
<p>PS: It’s worth thinking through how your medium of choice works for sharing these ‘idea seeds’. I’ve got some fun plans in solveit for this - a jupyter notebook packaging up demo code + suggested prompts seems like a nice format for this. Still trying to convince myself this is needed vs a simple .md file or screenshot, but we’ll see :)</p>
<p>PPS: What’s the coolest piece of software you’ve seen that can be distributed in this way? (i.e.&nbsp;as a one-shot prompt). I’d love to see cool examples.</p>



 ]]></description>
  <category>essays</category>
  <guid>https://johnowhitaker.dev/essays/distributables.html</guid>
  <pubDate>Mon, 23 Feb 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Quick and dirty strobe tachometer</title>
  <link>https://johnowhitaker.dev/mini-hw-projects/tachometer.html</link>
  <description><![CDATA[ 




<p>I wanted to know how fast my dremel ‘centrifuge’ spins, so I hooked up a transistor + LED to an ESP8266 module I had lying around, and had codex spin up something that gives me a webUI to vary the pulse rate of the LED. With a bit of fiddling you can figure out how fast something is spinning. Pics:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/tach_3.jpg" class="img-fluid figure-img"></p>
<figcaption>The worst-looking circuit I’ve soldered in a while</figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/tach_1.jpg" class="img-fluid figure-img"></p>
<figcaption>The Web UI that I can use to control the pulse rate from my phone</figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/tach_2.jpg" class="img-fluid figure-img"></p>
<figcaption>I drew a dot on the spinny bit - symmetry can mean wrong estimates of speed</figcaption>
</figure>
</div>
<p>Doesn’t seem worth sharing the code, ideas if you want to re-create this:</p>
<ul>
<li>A transistor lets you push more current through an LED compared to wiring one directly to a pin of the ESP8266. I used a BC547 that I had on hand. The base of the transistor is connected to a GPIO pin of the ESP8266 through a resistor (e.g., 1kΩ), the emitter is connected to ground, and the collector is connected to the negative leg of the LED. The positive leg of the LED is connected to a power source (e.g., 3.3V or 5V) through a current-limiting resistor (e.g., 220Ω).</li>
<li>Ask for codex to close the loop - I didn’t want to be copying code back and forth to the Arduino IDE for this, I’m sick and I know just what I want. So I installed the arduino cli, and it was more than happy to use that plus misc scripts and such that it wrote for itself to find the board, connect, verify that it could read the serial output, etc etc. I basically just had to give it my WIFI creds and some gentle steering towards the behaviour I wanted.</li>
</ul>



 ]]></description>
  <category>mini-hw-projects</category>
  <guid>https://johnowhitaker.dev/mini-hw-projects/tachometer.html</guid>
  <pubDate>Thu, 19 Feb 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Lab Notes Feed</title>
  <link>https://johnowhitaker.dev/posts/lab_notes_feed.html</link>
  <description><![CDATA[ 




<p>My bio practice is turning out to involve lots of longer-term projects, and while individual chunks/experiments can be interesting, I usually want to wait for things to accumulate before they get a full post/video. I thought youtube shorts might work as a venue for smaller in-progress updates but 1) video is still high friction and 2) they get shown to thousands of people, usually as a first impression. So, I made my own feed where I can post pics of my physical lab notebook along with other reference pics and notes: <a href="https://ln.johnowhitaker.com/">https://ln.johnowhitaker.com/</a>. I’ll still try to keep things coming through to this blog, but hopefully this will avoid me polluting the everything feed here with too much everything :) What I might do is have a ‘lab notes digest’ that summarizes any interesting bits from there once every few months.</p>
<p>Why post all these? Adam Savage said “The difference between screwing around and science is writing it down.” I’ve been taking notes, but I was chatting recently with Sebastian Coechiba and he encouraged me to make sure everything I capture is public, otherwise others can’t benefit from it. So, Seb, here you go - my public lab notebook :)</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/posts/images/gel_colors.png" class="img-fluid figure-img"></p>
<figcaption>One of the first little experiments written up there, so that this post gets an image preview.</figcaption>
</figure>
</div>



 ]]></description>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/posts/lab_notes_feed.html</guid>
  <pubDate>Thu, 12 Feb 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Sequencing Pseudomonas putida, Predicting Pyoverdine Structure</title>
  <link>https://johnowhitaker.dev/posts/putida.html</link>
  <description><![CDATA[ 




<p>In my <a href="https://johnowhitaker.dev/posts/pseudomonas.html">previous post</a> I showed a bacteria isolated from the water around the roots of a Jade plant on our windowsill, which secreted something that fluoresced a lovely blue under UV light. My best guess was that it was some species of Pseudomonas, and the blue was from pyoverdine. But how can we know for sure? Well, I put it off because money, but since I like working with this bacteria and want to do more with it, I figured I’d bite the bullet and pay the ~$120 to get my answers :) It turns out that the closest match is P. putida, and that the pyoverdine variant that this makes is probably different to anything documented in the literature. Exciting stuff! Update: found a likely match in the literature - see end of post :)</p>
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/KoZu49WAaY0" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
<p>I’ve also recorded a video (30/01) above for those who prefer that format.</p>
<section id="sequencing-with-plasmidsaurus" class="level2">
<h2 class="anchored" data-anchor-id="sequencing-with-plasmidsaurus">Sequencing with Plasmidsaurus</h2>
<p>I went with Plasmidsaurus’ ‘Standard Bacterial Genome Sequencing with Extraction’ <a href="https://plasmidsaurus.com/genome">service</a>. I sent the sample (~15mg cells suspended in Zymo DNA Shield) off on Tuesday morning and by Wednesday evening the results were ready.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center collapsed" data-bs-toggle="collapse" data-bs-target=".callout-1-contents" aria-controls="callout-1" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Returned stats:
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-1" class="callout-1-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>Species ID (Mash)</p>
<ul>
<li>Best match: Pseudomonas putida NBRC 14164</li>
<li>Identity: 95.6% (1946/5000 shared hashes)</li>
</ul>
<p>Genome Quality (CheckM)</p>
<ul>
<li>Completeness: 99.88% — excellent!</li>
<li>Contamination: 2.15% — very low</li>
<li>Lineage marker: Pseudomonas</li>
</ul>
<p>Assembly Stats</p>
<ul>
<li>Genome size: 6.54 Mb (typical for Pseudomonas)</li>
<li>Total reads: 66,830 (398 Mb total)</li>
<li>Estimated coverage: ~58x</li>
<li>Longest read: 88.4 kb</li>
<li>Read N50: 9.7 kb</li>
</ul>
</div>
</div>
</div>
<p><img src="https://johnowhitaker.dev/posts/images/pseud_contig.png" class="img-fluid"></p>
<p>They give you <a href="https://drive.google.com/drive/folders/1p8dQGtGOjfowySz2ltuYEjhGZroxdjUh?usp=sharing">lots of data</a>, including annotating the genome for you with <a href="https://doi.org/10.1099/mgen.0.000685">bakta</a>. Great stuff! We can see right away that our guess was right - this is a Pseudomonas species (P. putida is the closest match) and are ready to dig in further to see what we can learn.</p>
</section>
<section id="pyoverdine-investigation" class="level2">
<h2 class="anchored" data-anchor-id="pyoverdine-investigation">Pyoverdine Investigation</h2>
<p>Pyoverdines vary but all come with three key parts: a dihydroxyquinoline core, a peptide chain, and a side chain. The peptide chain especially varies strain-to-strain - see <a href="https://en.wikipedia.org/wiki/Pyoverdine#Structure">here</a> for some examples.</p>
<p>Step one was looking for the pyoverdine Biosynthetic Gene Cluster (BGC). A <a href="https://chatgpt.com/share/697294ce-6a40-8010-bb23-a7047045b8cb">Deep Research</a> run gave some promising genes to start the hunt with. Some hits let us narrow in on a key region between 4.71 and 4.76M bp, with a number of promising-looking genes. A tool called antiSMASH likewise identified a region (4,696,705–4,796,912), labeled as ‘NRP-metallophore’ - this is our BGC alright :)</p>
<p><img src="https://johnowhitaker.dev/posts/images/antiSMASH.png" class="img-fluid"></p>
<p>By looking at the A-domain predictions for this region, we can start on a predicted peptide sequence: Glu-D-Tyr-Dab─Asp─Ala─Asp─D-OHOrn─X─OHOrn (where Glu-D-Tyr-Dab forms the conserved pyoverdine chromophore after cyclization). That X is an unknown, which we’ll have to work on later - my best guess was Gly, although a later lit search makes me think Ser (see later update section).</p>
<p>The next step is to figure out which side chain is present. (Some strains make some of both). The side-chain type is determined by which gene is present:</p>
<ul>
<li>pvdN (PLP-dependent aminotransferase) → succinamide side chain</li>
<li>ptaA (<a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC5682972/">periplasmic transaminase</a>) → α-ketoglutarate side chain</li>
</ul>
<p>We BLAST the genome against known reference sequences, finding an 83% match to PvdN (NP_251095.1) but only a 23% match for PtaA (AAY94407.1) -&gt; fair guess that this strain produces succinamide side chain.</p>
<p>This info gives us enough info to reasonably guess at the structure of the pyoverdine precursor (ferribactin):</p>
<p><img src="https://johnowhitaker.dev/posts/images/pyoverdine_precursor_pred.png" class="img-fluid"></p>
<p>Here’s <a href="https://gist.github.com/johnowhitaker/8659d6f38c799e9d4d8e417e1641e6e0">a notebook</a> running over the steps, with some light annotation. (I’ve since been fiddling a bit more, LMK if you’re wanting to dive into this deeply)</p>
</section>
<section id="future-plans" class="level2">
<h2 class="anchored" data-anchor-id="future-plans">Future Plans</h2>
<p>It’s one thing to poke at a genome and predict a structure, it’s another entirely to verify it. I’m hoping to work with a local university to run LC-MS on this to answer a few remaining questions and nail down the final structure exactly. Will require dusting off and improving my organic chemistry and learning a lot more! Stay tuned for that in some future blog post hopefully :)</p>
<p>Also, it’s probably obvious but worth stating explicityl: I AM OUT OF MY DEPTH HERE AND EVERYTHING IN THIS POST SHOULD BE TAKEN WITH A GRAIN OF SALT, ESPECIALLY WHILE IT IS MARKED ‘DRAFT’ :)</p>
<p>For the curious, raw data <a href="https://drive.google.com/drive/folders/1p8dQGtGOjfowySz2ltuYEjhGZroxdjUh?usp=sharing">is on Google Drive</a>, I’m open to questions <span class="citation" data-cites="johnowhitaker">@johnowhitaker</span>. <a href="https://share.solve.it.com/d/7584c91e2c239ff2c01ecd5fb270a3c7">This solveit dialog</a> has the key code in a nice rendered form.</p>
</section>
<section id="update-a-potential-match" class="level2">
<h2 class="anchored" data-anchor-id="update-a-potential-match">Update: A Potential Match</h2>
<p>In <a href="https://sci-hub.ru/https://pubmed.ncbi.nlm.nih.gov/23877277/">A combinatorial approach to the structure elucidation of a pyoverdine siderophore produced by a Pseudomonas putida isolate and the use of pyoverdine as a taxonomic marker for typing P. putida subspecies BioMetals, 2013</a> I found the following: P. putida BTP1/90-40 Asp–Ala–Asp–AOHOrn–Ser–cOHOrn (citing Jacques et al.&nbsp;(1995)). This is pretty much spot on for ours, and would mean the mystery X is Ser (serine), not Gly as guessed. It also answers a mystery - I’d been searching fruitlessly for pvdF in my genome to figure out if OHOrn gets formylated, this would indicate it doesn’t in this case.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center collapsed" data-bs-toggle="collapse" data-bs-target=".callout-2-contents" aria-controls="callout-2" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Nomenclature
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-2" class="callout-2-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>AOHOrn = “amide-linked” hydroxyornithine (connected via α-amino group)</p>
<p>cOHOrn = “cyclic” hydroxyornithine (C-terminal, forms lactam ring with its own side chain)</p>
<p>BTP1/90-40 is the strain from the paper</p>
<p>fOHOrn/formyl-hydroxyornithine is the formylated form (hehe) of hydroxyornithine, pvdF is the “hydroxyornithine transformylase enzyme” that does this in some Pseudomonas.</p>
</div>
</div>
</div>
</section>
<section id="ps-molecule-viewer-test" class="level2">
<h2 class="anchored" data-anchor-id="ps-molecule-viewer-test">PS: Molecule viewer test</h2>
<p>Here’s the predicted ferrobactin precursor molecule, copied from the output of <a href="https://gist.github.com/johnowhitaker/81ed1c6eb4496556cca9792107c85832">this code</a>:</p>
<div class="space-y-3">
<div id="3dmolviewer_1769122862701931" style="position: relative; width: 400px; height: 300px;">
<pre><code>    &lt;canvas id="undefined" width="1000" height="750" style="width: 400px; height: 300px; padding: 0px; position: absolute; top: 0px; left: 0px; z-index: 0;"&gt;&lt;/canvas&gt;&lt;canvas id="undefined" width="1000" height="750" style="width: 400px; height: 300px; padding: 0px; position: absolute; top: 0px; left: 0px; z-index: 0;"&gt;&lt;/canvas&gt;&lt;/div&gt;</code></pre>
<script>

var loadScriptAsync = function(uri){
  return new Promise((resolve, reject) => {
    //this is to ignore the existence of requirejs amd
    var savedexports, savedmodule;
    if (typeof exports !== 'undefined') savedexports = exports;
    else exports = {}
    if (typeof module !== 'undefined') savedmodule = module;
    else module = {}

    var tag = document.createElement('script');
    tag.src = uri;
    tag.async = true;
    tag.onload = () => {
        exports = savedexports;
        module = savedmodule;
        resolve();
    };
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});
};

if(typeof $3Dmolpromise === 'undefined') {
$3Dmolpromise = null;
  $3Dmolpromise = loadScriptAsync('https://cdn.jsdelivr.net/npm/3dmol@2.5.4/build/3Dmol-min.js');
}

var viewer_1769122862701931 = null;
var warn = document.getElementById("3dmolwarning_1769122862701931");
if(warn) {
    warn.parentNode.removeChild(warn);
}
$3Dmolpromise.then(function() {
viewer_1769122862701931 = $3Dmol.createViewer(document.getElementById("3dmolviewer_1769122862701931"),{backgroundColor:"white"});
viewer_1769122862701931.zoomTo();
    viewer_1769122862701931.addModel("\n     RDKit          3D\n\n136136  0  0  0  0  0  0  0  0999 V2000\n   -6.6151   -0.7552   -3.4462 N   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.0017    0.2169   -2.4168 C   0  0  1  0  0  0  0  0  0  0  0  0\n   -7.7288    1.4440   -2.9763 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -9.0112    1.1321   -3.7521 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -9.6584    2.3947   -4.2537 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -9.1281    3.4847   -4.3971 O   0  0  0  0  0  0  0  0  0  0  0  0\n  -10.9498    2.2082   -4.5886 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.8521   -0.4792   -1.3316 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.6439   -1.3865   -1.5735 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.6574    0.0198   -0.0633 N   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.5164   -0.3636    1.0610 C   0  0  2  0  0  0  0  0  0  0  0  0\n   -9.8384    0.4264    1.1240 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -9.7679    1.8828    0.7053 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.9777    2.8041    1.4016 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.9042    4.1326    0.9787 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -9.6240    4.5477   -0.1345 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -9.5082    5.8499   -0.5194 O   0  0  0  0  0  0  0  0  0  0  0  0\n  -10.4428    3.6590   -0.8184 C   0  0  0  0  0  0  0  0  0  0  0  0\n  -10.5132    2.3273   -0.3991 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.6878   -0.2979    2.3608 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.0723    0.2481    3.3912 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -6.4952   -1.0011    2.2854 N   0  0  0  0  0  0  0  0  0  0  0  0\n   -5.6185   -1.1581    3.4492 C   0  0  1  0  0  0  0  0  0  0  0  0\n   -6.2188   -2.0839    4.5248 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -6.3963   -3.5288    4.0464 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -6.9688   -4.3442    5.1118 N   0  0  0  0  0  0  0  0  0  0  0  0\n   -4.2015   -1.6477    3.0755 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -3.3292   -1.8373    3.9236 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -4.0019   -1.9044    1.7326 N   0  0  0  0  0  0  0  0  0  0  0  0\n   -2.7034   -2.3975    1.2685 C   0  0  1  0  0  0  0  0  0  0  0  0\n   -2.8950   -3.3536    0.0900 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -1.5946   -3.7673   -0.5302 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -1.3548   -3.7718   -1.7260 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -0.6690   -4.1212    0.3846 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -1.8323   -1.1885    0.8523 C   0  0  0  0  0  0  0  0  0  0  0  0\n   -2.3118   -0.1884    0.3252 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -0.4840   -1.3560    1.0838 N   0  0  0  0  0  0  0  0  0  0  0  0\n    0.5460   -0.5463    0.4382 C   0  0  1  0  0  0  0  0  0  0  0  0\n    1.4120    0.1456    1.4762 C   0  0  0  0  0  0  0  0  0  0  0  0\n    1.3962   -1.5073   -0.4244 C   0  0  0  0  0  0  0  0  0  0  0  0\n    1.3456   -2.7339   -0.2921 O   0  0  0  0  0  0  0  0  0  0  0  0\n    2.2357   -0.9102   -1.3381 N   0  0  0  0  0  0  0  0  0  0  0  0\n    3.0789   -1.7397   -2.2056 C   0  0  1  0  0  0  0  0  0  0  0  0\n    3.5303   -0.9925   -3.4633 C   0  0  0  0  0  0  0  0  0  0  0  0\n    4.5496    0.0402   -3.0881 C   0  0  0  0  0  0  0  0  0  0  0  0\n    4.3977    0.8650   -2.1953 O   0  0  0  0  0  0  0  0  0  0  0  0\n    5.7134   -0.1104   -3.7411 O   0  0  0  0  0  0  0  0  0  0  0  0\n    4.3018   -2.3108   -1.4473 C   0  0  0  0  0  0  0  0  0  0  0  0\n    4.8576   -3.3478   -1.8052 O   0  0  0  0  0  0  0  0  0  0  0  0\n    4.8370   -1.4907   -0.4639 N   0  0  0  0  0  0  0  0  0  0  0  0\n    6.1396   -1.8296    0.0968 C   0  0  2  0  0  0  0  0  0  0  0  0\n    6.4054   -1.2404    1.4926 C   0  0  0  0  0  0  0  0  0  0  0  0\n    5.8851    0.1736    1.7937 C   0  0  0  0  0  0  0  0  0  0  0  0\n    6.4956    1.2673    0.9227 C   0  0  0  0  0  0  0  0  0  0  0  0\n    6.0387    2.6005    1.3279 N   0  0  0  0  0  0  0  0  0  0  0  0\n    6.7366    2.9043    2.5687 O   0  0  0  0  0  0  0  0  0  0  0  0\n    7.2660   -1.4847   -0.9093 C   0  0  0  0  0  0  0  0  0  0  0  0\n    7.2494   -0.4972   -1.6470 O   0  0  0  0  0  0  0  0  0  0  0  0\n    8.3267   -2.3618   -0.8948 N   0  0  0  0  0  0  0  0  0  0  0  0\n    9.3494   -2.3715   -1.9370 C   0  0  0  0  0  0  0  0  0  0  0  0\n   10.5717   -1.5281   -1.5723 C   0  0  0  0  0  0  0  0  0  0  0  0\n   11.7192   -1.9478   -1.7134 O   0  0  0  0  0  0  0  0  0  0  0  0\n   10.2854   -0.2356   -1.1853 N   0  0  0  0  0  0  0  0  0  0  0  0\n   11.3126    0.6002   -0.5724 C   0  0  1  0  0  0  0  0  0  0  0  0\n   11.1216    2.0813   -0.9180 C   0  0  0  0  0  0  0  0  0  0  0  0\n    9.8109    2.6920   -0.3987 C   0  0  0  0  0  0  0  0  0  0  0  0\n    9.7221    4.1810   -0.7540 C   0  0  0  0  0  0  0  0  0  0  0  0\n    8.5066    4.8221   -0.2402 N   0  0  0  0  0  0  0  0  0  0  0  0\n    7.3957    4.2118   -0.9549 O   0  0  0  0  0  0  0  0  0  0  0  0\n   11.3203    0.3602    0.9403 C   0  0  0  0  0  0  0  0  0  0  0  0\n   10.4579   -0.2116    1.5958 O   0  0  0  0  0  0  0  0  0  0  0  0\n   12.4089    0.8703    1.5479 O   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.4240   -1.3231   -3.6980 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -6.3168   -0.2721   -4.2919 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -6.0742    0.5621   -1.9441 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.9745    2.1237   -2.1557 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.0413    2.0007   -3.6261 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -9.7258    0.6166   -3.1045 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.8014    0.5009   -4.6229 H   0  0  0  0  0  0  0  0  0  0  0  0\n  -11.2422    3.0698   -4.9501 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.1668    0.9029    0.0276 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.7787   -1.4245    0.9436 H   0  0  0  0  0  0  0  0  0  0  0  0\n  -10.2870    0.3702    2.1227 H   0  0  0  0  0  0  0  0  0  0  0  0\n  -10.5526   -0.0835    0.4583 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.4217    2.5109    2.2901 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -8.2870    4.8438    1.5186 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -9.9747    5.9667   -1.3639 H   0  0  0  0  0  0  0  0  0  0  0  0\n  -11.0310    3.9804   -1.6735 H   0  0  0  0  0  0  0  0  0  0  0  0\n  -11.1552    1.6421   -0.9427 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -6.4017   -1.6561    1.5147 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -5.4964   -0.1581    3.8823 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.1919   -1.6920    4.8523 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -5.5659   -2.0769    5.4085 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -5.4314   -3.9631    3.7575 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.0566   -3.5698    3.1756 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.8757   -3.9706    5.3915 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -7.1387   -5.2901    4.7738 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -4.4537   -1.2402    1.1064 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -2.2108   -2.9248    2.0947 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -3.4940   -2.8662   -0.6903 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -3.4410   -4.2526    0.3977 H   0  0  0  0  0  0  0  0  0  0  0  0\n    0.1879   -4.0867   -0.1123 H   0  0  0  0  0  0  0  0  0  0  0  0\n   -0.1762   -2.2691    1.4186 H   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0786    0.1899   -0.2260 H   0  0  0  0  0  0  0  0  0  0  0  0\n    0.8120    0.8269    2.0879 H   0  0  0  0  0  0  0  0  0  0  0  0\n    1.8841   -0.5800    2.1524 H   0  0  0  0  0  0  0  0  0  0  0  0\n    2.2130    0.7265    1.0089 H   0  0  0  0  0  0  0  0  0  0  0  0\n    2.3996    0.0938   -1.3059 H   0  0  0  0  0  0  0  0  0  0  0  0\n    2.4703   -2.6042   -2.5136 H   0  0  0  0  0  0  0  0  0  0  0  0\n    3.9814   -1.7008   -4.1694 H   0  0  0  0  0  0  0  0  0  0  0  0\n    2.6922   -0.4957   -3.9710 H   0  0  0  0  0  0  0  0  0  0  0  0\n    6.4124    0.2136   -3.1233 H   0  0  0  0  0  0  0  0  0  0  0  0\n    4.5844   -0.5089   -0.5171 H   0  0  0  0  0  0  0  0  0  0  0  0\n    6.1581   -2.9216    0.2138 H   0  0  0  0  0  0  0  0  0  0  0  0\n    5.9355   -1.9057    2.2267 H   0  0  0  0  0  0  0  0  0  0  0  0\n    7.4807   -1.2694    1.7025 H   0  0  0  0  0  0  0  0  0  0  0  0\n    6.1051    0.3840    2.8471 H   0  0  0  0  0  0  0  0  0  0  0  0\n    4.7928    0.1904    1.7048 H   0  0  0  0  0  0  0  0  0  0  0  0\n    6.1797    1.1327   -0.1133 H   0  0  0  0  0  0  0  0  0  0  0  0\n    7.5882    1.2151    0.9461 H   0  0  0  0  0  0  0  0  0  0  0  0\n    6.4469    3.2816    0.6749 H   0  0  0  0  0  0  0  0  0  0  0  0\n    5.9941    3.1631    3.1515 H   0  0  0  0  0  0  0  0  0  0  0  0\n    8.2435   -3.2077   -0.3454 H   0  0  0  0  0  0  0  0  0  0  0  0\n    9.6664   -3.4118   -2.0625 H   0  0  0  0  0  0  0  0  0  0  0  0\n    8.9299   -2.0093   -2.8807 H   0  0  0  0  0  0  0  0  0  0  0  0\n    9.3196   -0.0623   -0.9284 H   0  0  0  0  0  0  0  0  0  0  0  0\n   12.2878    0.2740   -0.9538 H   0  0  0  0  0  0  0  0  0  0  0  0\n   11.1603    2.2030   -2.0083 H   0  0  0  0  0  0  0  0  0  0  0  0\n   11.9648    2.6547   -0.5065 H   0  0  0  0  0  0  0  0  0  0  0  0\n    8.9621    2.1560   -0.8385 H   0  0  0  0  0  0  0  0  0  0  0  0\n    9.7528    2.5742    0.6890 H   0  0  0  0  0  0  0  0  0  0  0  0\n   10.5797    4.7025   -0.3140 H   0  0  0  0  0  0  0  0  0  0  0  0\n    9.7872    4.3239   -1.8375 H   0  0  0  0  0  0  0  0  0  0  0  0\n    8.3401    4.5252    0.7269 H   0  0  0  0  0  0  0  0  0  0  0  0\n    6.9409    4.9959   -1.3276 H   0  0  0  0  0  0  0  0  0  0  0  0\n   12.3044    0.6155    2.4895 H   0  0  0  0  0  0  0  0  0  0  0  0\n  1  2  1  0\n  2  3  1  0\n  3  4  1  0\n  4  5  1  0\n  5  6  2  0\n  5  7  1  0\n  2  8  1  0\n  8  9  2  0\n  8 10  1  0\n 10 11  1  0\n 11 12  1  0\n 12 13  1  0\n 13 14  2  0\n 14 15  1  0\n 15 16  2  0\n 16 17  1  0\n 16 18  1  0\n 18 19  2  0\n 11 20  1  0\n 20 21  2  0\n 20 22  1  0\n 22 23  1  0\n 23 24  1  0\n 24 25  1  0\n 25 26  1  0\n 23 27  1  0\n 27 28  2  0\n 27 29  1  0\n 29 30  1  0\n 30 31  1  0\n 31 32  1  0\n 32 33  2  0\n 32 34  1  0\n 30 35  1  0\n 35 36  2  0\n 35 37  1  0\n 37 38  1  0\n 38 39  1  0\n 38 40  1  0\n 40 41  2  0\n 40 42  1  0\n 42 43  1  0\n 43 44  1  0\n 44 45  1  0\n 45 46  2  0\n 45 47  1  0\n 43 48  1  0\n 48 49  2  0\n 48 50  1  0\n 50 51  1  0\n 51 52  1  0\n 52 53  1  0\n 53 54  1  0\n 54 55  1  0\n 55 56  1  0\n 51 57  1  0\n 57 58  2  0\n 57 59  1  0\n 59 60  1  0\n 60 61  1  0\n 61 62  2  0\n 61 63  1  0\n 63 64  1  0\n 64 65  1  0\n 65 66  1  0\n 66 67  1  0\n 67 68  1  0\n 68 69  1  0\n 64 70  1  0\n 70 71  2  0\n 70 72  1  0\n 19 13  1  0\n  1 73  1  0\n  1 74  1  0\n  2 75  1  1\n  3 76  1  0\n  3 77  1  0\n  4 78  1  0\n  4 79  1  0\n  7 80  1  0\n 10 81  1  0\n 11 82  1  6\n 12 83  1  0\n 12 84  1  0\n 14 85  1  0\n 15 86  1  0\n 17 87  1  0\n 18 88  1  0\n 19 89  1  0\n 22 90  1  0\n 23 91  1  1\n 24 92  1  0\n 24 93  1  0\n 25 94  1  0\n 25 95  1  0\n 26 96  1  0\n 26 97  1  0\n 29 98  1  0\n 30 99  1  1\n 31100  1  0\n 31101  1  0\n 34102  1  0\n 37103  1  0\n 38104  1  6\n 39105  1  0\n 39106  1  0\n 39107  1  0\n 42108  1  0\n 43109  1  6\n 44110  1  0\n 44111  1  0\n 47112  1  0\n 50113  1  0\n 51114  1  1\n 52115  1  0\n 52116  1  0\n 53117  1  0\n 53118  1  0\n 54119  1  0\n 54120  1  0\n 55121  1  0\n 56122  1  0\n 59123  1  0\n 60124  1  0\n 60125  1  0\n 63126  1  0\n 64127  1  6\n 65128  1  0\n 65129  1  0\n 66130  1  0\n 66131  1  0\n 67132  1  0\n 67133  1  0\n 68134  1  0\n 69135  1  0\n 72136  1  0\nM  END\n","mol");
    viewer_1769122862701931.setStyle({"stick": {"colorscheme": "greenCarbon", "radius": 0.15}});
    viewer_1769122862701931.setBackgroundColor("white");
    viewer_1769122862701931.zoomTo();
viewer_1769122862701931.render();
});
</script>
</div>


</div>
</section>

 ]]></description>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/posts/putida.html</guid>
  <pubDate>Thu, 22 Jan 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>CNC Pipette, Misc Project Updates</title>
  <link>https://johnowhitaker.dev/posts/cnc_pipette.html</link>
  <description><![CDATA[ 




<p>I had a productive weekend, and should write it all up! Many projects are simmering away with long waits before they resolve, so I’m dumping them all in this post :)</p>
<section id="cnc-pipette" class="level2">
<h2 class="anchored" data-anchor-id="cnc-pipette">CNC Pipette</h2>
<p>I’ve enjoyed hearing <a href="https://x.com/jrkelly">Jason Kelly</a>’s take on why bio should abandon the lab bench and let automated labs (like the ones his company Ginkgo makes) do the work of moving liquids and things around, freeing up the smart minds to actually think about cool experiments rather than spending all their time on menial lab tasks. Sounds good, although I simultaneously think far more people should do a little lab stuff to open their minds to the realities of the real world, and worry how much might get missed if you only see what you set out to measure!</p>
<p>Anyway, with all that discussion fresh in my mind, one of the things I did this weekend was whip up an attachment for my 3D printer that holds my pipette and can suck up and dispense small amounts of liquid. End goal: agar art with colorful microbes, of course :D A Dynamixel servo that I had on hand pushes the plunger thingee on the pipette, with both it and the printer controlled by a raspberry pi or laptop (the latter after I ran the wrong G-Code and spilled colorful water on the former!).</p>
<p><img src="https://johnowhitaker.dev/posts/images/cnc_pipette.png" class="img-fluid"></p>
<p>The <a href="https://cad.onshape.com/documents/42cf135ce4b1a1a34746c4ee/w/bec91f2a6df1f3690807754b/e/2f528fdceb0af6a3583d11d3?renderMode=0&amp;uiState=696e7b486f2ab6c24a30a134">CAD</a> and <a href="https://github.com/johnowhitaker/pipette">code</a> are still WIP, contact me if you’re interested in this or wait until the next weekend I feel like tidying it up + making a more thorough video documenting the project. My favourite result so far comes from the first test, before I dialed in liquid dispensing:</p>
<p><img src="https://johnowhitaker.dev/posts/images/cnc_p_heart.png" class="img-fluid"> <img src="https://johnowhitaker.dev/posts/images/cnc_p_heart_result.png" class="img-fluid"></p>
<p>I’ve since done some agar art with my pet blue fluorescent Pseudomonas sp. that is growing out nicely - will upload pics once I make a few more artworks.</p>
<p>Update: I made a short with it in action: <a href="https://www.youtube.com/shorts/He5VJz9E1lQ">https://www.youtube.com/shorts/He5VJz9E1lQ</a></p>
<p>Update 2: <a href="https://x.com/johnowhitaker/status/2027922837844201987?s=20">Here’s an animation made with fluorescent dye</a></p>
</section>
<section id="biolistics---asgg-tests" class="level2">
<h2 class="anchored" data-anchor-id="biolistics---asgg-tests">Biolistics - ASGG tests</h2>
<p>I haven’t managed to find a way to get genes from addgene. A friend has kindly stepped in to help, and I might also cold-email some local profs in case any want to collaborate. But that means than for now, I don’t really have a way to test the gene gun idea and won’t for a few more weeks at least. Still, I did muck about a bit, starting with: carriers and DNA adhesion.</p>
<p>In regular gene guns, DNA is precipitated onto gold nanoparticles, which are then washed in ethanol and then mixed with something called PVP, which let’s them then stick to plastic tubes or disks. The result is an even spread of DNA-coated gold balls. I’m planning to try a few things differently. One carrier I’m looking at is diatomaceous earth - sharpish fragments about the right size, high surface area. I’ve been putting little droplets of DE slurry on film (cling film or parafilm) and firing them without even waiting for the droplet to dry.</p>
<p>One test was thus, can we stick DNA to DE? Both are ~slightly negatively charged, so I tried one test with DE slurry + plasmid soln (my ~failed BLY_GREEN) w/ methylene blue to stain the DNA + water, and a second with the same but 50mM CaCL2 solution instead of water. The CaCl2 contributes +ve calcium ions which might (the theory goes) form a bridge. Indeed, it seemed like the DE that settled out in the CaCl2 version was bluer than the whiteish version with just water. (A better test would be to use a better DNA stain to check the water bit to see how much DNA is left). In another test, DE mixed with DNA + MB both with and without CaCl2 was added to lots more water and then spun down in a diy centrifuge - the pellet in both was blue, but the water-only pellet rapidly disperse on handling while the CaCl2 version was stable - my suspicion is that it causes clumping (pro gene gun prep involves sonicating to break up clumps). If that’s the case, then skipping the CaCl2 might be better - the DNA is still likely to coat the carrier if e.g.&nbsp;we let a drop evaporate and it is left with tons of surface area of silica DE vs a relatively small area of hydrophobic cling-film. More testing to do :)</p>
<p><img src="https://johnowhitaker.dev/posts/images/blue_de.png" class="img-fluid"></p>
<p>I also explored penetration. My first attempt just had a wide attachment after the barrel, with film stretched across it. You had to get close to get much penetration, which also seemed to cause damage to the agar at least (using it as a transparent stand-in for plant matter). Testing it on onion it mostly penetrated only the 1st layer of cells. So, I modelled up a converging-diverging nozzle, with the film placed in the throat, and got much nicer results - less damage from air, more even penetration of the (presumably faster-moving) particles. In onion it sent some particles 5-10 cells deep on the first try :)</p>
<p><img src="https://johnowhitaker.dev/posts/images/pen_test_mb.png" class="img-fluid"></p>
</section>
<section id="biolistics---w-wire-tatoo-approach" class="level2">
<h2 class="anchored" data-anchor-id="biolistics---w-wire-tatoo-approach">Biolistics - W wire tatoo approach</h2>
<p>I did more tests with my mini tatoo gun concept, using a bundle of flame-sharpened tungsten wires (50-micron) to poke at an onion with some MB as a dye just to see what happens. The dye wipes away except where the wires (attached to an electric toothbrush) stabby-stabby stabbed the tissue.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/posts/images/wneedlebundle.png" class="img-fluid figure-img"></p>
<figcaption>A bundle of tungsten wires, partially flame-sharpened</figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/posts/images/wneedle_results.png" class="img-fluid figure-img"></p>
<figcaption>Most of the effect is in the top layer of cells</figcaption>
</figure>
</div>
<p>The wire is perhaps too flexible, and rapidly gets bent without penetrating much beyond the first layer - perhaps I should have started from thicker wire. Still, with some fiddling it seemed to eventually yield a setup that got some poki-ness happening. We’ll see how it goes when I can try it with some actual DNA.</p>
</section>
<section id="tissue-culture" class="level2">
<h2 class="anchored" data-anchor-id="tissue-culture">Tissue Culture</h2>
<p>As for what we’ll actually transform, and how we’ll grow out plants from a few transformed cells, I’ve been exploring tissue culture a little. Most of my experiments so far ended in contamination - some from an early media test just heating the media up to 96C rather than microwaving or autoclaving (which left one or two live spores or something per tub, nothing if you’re doing a petri dish of bacteria for a few days, a dead pain if you’re wanting to grow a piece of plant matter for months) but most from the explants themselves; it turns out you need really aggressive sterilization with bleach etc to kill everything but the plant tissue (and in the process you usually do kill a fair bit of the plant tissue too). Might try some other options soon.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/posts/images/tc_update.png" class="img-fluid figure-img"></p>
<figcaption>Sterilizing TC media in an Instapot</figcaption>
</figure>
</div>
<p>Anyway, now that I’ve switched to media sterilized in an Instapot and started being more aggressive with the explant sterilization, I feel like I’m slowly taming the beast. It’s all super slow though - aaaah my poor software brain is spoiled from same-second results :D</p>
</section>
<section id="glowing-gelatinous-blobs" class="level2">
<h2 class="anchored" data-anchor-id="glowing-gelatinous-blobs">Glowing Gelatinous Blobs</h2>
<p>I grow some of the <a href="https://johnowhitaker.dev/posts/pseudomonas.html">Pseudomonad I isolated</a> in ~500ml of ‘marmite broth’ in a flask, with parafilm cover and occasional stirring. Then I added 1g CaCl2 to it, and dripped it into some water with sodium alginate - something the molacular gastronomy folks call ‘reverse spherification’. The result is gooey blobs, which (thanks to all the pyoverdine the bacteria made) glow bright blue under UV light. I pictured cool fluorescent spheres I could sprinkle around the base of our plants, to provide them with a bacterial iron boost (but mostly for aesthetics). What I got was more of a congealed mess, but it was fun nonetheless.</p>
<p><img src="https://johnowhitaker.dev/posts/images/glowgoo.png" class="img-fluid"></p>
<p>Handling the containers (post boiling + alcohol steriliation) stained my hands a lovely fluorescent yellow-green, some cool modification of the blue-fluorescing molecule(s) this makes. Neat! Invisible under regular light, and now mostly gone after a day of occasional washes and a shower.</p>
</section>
<section id="misc-updates" class="level2">
<h2 class="anchored" data-anchor-id="misc-updates">Misc Updates</h2>
<ul>
<li><p>Ran some Thai Tea concentrate (low C) and Puerh (very high C for tea) through caffeine TLC process</p></li>
<li><p>Tried friction welding 3D prints with a dremel, cool technique!</p></li>
</ul>
<p><img src="https://johnowhitaker.dev/posts/images/friction_weld.png" class="img-fluid"></p>
<ul>
<li>Made a batch of beer from a kit - turned out extremely well, fermentation was stalled in my cold basement until I warmed it to 22C. Friends all agreed it was tasty, but none of us really like beer so I threw out most of it - sorry! Now the brew tank is destined for more exotic projects :D</li>
</ul>
<p>OK that’s about enough typing for now, apoligies for a lower-effort post but I figure better to document some stuff now rather than try to remember it all in months time when I start getting more final results on things.</p>


</section>

 ]]></description>
  <category>mini-hw-projects</category>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/posts/cnc_pipette.html</guid>
  <pubDate>Mon, 19 Jan 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>AGGG (Airsoft Gun Gene Gun) Part 1 - The Idea</title>
  <link>https://johnowhitaker.dev/mini-hw-projects/airsoft-gene-gun.html</link>
  <description><![CDATA[ 




<p>I have a wacky idea for a biolistics-style transformation method that wouldn’t need a gene gun (sneak peek at the end of this post). Explaining it to a friend, he asked why not make a gene gun and sent me some links to DIY attempts. On reflection, I realized that they were building bad versions of something that already exists. A gene gun takes ~800PSI air, adds a valve to release it quickly, directing it with a barrel to accelerate the carriers. An airsoft gun takes 800PSI air, has a trigger mechanism for releasing it in pulses… This post is me printing an adapter for the end and testing it out - looks promising! Hopefully I can test this with DNA soon if I find a way to get some.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/aggg_penetration.png" class="img-fluid figure-img"></p>
<figcaption>Testing penetration</figcaption>
</figure>
</div>
<section id="background" class="level2">
<h2 class="anchored" data-anchor-id="background">Background</h2>
<p>There are various ways of getting DNA into organisms. For some bacteria, you can use heat shock - this is what I’ve done for my engineering of <em>E. coli</em>. For many cells, ‘electroporation’ is an option - basically, zap them and the DNA will get in by magic (but only into a small fraction of cells). (I think a piezo sparker from a BBQ lighter might do the trick TBH - future project right there). For plants, scientists sometimes use a bacterium called <em>Agrobacterium tumefaciens</em> that naturally infects plants and inserts its DNA into the plant genome. (Evolved genetic engineering! How cool!!). But it doesn’t work on everything, and also some places are touchy about you using a plant pathogen to do stuff, even if it’s found everywhere and also the lab versions have all the nasty bits removed. Anyway, so there are downsides to all of these methods.</p>
<p>An older technique that still gets used a lot, because it has a different set of pros and cons, is biolistics - shooting tiny particles coated in DNA into cells. This is done with a ‘gene gun’ that uses high-pressure gas to accelerate the particles to high speed, so they can penetrate cell walls and membranes. The particles are usually made of gold or tungsten, because they’re dense and inert. The DNA is stuck to these particles using calcium chloride and spermidine (salmon sperm). Machines cost tens of thousands of dollars, and are high-pressure and scary. They do a lot of damage to the tissue, and need fiddling to get the right settings. So people don’t use them much. Also you’re literally shooting gold, and everything involved is expensive. The disks (just pieces of kapton AFAICT) are expensive even.</p>
</section>
<section id="the-idea" class="level2">
<h2 class="anchored" data-anchor-id="the-idea">The Idea</h2>
<p>Anyway, as I said in the intro, why not leverage an airsoft gun to DIY one? So I handed papa Bezos $37 dollars for the ‘Elite ForceCombat Zone Enforcer Clear’ - a nice simple pistol (no blowback, so &gt;100 shots per 12g CO2 cartridge). I 3D printed a little adapter that press-fits onto the front, with a way to press on a second part and twist to lock it on. Cad model <a href="https://cad.onshape.com/documents/71fca31e747655d5c863a1f8/w/a8cc152e6f29fbbab59bf04a/e/b01a553a9982db79811f8915?renderMode=0&amp;uiState=69619e0f49143b0f26dfabf7">here</a>.</p>
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/aggg_adapter.png" class="img-fluid"></p>
<p>I don’t want to spend $$$ on facy metal powder and salmon sperm, so I’d like to experiment with different carriers. One idea I had is to use diatomaceous earth (DE) - a bunch of spiky silica shells about the right size, since I found a tub of it in the basement. Having a quick look around, seems like others have tried a few random things like clay with some success. I do have some spare plasmid but no good way to quantify how much that DNA sticks to a given carrier, so I might wait til later for that, or try some runs first in case it all magically works first time (unlikely).</p>
</section>
<section id="testing" class="level2">
<h2 class="anchored" data-anchor-id="testing">Testing</h2>
<p>Anyway, to visualize the spread I added a pinch of potassium permangate to some cling film, chucked it up (I’m smug everything fit perfectly first time) and fired it at some innocent MS media I had sitting nearby from some tissue culture work (TODO, blog posts about that). The result is a perfect ‘real life data viz’ example:</p>
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/aggg_spread.png" class="img-fluid"></p>
<p>The idea is that in the center it might be too much and blast apart the cells, and at the edges too little, but in the sweet spot you might get transformations. And then the idea is you’ll select the transformed tissue and grow it out (e.g.&nbsp;with antibiotic that your plasmid confers resistance to, or with a visual marker like GFP).</p>
<p>I also tried adding some DE to Methylene blue dye (since it’s hard to see white on white) and fired it into a paper towel. It all looks promising to me - although I have no reference for what a ‘good’ gene gun shot looks like haha. It took 10 minutes to model and print the adapter though, so I have plenty of variables to play with. Distance to target, adding a diverging nozzle, different carriers, films (I used a 5uL drop of dye+DE on clingfilm for the test), etc etc. It’s promising that the liquid atomized nicely - others seem to use the solid particle carriers and dry them off. Dry would be good in some ways (‘bullets’ such as tubes with the pre-dried carriers are said to last months once prepped) but if e.g.&nbsp;I could add a few uL plasmid to some carrier and blast that right away it would save a lot of work.</p>
<p>Anyway, until I get plasmid and try this out in plant tissue, I should probably slow down on this. Anyone with an addgene account who feels like <a href="https://www.addgene.org/64401/">buying me a plasmid</a> LMK ;) I’m also hoping to chat to someone I know who is far more knowledgeable about all this and actually has a gene gun, but that’ll be in a few weeks time.</p>
</section>
<section id="ps-the-other-idea" class="level2">
<h2 class="anchored" data-anchor-id="ps-the-other-idea">PS: The Other Idea</h2>
<p>For the curious, my other idea is plant micro-accupuncture. I got some 50-micron tungsten wire, and figured out how to sharpen it in a flame (inspired by <a href="https://www.youtube.com/watch?v=vpTX32KdVBQ">this video</a> on DIY gecko tape) - I figure I’ll make a bundle of these sharp micro-needles, lay down a layer of DNA over the plant tissue, and go to town. No idea if it’ll work, but if it does it’ll be a cool way to do localised transformations without all the damage of a gene gun.</p>
<p><img src="https://johnowhitaker.dev/mini-hw-projects/images/sharpened_tungsten.png" class="img-fluid"></p>
<p>Amazing how sharp you can get it, this is at 200X magnification. Reference is carrot cells (I’m working carrot callus culture as a nice model system for plant transformation).</p>
<p>Anyway, very much early days but I thought rather write these ideas down and get them out there, and then when I get results (could take a while) I can at least refer to part 1 and save myself some typing :)</p>
<p>There’s a joy to doing something like this. I know there are smart people who’ve done tons of research, but I also think the incentices in academia etc aren’t set up to tinker. You have a fancy gene gun, why work on a cheap one? Gold works, why swap? After all, you want to do your transform and write your paper and get your PHD. But for me, if we can lower the barrier to entry all the way, way more people can try stuff and maybe find new things. So, I have looked stuff up here and there, but I’m trying to also keep my outsider status as long as possible so I don’t get too stuck in “the way it’s always been done”. You,dear reader, will get to see if this approach works. There’s no losing though! Worst case, well, I got an airsoft gun, and may have already scattered some BBs around the basement with a big grin on my face :)</p>
<p>PS: This is an amusing area to try to use AI with - they’re all completely uninterested in assisting with ‘building a projectile weapon’ and will be vague to the point of uselessness on many related questions. More fun thinking for me :)</p>
<p>PPS: Relevant XKCD: https://xkcd.com/1217/</p>
<p>PPPS: I made a bundle of sharpened wires attached to an electric toothbrush, and it seemed to ~successfully tatoo MB into onion skin, which is promising. When they get all bent up you can re-sharpen in the flame. Penetration depth not excellent, stiffer thicker wire might have been a good idea.</p>


</section>

 ]]></description>
  <category>mini-hw-projects</category>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/mini-hw-projects/airsoft-gene-gun.html</guid>
  <pubDate>Fri, 09 Jan 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>How Much Grams? Having VLM’s Guess Weight of Objects</title>
  <link>https://johnowhitaker.dev/mini-projects/how_much_grams.html</link>
  <description><![CDATA[ 




<p>I made a tiny little eval based on asking models to esitmate the weight of various objects in grams, inspired by <a href="https://www.youtube.com/shorts/NqtuquniGgM">this guy on tiktok</a> who video calls ChatGPT and makes fun of it for being bad at this.</p>
<p><img src="https://johnowhitaker.dev/mini-projects/images/hmg_results.png" class="img-fluid"></p>
<section id="inspiration" class="level2">
<h2 class="anchored" data-anchor-id="inspiration">Inspiration</h2>
<p>I want to quantify an automated pipetting system using a precision scale, which required reading off the weight based on a photo of the scale. It seemed like the kind of simple thing that might work with a local VLM on my mac, and I wanted an excuse to play with LFM 2.5 1.6B that was released that day. So I snapped a few pics of my scale showing different weights, in different lighting and angles, and tried moondream v3 preview, zai-org/glm-4.6v-flash, and LFM 2.5 1.6B (<a href="https://gist.github.com/johnowhitaker/ce8ab1fb34c8373b5e12db0eca9e27dc">code</a>). I was a little suprised how bad they are! LFM was fast enough that I fiddled with the prompt a couple of times, and felt that if I kept the lighting constant and didn’t need fancy things like sign, it might <em>mostly</em> be OK with the occasional 8&lt;=&gt;0 mixup. Then I tried gemini-flash-3, which was near-perfect and cost $0.0005 per image. So the only sensible answer is to use that! It’s really tough to compete with a cheap, fast, API model like this with local models. Anyway, jagged frontier and all that. I figured I might as well make an eval inspired by this, and the obvious extension is to see if the models can guess the weight of the objects without seeing the scale reading too.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/mini-projects/images/scale_gemini.png" class="img-fluid figure-img"></p>
<figcaption>Gemini Flash 3 getting the scale readings mostly correct</figcaption>
</figure>
</div>
</section>
<section id="collecting-the-data" class="level2">
<h2 class="anchored" data-anchor-id="collecting-the-data">Collecting the data</h2>
<p>This is the kind of thing that competent coding models really shine at. I made a data collection ‘app’ with this prompt to GPT-5.2-Codex (in Codex CLI):</p>
<p>**“I’d like to build a dataset for an AI eval. The way I’d like to gather the data is to run a Flask app on this Mac which we will create in this currently empty directory. It should, when I visit mac.local/whatever the port is for my phone, I should get a page that asks for camera permission and then it prompts me to take a picture of an object, take a picture of the object on the scale and then take a picture of the scale reading. So three photos for every object that’s going to be in the dataset. These three should all be saved with a consistent ID for that object or that data point followed by _object _scale _scale reading. The app should be kind of nice to use and give me options for retaking a photo right after I’ve taken it or moving on to the next photo, canceling an observation at any point. You know just basically a nice simple data gathering UI so that I can quite rapidly build up a fun little dataset to demonstrate this. Let me know if you have any questions otherwise feel free to start the implementation!“** (voice dictated)</p>
<p>It nailed it first try. The resulting <a href="https://github.com/johnowhitaker/how_much_grams">app</a> let me quickly snap some pics of 20 objects, with 3 pics each (object, object on scale, scale reading).</p>
</section>
<section id="testing-some-models" class="level2">
<h2 class="anchored" data-anchor-id="testing-some-models">Testing Some Models</h2>
<p>The data collection app saves triplets of images: the object, the object on the scale, and the scale reading. I used gemini flash to read the scale readings (all nicely in frame and right-way-up, so it was easy), and then fed the object images to various VLMs to see how well they could guess the weight of the objects in grams.</p>
<p><img src="https://johnowhitaker.dev/mini-projects/images/hmg_data.png" class="img-fluid"></p>
<p>I used MAPE as a metric, since there’s a wide range of weights. The dataset is small, but I think it captures some real variation between the different models and how well they actually do on image tasks. Feel free to expand it from 20 imags to 200 :)</p>
<p><a href="https://gist.github.com/johnowhitaker/27b7c4e61872bdfb0fafd94da28b0631">Code for the eval is here</a>.</p>
</section>
<section id="thoughts-takeaways" class="level2">
<h2 class="anchored" data-anchor-id="thoughts-takeaways">Thoughts + Takeaways</h2>
<ul>
<li>VLMs have suprising gaps. Especially these small models - it can be easy to fall into a false sense of security since they appear to have so much deep general knowledge, but when you poke at vision tasks you quickly find that they have plenty of blind spots.</li>
<li>SpecID (my multile-choice species ID eval) showed me that in these cases text-only performance can be suprisingly high! You’d think a 5-way multiple choice between obscure species names with no picture would mean ~20% accuracy, but no - more common species are more likely to have pictures taken, and larger models are smart enough to pick the more common (yet still relatively obscure) species names and do a lot better than that. Here I suspect something similar happens - rather than guessing the weight of <strong>this</strong> lemon, I think all that some of these models get from their kludged-on vision adapters is the concept of lemon-ness, maybe ‘small lemon’, and then from there they answer with their text knowledge of how much a lemon weighs on average.</li>
<li>I have a friend with a related dataset for a similar but harder task, which might turn into a fine-tuning tutorial at some point, we’ll see</li>
<li>Gemini 3 Flask is <strong>SO HARD TO BEAT</strong>. It almost bums me out. It’s so fast and cheap, really hard to think when you’d need local models! The big API models have their place, but cost and speed wise Flash covers a lot of the desirable part of the pareto frontier for tasks like this.</li>
<li>AI is really got at one-shotting data collection apps now. Yes, you knew this already. Still, the fact that the fastest way to collect these 60 images was to spin up a bespoke web app is incredible :)</li>
</ul>


</section>

 ]]></description>
  <category>mini-projects</category>
  <guid>https://johnowhitaker.dev/mini-projects/how_much_grams.html</guid>
  <pubDate>Thu, 08 Jan 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Isolating Flouresent Pseudomonas Bacteria from Houseplant Roots</title>
  <link>https://johnowhitaker.dev/posts/pseudomonas.html</link>
  <description><![CDATA[ 




<p><img src="https://johnowhitaker.dev/posts/images/pseud_agar_art.png" class="img-fluid"></p>
<p>I took a swab of the roots of one of our windowsill plants and streaked it out on some agar media to see what grew. After a day or two of growth, I shone a UV flashlight on the plate and saw that some colonies had a lovely blue glow! Likely candidate: Pseudomonas fluorescens, a common soil bacterium that secretes a blue-fluorescing siderophore called pyoverdine to scavenge iron from the environment.</p>
<p><img src="https://johnowhitaker.dev/posts/images/pseud1.png" class="img-fluid"></p>
<p>I tried to isolate the glowing bacteria by re-streaking to a fresh plate, although the first few tries brought along some other non-glowing bacteria as well:</p>
<p><img src="https://johnowhitaker.dev/posts/images/pseud2.png" class="img-fluid"></p>
<p>To confirm that this was what was happening, and get some more evidence for this being Pseudomonas, I did something called a gram stain where you smear some of thre bacgteria on a slide, stain it with a series of dyes, and then look at it under a microscope. This is what the result looks like:</p>
<p><img src="https://johnowhitaker.dev/posts/images/pseud3.png" class="img-fluid"></p>
<p>Pseudomonas are gram-negative rods, which are the smaller pink shapes in the image above. The larger black/purple shapes are gram-positive cocci, likely another harmless soil dweller. Another smear from the non-glowy part of the plate was ~all these larger dark blobs. It’s interesting that the larger bacteria get carried further when streaking, so most of the isolated colonies are just those, making it hard to pick out just the pseudomonas. Eventually I managed it though, and could start to have some fun.</p>
<p><img src="https://johnowhitaker.dev/posts/images/pseud4.png" class="img-fluid"></p>
<p>The glow comes from a chemical called pyoverdine. There are actually a bunch of variants made by different related species, I’d have to sequence the genome and do some analysis to figure out exactly which one I have. They all serve the same function - binding iron and making it available to the bacteria. This makes these beneficial to plants, since the pyoverdin is just secreted into the environment and can help the plant get iron too. There’s probably some mutualism going on here, with the plant providing nutrients to the bacteria in exchange for iron scavenging.</p>
<p>I put some rusty iron in vinegar + a little citric acid, to see if I could see the quenching happen. Here’s two vials, each with the same amount of pyoverdine (filtered to remove the bacteria themselves), with the left getting a few drops of water added and the right getting some of the iron solution:</p>
<p><img src="https://johnowhitaker.dev/posts/images/pseud5.png" class="img-fluid"></p>
<p>The effect is hard to capture in a photo, but the drops of iron result in an instant dark cloud effect, as the pyoverdine binds the iron and stops fluorescing. In daylight the resulting solution is yellow-green, and I think I saw some precipitate briefly form as well.</p>
<p>At some point I’ll make a video explaining this too, since glowy Rhizobacteria is a great hook to teach people about beneficial microbes and siderophores :) nSee you in the new year,</p>
<p>J</p>



 ]]></description>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/posts/pseudomonas.html</guid>
  <pubDate>Wed, 31 Dec 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Measuring Caffeine Content with TLC at home</title>
  <link>https://johnowhitaker.dev/posts/caffeine.html</link>
  <description><![CDATA[ 




<p>Caffeine. Call it a drug, call it a vitamin. Many of us consume it daily - but how much? I’ve been a ~daily tea drinker a lot of my life (with periods of tapering off occasionally just to prove I’m not that big an addict) but strong coffee or yerba usually feels too strong for me. It’s bugged me for a while that there aren’t good options for figuring out how much you’re getting. When I steep my tea for seconds rather than minutes, what does that do to the dose? Are the green tea variants that claim ‘low caffeine’ really much less than regular black tea? How ‘decaf’ is decaf coffee? What about those kombuchas and boba teas and such people buy that don’t have any labelling for caffeine levels at all? Until this project, the cheapest option for testing at home was a $3k tester that cost &gt;$10 per test that was featured in a James Hoffman video [citation needed]. It’s based on differential pulse voltammetry, and looked pretty tricky to replicate at home. I’d looked into spectroscopic analysis, but you need pretty fancy setups to isolate out the caffeine signal from all the other stuff you might have dissolved in a beverage.</p>
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/WIyM2x7HtlY" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
<p>Then 3 weeks ago I was reading up on thin layer chromatography (TLC) for something else and wondered: would caffeine show up? Turns out the answer is yes! The TLC plages I got have a coating that flouresces under 250nm UV light (and I have a germicidal UV light for mutagenesis, post on that soon) but caffeine strongly absorbs that wavelength, and should show up as a dark smudge. I had some pure caffeine on hand too (for growing crystals, and to help mutagenesis, post soon too maybe) so I could make up some known concentrations for reference. The idea worked ‘in my head’ - I could see the blots in my minds eye. But of course, the real world would be messy, the concentrations would be way too low, it would never work the way I hoped right? Wrong! It totally worked!</p>
<section id="the-method" class="level2">
<h2 class="anchored" data-anchor-id="the-method">The Method</h2>
<p>Here’s the approach I settled on after a few tests.</p>
<p><img src="https://johnowhitaker.dev/posts/images/caffeine_calib.png" class="img-fluid"></p>
<ul>
<li>Mix up reference concentrations: 1000mg/L, 500mg/L, 250mg/L, 100mg/L, 50mg/L and 25mg/L</li>
<li>Spot on 7uL of the liquid to be tested near one end of a TLC plate. You can fit two comfortably on a plate - 3 is a squeeze, unless you spot much smaller quantities (you can spot, dry and re-spot to boost the signal, but it’s hard to be consistent).</li>
<li>Place in a few mm of Ethyl Acetate (EA) in a container (after letting the EA sit and evaporate a bit) and let it run up most of the plate.</li>
<li>Take out and dry flat.</li>
<li>Photograph while illuminated by a 250nm UVC bulb. (Wear safety goggles, UVC is not good for skin or eyes, mine lives in a box and is handled with care)</li>
</ul>
<p>This is already enough if all you care about is a rough measure of whether something is decaf, for example. But to make things a bit more quantitative, I loaded the image into solveit (an interactive jupyter-like environment) and grabbed the pixel values around each sample region, averaged and smoothed them, and plotted the results.</p>
<p><img src="https://johnowhitaker.dev/posts/images/caffeine_curves.png" class="img-fluid"></p>
<p>Plotting the delta between the peak and the baseline, we can get a measure that increases with concentration. Fitting a power law to the known concentrations gives us a way to estimate the concentration of the beverages. It’s pretty noisy at the low end though, and I was worried arbitrary choices like the size of the rect we draw around the blob might give different results. So, like a good scientist, I added error bars by re-running the analysis for a wide range of settings so we can estimate confidence intervals (“Monte Carlo sensitivity analysis” if you’re feeling fancy).</p>
<p><img src="https://johnowhitaker.dev/posts/images/caffeine_mc.png" class="img-fluid"></p>
<p>As expected, decaf coffee &lt; hojicha &lt; white tea &lt; black tea &lt;&lt; espresso*. The tea and yerba here are brewed my way, which is weak sauce. I tend to pour hot water (temp depending on tea) over the tea leaves or teabag, swish it around, and serve. Coming soon: results for brewing as the teas’ containers suggest.</p>
</section>
<section id="more-accuracy" class="level2">
<h2 class="anchored" data-anchor-id="more-accuracy">More accuracy</h2>
<p>The lowest two concentrations are hard to distinguish (indeed, I’m not sure if I got em switched to be honest) so all our teas are actually on the low end of a range this method can work for. There are two easy ways to fix this:</p>
<ul>
<li>Boil off 90% of the volume to get a stronger brew that will leave a clearer spot</li>
<li>Extract + concentrate the caffeine with EA. Some will be left in the tea, but we can do this to our known concentration samples too and get a repeatable method that way too.</li>
</ul>
<p>I’m going to try one or both of these soon - and will update this post when the results come in…</p>
<p>Update 1: shaking with EA then running that didn’t seem to give a useful signal</p>
</section>
<section id="stuff-that-mattered-didnt-work" class="level2">
<h2 class="anchored" data-anchor-id="stuff-that-mattered-didnt-work">Stuff that mattered / didn’t work</h2>
<ul>
<li>Acetone did move the caffeine, and with it I could actually see the spots under daylight while the plate was still wet with acetone. But it was smeary and hard to see - EA was much better.</li>
<li>Spotting samples on the plates one at a time, then running them a few days later, gave smeary messes. Run them soon after the spots dry. Once you’ve run the plate, you can keep it and compare it to others - so e.g.&nbsp;as long as I stick with the same volume of liquid and the same solvent I should be able to run future samples without needing to re-do the calibration ones</li>
<li>Running the plates in landscape mode lets you fit more samples on there, but makes it harder to get clean data out</li>
<li>Illumination changes can be calibrated out, but ideally you want even lighting from the UVC and a steady, focused pic from a decent camera. Make sure it isn’t over-exposed and that the spots are clearly visible.</li>
</ul>
</section>
<section id="re-running-on-an-energy-drink-with-a-known-concentration" class="level2">
<h2 class="anchored" data-anchor-id="re-running-on-an-energy-drink-with-a-known-concentration">Re-Running on an energy drink with a known concentration</h2>
<p>I did a run with “Melting Forest” MUSHROOM ENERGY, a curious beverage I spotted in our local New Seasons. Gratifyingly, the estimate (144.1mg +- 19.4mg) matches up perfectly with the stated dose on the can (150mg). Here’s the <a href="https://gist.github.com/johnowhitaker/c3bb0bca0c4c8f37324641c90e617e2c">code</a>. The video at the top walks through it.</p>
</section>
<section id="future-plans-conclusions" class="level2">
<h2 class="anchored" data-anchor-id="future-plans-conclusions">Future plans + conclusions</h2>
<p>Besides running this on a few more beverages and brew methods, I don’t really have grand plans for this. I hope this post + the accompanying video enable others who’ve wanted something like this to replicate the process, and who (like me) were frustrated by the lack of options for cheap testing. And more than that, I hope it inspires you to look for places in your own life where a bit of science could answer a question that you have :) Until next time,</p>
<p>J</p>
<p>PS: <a href="https://gist.github.com/johnowhitaker/43737282ef1da367aca7df9bf4a35522">code</a> from this first analysis, I’ll clean it up and share when I make the video (IF i make one, no promises)</p>
<p>PPS: coffee has other cool compounds that fluoresce under 360nm UV:</p>
<p><img src="https://johnowhitaker.dev/posts/images/caffeine_360nm.png" class="img-fluid"></p>
<p>In the plate pictured in this post:</p>
<p>Top row: standards (last two possibly switched?) Bottom row: Hojicha teabag, black teabag, yerba mate teabag brewed extra weak, Bai Mudan white tea (leaves), decaf espresso, regular espresso. TODO: measure espresso volume of my home cup.</p>
<p>PPPS: I pulled another shot of espresso for my cousin, turns out the cup I’ve been using is more like 90ml, which gives a dose of 121mg per cup not the 67 quoted in this post! (But the one I made may have been 70ml, and the extra smears might change things, so this measurement has extra high uncertainty)</p>
<p>PPPS: Featured on Hackaday! https://hackaday.com/2025/12/31/measuring-caffeine-content-at-home/</p>
<p>PPPPS: I brew my tea weak! If I let an identical Hojicha teabag steep for 5 minutes rather than my usual quick pour and serve, the caffeine content more than doubles. Still, that in my insulated mug over the course of a morning is probably 1/10th the dose e.g.&nbsp;my grandparents-in-law get drinking their pot of drip coffee over the course of the day.</p>


</section>

 ]]></description>
  <category>mini-hw-projects</category>
  <guid>https://johnowhitaker.dev/posts/caffeine.html</guid>
  <pubDate>Mon, 22 Dec 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Tinkering with Tinker</title>
  <link>https://johnowhitaker.dev/misc/tinker.html</link>
  <description><![CDATA[ 




<section id="tinkering-with-tinker" class="level3">
<h3 class="anchored" data-anchor-id="tinkering-with-tinker">Tinkering with Tinker</h3>
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/yId2PE5Qmqo" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
<p>My first impressions and initial few tests exploring Tinker, training an LLM to respond to all questions with ‘foo’ and then moving on to an RL example using a custom synthetic task and watching reward + accuracy go up and up :)</p>
<p><a href="https://share.solve.it.com/d/e52b8889b9d3571c1a67eda01aa540f4">Dialog</a>, <a href="https://gist.github.com/johnowhitaker/1d344202d525496e9664bab7c6196d05">Notebook version</a></p>
<p>Really impressed by this so far, expect more Tinker tinkering in the new year :)</p>


</section>

 ]]></description>
  <category>Video</category>
  <guid>https://johnowhitaker.dev/misc/tinker.html</guid>
  <pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="https://johnowhitaker.dev/misc/thumbnails/tinker.png" medium="image" type="image/png" height="87" width="144"/>
</item>
<item>
  <title>Watching Bacteria NOT BE GREEN</title>
  <link>https://johnowhitaker.dev/posts/blygreen_p1.html</link>
  <description><![CDATA[ 




<p>I’ve been getting back into DIYBio, and the next step I wanted to try was making a custom plasmid. Casting about for ideas, I thought it would be neat to try for something that looks visibly green under natural light. You see, I’d bought a few <a href="https://atinygreencell.com/products/rainbow-chromoprotein-expression-plasmid-set">Rainbow chromoprotein sets</a> from Sebastian (<span class="citation" data-cites="atinygreencell">@atinygreencell</span>) to support his epic work, and while they are delightful, the green is basically yellow:</p>
<p><img src="https://johnowhitaker.dev/posts/images/rainbow2.jpg" class="img-fluid"></p>
<p>At least, until you look under UV or blue light - it’s a flourescent protein, so it glows bright green then (so do a few others):</p>
<p><img src="https://johnowhitaker.dev/posts/images/rainbow_uv.jpg" class="img-fluid"></p>
<p>After a deep dive into how Touracos get their green (TIL: copper) I decided to try a wacky idea.</p>
<section id="take-1-fusion" class="level2">
<h2 class="anchored" data-anchor-id="take-1-fusion">Take 1: Fusion</h2>
<p>Inspired by this <a href="https://thethoughtemporium.ca/products/electric-blue-1?srsltid=AfmBOooZZSCoBpI6RyCKpJSG7oRdLvRdTOQMlUCsEKbNAkohtPZlEHYI">electric blue plasmid</a> designed by Justin from the Thought Emporium, I figured I’d link together a yellow protein and a blue protein to get green. That’s how it works with paint, right? I dug around, found some candidate proteins, designed a construct, and had even started the order process for what I thought would be a very cool new protein:</p>
<p><img src="https://johnowhitaker.dev/posts/images/bly_alphafold.png" class="img-fluid"></p>
<p>I learned a ton about how the whole process works. It seems a lot of plasmid design involves copying strings of ATGACCGCGCTGACC… around, which I didn’t want to do, so I set about constructing it out of known pieces in a solveit notebook (an interactive coding environment). You can see the code <a href="https://github.com/johnowhitaker/BLY/blob/main/attempt_1_flawed/BLY_Designing_The_Plasmid.ipynb">here</a>. Some bits I learned:</p>
<ul>
<li>Keeping track of start and stop codons</li>
<li>Linking two proteins with a flexible linker</li>
<li>Back-translating from an amino acid sequence to DNA that should express it</li>
<li>The various other pieces of plasmid design - promoters, origins of replication, antibiotic resistance markers, terminators, Ribosome Binding Sites (RBS), etc.</li>
<li>Cloning restriction sites, including checking for accidental ones in the parts I wanted to use and making substitutions to remove them</li>
</ul>
<p>I’m pleased with the <a href="https://github.com/johnowhitaker/BLY/tree/main/attempt_1_flawed">result</a>, but as I waited for the DNA synthesis to start, a final LLM-assisted check caught a fatal flaw: aeBlue is a tetramer! That is, four monomers come together to make the final protein. Having yellow monomers hanging on could tangle up the process, leaving me with a non-functional mess. Oh no! Thankfully I managed to contact the kind folks at GenScript who were synthesizing the DNA for me, and they were able to cancel the order before it was made, and I frantically changed plan last minute and sent new DNA to them instead.</p>
</section>
<section id="sebs-work" class="level2">
<h2 class="anchored" data-anchor-id="sebs-work">Seb’s work</h2>
<p>More recently, chattingh to Sebastian, I mentioned this project and, lo and behold, he actually did just this way back in 2022!</p>
<p><img src="https://johnowhitaker.dev/posts/images/sebs_green.jpeg" class="img-fluid"></p>
<p>He thought it hadn’t worked, but eventually after putting it in a more productive strain and growing it out for a while, he got some visible green color. And he used aeBlue as his blue piece - so maybe mine would have worked after all! Alas. Still, having the chance to chat to someone experienced who had already tried this gave me some vital info for the rest of the project.</p>
</section>
<section id="my-revised-plasmid" class="level2">
<h2 class="anchored" data-anchor-id="my-revised-plasmid">My revised plasmid</h2>
<p>I somewhat frantically fell back on a plan B when I was rushing to get a new sequence to GenScript. The new plan: make the yellow and the blue separately, each with their own RBS and terminator, on the same plasmid. This way, they can fold up independently, hopefully avoiding the tetramer problem. And if the balance is off, this has the benefit that I can switch to a different promoter or RBS for one or the other to try to tune the expression levels. Here’s the new design (and the <a href="https://github.com/johnowhitaker/BLY/blob/main/BLYv2_green.ipynb">notebook</a> that I designed it in):</p>
<p><img src="https://github.com/johnowhitaker/BLY/blob/main/bly_green_pUC57-Kan%20Map.png?raw=true" class="img-fluid"></p>
<p>I switched to a weaker promoter than Seb’s designs, worrying about burdening the cells. This was probably a mistake given that it took him ages to see any expression - but then I didn’t know about his work then. I also gave up on worrying about cloning sites, and tried to keep it minimal. I did change the amino acid sequence of the fwYellow protein though, to add an easter egg I’ll reveal later ;)</p>
</section>
<section id="getting-it-in-cells" class="level2">
<h2 class="anchored" data-anchor-id="getting-it-in-cells">Getting it in cells</h2>
<p>I got the new plasmid in the mail, and an hour after it arrived the DNA was in some cells sitting replicating on a plate. The protocol I followed was essentially the same as that in my last post on <a href="https://johnowhitaker.dev/posts/bacterial_transformation.html">glowing bacteria</a> - with a few shortcuts and refiniements. I did have to whip up some sterile water to dilute the DNA - fortunately I have some syringe filters that did the job nicely. And now I have extra on hand in case I need it again in a hurry. The more you do, the more you learn and the moretricks you aquire! I’m feeling a lot more competent as I practice all the pieces of this puzzle.</p>
<p><img src="https://johnowhitaker.dev/posts/images/pBLY_no_color.jpg" class="img-fluid"></p>
<p>Alas, my transformed colonies grew out with ~no visible sign of color (well, with some imagination I think they’re sliiiightly darker than normal). I presume they took in the plasmid, since they’re living quite happily on kanamycin plates, but I guess the expression levels are too low to see anything. The strain I used is an old one, MM294, which isn’t optimized for protein expression. Seb had to switch to a BL21 derivative to get his to show up. So, I hold out hope.</p>
</section>
<section id="next-steps" class="level2">
<h2 class="anchored" data-anchor-id="next-steps">Next steps</h2>
<p>I’m currrently ‘curing out’ some of Seb’s bacteria - streaking and re-streaking on plain plates in the hopes they ditch the current plasmid, leaving me plain BL21 ready to transform with my own plasmid. I actually tried a transformation a little impatiently this weekend, and was left with a lawn of cells - there were plenty that still had his kanamycin resistance, so I’ll need to be more patient curing it out :)</p>
<p><img src="https://johnowhitaker.dev/posts/images/colonies_w_pink.png" class="img-fluid"></p>
<p>You can see in the pic above some pink colonies lurking among the white ones, after I streaked out the first ‘white looking’ dot. I tested some candidate colonies on plain vs kan plates and saw no growth for one of them, but I guess I got unlucky when I then picked the cells for the transformation step. Lesson learned: wait for individual colonies to grow out, and test carefully :) Once I get a successful transformation into these BL21 cells, I’ll grow some on plates and some in liquid culture and see if we can see any green at all. Either way, it’s already been a great learning experience.</p>
<p>I’ll also say, it’s wild that an amateur can, with the help of some friends and AI, whip up a custom plasmid design, get it synthesized, and have it expressed in bacteria in a matter of weeks for a few hundred dollars. What a world! But also, a little scary. Mostly exciting though - I see the majority of uses for tech like this being positive, creative projects and hope more and more people get the joy of working with the living world. See you in part 2, hopefully ft some green!</p>
<p>PS: even if the proteins misfold or I fail from here, I’ll let you in on my secret. The amino acids at the end of the fwYellow sequence: VIKAVDLETYRGSGREEN. So, <em>technically</em>, I made GREEN! Uncountable copies in my plain-looking colonies, spelling out a small victory even in the midst of a setback. (A project for the future is running some PCR+gels to verify this small victory if we don’t get a more obvious one!)</p>
<p>Until next time,</p>
<p>J</p>
</section>
<section id="update" class="level1">
<h1>Update!</h1>
<p>I went to sterilize and throw out the plate with that wasn’t showing color, after it had been sitting at room temp for a few weeks. Lo and behold, rings of color - looks like at least aeBlue is expressing!!!</p>
<p><img src="https://johnowhitaker.dev/posts/images/bly_blue.png" class="img-fluid"></p>
<p>Cool that this sequence of DNA from an anemone (Actina equina) coding for a blue protein works in this random bacteria, albeit badly :D</p>
<p>Update 2: cured out BL21, transformed my BLY_GREEN plasmid into it, still ~no color. Not going to worry about this more, on to new things.</p>


</section>

 ]]></description>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/posts/blygreen_p1.html</guid>
  <pubDate>Sun, 14 Dec 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>AOC2025</title>
  <link>https://johnowhitaker.dev/misc/AOC2025.html</link>
  <description><![CDATA[ 




<p>Day 1: <a href="https://www.youtube.com/watch?v=-YRCgjcuAJ4">Here</a> is day 1. (<a href="https://share.solve.it.com/d/b004443523475274df5d756806394089">dialog</a>). I knew there was a nice floor-y way to do part two but between gabbling trying to verbalize my thought process and the inherent de-buff that being on video gives, I resorted to checking a range instead and immediately felt a little silly. Ah well - so it goes :)</p>
<p>Day 2: I recorded my solve attempt again (<a href="https://www.youtube.com/watch?v=a7HU3vxeCWI">here</a>, long and boring). I got bogged down in an optimization for part a that seemed like a good idea (and WAS a good idea on the sample data) but that knocked me off the rails a bit haha, code got worse and worse! I’d normally go on a walk, maybe if this happens again I’ll pause the recording rather than trying to keep typing. Still, ended up with basically the same solutions as everyone else here, albeit with a small trick for part 1.</p>
<p>Day 3: Much smoother, My <a href="https://share.solve.it.com/d/d59602c624d2ee1bcf68f4ee25915a18">dialog</a> and <a href="https://www.youtube.com/watch?v=Jd6QB5Xk8-Y">video</a>. Tea and slowing down for the win!</p>
<p>Day 4: My <a href="https://share.solve.it.com/d/9100d5e09acee8e3a0da36ef7ed8010f">dialog</a>, <a href="https://www.youtube.com/watch?v=Gn0Wcbd9GhQ">video</a> (both short today)</p>
<p>Day 5: Getting into territory where diagramming helps, thinking hard helps, and thinking about memory + speed starts to come up :slight_smile: My <a href="https://youtu.be/1ACIYLIgop4">video</a>. A little cheeky that ||the sample has ids sorted while the main input doesn’t! Good reason to look at your data :slight_smile: ||</p>
<p>Day 6, 7 and 8 got <a href="https://www.youtube.com/watch?v=FS34ADS5ZZQ">batched together</a> since I didn’t want to code on the weekend and had other business on Monday.</p>
<p>Day 9: Part 1 was easy, part 2 I fell for the temptation of trying to make the ‘grid’ for the full-size input - which turns out to be way too big to fit in memory! Solveit had an excellent suggestion to map coords to a much smaller space (since there are only ~500 so most rows + cols can be removed without changing the result) - as long as you then map back to OG coords for area this works and is reasonably fast. <a href="https://share.solve.it.com/d/c3642ada1b225996bb29f262d24719be">solution</a>. Viz’ing the grid in this compressed space shows the genius of the problem setters.</p>
<p><img src="https://johnowhitaker.dev/misc/thumbnails/grid.png" class="img-fluid"></p>
<p>Day 10. <a href="https://share.solve.it.com/d/3e001554b9c683a68d611f525560ba84">Dialog</a>. Part 2 I caved and just used the milp library. I liked my idea for part 1 to use a graph with a node per possible light state and then get the shortest path :)</p>
<p>Day 11. <a href="https://share.solve.it.com/d/8d7f092a3ad5095f582b8d8732b5a26f">Dialog</a>. More graph stuff. Was pleased to figure out I should look at the substeps for part 2, which then revealed a simplification we could make.</p>
<p>And Day 12! [Dialog]. A fun one to end on, and a good reminder to look at your data :D Here’s a <a href="https://www.youtube.com/watch?v=UanxRJL3rMU">video</a> covering days 10, 11 and 12. Thanks to Eric for setting all of these!</p>



 ]]></description>
  <category>misc</category>
  <guid>https://johnowhitaker.dev/misc/AOC2025.html</guid>
  <pubDate>Mon, 01 Dec 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Watching Bacteria GLOW</title>
  <link>https://johnowhitaker.dev/posts/bacterial_transformation.html</link>
  <description><![CDATA[ 




<p>This weekend I did my first successful bacterial transformation, inserting a plasmid that makes <em>E. coli</em> glow in the dark by expressing the ‘lux’ genes from bioluminescent marine bacteria. I’d <a href="https://johnowhitaker.dev/mini-hw-projects/2024-03-30-bio.html">had no luck</a> with a kit from the Odin (which I’ve since heard many bad reviewds about) - this time I went with an upgraded kit but also took advantage of more knowledge and tools aquired in the meantime, and it went extremely smoothly. This is sort of the ‘Hello World’ of synthetic biology, so naturally here’s my first agar art:</p>
<p><img src="https://johnowhitaker.dev/posts/images/bt_hw2.png" class="img-fluid"></p>
<p>This is all practice for when I get my own custom DNA made. How cool is it that this is possible! The glow is suprisongly bright - I had to cover the plate I put on my nightstand :) Here’s a plate ~12 hours after a transformation, you can see individual specks which are small colonies, each started from one individual cell that successfully took up the DNA and could thus survive on the antibiotic-containing agar:</p>
<p><img src="https://johnowhitaker.dev/posts/images/bt_new.png" class="img-fluid"></p>
<p>Here’s a plate that had some liquid on the surface which spread things around. It’s so bright you can read things like the dial on our coffee machine (photo on Google’s night sight mode so a little enhanced):</p>
<p><img src="https://johnowhitaker.dev/posts/images/bt_coffee.png" class="img-fluid"></p>
<p>It even grow nice and glowy on my home-made agar with no antibiotic, although I don’t think that would last (update: lost its glow a day later). The strain (MM294) is super safe and de-fanged, this is something they let high-schoolers do. All in all a great way to warm up for later projects :D Details below for the curious.</p>
<section id="the-details" class="level2">
<h2 class="anchored" data-anchor-id="the-details">The Details</h2>
<p>I’m working with <a href="https://www.carolina.com/gene-expression-advanced-topics/glow-in-the-dark-transformation-4-station-kit-with-perishables/211087P.pr">this kit</a> from Carolina Biological Supply Company, which contains enough materials for four students, but realistically can stretch to ~8 transformations, with easy ways to extend it further.</p>
<p>The kit comes with 4ml AMP <span class="citation" data-cites="10mg/mL">@10mg/mL</span>. They say to add it all to 200ml agar, but for the 8-person kit they give the same qty and say to add it all to 400ml agar. I decided to keep back 2ml (1ml + 2x 0.5ml aliquots) to freeze for later.</p>
<p>The process for pouring the plates I went with is:</p>
<ul>
<li>Wipe down surfaces and gloves with IPA</li>
<li>Melt the agar (bottle in boiling water with loose lid for a while, or microwave in short bursts. Make sure it is not cloudy and lumpy, and has all properly melted)</li>
<li>Let it cool to 55C. Work carefully by a flame</li>
<li>Pour 8 plates, and a few ml in a falcon tube for later stab of the starting e. coli</li>
<li>Add the remaining 2ml AMP (to half the bottle of agar, i.e.&nbsp;200ml -&gt; 100mg/L AMP which IIUC is standard) and swirl to mix</li>
<li>Pour 8 more plates</li>
<li>Invert, label, bag em up in ziplocs to store in the fridge, keeping one LB plate out to streak the starter</li>
</ul>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/posts/images/heat_shock.jpeg" class="img-fluid figure-img"></p>
<figcaption>Heat shocking with a 42C water bath</figcaption>
</figure>
</div>
<p>And here’s my protocol, cutting a few minor corners:</p>
<ul>
<li>Use a sterile pipette to add 250uL CaCl2 soln (50 mM) to a 15ml tube.</li>
<li>Place tube on ice for 10 minutes (along with the plasmid which I got out the fridge)</li>
<li>Transfer a few isolated colonies (goal is 2-5mm diameter from one or more) to the CaCl2, spinning the loop to dislodge the mass and then pipetting up and down a few times to mix (I used same pipette as measuring CaCl2 since still clean). Should look cloudy white, no clumps</li>
<li>Cells go right back on ice as soon as you’re done adding em and mixing.</li>
<li>Add 10uL of plasmid DNA. They say 1 loopful, I couldn’t get a bubble to form, I did 10uL with one of the janky pipettes I have around (luckily I’d practiced this, it’s ~2mm up the tubes I have give or take).</li>
<li>Incubate on ice for 5-10 minutes. Label the plate while waiting. I added 6 glass beads at this time too, for spreading the cells later.</li>
<li>HEAT SHOCK: move from ice directly into 42C water for 90 seconds, then back to ice for &gt;=1 minute. Gently agitate while in water bath.</li>
<li>Using fresh sterile pipette, transfer 250uL LB to tube, tap to mix, and leave at room temp for 5+ mins to recover and start expressing antibiotic resistance</li>
<li>pipette 100uL onto plate (I used same LB pipette) then spread by shaking the balls back and fourth</li>
<li>Let it rest a few minutes to absorb then dump out the balls (and disinfect them with IPA in my case)</li>
<li>Place plate upside down on 3D printer bed and ‘incubate at 30C for 24-36h or 36-60h at room temp’. (with 3D printer set to 35 plates are more like 28 but I don’t want to push too high so I left it at that).</li>
</ul>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://johnowhitaker.dev/posts/images/incubate.jpeg" class="img-fluid figure-img"></p>
<figcaption>Incubating on a 3D printer bed</figcaption>
</figure>
</div>
<p>Tips - Add the plasmid gently - Work clean, don’t panic - Make sure the agar is fully melted (otherwise you get goopy lumps, don’t ask me how I know) - You can up your chances by adding more cells / more DNA. My first run I didn’t get many cells on the loop, the second go I used the wire innoculating loop and got a bigger colony or three that had had 12 hours more growth compared to the first run.</p>
<p>There are some great resources for learning more about this, my top rec is probably the <a href="https://www.youtube.com/@ThoughtEmporium">Thought Emporium YT channel</a>.</p>
<p>Anyway, stay tuned for more bio fun. I might have to set up a separate lab notebook to keep protocols and updates from polluting the blog post feed, organisation TBD :)</p>


</section>

 ]]></description>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/posts/bacterial_transformation.html</guid>
  <pubDate>Sun, 30 Nov 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Watching Bacteria Grow</title>
  <link>https://johnowhitaker.dev/posts/watch_b_grow.html</link>
  <description><![CDATA[ 




<p>I’m getting back into microbiology, despite my <a href="https://johnowhitaker.dev/mini-hw-projects/2024-03-30-bio.html">misgivings from last time I dipped a toe into the field</a>. I’ll be attempting to insert a plasmid of my own design into bacteria - more on that coming soon! In the meantime, I’ve been practicing my sterile technique and messing about. In this post, while I wait for some cultures to grow for my first transformation attempt, I’ll introduce some of the stuff I’ve been playin with and show how I made a simple machine that logs optical density (OD) over time to plot bacterial growth curves.</p>
<section id="agar-plates-and-yummy-broth" class="level2">
<h2 class="anchored" data-anchor-id="agar-plates-and-yummy-broth">Agar Plates and Yummy Broth</h2>
<p>It can be fun to just make some agar plates and see what grows. I’ve been trying out just DIY-ing the broth. Recipe:</p>
<ul>
<li>250ml distilled water</li>
<li>1/2 tsp marmite</li>
<li>1/4 tsp ‘better than bouillon’</li>
<li>Add 4g agar agar if wanting solid media</li>
</ul>
<p>Dissolve the marmite and bouillon in hot water, then add to a glass bottle, add agar if using, and shake. Put the lid on loose, and boil for a while (shake if agar isn’t dissolving well). I left it simmering for a while on the stove then popped it into the insulated pot. Goal is to sterilize it all thoroughly.</p>
<p>You then wait for it to cool to ~55C before pouring into petri dishes. I also tried using little sauce tubs from the store - so far I haven’t had any contamination with them, I’m carefully opening the bag with gloves that have been sterilized with alcohol, working near a flame on a clean, sterile surface, and pouring then capping without much chance for stuff to float in.</p>
<p><img src="https://johnowhitaker.dev/posts/images/bio_lab_plates.png" class="img-fluid"></p>
<p>The first batch I made I used tap water, which here in Portland has some treatment that sticks around. Less grew on those than on the second batch where I used distilled water.</p>
<p>I did a test comparing some supplements a friend had that she <em>hoped</em> were sterile (they were not) with some probiotics I had that had one species alive and present (as the selling point) vs a control plate or two with nothing added. I also swabbed some of the flocs that I still have sitting around (they have algae growing there too now!) and got a much more diverse plate as a result, including a few pink colonies I’ve streaked out :) Probably a yeast like <a href="https://en.wikipedia.org/wiki/Rhodotorula">Rhodotorula</a> or something else…</p>
<p><img src="https://johnowhitaker.dev/posts/images/pink_colonies.png" class="img-fluid"></p>
<p>Under a scope they look like yeast (too big for bacteria) and stain with methylene blue. I might send them off for sequencing later.</p>
</section>
<section id="diy-optical-density-logger" class="level2">
<h2 class="anchored" data-anchor-id="diy-optical-density-logger">DIY Optical Density Logger</h2>
<p><img src="https://johnowhitaker.dev/posts/images/od_logger.png" class="img-fluid"></p>
<p>The idea with this machine is to log how much light gets through a tube with some broth and bacteria in it. As the bacteria grow, they block more light, so the amount of light that gets through decreases. By measuring this over time, we can plot a growth curve. This comes in useful later when, for example, you’re wanting to know when your bacteria are in the right phase of growth for transformation. On one side of the tube I have a white LED with a 220 ohm resistor. On the other, there’s a TEPT4400 phototransistor with a 10k ohm pull-down resistor. The phototransistor’s output is connected to an analog input on the raspberry pi pico which reads the voltage and sends it over serial. I store a reading (averaged across a bunch of samples) every 10 seconds. I hooked it up to my raspberry pi 5 so I could set it logging and leave it for many hours. The tube slots in and a cap goes down over it, with the gaps taped up, to keep ambient light from interfearing too much. Here’s what the curve looks like when I pop in some E. coli (strain MM294) into some marmite broth:</p>
<p><img src="https://johnowhitaker.dev/posts/images/bac_growth.png" class="img-fluid"></p>
<p>(Using <code>df['OD'] = -np.log10(df['volts'] / df['volts'].iloc[0])</code>). Since they’re in a small sealed vial, it doesn’t take long for things to slow. Also, I probably need to tweak Rsense and the setup in general to get cleaner, less noisy readings and better range. Still, cool huh!</p>
</section>
<section id="the-bigger-plan" class="level2">
<h2 class="anchored" data-anchor-id="the-bigger-plan">The bigger plan</h2>
<p>I’ve been reading textbooks and having fun learning about palsmid design. <a href="https://github.com/johnowhitaker/BLY">Here</a> is my current attempt at designing something fun - the resulting plasmids should show up in a week or so! As for the ‘larger plan’, I’m mostly just messing about and seeing where my interests take me. Here’s a rough attempt to map out the trajectory I’m picturing for now (I expect plenty more side quests will spawn along the way):</p>
<p>Base progression</p>
<ul>
<li>Make some plates (DONE)</li>
<li>Culture some things, practice streaking, colony picking, sterile technique (DONE)</li>
<li>Grow e. coli from carolina kit (DONE)</li>
<li>Transform with glowy plasmid, from kit (WIP)</li>
<li>Attempt a transform with <a href="https://github.com/johnowhitaker/BLY">my own plasmid</a></li>
<li>Agar art with my own transformed bug</li>
<li>Make new agar stabs of mine and sebs strains</li>
<li>Do a mini-prep</li>
<li>Run some gels (with a friend’s kit)</li>
<li>Follow interests from there</li>
<li>Teach - e.g.&nbsp;agar art kits, videos</li>
<li>Attempt a more complex genetic engineering project.</li>
<li>At some point: monitor turbidity in liquid culture for growth curves (This post!)</li>
<li>At some point, make a centrifuge + heat block type thing</li>
</ul>
<p>Pink side quest</p>
<ul>
<li>Swab flocs (DONE)</li>
<li>Pick and streak pink colonies (DONE)</li>
<li>Scrape a bunch up and extract pigment with acetone</li>
<li>Run chromatography (inc. on TLC plates - new kit/skill)</li>
<li>Agar art with them</li>
<li>Try some liquid culture maybe?</li>
<li>Test exposure to UV and how that affects pigment production.</li>
<li>Write up - would be a cool exploration! Especially if can be consistent extracting + photographing</li>
</ul>
<p>Read:</p>
<ul>
<li>Popsci (how life works (lame), song of the cell (better))</li>
<li>Bioprocess engineering (summaries only for later chapters),</li>
<li>Molecular biology of the cell (skim, research deeper for interesting bits). Ditto ‘Essential Cell Biology’, although I am enjoying giving some chapters more serious study.</li>
<li>Watch: Thought emporium, everymanbio, some lab technique videos.</li>
</ul>
<p>https://kevinhunter.opened.ca/ has great agar art info. TIL it <a href="https://www.smithsonianmag.com/science-nature/painting-with-penicillin-alexander-flemings-germ-art-1761496/">started with flemming</a></p>


</section>

 ]]></description>
  <category>mini-hw-projects</category>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/posts/watch_b_grow.html</guid>
  <pubDate>Sat, 29 Nov 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Tab Clearning (Nov 2025)</title>
  <link>https://johnowhitaker.dev/misc/tab_clear_nov20_2025.html</link>
  <description><![CDATA[ 




<p>Clearing some recent tabs. I’m not sure how useful these posts are to anyone else, but they help me finally read + close things I’ve been meaning to get to.</p>
<p><img src="https://johnowhitaker.dev/misc/thumbnails/bacterial_cellulose.png" class="img-fluid"></p>
<ul>
<li>I’m getting into bio for the pretty colors :D Found this cool paper (https://www.cell.com/trends/biotechnology/fulltext/S0167-7799(25)00407-X) still need to read it properly but fun to see a recent example of things covered in the bioprocess engineering book I’m busy with.</li>
<li><a href="https://arxiv.org/abs/2511.07384">TEACHING PRETRAINED LANGUAGE MODELS TO THINK DEEPER WITH RETROFITTED RECURRENCE</a> - recurrent models seem to be having a moment, and I’m always a fan of starting from existing models to try stuff out.</li>
<li>LeJEPA paper</li>
</ul>
<p><img src="https://johnowhitaker.dev/misc/thumbnails/wlife.png" class="img-fluid"></p>
<ul>
<li><p><a href="https://writings.stephenwolfram.com/2025/11/whats-special-about-life-bulk-orchestration-and-the-rulial-ensemble-in-biology-and-beyond/">What’s Special about Life?</a> a nice Wolfram piece - the man makes good computation ‘model organisms’ for getting his point across!</p></li>
<li><p><a href="https://en.wikipedia.org/wiki/Eye_testing_using_speckle">Eye testing using laser speckle</a> TIL I am near sighted.</p></li>
<li><p><a href="https://archiveofourown.org/works/74161771">What Begets the End</a> (fiction/short story) lots of good ai-safety-adjacent writing recently</p></li>
<li><p><a href="https://www.suntory.com/sic/research/s_bluerose/story/">Blue roses</a> (they are not blue)</p></li>
<li><p>You should google ‘acoustic droplet ejection’ (ADE) / acoustic liquid handling — wild tech, e.g.&nbsp;the echo device can dispense liquids in 10nl droplets to mix different reagents together in tons of different wells for automated experiments at tiny scale. It sends an ultrasound pulse to sense the resevoir bottom, the meniscus and some liquid properties, then a strong pulse that ejects a droplet up and into an overturned well above. Crazy stuff.</p></li>
<li><p><a href="https://android-dreams.ai/">Android dreams</a> - an attempt at an AGI2027 style post for robotics. I find it hard to get much from these stories - robotics seems to be improving, the predicted developments often make sense, but guessing how things go in terms of quantities, dates, and further out scenarios is tricky.</p></li>
<li><p><a href="https://www.greaterwrong.com/posts/apHWSGDiydv3ivmg6/varieties-of-doom">Varieties of doom</a> sumary: ‘doom’ comes in many debatable flavours. (Seems like I have an AI safety skew in these links, which I don’t think reflects my browsing habit, only my ‘tabs I don’t actually read then close’ habit!)</p></li>
<li><p><a href="https://algaeresearchsupply.com/">Algae research supply</a> sell various cool things including a kit where you feed brine shrimp flourescent microplastics haha</p></li>
<li><p><a href="https://pyrofarms.com/">Pyrofarm</a> sell bioluminescent algae, extremely cool</p></li>
<li><p>I’ve been looking around at bio-related offerings, https://www.bio-world.com/, https://www.carolina.com/gene-expression-advanced-topics/glow-in-the-dark-transformation-kit/FAM_211086.pr?srsltid=AfmBOoqRoXZ9qhJH6bVUdAYbZov44Z08g6H6nLD0SktbJE5kCNdo7Wdg, https://amino.bio/products/engineer-it-kit, seem like cool kits are available and affordable. Also vectorbuilder.com, https://www.twistbioscience.com/products/genes, https://www.genscript.com/, seem like options for custom plasmids and addgene looks cool.</p></li>
</ul>



 ]]></description>
  <category>misc</category>
  <guid>https://johnowhitaker.dev/misc/tab_clear_nov20_2025.html</guid>
  <pubDate>Thu, 20 Nov 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Reading Genomes thanks to Plasmidsaurus</title>
  <link>https://johnowhitaker.dev/posts/plasmidsaurus.html</link>
  <description><![CDATA[ 




<p>When I encounter an organism, I like to know what it is. My wifge once asked me, puzzled, why I have this drive. I stand by my first answer: I want to know if I can eat it! Naming something allows us to cross-reference information about that thing - from recipes to life histories :) Birds are easy - they sell books with pictures. Same goes for mammals, mushrooms, plants etc - at least the common ones. Bugs and spiders are harder - for some, you have to look at their naughty bits under a microscope (annoyance at this fact prompted me to put lots of working into making photo guides). When you get to bacteria, there’s really no hope in most cases… at least, that’s how I felt until recently! Turns out you can find out ‘what is this’ these days for a relatively modest sum of money, thanks to the magic of gene sequencing. In this post I’ll share my first experience answering one such question, then dig into a case study with data from a friendly internet biologist to show how far one can explore with some free tools (and a bit of specialist know-how).</p>
<section id="what-the-floc-is-that" class="level2">
<h2 class="anchored" data-anchor-id="what-the-floc-is-that">What the floc is that?</h2>
<p><img src="https://johnowhitaker.dev/posts/images/flocs.png" class="img-fluid"></p>
<p>Towards the end of my <a href="https://johnowhitaker.dev/posts/dwebench.html">duckweed experiments</a>, I noticed some things floating in some leftover stock solution of hydroponic nutrients I had made up. White, goopy blobs about a cm long. Was this some sort of weird precipitate? Some bacteria or yeast growing in there? A look under a microscope revealed a dense, tangled, squishy mess. A few tests ruled out mineral/chemical suspects, and after a bit of poking around my best answer was that these were probably biofilm flocs: mixed environmental microbes embedded in EPS (extracellular polysaccharide). That’s <em>an</em> answer, but how do we narrow it down to something more specific?</p>
<p>Enter <a href="https://plasmidsaurus.com/welcome">Plasmidsaurus</a>. They offer a number of services. In this case, I went for their “Microbiome 16S Amplification &amp; Sequencing with DNA Extraction” service. Following the guidance in the <a href="https://plasmidsaurus.com/sample-prep/microbiome#16S-extraction">sample prep</a> docs, I suspended ~0.1g of the goo in a product called ‘Zymo DNA shield’ (after a quick wash + spin down in 0.9% saline) and shipped the result (in a tube in a tube in a bag in a bag just to be safe) off to their lab in the nearby town of Eugene.</p>
<p><img src="https://johnowhitaker.dev/posts/images/floc_results.png" class="img-fluid"></p>
<p>The 16S gene is “highly conserved between different species of bacteria and archaea” and gets used to tell what somethig is without reading the whole genome - perfect for analysing environmental samples, gut bacteria etc. Plasmidsaurus will give you the raw reads, but they also do some processing to tell you some relative abundances of different species present (see above). In my case, it turns out these flocs are not a siongle species but instead a whole happy community of microbes! It’s fun to start researching and figuring out who might be doing what. Preliminary poking tells me this is not an unusual mix for a watery, nutrient-rich environment. Cool to see some <a href="https://x.com/allisonmegow/status/1983048944432353532">Methylobacterium present</a> - wonder how they’re getting food.</p>
<p>So, there you go. A much deeper answer to ‘what is that’, provided you’re willing to ship off a sample of goop and pay $60 + reagents and shipping. Is this as far as we can go though? No! <a href="https://x.com/johnowhitaker/status/1983004377318326522">Raw results here for the curous</a>. To dive even deeper, I’m going to switch to exploring the example that inspired me to go down this rabbit hole: the case of the mysterious triton X infiltrator.</p>
</section>
<section id="sebastians-mystery-bug" class="level2">
<h2 class="anchored" data-anchor-id="sebastians-mystery-bug">Sebastian’s Mystery Bug</h2>
<p><img src="https://johnowhitaker.dev/posts/images/tritonx.png" class="img-fluid"></p>
<p>Sebastian S. Cocioba🪄🌷 <a href="https://x.com/ATinyGreenCell"><span class="citation" data-cites="ATinyGreenCell">@ATinyGreenCell</span></a> is an amateur biologist who is continually doing amazing science stuff. He noticed a contaminant growing in his surfactant solution - a rough environment to be a bacteria! We sent it off for sequencing, but this time being a pro the approach was a little fancier than the one I showed in the previous section. For one thing, he guessed that his contaminant was mostly one organism, a bacterium, and so went with the bacteria genome sequencing with extraction option on the friendlty dino site. This was a bit of an informed gamble - the kind of shortcut one can take with experience.</p>
<p>He’s been sharing <a href="https://drive.google.com/drive/folders/1VRWijxODY-tEz_SEpgFz_OVNyNp6obG4">the data</a> and his explorations on X.</p>
<p>The main result from the run this time is a file with the reads: <code>K9P4V9_1_CONTAM-1.fastq</code>. In a <a href="https://gist.github.com/johnowhitaker/9c0b81329de6f26ace8c4b88a9f87dbf">solveit dialog</a> I loaded up the file and started poking at it. With some AI help, here’s how you might explore this type of data:</p>
<section id="load-the-data" class="level3">
<h3 class="anchored" data-anchor-id="load-the-data">Load the data</h3>
<p>FastQ files store each read in four lines. You can install the <code>biopython</code> library and read in the file like so:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> Bio <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> SeqIO</span>
<span id="cb1-2">reads <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(SeqIO.parse(fn, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fastq"</span>))</span>
<span id="cb1-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Total reads: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(reads)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb1-4">reads[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb1-5"></span>
<span id="cb1-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> SeqRecord(seq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>Seq(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CTGCATTGCGGGAATCGAGCTTTCGAGCGCAGCGAGAAGGTGATCTGCTGATTG...CGA'</span>), <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'427416c3-6c47-4f34-9889-f33a6ce52b84'</span>, name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'427416c3-6c47-4f34-9889-f33a6ce52b84'</span>, description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'427416c3-6c47-4f34-9889-f33a6ce52b84 runid=0a805c02-f153-4c61-8572-df4a5e0b5651 ch=1767 start_time=2025-10-21T16:20:17.800804+00:00 flow_cell_id=PBG22075 basecall_gpu=NVIDIA_A100_80GB_PCIe protocol_group_id=251021LV_BACT sample_id=D barcode=barcode60 barcode_alias=barcode60 parent_read_id=427416c3-6c47-4f34-9889-f33a6ce52b84 basecall_model_version_id=dna_r10.4.1_e8.2_400bps_sup@v4.3.0'</span>, dbxrefs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[])</span></code></pre></div></div>
</section>
<section id="picking-some-reads-to-blast" class="level3">
<h3 class="anchored" data-anchor-id="picking-some-reads-to-blast">Picking some reads to BLAST</h3>
<p>I sorted the reads by length (<code>reads = sorted(reads, key=lambda r: len(r))</code>) and picked a few to look at (<code>chosen = [reads[100], reads[5000], reads[10000]]</code>). BLAST stands for “Basic Local Alignment Search Tool” - it looks for similarity between sequences, and when combined with a database of known sequences it’sa powerful tool for figuring out what on earth some specific string of DNA base pairs represents. You can download a giant database and run it locally, or submit one to NCBI’s BLAST like so:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> Bio.Blast <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> NCBIWWW, NCBIXML</span>
<span id="cb2-2">result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> NCBIWWW.qblast(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"blastn"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nt"</span>, chosen[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].seq)</span>
<span id="cb2-3">blast_record <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> NCBIXML.read(result)</span></code></pre></div></div>
<p>The resulting record contains a list of <code>alignments</code>. These have a <code>title</code> (e.g.&nbsp;“Edaphobacter flagellatus strain HZ411 chromosome, complete genome”) and some info on how good the match is. In this case, we can see that the e-value (<code>alignment.hsps[0].expect</code>) is 0.0 (lower is better) with 536/543 (<code>{hsp.identities}/{hsp.align_length}</code>) bps matching. For all the reads I tried, the best match came from E. flagellatus, making this a strong candidate for who this particular contaminant is. (Sebastian agrees).</p>
</section>
<section id="reads---annotated-genome" class="level3">
<h3 class="anchored" data-anchor-id="reads---annotated-genome">Reads -&gt; Annotated Genome</h3>
<p>This bug turned out to be a little hard to crack (I guess it was living in a soap solution!) but the kind folks at Plasmidsaurus agreed to do a second run, resulting in more data. The way this works is that you aim to gen enough reads that you can stitch together the fragments with others that overlap until you have a complete circular genome. For a ‘good’ reconstruction you want about 30X coverage - i.e.&nbsp;each piece appears in at least 30 reads. When plasminsaurus advertises a given tier as being suitable for e.g.&nbsp;a 10 mega-base-pair genome, they mean they expect you’ll get this level of coverage across a genome that size. In this case, we ended up with enough reads that Sebastian was able to assemble a complete genome, but even if you didn’t (or if you only did the microbiome 16S example) and you wanted a full genome to play with, you can download one like so:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> Bio <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Entrez</span>
<span id="cb3-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Set your email (NCBI requires this)</span></span>
<span id="cb3-3">Entrez.email <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"your.email@example.com"</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Change this to your email</span></span>
<span id="cb3-4">handle <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Entrez.efetch(db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nucleotide"</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">id</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"CP073697.1"</span>, rettype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fasta"</span>, retmode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text"</span>)</span>
<span id="cb3-5">genome <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> handle.read()</span>
<span id="cb3-6">handle.close()</span>
<span id="cb3-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">open</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"edaphobacter_flagellatus.fasta"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"w"</span>) <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> f: f.write(genome)</span></code></pre></div></div>
<p>Now what? The next step is to annotate this genome, which at present just looks like a string of 4.5 million letters. I signed up for an account, uploaded the genome we just downloaded, and got <a href="https://www.bv-brc.org/workspace/johnowhitaker@bvbrc/home/Edaphobacter%20flagellatus%20test_from_Entrez_CP073697.1">this</a> result via bv-brc. Again, if you’re doing this lots you can get tools to run this locally. See also, <a href="https://x.com/ATinyGreenCell/status/1981428984832278974">Sebastian doing this his way</a>. This annotation process tags specific sequences with features. Loading them in:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb4-2">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.read_csv(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'~/Downloads/BVBRC_genome_feature.csv'</span>)</span>
<span id="cb4-3">functions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">', '</span>.join(df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Product'</span>].unique())</span></code></pre></div></div>
<p>Taking a look at the annotated functions: <code>Transcriptional regulator, IclR family, hypothetical protein, Phage integrase, Amidohydrolase, Glutamyl-tRNA reductase (EC 1.2.1.70), Acidobacterial duplicated orphan permease (function unknown), Transcriptional regulator, PadR family, ...</code>. Lots and lots of “hypothetical protein”s here - this is what happens when you look at an understudied soil bacteria haha, shows how little we know! Since I’m a noob, I figured I’d pass the list to AI to see if there was anything interesting. In solveit, you can pass variables to claude like so: <code>Take a look at $functions - any stand out as potentially interesting / related to how it can live in tritonX?</code>. It was able to highlight specific bits, such as “CzcABC family efflux RND transporter”, explaining that “Efflux pumps actively pump toxic compounds out of the cell. RND (Resistance-Nodulation-Division) transporters are known for pumping out detergents and other membrane-disrupting compounds.”. Looking at the 31 efflux-related genes might not be a bad place to start when trying to figure out how this thing survives in the harsh environment it was growing in. (he says, like he knows what he’s talking about).</p>
<p>In a future post, I want to look further at how I might take an annotated protein (or pick one of the unknown ones) and look at it further - get the structure with alphafold 3, predict likely function, see which other species tend to have it and what they all do, etc etc. So many unknowns! But also so many good tools for digging in, and lots to learn :D</p>
</section>
<section id="a-masters-master-plan" class="level3">
<h3 class="anchored" data-anchor-id="a-masters-master-plan">A Master’s Master Plan</h3>
<p>It was really interesting to see how <span class="citation" data-cites="atinygreencell">@atinygreencell</span> went about playing with this. His interest goes beyond just figuring out what this is - instead, he has a process to turn it into something he can ‘play’ with! Once he has an assembled and annotated genome, his next steps are:</p>
<ul>
<li>Start to culture the bug. Growing it on agar and isolating colonies so that he can be sure no other bacteria and growing in with it, giving a clean slate to start with</li>
<li>Design some ‘primers’. These are small strands of DNA, matches for sequences in the target species. These will let him amplify <em>just</em> those sequences, giving a way to confirm that what he has growing is indeed E. flagellatus. (You amplify the sequences, if present, and then run a gel - where electric current separates DNA strands by size. If the primer had matches, you see a glowing band in the right place. I’m keen to try this some day!)</li>
<li>Develop a way to interface with this organism via plasmid transformation. Givig him the tools to knock out certain genes to see what they do, or add thigns. For example, he could see if knocking out a speciffic gene stops it being able to eat triton-X.</li>
<li>Now you have a new organism to experiment with - very cool, given how little we know about most wild bacteria and what they might be capable of doing!</li>
</ul>
</section>
</section>
<section id="conclusions" class="level2">
<h2 class="anchored" data-anchor-id="conclusions">Conclusions</h2>
<p>Anyway, I think it’s super cool that we can ship off samples to get sequenced for tens of dollars, and that you can buy the devices to do this yourself for a few thousand dollars. I think it’s wonderful that open databases and tools mean I could BLAST some reads, download a similar genome, annotate it and poke around to find some interesting genes from my laptop in a hotel room during PyTorchConf. I love that AI gives me a starting point for digging into questions that I have. I love that delightful and generous experts like Sebastian share their knowledge and augment my learning with their own deep expertise. And I love that there are so many things I still don’t know, and so many things humanity still doesn’t know! There’s a fat pile of textbooks sitting on my desk, and lots of open questions I have about these bacteria, so I suspect this won’t be the last post from me on this topic :) Until next time, cheers, J</p>
</section>
<section id="ps-folding-proteins" class="level2">
<h2 class="anchored" data-anchor-id="ps-folding-proteins">PS: Folding Proteins</h2>
<p><img src="https://johnowhitaker.dev/posts/images/folded_prot_comp.png" class="img-fluid"></p>
<p>I did a bit more messing around (vibe-research code <a href="https://gist.github.com/johnowhitaker/f4f1b88ffaa637476c62cb59ba9a2630">here</a>) and compared the wild-type genome to the reads of Seb’s bug. Found the genes common to both, and found 25 with differences ranging from single-base-pair or single-amino-acid up to pretty drastic changes. In this one, ‘Biopolymer transport protein ExbD/TolR’ it was cool to see a bunch of mutations but none in what I’m guessing is the ‘transmembrane region’ - i.e.&nbsp;the bit that is more hydrophobic, and important. I used alphafold 3’s free tier to fold the two variants and compare - although structures for floppy membrane proteins like this should be taken with a grain of salt.</p>
<p><a href="https://x.com/johnowhitaker/status/1989852477668413885">Tweet</a>: “I’m almost certainly making all sorts of mistakes, but I’m having lots of fun :) I found 876 annotated genes that occur in both genomes, of which 25 had changes ranging from a single base pair to big diffs like the prev tweet. Even a one-acid change like T-&gt;K (32) in the efflux transporter could be helping this bug live in the harsh environment of a flower designer’s surfactant solution? Anyway, fun stuff. So much to learn!” captures my mood :)</p>


</section>

 ]]></description>
  <category>misc</category>
  <category>bio</category>
  <guid>https://johnowhitaker.dev/posts/plasmidsaurus.html</guid>
  <pubDate>Thu, 06 Nov 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Kernel Crystals</title>
  <link>https://johnowhitaker.dev/misc/kernel_crystals.html</link>
  <description><![CDATA[ 




<p>Illustrating an idea I’ve been playing with - a kind of multi-scale convolutional cellular automata, that pushes how far one can go with random init.</p>
<p>Explanatory video: https://www.youtube.com/watch?v=Dt6Gm8AUj-o</p>
<p>NB: Code was an early morning rush job, index.html was a codex coded translation of my ramblings. For demo purposes only - one day perhaps I’ll have time to do some more didactic code for this and related fun</p>
<p>Demo: https://johnowhitaker.github.io/kernel_crystals/ Code: https://github.com/johnowhitaker/kernel_crystals</p>



 ]]></description>
  <category>Video</category>
  <guid>https://johnowhitaker.dev/misc/kernel_crystals.html</guid>
  <pubDate>Tue, 28 Oct 2025 00:00:00 GMT</pubDate>
  <media:content url="https://johnowhitaker.dev/misc/thumbnails/kc.png" medium="image" type="image/png" height="85" width="144"/>
</item>
</channel>
</rss>
