About
I’m a Senior Software Engineer and Tech Lead at Qualtrics in Dublin, on the Partner Accelerator team, where we build tooling that gets partners up and running on the platform faster. Before that I was on Distributions, working on interactive survey taking across channels and the services behind it.
I hold a Masters in Computer Science from Trinity College Dublin. My dissertation, Understanding Emotion with Multimodal Machine Learning, trained models to read emotion from facial movement, gesture and voice together, using recordings of real conversations instead of posed expressions. The best results came from combining audio and video and modelling how the signals changed over the course of a conversation.
Outside work I cycle and run, which is where a few of the 3D models started, including a bike mount. Two years of rides are drawn as a heatmap of everywhere I’ve been on the bike. There are some generative sketches and parametric design below too.
Projects
Most of these run on a server at home. One is out on the open web.
-
Marginal Watts
A free cycling calculator. Describe your bike, your watts and your distance, and it solves the Martin et al. (1998) road cycling power model for your speed and time. It then re-solves the same ride with every compatible upgrade swapped in and ranks them by cost per second saved, so a free tyre-pressure change competes on the same scale as an aero wheelset.
The numbers behind it come from a corpus of 1,500+ measurements drawn from 250+ published sources, each row carrying its test conditions, method and a confidence tier. Every figure in the component catalog traces back to it. It is TypeScript throughout: a dependency-free physics package implements the model, a Next.js frontend draws the form, and the solve runs server-side so the fitted constants and component data never reach the browser.
-
Home automation
A Home Assistant install I keep extending: 48 automations across seven areas of the house, with most sensors on Zigbee through zigbee2mqtt. It tracks energy use, temperature and humidity room by room, drives the lighting and blinds, and reacts to the doorbell, to who is home, and to camera detections from Frigate.
-
Departure board
A small FastAPI service in Docker, modelled on the dot-matrix boards at Dublin Heuston. It serves JSON listing the trains passing in the next while, departing west or arriving east, with scheduled and expected times and how late each one is running.
The table below was fetched from a local server I’m running when you opened this page.
Sketches
Small things that run in the browser: a p5.js sketch, a game, and a map drawn from my own GPS tracks.
-
Random Walk
A circle picks a direction at random every frame: up, down, left or right. Each time it passes through a cell in the grid that cell’s opacity increases, so the path it has taken slowly emerges.
It’s currently running as the background of this page.
-
Minesweeper
The game, written from scratch in plain JavaScript with no framework or dependencies, about twenty kilobytes. The rules and the drawing are separate files, and the board opens as a ripple spreading out from the cell you clicked.
-
Bike heatmap
Two years of GPS tracks drawn straight onto a canvas, so the roads I ride most often come out darkest. No tile server and no mapping library, just the tracks themselves over the land underneath.
3D design and printing
CAD, parametric modelling and generative design, published free on MakerWorld for anyone to print.
OpenSCAD · SolidWorks · topology optimisation · FDM printing
- 13 models
- 6.5k downloads
- 3.6k prints
- 3.6k likes
-
Infinite Unique Snowflake Generator
Generates a different snowflake on every run, and the same one again if you reuse the seed. Complexity, branching and size are exposed as parameters, and the output is tuned to print support-free even at the finest tips.
-
Cube Shelf for SKÅDIS
Both side panels carry the SKÅDIS slot spacing, so the pegboard grid continues straight through the shelf and hooks still mount to it. Prints as a single piece.
-
Organic Shelf Bracket
Designed with topology optimisation: the solver strips material from everywhere the load path doesn’t travel, which leaves a bone-like shape. Holds a 10kg shelf in PLA+ at 25% infill.
-
Parametric LEGO frames and shelves
A family of SKÅDIS display pieces driven from a handful of variables, so one source file generates every size in the set.