Skip to main content

VESPER

Vetting Exoplanet Signals with Pixel-informed Evidence, Rapidly.

VESPER vets transiting-planet candidates around TESS M dwarfs. Give it a candidate ephemeris; it returns a calibrated probability that the signal is a planet, seven named impostor scores, and a keep/reject verdict — in about a tenth of a second per star once the data are in.

Everything else is fetched automatically from public archives: the photometry, the pixel data for the centroid measurement, the PRF models, the stellar parameters. One CSV in, one table out.

VESPER 1.0 ships an ensemble of four sibling networks trained on the same school, their seeds fixed in advance; each member calibrates its own probability and the served p_cal is the mean of the four. On its sealed evaluation (162 sequestered confirmed-planet hosts, 2026-08-17) it keeps 160/167 = 95.8 % of confirmed planets — every one of the 10 deeper than 50,000 ppm included — at 0.099 false alarms per host, against 155/167 = 92.8 % at 0.119 false alarms per host for the TRICERATOPS stage it replaces (funnel-only, the same convention as the 0.099; counting every non-catalogue-planet signal kept, the pair is 0.119 vs 0.139), and the vetting itself took 24.1 s for 150 hosts.

The frozen ensemble, its certified performance and its limitations are documented in the model card (one provenance note matters: the sealed terrain behind these numbers was exposed twice, each time under a pre-registered protocol — 2026-08-07 and 2026-08-17 — and the second read is terminal): https://gitlab.com/yohanntschudi/exoplanets-project/-/blob/main/documentation/pipeline_ml/VETTER_MODEL_CARD.md

Install

Python ≥ 3.10, in a fresh virtual environment. CPU-only torch is enough.

macOS / Linux:

python3.11 -m venv vesper-env
source vesper-env/bin/activate
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install "tess-vesper[acquire,spatial]"

Windows (PowerShell):

python -m venv vesper-env
vesper-env\Scripts\Activate.ps1
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install "tess-vesper[acquire,spatial]"

If PowerShell blocks Activate.ps1, skip activation and call vesper-env\Scripts\vesper.exe directly — it works identically.

The wheel bundles the frozen ensemble (~2.7 MB); its SHA-256 fingerprints are verified at every load. Nothing else to configure.

Inside the package the artifacts live in one directory: four member subdirectories s101/ s202/ s303/ s404/ (each holding model_best.pt, calibrateur_isotonique.pkl and args.json), candidate_config.json (the sealed pin table: per-member SHA-256, threshold, school manifest), threshold.json (threshold provenance) and the bundled stellar catalog. $VESPER_ARTIFACTS may point to an alternative directory with the same layout; the fingerprints are checked wherever the artifacts come from.

Try it — two commands

vesper example
vesper vet-batch --candidates candidates_example.csv --curves-dir example_curves --out example_results.csv

The bundled example is twelve signals on six M-dwarf hosts: the confirmed planets of L 98-59 and TOI-700 (including the habitable-zone TOI-700 d), one unconfirmed candidate signal, and four TFOPWG-certified false positives. VESPER downloads the photometry and the pixel data itself — the first run takes a while (TOI-700 alone has 30+ sectors). Everything is cached, and an interrupted run resumes with the same command.

For each host you get a table like:

TIC 307210830 (4 signals)
 sig      P [d]   T0 [BTJD]   dur[h]  P(pl)   verdict  BEB    alias  EB     rot    comp   empty  syst
 .02     2.2531   1354.9054     0.24  1.000   KEEP     0.000  0.000  0.013  0.000  0.008  0.000  0.000
 .01     1.0492   1354.7153     0.32  0.017   REJECT   0.071  0.113  0.811  0.024  0.033  0.008  0.085

