Major update microlensing - #35
Merged
Merged
Conversation
Delivers the follow-on from the Harris et al. 2026 credit: an in-app implementation of the joint TESS + Gaia PSPL fit that paper uses to break the tE ↔ u0 degeneracy TESS's short single-sector baseline cannot resolve. Single-lens only for now — binary-lens (planetary anomaly) joint fits remain future work. Backend: - backend/app/gaia_photometry.py — pulls a per-alert G-band CSV from the public Gaia Alerts feed (https://gsaweb.ast.cam.ac.uk/alerts), plus a cone-search helper against the cached alerts master index. Errors inflated per Kruszynska+2022 (A&A 662 A59) approximation: σ² = (1.5·σ_reported)² + (3 mmag)². Permissive CSV parser handles the various header spellings the Gaia feed has drifted through, drops 99.999 sentinel rows, and validates alert IDs against /^Gaia[0-9A-Za-z]+$/ to keep path segments clean. - backend/app/microlensing.py::fit_pspl_joint — 7-parameter fit sharing (t0, tE, u0) across bands with per-band (f_s, f_b). Residuals from both bands concatenated with per-cadence weights, one scipy.optimize.least_squares call. Returns per-band χ² and joint BIC. - backend/app/microlensing.py::analyze_event_joint — full pipeline: TESS windowing + baseline-normalisation (same recipe as single-band), Gaia mag → relative flux via 10^(-0.4·(G-G_base)) with propagated errors σ_F = F·0.4·ln(10)·σ_G, out-of-event baseline mag from median of epochs outside t0 ± 100 d (faint-tail-quantile fallback), JD_TCB → BTJD via −2 457 000 (TCB↔TDB seconds-level offset ignored — negligible for microlensing scales). Recomputes observables + planet predictions from the joint-fit shared geometry. Three new endpoints: - POST /api/microlensing/gaia_alert_lightcurve {alert_id} → GaiaLightcurve - GET /api/microlensing/gaia_alerts_near ?ra&dec&radius_arcsecµlensing_only - POST /api/microlensing/fit_joint {tess…, gaia…, window, t0_guess} → JointFitResponse Frontend: - MicrolensingClassifier gains a Gaia baseline section: alert-ID text input + Fetch Gaia LC button, Search near target coords button (uses prefill or autoload coords), clickable list of nearby microlensing alerts, and a compact loaded-state summary (n_points, JD range, G range, error-model note). - Fit joint (TESS + Gaia) button appears alongside the standard Fit button once a Gaia LC is loaded. Runs the joint fit; results render in a new JointResultsPanel showing shared params + per-band χ² + BIC + observables + planet predictions. Tests: 43 pass total. New: - test_gaia_photometry.py (14): URL validation, Kruszynska error inflation with a known reported error + missing-error magnitude-tiered fallback, permissive CSV parsing across header variants + sentinel-null filtering, mocked fetch, alerts index parsing, cone-search filtering by class + distance (Haversine on sphere). - test_microlensing.py joint fit (3): shared-parameter recovery from a synthetic two-band PSPL (t0/tE/u0 recovered within few-percent), input validation (rejects <5 Gaia points), stable response-shape contract. Docs: - SCIENCE.md §18.3 added: full joint-fit derivation (mag→flux conversion, error propagation, time-system handling, Kruszynska calibration formula, scipy fit setup), references Harris et al. 2026 §5 for the pyLIMA reference implementation Vetstar mirrors in single-lens form. - README §API endpoints lists the three new routes with query/body shapes. - README §Project layout adds gaia_photometry.py. Verified end-to-end in the browser with a synthetic Gaia LC (mag = 17.5 − 2.5·log10(A(t)), 60 epochs over 5 years) injected into the frontend Gaia fetcher via fetch mock: joint fit recovered Gaia baseline G = 17.500 exactly, χ²(Gaia) ≈ 0 (noiseless), χ²(TESS) = 99.1 on 120 noisy points, BIC = 135.5, joint results panel rendered with shared params + per-band goodness + observables + planet predictions. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fixes the "ExoFOP zip" that was actually just an analysis bundle, adds a
proper transit-tab ExoFOP-TESS bulk-upload panel, brings in the missing
FFI+Gaia overlay, an ExoFOP planet-parameters table, and CyclingLoader
loading circles across every long-running action.
ExoFOP zip conventions (fix)
- Reuse the shared ExofopBulkPanel from the transit tab: bundles PNGs as
TIC{id}O-xxYYYYMMDD.slug.png inside xxYYYYMMDD-nnn.zip with the
matching .txt descriptor per the ExoFOP-TESS bulk file upload spec.
Initials + data tag persisted in localStorage the same way. Only
mounts once the classifier has a TIC id.
- Rename the old ad-hoc "Download ExoFOP package" button to
"Analysis bundle" so it stops claiming an ExoFOP-conformant format.
The bundle itself (summary.csv, lightcurve_windowed.csv, fit_full.json,
notes.md, plot.png) is unchanged and still useful for local archiving.
FFI cutout + Gaia DR3 overlay
- New backend module microlensing_ffi.py: tangent-plane sky→pixel
projection at 21″/px, matplotlib inset overlay of Gaia DR3 sources
sized by G-band magnitude, target crosshair, source table with
source_id + separation returned alongside the PNG. Gaia cone-search
via astroquery.gaia (radius = cutout diagonal). Non-fatal on Gaia
query failure — base cutout still returned.
- New endpoint POST /api/microlensing/ffi_cutout, reuses the transit
pipeline's make_ffi_cutout() for the underlying TESScut fetch.
- Classifier auto-fetches when target coords + sector are known.
FfiCutoutSection renders the PNG + a summary card (sector, frames
stacked, FOV radius, Gaia source count, brightest neighbours drawer).
- PDF vetting report gains an FFI + Gaia overlay section.
ExoFOP planet parameters (microlensing-derivable subset)
- New helper compute_exofop_planet_rows() mirrors the transit tab's
observables.exofop_param_rows in shape and naming but scoped to what
a single-lens fit can honestly report: t0/tE/u0 direct outputs; host
M_L and R_star under fiducial bulge priors via a Pecaut & Mamajek
(2013) dwarf-sequence M-R interpolation; r_E in AU and projected
a_perp; planet mass floor in Earth/Jupiter units + Rp/R_star from
the Chen & Kipping (2017) forecaster + q_min. Un-derivable rows
(Orbital Period, Eccentricity, Inclination, T_eq, RV K) explicit
None so the frontend renders "—" without pretending.
- analyze_event + analyze_event_joint both populate exofop_rows.
- Frontend ExofopPlanetParamsPanel renders the table with required-
field markers and the "—" convention.
- PDF report gains an ExoFOP planet-parameters table.
Loading circles (transit-tab convention)
- Extract CyclingLoader from App.tsx into a shared Loaders.tsx.
- Add microlensing message packs (MICROLENSING_FIT_MSGS,
MICROLENSING_JOINT_MSGS, GAIA_FETCH_MSGS, GAIA_SEARCH_MSGS,
TIC_LC_MSGS, COORD_LC_MSGS, COVERAGE_MSGS, PDF_MSGS, FFI_CUTOUT_MSGS)
matching the transit tone.
- Swap every plain "Fitting…"/"Fetching…" text for the appropriate
CyclingLoader (Fit PSPL, Fit joint, TIC fetch, coord-autoload,
Gaia fetch, Gaia search, PDF download, FFI section).
Tests: 45 pass (2 new — ExoFOP row shape/naming, Pecaut-Mamajek
R_star interpolation).
Verified end-to-end in browser: fit → verdict MICROLENSING, ExoFOP
planet table with Host R_star=0.30 R_Sun, planet mass floor 4.82 M_Earth,
Rp/R_star=0.062, a_perp=1.91 AU. FFI section auto-populated (mocked
backend): sector S088, 2 Gaia sources in FOV. ExofopBulkPanel mounted
once TIC was known.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refined the microlensing sevtion to add FFI and Gaia overlay and other changes to fully align it with the transit tab such as ExoFOP compatible observables section