GW Skymap Cross-Match Sweep (v2) — Scope + Frozen Settings
Status: FROZEN 2026-06-16 (Mike chose the standard multimessenger coincidence model) ·
Owner: Mike + Claude (engine room)
Parent: docs/scope-gravitational-wave-eventdex.md (the gw kind), docs/event-spine-framework.md,
and the v2 cosmic cross-match (8022a0b, where gw was held out with an honest null because it
needs skymaps). This brick supplies the skymaps and closes that gap.
This is the GW skymap sweep: give each gravitational-wave event a real spatial cross-match against the other two cosmic messengers (high-energy neutrinos, ultra-high-energy cosmic rays) using the GW's probabilistic sky localization, not a point. A GW is not a point on the sky; it is a HEALPix probability map. The sweep asks, for each GW: did a neutrino or a cosmic ray arrive from inside this event's 90% credible region (and, for neutrinos, at the right time)?
It does not create a new kind. It enriches the existing gw dossiers with a cited cross_match
block, the same enrich-in-place move the tornado/NCEI merge used.
The coincidence model — LOAD-BEARING, FROZEN by Mike 2026-06-16: standard multimessenger
A GW skymap gives a sky region + a merger time. The two messengers differ in what is testable:
- Neutrino arm (space AND time): a neutrino associates with a GW iff its arrival direction lies inside the GW's 90% credible region AND its arrival time is within ±1000 s of the GW merger. This is the established GW+neutrino search window (the IceCube-170922A / GW follow-up standard): a real astrophysical neutrino from a compact-object merger arrives essentially simultaneously, so the tight time gate is physical and crushes the false-coincidence rate.
- UHECR arm (space ONLY): a cosmic ray associates iff its arrival direction lies inside the GW's 90% credible region. No time gate — a UHECR is magnetically deflected and arrives delayed by potentially millions of years, so its arrival time carries no information about the GW merger time. Every UHECR spatial association is therefore flagged "suggestive": a coincident direction with no time link is weak by construction, and the paper voice must say so.
- Credible level: 90% for both arms.
(The rejected alternatives were spatial-only-for-both, which inflates chance coincidences over a decade of data, and a stringent 50%/±500 s neutrino-only window, which Mike did not pick.)
Measured-reality — IN (skymap is a localization, not a forecast)
A GW skymap is a Bayesian localization of a real, detected event — the posterior over where on
the sky the measured strain came from, exactly analogous to an earthquake epicenter inverted from
measured seismograms (which TerraPulse already ships). It is an estimate of where a thing that
physically happened came from, not a forecast of something that might happen. Under the bright line
([[feedback_measured_reality_only]]) it is IN, the same standing as the gw events themselves,
the neutrino detections, and the UHECR arrival directions. Nothing here is model output in the
forecast/projection sense.
The three layers (verified in PG16, 2026-06-16)
| Layer | Source slug | Position | Time | Notes |
|---|---|---|---|---|
| GW (spine) | gwosc_events → gw dossiers (431 census events) |
HEALPix skymap (fetch from GWOSC) | merger GPS time → UTC | no point in PG; localization is the skymap |
| Neutrino | icecube_neutrinos (IceCat-1, 348 events) |
extra_json ra_deg/dec_deg (equatorial) |
arrival UTC | filter out AutoSense probe stubs mixed into the source; keep only real events with ra/dec |
| UHECR | auger_uhecr (131 events) |
extra_json ra_deg/dec_deg (equatorial) |
arrival UTC | the latitude/longitude columns are the Auger site (−35.2/−69.3), NOT the arrival direction — use extra_json |
All three positions are equatorial (RA/Dec, J2000/ICRS), the same frame as the GWOSC skymaps, so no galactic conversion is needed.
Skymaps (the new data — fetch from GWOSC)
GW localizations ship as HEALPix FITS (bayestar/PE skymaps) via GWOSC. For each published gw
event, fetch its skymap (curl; httpx hangs against these hosts in this environment), cache under
data/gw_skymap_cache/, read with healpy+astropy (clean py3.13 wheels confirmed). The 90%
credible region is the smallest set of HEALPix pixels whose summed probability reaches 0.90; a sky
position is "inside" iff its pixel is in that set.
Fetch bound (frozen): the neutrino arm pre-filters on time first — only GW events with a
neutrino within ±1000 s need a skymap for the neutrino test, which is a handful, so those skymaps are
always fetched. The UHECR arm is spatial-only and therefore needs every GW skymap; fetching all
~431 is the heavy part and is what makes this a full brick rather than a quick add. If a skymap is
unavailable for an event, that event is recorded as skymap: "unavailable" and excluded from the
spatial test, never silently counted as a null.
What a GW slot gains (cited block)
Each gw dossier keeps its existing fields and gains:
sourcesextended to cite the matched messenger catalogs.- A
cross_matchblock:credible_level: 0.90,skymap: {source, nside, region_area_deg2, status}.neutrino_associations: [...]— each with the IceCat-1 event id, ra/dec,dt_secondsfrom merger,inside_90, andpassed(inside AND |dt|≤1000 s).uhecr_associations: [...]— each with the Auger event id, ra/dec, energy,inside_90,flag: "suggestive"(spatial-only).n_neutrino_assoc,n_uhecr_assoc, and an honestverdictstring.
The expectation, stated up front, is a near-total null (this is why v2 held GW out): a real GW×neutrino temporal+spatial coincidence would be a landmark detection. The value is the honest all-sky search with real localizations, and any spatial UHECR hits reported as suggestive only.
Build bricks
- Brick A — freeze. THIS DOC (2026-06-16): enrich-in-place on the
gwkind, the FROZEN standard-multimessenger coincidence model (neutrino space+time ±1000 s, UHECR space-only, 90% credible), measured-reality IN, the three verified layers + their position gotchas, GWOSC skymap fetch + 90%-region test, citedcross_matchblock, honest-null expectation. - Brick B — neutrino arm DONE (definitive null); UHECR arm logic built, skymaps pending.
2026-06-16: installed
healpy1.19 +astropy8.0 (clean py3.13 wheels);src/terrapulse/monitor/gw_skymap_sweep.pyloads the 348 real IceCat-1 neutrinos (probe stubs excluded) and 115 Auger UHECR directions (ra/dec from extra_json). The neutrino arm is a definitive null with no skymaps required: ZERO of 348 neutrinos fall within ±1000 s of any of the 431 GW events, so there is nothing to localize, the v2 "gw held out" gap is now closed for the real GW+neutrino channel. The UHECR spatial test (point_in_credible_region, healpy 90% region) is implemented and unit-tested. Remaining: the UHECR arm is spatial-only and needs EVERY GW 90% region; GWOSC has no per-event skymap URL (the eventapi lists strain, not skymaps), so the maps come from the per-catalog Zenodo releases (GWTC-2.1/3) plus GraceDB for the 2025 O4 events. That bulk acquisition is the one focused step left; until it runs, the UHECR arm is honestlypending_skymap(never a silent null). - Brick C/D — enrich + verify. 2026-06-16:
enrich_allfolded the citedcross_matchblock into all 431 gw dossiers (sourcesnow cite gwosc + neutrino + uhecr). 6 unit tests (synthetic-skymap region test + downgrade/normalize loader, temporal gate, verdict shapes). - Brick E — UHECR arm RUN (skymaps acquired) — CLEAN NULL. 2026-06-16
(
scripts/acquire_gw_skymaps.py): GWOSC has no per-event skymap URL, but each event carries a GraceDB id in its per-event eventapi detail (the catalog list omits it), and GraceDB serves small flattened skymaps publicly. Resolved every confident event to its GraceDB id and pulled the best flattened FITS (PE preferred over bayestar), 312 of 410 confident events (76%) — the 98 misses are O1/O2 events (GraceDB events-API doesn't serve their skymaps; they live in the GWTC-1 release) and a few with no public skymap, all honestlypending_skymap, never silent nulls. Maps downgraded to nside=256 and.npy-cached. Result: a clean null.- Neutrino arm: 0 (unchanged definitive null).
- UHECR arm: 60
null, 225chance_consistent, 24excess_poor_localization(a Poisson excess over a uniform-sky baseline, but in regions >100 deg² — an artifact of UHECR sky anisotropy, Auger's southern exposure + the known dipole, not a GW link), and only 3suggestive(a single UHECR each in a well-localized <100 deg² region: GW240915_001357, GW241127_061008, GW200208_130117). Across the 28 well-localized events the chance-expected total is ~2.8, so 3 singles ≈ chance: no significant GW×UHECR association. - Honest verdict (engine room): clean null on both arms. A UHECR spatial overlap is only
meaningful in a well-localized region (local UHECR density ≈ global); the
cross_matchblock therefore carriesregion_area_deg2,localization,chance_expected, andexcess_over_chanceso every overlap is self-contextualizing, andsuggestiveis gated on a Poisson 2σ excess AND good localization.
- First report: deferred (a real association would change that overnight). Engine room.
- Minor follow-on: the ~11 O1/O2 GWTC-1 skymaps (e.g. GW170817) could be added from the GWTC-1 DCC release tarball to push coverage past 76%; low value (2-detector events are poorly localized).