2026-05-11 · build log · helio-mirror

HelioCast — predicting how much sunlight a planet will receive in the next 24 h

PSP measures the Sun directly. JWST observes other bodies that reflect the Sun. Cross-correlate the two and you can measure — and then forecast — the irradiance delivered to specific bodies in the solar system. The first end-to-end pipeline is live; the data scale isn't there yet, and we're saying so.

The question

For any body in the solar system — a planet, a moon, a satellite, a future harvester — how much sunlight will reach it over the next 24 hours? The deterministic part is geometry: orbits set the distance and view angle. The stochastic part is the Sun's own state: sunspot rotation, faculae, flares, CME-driven irradiance dips. To forecast you need to measure both.

Two instruments, one product

SourceWhat it measuresWhat it can't see
PSPDirect in-situ B-field, plasma, energetic particles at 0.1–0.2 AU. Sees solar events at their source.Only its own location. Can't tell you what's hitting Earth or Mars unless they're on the same Parker spiral.
JWSTReflected sunlight off bodies (Mars, Jupiter, Saturn, moons, asteroids). Each body is a mirror of the solar irradiance at its position.Photometric, not in-situ. Phase angle and albedo are in the way; need to invert the planetary photometry to recover the underlying Isolar.

The pipeline (six stages, all cloud)

┌─ 1 pull ───────────────────────────────────────────────────────────────┐ │ pyspedas → PSP FIELDS L2 + SWEAP/SPAN-I L3 │ │ astroquery → JWST solar-system observations (Mars / Jupiter / …) │ │ JPL Horizons→ ephemerides for PSP + every candidate body │ └────────────────────────────────────────────────────────────────────────┘ │ ┌─ 2 register ──────────────────────────────────────────────────────────┐ │ Every measurement gets (helio_lon, helio_lat, r_AU, t). │ │ PSP B-field samples tagged with PSP's position at sample time. │ │ Each JWST FITS tagged with the target body's heliographic position. │ └────────────────────────────────────────────────────────────────────────┘ │ ┌─ 3 detect ────────────────────────────────────────────────────────────┐ │ PSP → PVI(τ=100s) > 3 candidate samples → cluster on 60-s gaps │ │ → distinct events with max PVI + duration │ │ JWST → per-FITS integrated flux on the SCI core (trim edges 10%) │ └────────────────────────────────────────────────────────────────────────┘ │ ┌─ 4 coincide ──────────────────────────────────────────────────────────┐ │ For each PSP event, predict arrival at each body via: │ │ WIND : t + (r_body − r_PSP) / v_sw (≈3.5 d at 1 AU) │ │ LIGHT : t + (r_body − r_PSP) / c (≤9 min) │ │ Match if (Δ_lon < 20°) and (Δ_t < tolerance per mechanism). │ └────────────────────────────────────────────────────────────────────────┘ │ ┌─ 5 calibrate ─────────────────────────────────────────────────────────┐ │ Invert Lambertian-disk photometry per FITS: │ │ F_obs ∝ I_solar · A_bond · R² · Φ(α) / Δ² │ │ → I_solar(at body) ∝ F_obs · Δ² / (A_bond · R² · Φ(α)) │ └────────────────────────────────────────────────────────────────────────┘ │ ┌─ 6 forecast ──────────────────────────────────────────────────────────┐ │ Per body, hourly for next 24 h: │ │ I(t+Δt) = I(t_last) · (r(t_last) / r(t+Δt))² │ │ PSP-event coincidence within the horizon → confidence-band flag. │ │ Write forecast/latest.json → dashboard reads it live. │ └────────────────────────────────────────────────────────────────────────┘

What's actually true today

First end-to-end run on perihelion E20 (2024-06-28 to 2024-07-02):

StageOutputNotes
pull5 days PSP FIELDS · 7 ephemerides · 3 JWST FITS (Mars × 2 NIRCam, Jupiter × 1)PSP SWEAP/SPC L3i is gappy post-E18; we switched to SWEAP/SPAN-I.
register3 long-form parquets in coords/~5 ms per FITS for the header read.
detect413 PSP events (clustered from 13,775 PVI>3 samples) · 3 JWST aggregatesReal CME-candidate and current-sheet count at perihelion.
coincide0 coincidencesHonest result: JWST observations in the cache pre-date E20 by ~1.5 y. Fixed by ±90 d temporal window in the next pull.
calibrate3 inferred-irradiance proxiesLambertian disk + Bond albedo + phase angle.
forecast24 × 3 hourly rows → dashboardFlat-looking because Jupiter barely moves in 24 h; the value of the model shows only when an event coincidence triggers the PSP flag.

Why zero coincidences is the most useful result of the first run

The first pull asked MAST "give me the most recent JWST observation of Mars / Jupiter / Saturn". MAST obliged with science-grade FITS from 2022–2023, irrespective of when PSP happened to be at perihelion. The pipeline did exactly what we asked. The pipeline doesn't decide what data is contemporaneous — we have to.

Patch (already shipped): the MAST query now requires t_min within ±90 days of the perihelion window. If a body simply hasn't been observed near a given perihelion, the search falls back to the nearest-in-time observation, with the gap logged. No silent empties.

What the resume bullet says

HelioCast — multi-spacecraft solar irradiance triangulator. Six cloud workflows (GH Actions + HF Datasets) ingest Parker Solar Probe in-situ measurements + JWST observations of solar-system bodies + JPL Horizons ephemerides, register everything in heliographic coordinates, detect PSP events (PVI > 3) and JWST reflectance excursions, match PSP→body advection (wind / light), invert Lambertian-disk photometry to recover per-body irradiance proxies, and forecast 24 h hourly. End-user dashboard at ask-meridian.uk/helio/ reads its own outputs from the public HF dataset luuow/meridian-helio-mirror. First end-to-end run on one perihelion; honest about the data-scale gap (3 JWST FITS, 0 coincidences in v0.1 — temporal query fixed in v0.2).

What's not in v0.1

Reproduce

git clone https://github.com/LuuOW/meridian-mcp
cd meridian-mcp
gh secret set HF_TOKEN -b "<your hf write token>"
gh workflow run helio-mirror-all.yml -f perihelion=E20

site: ask-meridian.uk · code: github