Listening for events…

Scope freeze — radiation_monitor Locationdex kind

Frozen 2026-06-26. Fifth kind of the Locationdex family (docs/locationdex-framework.md), after neutron_monitor, tide_gauge, magnetic_observatory, and streamgauge. The slot is a place: one EPA RadNet station.

Source pivot (Mike's call 2026-06-26): the triage doc queued radiation_monitor against EURDEP, but EURDEP's openly-accessible JRC FTP holds only three historical episodes (Chernobyl, Norway/Sweden/Finland, Ruthenium-2017), and its live ~5,000-station network is login-gated. EPA RadNet is the openly-fetchable measured replacement. Unlike the prior Locationdex kinds, RadNet was not previously ingested, so this build registers BOTH a new measured feed and the spine.

The slot

  • One slot = one EPA RadNet station. Slot ID = the RadNet location number (loc_num).
  • Full roster: all 333 RadNet stations from EPA Envirofacts ERM (Environmental Radiation Monitoring), across the US states/territories.
  • A station IS a place, anchored to its city centroid (see Coordinates). A spatial sweep is buildable later; this kind stays catalog-first.

Two registrations (one reload)

scripts/reload_epa_radnet.py pulls the ERM tables once and registers:

  1. epa_radnet (measured feed) — every RadNet lab result as one observation: a measured radionuclide concentration (SI, e.g. Bq/L) at a station, tagged with material + analyte + date; the detectable flag in quality_flag. ~hundreds of thousands of results, 1978-present.
  2. epa_radnet_stations (spine) — the 333 stations as place-slots.

Join chain: ERM_RESULT(ana_num)ERM_ANALYSIS(ana_num→samp_num)ERM_SAMPLE(samp_num→loc_num, mat_id)ERM_LOCATION(loc_num).

Slot contents

  • Identity: RadNet location number, station name, city, state.
  • Place: latitude, longitude (city centroid), PostGIS point, geocoded flag.
  • Measured-series summary joined from epa_radnet by loc_num: measurement count, coverage span, distinct analytes, distinct materials, detectable count — cited to epa_radnet. The RadNet series is multi-analyte and multi-material, so the slot summarizes monitoring breadth, NOT a single scalar mean (averaging Cs-137-in-milk with I-131-in-air is meaningless). Stations with no joined results are kept registry-only.

Measured reality

  • IN: RadNet lab measurements of real environmental samples (air particulate, precipitation, milk, drinking/surface water) analyzed for specific radionuclides. Non-detects are kept (real measurements, flagged). Clean per feedback_measured_reality_only.
  • OUT: no model output. (The EURDEP JRC-FTP catalog crawl and the login-gated EURDEP live network are unrelated; held out.)

Coordinates (the one compromise, flagged not hidden)

Envirofacts gives stations at city level with no coordinates. Per Mike's scope call, the place is anchored to the city centroid via the project geocoder (forward_geocode, OSM Nominatim, throttled to 1 req/s and cached), with geocoded="city-centroid" recorded on every slot. This is approximate, not the exact monitor position; it is the documented limit of the open data.

Storage

  • Sources epa_radnet (measured feed) + epa_radnet_stations (registry, active=False).
  • Slots in the third sibling storehouse data/location_storehouse/, reusing the event_storehouse write + disk-rebuilt-index machinery via its base_dir argument.

Gotchas (reuse-critical)

  • RadNet has two faces: the openly-documented Envirofacts ERM lab program (this build) vs the near-real-time gamma-monitor dashboard (locked API, exact coords). The ERM path is what is fetchable; its locations are city-level only.
  • Station keyed in extra_json->>'loc_num' in the feed; quality_flag holds the detectable flag (Y/N), not the station.
  • Geocoding is throttled (OSM 1 req/s) and cached at data/epa_radnet_cache/geocode.json — a few stations may fail to geocode and remain registry places with null coords.

Frozen vs deferred-v2

  • Frozen (this brick): 333-station roster as place-slots; measured radionuclide feed ingested + cited; monitoring-breadth summary; catalog index.
  • Deferred-v2: spatial sweep; exact gamma-monitor coordinates if the dashboard API opens; per-analyte or per-material stratified slot views; the near-real-time gross count-rate series.
Live Feed