Skip to main content

VESPER

Vetting Exoplanet Signals with Pixel-informed Evidence, Rapidly.

VESPER is a fast, learned vetter for transiting-planet candidates around TESS M dwarfs. Give it a star's TESS photometry and a candidate ephemeris (period, epoch, duration); it returns a calibrated probability that the signal is a planet, seven named impostor scores — in the output's aux_* column order: background eclipsing binary (aux_beb), window alias (aux_alias), eclipsing binary on target (aux_eb), stellar rotation (aux_rot), companion dilution (aux_comp), no signal at the ephemeris (aux_vide, printed as "empty"), spacecraft systematics (aux_sys) — and a keep/reject disposition, in about a tenth of a second per star, entirely offline (no external service calls).

The frozen model, its full performance record and its known limitations are documented in the model card, linked from this page: https://gitlab.com/yohanntschudi/exoplanets-project/-/blob/main/documentation/pipeline_ml/VETTER_MODEL_CARD.md

Install

Python ≥ 3.10 required — check with python3 --version. Work in a fresh virtual environment (system Pythons are often older and their site-packages messy):

python3.11 -m venv vesper-env          # any Python >= 3.10
source vesper-env/bin/activate         # Windows: vesper-env\Scripts\activate
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install "tess-vesper[acquire]"

CPU-only torch is enough. The [acquire] extra adds lightkurve, used by vesper fetch to download and prepare TESS photometry for you. The wheel bundles the frozen model (weights, calibrator, decision threshold, M-dwarf stellar catalog) — nothing is downloaded at vet time — and the artifacts' SHA-256 fingerprints are checked at every load.

How it works

  1. You provide the ephemeris — VESPER judges a candidate at a given (period, T0, duration); it complements your transit search and your follow-up, taking the statistical-vetting step in between.
  2. VESPER prepares its own photometry. From stitched, median-normalised PDCSAP flux before any detrending, it removes stellar variability with its own Gaussian-process model on a 200 s grid — the exact preparation the network was trained and certified on. vesper fetch builds that input for any TIC directly from the TESS archive. Supplying your own curves instead: one pickle per host, named TIC{tic}_stitched.pkl, holding a dict with keys time (BTJD), flux (PDCSAP, quality flag 0, per-sector median-normalised to ~1.0, before any stellar-variability detrending), and optionally flux_err and sector — exactly what vesper fetch writes. Do not feed already-detrended flux: the certified numbers do not hold for it.
  3. It folds and judges. The signal is folded into shape views (global, transit zoom, secondary, odd/even, per-observing-block), normalised to the star's own noise, and weighed together with the stellar parameters and — when you have them — difference-image centroid measurements.
  4. It answers in calibrated units. p_cal is a calibrated probability; the shipped threshold (0.29565…, set on the model's sealed calibration split to keep ≥ 95 % of its planets — 96.1 % realized there, 92.2 % of confirmed planets kept on the certified hold-out) turns it into a disposition, and the named impostor heads tell you what the signal most resembles when it is not a planet.

Domain of validity: TESS M dwarfs (Teff ≲ 4,000 K), periods ~0.5–100 d, native cadences 20–300 s (served on a uniform 200 s grid; coarser products — e.g. native 600 s — are not servable). Anything the data contract cannot serve comes back as an explicit blocked:... status, never a silent skip. The contract checks the data, not the star: VESPER does not verify that your target is an M dwarf — a K- or G-dwarf curve will serve and return a number, but an unvalidated one. Check Teff yourself; outside the M-dwarf regime the output is uncertified.

Try it — the bundled example

Twelve signals on six M-dwarf hosts, both sides of the decision: L 98-59 (three small confirmed planets, plus one unconfirmed 1.05 d candidate signal — judge it yourself), TOI-700 (four confirmed planets, including the habitable-zone TOI-700 d), and four TFOPWG-certified false positives spanning the impostor zoo — a 22.6 % deep eclipse, a short-period eclipsing binary, a long-period shallow false alarm, and a 790 ppm signal with a perfectly planet-like depth.

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

The fetch downloads every SPOC-family sector of all six stars — TOI-700 alone has 30+ — through lightkurve's cache (~/.lightkurve/cache): a few hundred MB of FITS and several network-bound minutes on the first run. Stars whose pickle already exists in --out-dir are skipped, so an interrupted fetch can simply be re-run.

For your own targets, write the same kind of CSV (header exactly as below, no spaces after the commas; extra columns such as toi or note are ignored):

tic_id,period_days,t0_btjd,duration_hours,depth_ppm,planet_num
307210830,7.450726,1355.290002,1.68,1002.2,4

t0_btjd is BTJD = BJD_TDB − 2,457,000 (native TESS time). ExoFOP lists full BJD epochs — subtract 2,457,000, or the row comes back blocked:t0_not_btjd. The four first columns are required on every row; depth_ppm (feeds the deep-eclipse prior) and planet_num (row labelling) are optional. Single candidates:

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

Reading the output

The results CSV (--out) echoes your input columns, then carries the science columns below, plus diagnostics (p_raw — the pre-calibration score; kept_0.5/kept_0.9 — stricter fixed thresholds; cascade_depth_source; n_sec_measured/n_sec_served — centroid-evidence sector count before/after its cap; log_scatter; cadence_s_native/ cadence_s_served). The console prints the same information as one aligned table per host.

Column Meaning
p_cal calibrated P(planet) — the number to read
kept_literal p_cal ≥ the shipped threshold — the threshold-only verdict (the calibration-split recall-95 operating point; hold-out performance in the model card §5)
cascade_fp the deep-eclipse prior fired (depth > 50,000 ppm and p_cal < 0.9). For very deep candidates around small stars, read kept_literal — already in the CSV — since giant planets on M dwarfs can exceed that depth; --no-cascade disables the rule outright
final_literal the disposition: True = keep as a planet candidate
aux_beb … aux_sys the seven impostor heads (mapping in the opening paragraph) — triage pointers to the most likely false-positive channel, not individually calibrated probabilities
spatial_status unmeasured = no centroid evidence supplied (the default for external users); pass --spatial CSVs when you have difference-image measurements
row_status served, or an explicit blocked:... reason

What p_cal is calibrated against. The calibration set is real M-dwarf light curves carrying injected planets and constructed impostors, held out from training — p_cal is well-scaled under that mixture. It is not a TRICERATOPS-style false-positive probability computed against a Galactic stellar-population model, and a high p_cal is not by itself grounds for statistical validation. Use it to rank and triage; validation still requires independent evidence.

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 0.1.2

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 0.1.2
File Interpreter ABI Platform
tess_vesper-0.1.2-py3-none-any.whl Python 3 none any Details

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

Download URL tess_vesper-0.1.2-py3-none-any.whl
Size 636.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c46988e25bca1e51aea876390b90fad37bbd0fc494f7fa38c26237322e0c3eba
BLAKE2b-256 checksum
How to use checksums
a2d5a56e6173d49673f5179ad41f711a9f1928079d982e33cb11643c1345d85d
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

1.0.0

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

This release

0.1.2 This release

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