harv
harv is a Python package for inferring Keplerian orbital parameters of binary-star and star–exoplanet systems from time series data. Built on JAX, NumPyro, and unxt for units-aware computation.
It's pronounced harvey.
⚠️ Warning! ⚠️
harv is in rapid development and is pre-alpha. Meaning the API is not stable or
guaranteed! Once the first version is released, we will have some guarantees about
backwards compatibility, but there are no guarantees for API stability with the current
development versions of this package. Sorry!
Installation
Requires Python 3.12+. Install from GitHub:
pip install git+https://github.com/adrn/harv
Or, if using uv:
uv add git+https://github.com/adrn/harv
Quickstart
TODO: move to a quickstart page in documentation and link here.
Radial velocity modeling
from unxt import Q
import harv
import harv.models as hm
# Load or create RV data with explicit units - some sample RV data:
data = harv.RVData(
time=Q([56000.0, 56100.0, 56250.0, 56400.0, 56600.0], "day"),
rv=Q([12.3, -8.7, 5.1, -14.2, 10.8], "km/s"),
rv_err=Q([1.2, 0.9, 1.1, 0.8, 1.0], "km/s"),
)
# Set up a prior with default structure (log-uniform in period, etc.)
prior = hm.StandardRV().default_prior(
period_min=Q(10, "day"),
period_max=Q(1000, "day"),
sigma_K0=Q(30, "km/s"), # RV semi-amplitude scale
sigma_v0=Q(10, "km/s"), # systemic velocity prior width
)
# Run the rejection sampler
sampler = harv.RejectionSampler(prior, harv.RVModel())
samples = sampler.run(data, n_prior_samples=1_000_000, seed=42)
# Inspect results — quantities carry units:
print(f"Accepted {samples.n_samples} posterior samples")
print(f"Period: {samples['period']}")
print(f"Eccentricity: {samples['eccentricity']}")
Gaia epoch astrometry
import numpyro.distributions as dist
import quaxed.numpy as jnp
astro_data = harv.GaiaAstrometryData(
time=Q([958.110978, 994.910525, 995.086642, 1010.091395, 1076.918577], "day"),
al_position=Q([147.066, 379.996, 378.656, 74.666, -293.923], "mas"),
al_position_err=Q([0.370, 0.446, 0.428, 0.270, 0.247], "mas"),
scan_angle=Q([-59.047, -5.114, -5.783, -68.579, -134.155], "deg"),
parallax_factor=jnp.array([0.70828, -0.46657, -0.45946, 0.19659, -0.21379])
)
prior = hm.StandardGaiaAstrometry().default_prior(
period_min=Q(50, "day"),
period_max=Q(3000, "day"),
sigma_a0=Q(1, "au"), # astrometric semi-major axis prior scale
sigma_parallax=Q(1.0, "mas"), # parallax prior width
sigma_pos=Q(1, "mas"), # position offset prior width
sigma_vtan=Q(30, "km/s"), # tangential velocity prior width
)
sampler = harv.RejectionSampler(prior, harv.GaiaAstrometryModel())
samples = sampler.run(astro_data, n_prior_samples=1_000_000, seed=42)
MCMC continuation
When the rejection sampler returns a small number of samples, you can refine with NumPyro MCMC, started from the posterior samples:
from harv.samplers import NumpyroSampler
samples = sampler.run(n_prior_samples=1_000_000, max_posterior_samples=128)
mcmc_sampler = NumpyroSampler(model=model, prior=prior)
mcmc_samples = mcmc_sampler.run(samples, seed=0)
How it works
harv is built on the same tricks as The Joker (Price-Whelan et al. 2017) to make rejection sampling practical for Keplerian orbit inference. It uses a two-level parameterization that separates orbital parameters into:
- Nonlinear parameters (period, eccentricity, argument of pericenter, phase) — sampled directly from the prior via rejection sampling, and
- Linear parameters (RV semi-amplitude, systemic velocity, astrometric offsets) — these can be analytically marginalized given each set of nonlinear parameters.
This approach makes rejection sampling possible for high-dimensional parameter spaces by reducing the effective dimensionality of the sampling problem. The main utility of the rejection sampler is to map out the multi-modal posterior distribution of orbital parameters in the low signal-to-noise or low number of observations regime, which is challenging or impossible for MCMC methods. The samples returned by the rejection sampler are exact draws from the posterior distribution, and can be used to initialize MCMC samplers for further refinement, if necessary.
All objects are Equinox modules (valid JAX
pytrees), so they work seamlessly with jax.jit, jax.vmap, and jax.grad.
Documentation
TODO: Full documentation will be available at harv.readthedocs.io.
License
harv is free software released under the MIT License. See LICENSE for details.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file harv-0.0.1.tar.gz.
File metadata
- Download URL: harv-0.0.1.tar.gz
- Upload date:
- Size: 152.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
092cfaec55d09806acc16eb5971349cbb0e4f9925a7182836146aa456d8fc6e2
|
|
| MD5 |
b06db307dc29b13f1918038a9f3f45cc
|
|
| BLAKE2b-256 |
e87fbcd4b06e512ddb3bfd3dbd0dccbfeaae59635034a3e903cafe0fdbdd5cd7
|
Provenance
The following attestation bundles were made for harv-0.0.1.tar.gz:
Publisher:
release.yml on adrn/harv
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
harv-0.0.1.tar.gz -
Subject digest:
092cfaec55d09806acc16eb5971349cbb0e4f9925a7182836146aa456d8fc6e2 - Sigstore transparency entry: 1757441778
- Sigstore integration time:
-
Permalink:
adrn/harv@2735fdfefbf6027564862f022459869e114d1b05 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/adrn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2735fdfefbf6027564862f022459869e114d1b05 -
Trigger Event:
release
-
Statement type:
File details
Details for the file harv-0.0.1-py3-none-any.whl.
File metadata
- Download URL: harv-0.0.1-py3-none-any.whl
- Upload date:
- Size: 148.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e6dd86e56887e707bed794d220e14891ceb922e4e89e319aaa357076ee677b0
|
|
| MD5 |
763f8346ac9e4366aff71dff9b3306e8
|
|
| BLAKE2b-256 |
44f7f784dfe80af61e653eadfd1ec51269a0e7a1ce07bb0435bbf20f5ed0150c
|
Provenance
The following attestation bundles were made for harv-0.0.1-py3-none-any.whl:
Publisher:
release.yml on adrn/harv
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
harv-0.0.1-py3-none-any.whl -
Subject digest:
3e6dd86e56887e707bed794d220e14891ceb922e4e89e319aaa357076ee677b0 - Sigstore transparency entry: 1757443043
- Sigstore integration time:
-
Permalink:
adrn/harv@2735fdfefbf6027564862f022459869e114d1b05 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/adrn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2735fdfefbf6027564862f022459869e114d1b05 -
Trigger Event:
release
-
Statement type: