Skip to content

kunalb541/BinML

Repository files navigation

BinML

Deep-learning classifier for gravitational microlensing light curves.
Flat · PSPL · Binary — built for Nancy Grace Roman Space Telescope cadence.

PyPI Python 3.9+ PyTorch CI MIT


BinML predicts, from a microlensing light curve, three physically-meaningful classes:

class meaning
Flat no event (baseline / noise)
PSPL single-lens microlensing — "there is a microlensing event"
Binary planetary / binary lens — the anomalous class (a binary is not a PSPL)

So every prediction answers two questions: detection — is this a microlensing event (P(PSPL) + P(Binary))? — and characterization — is it anomalous, i.e. binary/planetary rather than a plain single lens (P(Binary))?

Install

pip install binml            # weights bundled — only needs torch + numpy

Quickstart

import binml

clf = binml.Classifier()                                 # fine-tuned model, CPU
t, mag, err = binml.surveys.fetch_ogle_ews(2014, 289)    # a real OGLE event
r = clf.predict(t, mag, err)

print(r)
# <BinML Binary (conf 1.00) | Flat 0.000 PSPL 0.000 Binary 1.000 | microlensing=1.00 anomalous=1.00>
r.is_microlensing   # 1.00  -> yes, a microlensing event
r.is_anomalous      # 1.00  -> binary/planetary, not plain PSPL
r.probabilities     # {'Flat': ..., 'PSPL': ..., 'Binary': ...}

Your own light curve — any time, mag, mag_err arrays (or is_flux=True for fluxes):

r = clf.predict(time, mag, mag_err)

Command line

binml classify phot.dat --format ogle          # classify a file
binml ogle 2017 482                            # fetch OGLE-2017-BLG-0482 and classify
binml evolution phot.dat -o evolution.png      # probability-evolution plot
binml evaluate test_set.h5                      # detectability-conditioned evaluation

Reporting binary performance honestly

A binary whose caustic isn't sampled/perturbing is observationally identical to a PSPL — calling it "PSPL" is physically correct, not an error. A single population-level binary recall therefore conflates real model skill with irreducible physical degeneracy. BinML makes the honest, detectability-conditioned metric the default:

report, detect = binml.evaluate_dataset(clf, "test_set.h5")
print(detect)   # binary recall vs Δχ², the indistinguishable fraction, detectable-only recall

Report detectable-only recall + the indistinguishable fraction, never the raw population number. See docs/evaluation.md.

Cadence matters

BinML is trained on Roman-quality cadence (dense ~15-min sampling). It transfers to the shape of real single-lens events, but binary characterization needs dense sampling — the short caustic anomaly must actually be observed. On sparse ground-survey cadence (e.g. LSST at multi-day gaps) detection degrades and characterization is not recoverable. Roman is the planet-finder; LSST is at best a detector.

Results (full 1,000,000-event held-out evaluation)

model accuracy Flat PSPL Binary notes
base 64.3% 100% 80.0% 52.2% balanced
fine-tuned (shipped) 67.2% 100% 70.9% 62.3% planetary recall 41→57%

Binary recall rises monotonically with anomaly strength (Δχ²) from ~11% (no detectable signal) to 85% (strong anomaly). At a Δχ²≥300 detection threshold, ~32% of binaries are physically indistinguishable from PSPL and the detectable-only binary recall is ~78% — the raw 62% understates the model. Validated on real OGLE-IV events (correctly flags caustic-crossing binaries such as OGLE-2014-BLG-0289 and OGLE-2013-BLG-0578).

Repository layout

binml/        installable inference package (Classifier, preprocess, evaluate, surveys, cli) + bundled weights
pipeline/     research pipeline — simulate.py, train.py, evaluate.py, select_subset.py,
              train_modal.py (Modal GPU orchestration), analysis/, curricula/
docs/         architecture, training, data format, evaluation, leakage audit
paper/        software paper (JOSS-style) + references
examples/     usage examples          tests/  smoke tests
data/  results/   simulated data and figures

Training from scratch

The full pipeline (simulate → detectability-aware subset → single-GPU streaming training → warm-start fine-tuning) is in pipeline/ and documented in docs/training.md. It runs locally on one GPU or on Modal via pipeline/train_modal.py. Fine-tuning uses targeted warm-starting (train.py --init-weights) on the hard low-mass-ratio regime — which moves the needle far more than additional base training.

Documentation

Citing BinML

If you use BinML, please cite it — see CITATION.cff (a "Cite this repository" button appears on GitHub) and the paper in paper/.

License

MIT © Kunal Bhatia

About

Real-time three-class classification of gravitational microlensing events (flat / PSPL / binary lens) using a CNN-GRU model for the Nancy Grace Roman Space Telescope.

Topics

Resources

License

Contributing

Stars

5 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages