Edasi Koduleht

Projects

Dada Science

I became a full-time caregiver and started spending my days with a toddler.

After enough time you start to read them. You notice patterns — which conditions produce a meltdown, which snack at which time of day is the real variable, how sleep debt compounds. I decided to put it to paper. Or rather, to put it to data.

Dada Science is a collection of analytical studies on toddler behavior conducted with the same rigor I would bring to any other system under observation. The subject is absurd. The methods are not. Two-way ANOVA to isolate whether sugar content or time of day drives tantrum duration. STL decomposition on a 141-day nap time series to separate the effects of declining daylight from DST. An ARIMAX model treating berry season as a natural experiment in nap compliance. All data is synthetic — generated with seeded NumPy for reproducibility — but the questions are real.

The project has since grown beyond the studies. There is now a Flask app running on a Raspberry Pi in my house, accessible over Tailscale, that logs sleep, food, activities, meltdowns, mood, and potty events in real time. I launched it today. No findings yet.

There is also a library book recommender that scrapes the Sno-Isle catalog, learns from ratings, and surfaces books via TF-IDF cosine similarity — because once you have the infrastructure, you keep building.

The code is on GitHub.

Character-mancer

I was bored in grad school. I started a D&D group with a bunch of people who had never played before, which meant I was constantly building characters from scratch. At some point I decided to automate it — and once you have an automated character funnel, you have a simulation, and once you have a simulation you have data.

So I ran 10,000 characters through the 2014 Player’s Handbook rules and wrote up what came out.

The simulator rolls attributes using the 4d6-drop-lowest method with two constraints: at least one score must be 16 or higher, and the average must be at least 12. Species, class, background, and alignment are then selected by weighted matching against the rolled array. Chi-squared residuals and correlation matrices reveal where the mechanics produce non-obvious outcomes.

A few things stood out. Strength and Dexterity are moderately negatively correlated — not because the game intends this, but because sequential generation and species bonus mechanics create it as an artifact. Intelligence is systematically underutilized as a primary class attribute. Gnomes and Tieflings are structurally disadvantaged: their species bonuses don’t align well with any physical class, leaving them clustered in a narrow band of options. Bard is the most mechanically unique class in the PHB; Fighter is the least. The adventuring population skews heavily Human and Elf, which turns out to be a direct consequence of their attribute flexibility rather than player preference for those species.

The image below shows chi-squared standardized residuals for species-class combinations — red means the pairing occurs more than the marginal distributions would predict, blue means less.

The code is on GitHub.

GrapeExpectations

I found myself at a wine tasting at Turnbull Winery in Napa. The server was describing how the position of a vine within the vineyard — its row, its elevation, its exposure — produces measurable variance in the grape and ultimately in the wine. I was fascinated. The question underneath it was familiar: how much does location explain outcome, and can you measure it precisely?

So I went home and started drawing polygons on Google Earth.

The project began by computing field geometry from measured acreage and row spacing — row counts, vine counts, wire lengths for trellis installation. Practically useful numbers, but that was the warm-up. The more interesting work was in the sensing data: using ridge regression to model how canopy-level variables relate to grape quality metrics, asking whether the variance the sommelier was describing could be captured quantitatively.

I reached out to Washington State University to see if the approach was worth pursuing at scale. They thought it was. We are now exploring deployment of Distributed Temperature Sensing (DTS) fiber optic cables to measure canopy temperature across vineyard rows — the same photonic sensing technology I worked with at the UW Photonic Sensing Lab, now applied to viticulture.

The code is on GitHub.

Tidewater and lake-terminating glaciers are systematically thicker

Published in Journal of Glaciology, 2026

Tidewater and lake-terminating glaciers are systematically thicker than glaciers ending on land — and that difference accounts for roughly 20% of non-ice-sheet global glacier volume.

We arrived at this by training a shallow neural network on glacier-averaged thickness measurements from GlaThiDa and surface attributes from the Randolph Glacier Inventory (216,501 glaciers globally), then comparing models trained with and without water-terminating glaciers in the training set. The gap between those models is the imprint of ice-ocean interaction on global ice volume. It is consistent with a simple mechanical explanation: water pressure at the ice front permits thicker termini than are stable in air, setting a different boundary condition for equilibrium glacier geometry.

The pipeline handles the messy reality of co-registering two independently maintained global datasets across different measurement epochs, using distance and area thresholds to filter unreliable matches. Leave-one-out cross-validation across 273 co-registered glaciers produces per-glacier uncertainty estimates that propagate through to a global volume uncertainty budget.

Seismic Ringing

This notebook is devoted to detecting and displaying seismic anomalies detected by the University of Washington Photonic Sensing Lab. A fiber optic cable connects UW Seattle to UW Bothell and runs the length of the city of Seattle, allowing our lab to detect ground moiton. While searching for signals generated by trains moving through underground tunnels in order to audit their schedule, we detected several strange high amplitude, low frequency events between the evening of November 10 thorugh the afternoon of November 14, 2022 under Red Square, the main plaza of the University of Washington Seattle campus.

It is currently unknown what is causing these signals as they span several channels of approximately 6 meter spacing per channel and do not always have similar features. An early hypothesis suggested these could be percussive signals from a nearby marching band or similar performance, however the events occur throughout the day and are non-dispersive. A percussive signal should be detected farther along the cable and be dispersive, however these detected signals are confined to only a few channels.

These signals are also accompanied by long “ring-down” time after detecting extremely large amplitudes as if the cable were kicked or picked up. There are also periods of extended shaking of several minutes as if a jackhammer is being operated right next to the cable. A likely candidate for these signals could easily be construction or maintenance in the parking garage below Red Square.

Two suggested next steps for this project would be to: 1: Perform a tap test in or under Red Square to precisly locate the cable location. 2: Review facilities maintenance records for the parking garage in case of heavy machinery is being used.

These anomalies were found by scanning repeating 10-minute windows of DAS data across four days. When large amplitudes were detected, the data was passed through two bandpass filters (0.01–0.1 Hz and 0.1–1 Hz) and plotted as a space-time heatmap. Selecting a single channel then revealed the ring-down in the time series — signals persisting for over a minute after the initial event.

Pyopoly

Monopoly has always been a fun way to kill time. First as a child playing star wars monopoly with my family, then later I made a board and dice from paper to play with fellow recruits in basic training. While on paternity leave I began writing a python based command line interface version of monopoly.

The board and properties are defined as classes, with NumPy for dice. The full mechanics are implemented: buying properties, building houses and hotels, paying rent, drawing Chance and Community Chest cards, going to jail. CPU opponents make automated buy and build decisions. The terminal output is colorized. It ends when someone goes bankrupt — unlike our current housing market, which does not.

The code is on GitHub.