Software

A selection of the packages for which I am the lead or a lead developer. Other open-source projects I have contributed to are listed at the end.

Astropy

The community core package for astronomy in Python, and cosmology.api, a standard interface for cosmology libraries.

The Astropy logo: a white spiral on an orange-to-red oval.

Core developer · Coordination Committee · Strategic Planning

Astronomy in Python

The community core package for astronomy in Python. The collaboration received the 2025 AAS Lancelot M. Berkeley Prize, a 2023 IOP Publishing Top Cited Paper Award and the 2022 ADASS software prize.

The cosmology.api logo, the cosmology-api organisation's mark: a near-white hexagon holding three linked cube outlines, on slate.

lead developer

A standard interface for cosmology libraries

Standard Python interfaces for cosmology codes, so one piece of code works with Astropy, CLASS, CAMB, or any library that follows them, with no run-time dependency.

Foundations: Arrays, Units & Coordinates

The layers the rest is built on, in JAX: quax lets custom array types through JAX’s primitives, with plum’s multiple dispatch beneath it; unxt adds units, and coordinax vectors, frames and transformations.

maintainer

Multiple dispatch in Python

Multiple dispatch for Python, close to Julia's, driven by type annotations and powered by Beartype.

The coordinax logo: a ruler crossed with a green arrow on a blue square.

lead developer

Coordinates in JAX

Coordinates in JAX: points, vectors, and reference frames, with differentiable, unit-aware transformations between coordinate systems.

The unxt logo: a ruler crossed with a green pencil on a blue square.

lead developer

Units in JAX

Unit-aware computing in JAX, with a Quantity familiar to astropy.units users that passes through jit, vmap, grad, and existing JAX code.

The quax logo: a black rubber duck, Material Design Icons' duck.

maintainer

Multiple dispatch in JAX

Multiple dispatch over array types in JAX, so custom arrays (sparse, structured, or carrying units) run through existing JAX programs.

The quaxed logo: a black rubber duck, quax's, with a white badge on its body carrying a blue tick.

lead developer

Pre-quaxed libraries

jax.numpy, jax.lax, and other JAX libraries, pre-wrapped with quax so they accept custom array types directly.

The quax-blocks logo: a black rubber duck, quax's, with a white badge on its body carrying three blue blocks stacked into a pyramid.

Building blocks for quax classes

Mixins for arithmetic, comparison and array protocols, so a new array type is a few lines.

Galactic Dynamics & Streams

Orbits, potentials and the stellar streams that trace them: galax integrates orbits and generates streams, and the rest measure streams and learn potentials — most of it in JAX, on the foundations above.

The galax logo, the GalacticDynamics mark: a painted spiral galaxy with a glowing core on a dark disk, circled by a dark ring, between a teal < and a purple > code bracket.

lead developer

Galactic dynamics in JAX

Galactic dynamics in JAX: gravitational potentials, orbit integration, mock stellar streams, and action-angle coordinates, all differentiable and GPU-ready.

The potamides logo: a capital Phi, for the gravitational potential, its ring a stream of stars shaded teal into purple with three arrows a side pointing in, on a dark rounded square.

co-lead developer

Constrain gravitational potentials from stellar stream curvature

Infers galaxy mass distributions from the projected shapes of stellar streams, fitting their tracks with splines and comparing the tracks' curvature to a potential's accelerations.

Orbits of a test particle in a Milky Way–LMC system, integrated in the true potential, a near-true analytic model, and three neural-network models. The most complete neural-network models track the true orbit almost exactly, while the near-true analytic model drifts away from it.

co-developer

Physics-informed neural networks for galactic potentials

Physics-informed residual neural networks augmenting analytic baseline models that learn time-dependent galactic gravitational potentials from position + acceleration data, built on JAX.

The phasecurvefit logo: noisy points along a self-crossing looped curve, coloured by their fitted order from red through yellow to blue, with the learned mean path drawn as a black line.

lead developer

Paths through phase space

Orders samples along a curve in phase space and fits a smooth track through them, using velocities as well as positions so curves that cross or fold back stay on the right strand.

Dark Matter Direct Detection

The code behind searching thunderstorms for macroscopic dark matter.

The macro_lightning logo: a dotted track through a cloud, ending below it in a black macro trailing a blue wake inside a yellow channel.

lead developer

Constrain macroscopic dark matter with lightning

Constraints on macroscopic dark matter from lightning, on Earth and Jupiter. Released with the PRD paper.

Numerics

Numerical pieces JAX was missing: extras for Diffrax, scipy.special, bounded loops and kernel density estimates.

The diffraxtra logo: diffrax's, an integral sign cut out of a black rounded square, with a big plus cut out beside it.

lead developer

Extras for Diffrax

An object-oriented interface to Diffrax's differential-equation solver, and interpolation over batched solutions.

The jaxmore logo: JAX's, its letters built from coloured rhombi, with the J's stem crossed by a dark-grey bar of the same rhombi into a big plus.

There's more to JAX

The utilities you keep re-writing, collected in one place.

The mvgkde logo: a kernel density estimate of points scattered along a slanted, handwritten M, drawn as filled contours from cream through gold and green to deep blue.

lead developer

Multivariate Gaussian KDE

Multivariate Gaussian kernel density estimation in JAX, with full control of the kernel's covariance, including a bandwidth per dimension.

The spexial logo: a capital Gamma shaded from teal through blue to purple on a dark rounded square.

lead developer

scipy.special in JAX

Special functions for JAX, following the scipy.special API: functions JAX lacks, such as the modified Bessel K and the polylogarithm, fixes where it returns wrong values, and hand-written derivatives where its own are slow or nan.

Utilities

Small, general-purpose packages that fell out of the work above.

The optional_dependencies logo: a package, drawn as a blue isometric cube, with a yellow badge carrying a question mark.

Construct checks for optional dependencies

Construct checks for optional dependencies

The dataclassish logo: a purple brace opening three fields, each a purple dot and a wavy teal tilde, beside a plain navy box.

lead developer

dataclasses, for everything

The dataclasses tools replace, fields, and asdict, extended to any Python object by registering per-type methods.

The is_annotated logo: square brackets around a teal block and a purple flag, the shape of Annotated[T, metadata], with a yellow badge carrying a tick.

Check whether a type hint is Annotated

Check whether a type hint is Annotated

The oncequinox logo: Equinox's, a navy circle solid on the left and a checkerboard on the right, with a big 1 cut out of its solid half.

Singletons for Equinox

Singletons for Equinox

The preamble logo: a document page whose top band, the preamble, is shaded purple and crossed by a big purple backslash, above grey lines of text.

author

A LaTeX preamble worth reusing

A LaTeX preamble worth reusing

The xmmutablemap logo: a teal snowflake between a pair of purple dict braces, a frozen mapping.

An immutable mapping, JAX-compatible

An immutable mapping, JAX-compatible

The zeroth logo: [0], a purple zero between navy square brackets.

Efficiently get the index-0 element of any iterable

Efficiently get the index-0 element of any iterable

Other Open-Source Contributions43