Research software

Code

Scientific Python released so other people can install, test, cite and extend it. Tests, continuous integration, typing and documentation are part of the work, not an afterthought.

Author · open source

PyVWF: bias-corrected wind power from reanalysis

A Python rewrite of the Virtual Wind Farm model behind the wind simulations on Renewables.ninja, implementing the granular bias-correction method from my 2024 Energy paper. It trains correction factors against observed generation at turbine, regional or national scale and applies them to ERA5. I wrote every commit in the v0.5.1 release, which carries a Zenodo DOI.

Python · Xarray · Dask · SciPy · scikit-learn · pytest · GitHub Actions · ruff · mypy · Sphinx · Docker

Public fork · PhD Part II

Wind representation in PyPSA-Eur

Extended the open European energy system model with a density-tiered wake-loss correction, the gridded PyVWF corrections, and a spatial splitting algorithm that decouples offshore resource resolution from network topology. Factorial studies (bias × wake × resolution) across a regional North Sea system and a 25-country network. Every manuscript figure regenerates from one script, and the headline claims are held under automated test.

Python · PyPSA · Atlite · Snakemake · Gurobi · GeoPandas

Post-PhD · experimental

Physics-informed wind correction

A constrained model meant to transfer corrections to regions with no observations. Gates and thirteen predictions were fixed before each run. As registered it beat uncorrected ERA5 in 5 of 5 held-out regions, with thin margins in two. Seven predictions failed and are published as failures. Two physics extensions were built, tested and rejected.

PyTorch · pre-registration · leave-one-region-out validation

Catastrophe modelling · 2026

ERA5 windstorm × Oasis LMF

Reproduced the Oasis LMF PiWind example model end to end, then ran a single-site exposure sensitivity study comparing AAL and EP curves, ground-up against insured. It is a reproduction and a sensitivity study, not a catastrophe model; the event set and vulnerability curves are PiWind's example data.

Python · oasislmf · AAL · OEP / AEP

Earth observation · 2020–21

I-Hex, the Island Health Explorer

A Google Earth Engine suite giving policymakers and island communities free access to satellite and climate data for the Maldives. I worked on the supervised land-cover and benthic-feature classification, and digitised and assembled its 861-point labelled training set across nine classes. The classified imagery uses separate Landsat and Sentinel-2 classifiers, with per-atoll median compositing to handle cloud.

Google Earth Engine · JavaScript · Landsat · Sentinel-2 · pandas

ML research code

WGAN regression

The codebase behind the MOR-GANs paper, extended past publication: a PyTorch port, and benchmarks against Gaussian process, mixture density network and conditional diffusion baselines on twelve datasets over five seeds. The README reports where the newer baselines win.

TensorFlow · Keras · PyTorch · WGAN-GP

AI evaluation

LLM personas against real UK opinion

An evaluation harness testing whether populations of LLM personas reproduce the distribution of opinion in two nationally representative UK surveys. Five prompt-level persona methods, two Claude models, distribution metrics (TVD, JSD) with bootstrap confidence intervals, and diagnostics for a model being right for the wrong reasons.

Python · Anthropic API · Docker · bootstrap CIs

Side project

OBK Gear Optimiser

Streamlit app for constrained multi-objective optimisation of kart-racing builds: exhaustive enumeration across five part categories, weighted scores, hard constraints and side-by-side comparison.

Python · Streamlit · Pandas

Side project

Guild availability tracker

Static PyScript site on GitHub Pages with shared state in a Supabase Postgres table over its REST API, and weekly reset logic.

PyScript · Supabase · Postgres · GitHub Pages

In development

Fool's Ascension

Roguelite card game built on the Russian card game Durak: branching three-act runs over a procedurally generated node map, with persistent meta-progression.

Godot · GDScript