The .01 line is the unconfirmed candidate: rejected, and the EB head says why. (The scores in this table illustrate the output format — run the example to get the shipped ensemble's actual numbers.)

Your own candidates

One CSV row per candidate:

column unit required
tic_id TIC number yes
period_days days yes
t0_btjd BTJD = BJD_TDB − 2,457,000 yes
duration_hours hours yes
depth_ppm ppm optional — feeds the cascade_fp diagnostic
planet_num integer label optional
vesper vet-batch --candidates my_candidates.csv --curves-dir curves --out results.csv

Two classic traps:

  • ExoFOP lists full BJD epochs — subtract 2,457,000, or the row comes back blocked:t0_not_btjd.
  • Header exactly as above, no spaces after the commas.

Single candidate:

vesper vet --tic 307210830 --period 7.450726 --t0 1355.29 --duration-h 1.68 --curves-dir curves

What VESPER fetches for you

data source opt-out without it
photometry (SPOC light curves) MAST --no-fetch provide the curve pickles yourself
pixel data + PRF models (centroid measurement) MAST + STScI --no-spatial neutral spatial vector, labelled
stellar parameters bundled M-dwarf catalog, then TIC-8 --no-tic8 training-mean values, labelled

Everything is cached, nothing is downloaded twice. Centroid measurements are saved one by one to a <out>_spatial.csv sidecar: an interrupted run resumes where it stopped, and the sidecar is reusable forever via --spatial.

Bringing your own photometry: one pickle per host, named TIC{tic}_stitched.pkl, a dict with time (BTJD), flux (PDCSAP before any detrending, median ≈ 1.0) and optionally flux_err/sector — exactly what vesper fetch writes. Never feed detrended flux: VESPER does its own detrending, and that is part of the certified contract.

How it works

  1. You provide the ephemeris. VESPER judges the signal at that period; it does not search for periods.
  2. It prepares its own photometry — stellar variability is removed with the same Gaussian-process model the network was trained with, on a 200 s grid.
  3. It folds and judges: shape views (global, transit zoom, secondary, odd/even, per-observing-block), the star's parameters, and the difference-image centroid — the pixel evidence that separates a background eclipsing binary from an on-target signal.
  4. Four networks answer, in calibrated units: each ensemble member scores the signal and maps its score through its own isotonic calibration; p_cal is the mean of the four calibrated probabilities, judged against the shipped decision threshold, alongside the named impostor heads.

Reading the results

The results CSV (--out) echoes your inputs, then:

column meaning
p_cal calibrated P(planet) — the mean of the four members' calibrated probabilities; the number to read
p_cal_s101 … p_cal_s404 the individual ensemble members' calibrated probabilities, for audit — a member far from the mean flags a signal worth a second look
final_literal the verdict: True = keep as a planet candidate
kept_literal p_cal at or above the frozen decision threshold. Equal to final_literal unless --cascade is passed
cascade_fp diagnostic only: the retired deep-eclipse rule (depth > 50,000 ppm and p_cal < 0.9) would have rejected this row. Always reported, never decides — unless you opt in with --cascade
aux_beb … aux_sys the impostor scores, in order: background EB, window alias, EB on target, stellar rotation, companion dilution, no signal, spacecraft systematics
spatial_status ok(n/m sec) = centroid measured · failed:... = tried, unusable · unmeasured = skipped
stellar_source catalog / tic8 / imputed
row_status served, or an explicit blocked:... reason

The deep-eclipse cascade is retired. The shipped disposition is threshold-only: rejecting deep eclipses is something the network learned in its school (V-vs-U bottom shape, secondary eclipses, duration–density coherence, the star's radius), not a depth cut imposed on its output — a depth cut kills exactly the genuine transiting giants around M dwarfs that make deep signals interesting. --cascade re-enables the retired rule for reproducing archived numbers only.

p_cal is calibrated against real M-dwarf light curves carrying injected planets and constructed impostors. It is not a TRICERATOPS-style FPP, and a high value is not by itself statistical validation: use it to rank and triage; validation needs independent evidence.

Domain of validity

  • TESS M dwarfs (Teff ≲ 4,000 K); periods ~0.5–100 d; native cadences 20–300 s (served on a 200 s grid; coarser products are refused with an explicit status).
  • VESPER checks the data, not the star: a G-dwarf curve will serve and return a number — an uncertified one. Check Teff yourself.
  • Known weak spot: ultra-short periods (P < 0.5 d — sub-hour transits leave few points per event on a 200 s grid). Full list in the model card.

License and citation

MIT. The reference article is in preparation; until it is out, cite this package and its model card (linked above), which carries the full provenance of the frozen model.

Metadata

Release files for tess-vesper 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for tess-vesper 1.0.0
File Interpreter ABI Platform
tess_vesper-1.0.0-py3-none-any.whl Python 3 none any Details

Release files / tess_vesper-1.0.0-py3-none-any.whl

Download URL tess_vesper-1.0.0-py3-none-any.whl
Size 2.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
7c5cb911ea2c775c21a9b23687c054227c0b672830c7bb34e0a0f901e37a5f95
BLAKE2b-256 checksum
How to use checksums
cd3f3c390794b59536fc350b9c2c1631ccdb96606c326327b0fd0b7a8ae11af9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.9

Release history Release notifications | RSS feed

This release

1.0.0 This release

1 release file

0.2.7

1 release file

0.2.6

1 release file

0.2.5

1 release file

0.2.4

1 release file

0.2.3

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.2.0

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page