Locationdex — the place axis (Framework Extension)
Status: framework extension · Opened: 2026-06-19 · Owner: Mike (mental model) + Claude
(engine room) · Parent: docs/event-spine-framework.md, docs/dex-data-model.md, and the
sibling docs/yeardex-framework.md.
Mike coined Locationdex on 2026-06-19 while draining the admin datasource backlog, on reaching the safecast radiation feed: "maybe the next dex type could be Locationdex, so each slot is the geographical location of the sensor." It is a first-class third family, not a side branch.
The one idea
The dex organizes measured data into indexed slots. Two axes already exist:
- Eventdex — a slot is one event (a tornado, an eruption, a chirp). Indexed by when it happened.
- Yeardex — a slot is one year of a statistical series. Indexed by which year.
Locationdex adds the third natural axis:
- Locationdex — a slot is one fixed place that hosts a sensor: a station, an observatory, a gauge, a monitoring site. Indexed by where it is.
A station is a stable, addressable, revisitable thing with an ID (its station code and its coordinates), exactly as an event has a stable ID and a year has its number. So a place qualifies as a slot under the same rules that let a hurricane or a year be a slot. The difference is only the axis: Eventdex indexes by event, Yeardex by year, Locationdex by place.
Why it was needed: the orphaned station networks
The dex coverage map had a whole category filed under "not dex material — continuous monitoring time series": magnetic observatories (INTERMAGNET), tide gauges (NOAA), streamgauges (USGS), neutron monitors (NMDB), fixed radiation posts. They are neither events nor years. But they are not un-indexable — they are places that report over time. Locationdex is their home. The reason they read as "not dex material" was that the dex had only an event axis and a year axis; the place axis they actually live on was missing.
What qualifies for Locationdex (vs Event / Year)
Use Locationdex when the data is a network of fixed sites, each reporting a continuous or repeated measurement from one stable location:
- A stable place ID — a station code and coordinates that do not move. A roving sensor (a car-mounted radiation logger; a research vessel) is not a Locationdex slot; its location is a track, not a place. (Mobile data is organized differently — by geographic cell — and is the considered-later case, not this family's slot.)
- Measured-reality provenance — the site records what is physically measured at it (a count rate, a water level, a field strength), not a model of it.
- A network worth a roster — several sites, deep enough to backfill the full published roster on day one (no-spiking: the full network, not the handful a live fetcher happens to stream).
The qualification test mirrors the spine test: a stable slot ID, measured provenance, and a roster with mass.
What a station slot holds
A Locationdex slot is catalog-first: the slot is the place plus what we know and measure there.
- Identity + place: code, name, jurisdiction, latitude, longitude, altitude, coordinate provenance.
- Instrument character: the permanent properties that distinguish this site from its peers (a neutron monitor's cutoff rigidity; a tide gauge's datum; an observatory's baseline).
- Measured-series summary, cited: a roll-up of the site's staged time series (coverage span, count, central value and range) with a pointer to the underlying observations. The raw series stays where it is (the platform's normalized observations); the slot summarizes and cites it.
A place is genuinely a place, so — unlike a Yeardex year, where "a year is not a place" makes a spatial sweep meaningless — a Locationdex slot can support a spatial sweep later (what else our sensors recorded near this site). That is an allowed extension, deferred until a kind needs it; the base family is catalog + series-summary.
Multi-source cited slots (universal rule applies)
A station slot obeys the universal cited-slot rule (docs/yeardex-framework.md Part 2): it accretes
data from more than one source, each datum cited. The pilot already shows two: the registry that
says where the station is, and the measured series that says what it records, each attributed.
A second catalog describing the same station (a different network's metadata for the same site)
would enrich the one slot, cited, never duplicate it.
Storage
A third sibling storehouse, data/location_storehouse/<kind>/<slot_id>.json, beside
event_storehouse/ and year_storehouse/. It reuses the shared event_storehouse write +
disk-rebuilt-index machinery via the base_dir argument, exactly as the Yeardex did — parallel
lists per the data model, stitched into a combined view only if a whole-dex walk is ever wanted.
Measured-reality bright line
Binding, unchanged: a slot accretes measurements of what physically happened at the place, never a model's estimate. A recorded count rate is in; a modeled or interpolated grid value standing in for a missing station is out.
Frozen vs open
Frozen (2026-06-19, Mike):
- Locationdex exists as a first-class third family: the slot may be a fixed place (a station/site).
- A roving sensor is not a slot; its location is a track. Mobile data is organized by geographic cell, a separate later question, not this family.
- The measured-reality bright line and the multi-source cited-slot rule both bind.
Open (decided per kind, in each docs/scope-*.md freeze):
- Which network; roster source and slot-JSON shape; whether and when a kind turns on the spatial sweep; how (and whether) mobile/roving data gets a binned-cell treatment.
Sequencing
- This framework doc — defines the family. ✅ (this file).
- First Locationdex kind —
neutron_monitor(NMDB),docs/scope-neutron-monitor-locationdex.md, 64-station deep-pull roster. Proves slot = place end to end. ✅ 2026-06-19. - Scale across the other fixed-station networks (tide gauges, magnetic observatories, streamgauges), each its own scope freeze. Bring safecast in later as the binned-mobile special case.
Shipped Locationdex kinds (11): neutron_monitor (64, NMDB), tide_gauge (301, NOAA CO-OPS),
magnetic_observatory (154, INTERMAGNET), streamgauge (9,478, USGS), radiation_monitor (334,
EPA RadNet; + a 2nd gamma series), coral_reef_station (77 across 2 surveys — EPA 2011 PR + 2009 USVI/St. Thomas coral-reef surveys,
docs/scope-coral-reef-station-locationdex.md), radiosonde_station (2,821 fixed, NOAA IGRA,
07d4ced — docs/scope-radiosonde-station-locationdex.md), reservoir_cyano_water_quality (20,
EPA ScienceHub / Smucker et al. 2021 — docs/scope-reservoir-cyano-water-quality-locationdex.md),
power_plant (14,361, EPA eGRID 2018-2023 — docs/scope-power-plant-locationdex.md),
water_quality_station (84, EPA Dungeness River BMP study — docs/scope-water-quality-station-locationdex.md),
precipitation_station (2,093, NOAA NCEI Cooperative Hourly Precipitation Data v2 — docs/scope-precipitation-station-locationdex.md).
The coral kind is the first whose slot carries a
one-off ecological-survey snapshot (multi-taxon reef condition) rather than an instrument's running
series; region + survey year are slot fields so sibling regional surveys extend it. That expansion
is now real: the EPA 2009 USVI/St. Thomas survey (13 reef stations on an east-west
disturbance gradient) was added 2026-06-30 as a second SURVEYS entry with no new reader (same
sheet shape as PR2011); its rugosity index, stored under the reciprocal convention, is recomputed
from the raw draped/linear lengths to stay comparable with PR2011. The
water_quality_station kind reuses that expandable-registry shape (Mike chose it 2026-06-28 over a
watershed-specific kind): the slot is a monitoring station, the STUDY/watershed is a slot field,
slot ids are namespaced <study_id>-<station_id>, and future EPA water-quality studies (or a broader
STORET/WQX pull) extend the same kind. First study = the EPA Dungeness River, WA BMP study (80 STORET
WQ stations + the USGS gauge + 3 COOP rain gauges); each slot embeds its per-characteristic summary +
raw samples (precip stations embed annual totals). Bright line runs row-by-row like power_plant:
grab samples / gauge readings / rain measured IN, USGS "Computation by NWIS algorithm" rows held OUT;
non-detects kept (value nulled, flagged).
The power_plant kind is the first where the source is a MIX of measured and calculated values
and the bright line runs THROUGH it row by row. EPA eGRID flags every emission value with its
provenance, so the slot keeps metered net generation (always) plus only the EPA/CAMD
continuous-monitor (CEMS) emissions, re-summed from the unit sheet over the monitored units; the
"Estimated using emissions factor" values and eGRID's blended plant totals and derived lb/MWh
rates are held out (feedback_measured_reality_only, Mike reconfirmed 2026-06-28 "no on
projections and/or models"). Each slot embeds its 2018-2023 annual series; n_units vs
n_units_cems make the measured coverage explicit, and a wind/solar/landfill-gas plant keeps its
generation with emissions nulled ("data is data"). 1996-2016 historical backfill deferred (older
schemas lack the per-row CEMS flag).
The reservoir_cyano_water_quality kind is the first whose slot EMBEDS its full annual measured
series (1987-2018) as an array, the way the neo CelestialObjectDex slot embeds its close-approach
array. EPA's 20 US Army Corps reservoirs (KY/IN/OH) behind Smucker et al. 2021 (warming reservoirs
→ worse cyanobacterial blooms + deep hypoxia). It was first prototyped as a 640-cell reservoir×year
YearLocationdex (91c7a27); Mike chose reservoir-as-place (2026-06-28), so each of the 20
reservoirs is one slot carrying identity + morphometry + a series summary (peak bloom and its year)
- the per-year indicators. IN = the raw measurements (max cyano cell density, chlorophyll, clarity, nutrients, summer precip, surface + deep temps, deep DO); OUT = the study's GAM model fits.
The radiosonde_station kind is the first ROSTER-rather-than-deep-pull Locationdex. The other
station kinds deep-pull each station's running series; for radiosondes that series is the soundings,
which the live igra_soundings feed already ingests, so the slot instead carries the roster's own
measured-record summary (first/last year + NOBS = the count of real balloon ascents) and an
in_live_feed flag pointing back at the live series. Global scope (all 2,821 fixed IGRA stations,
219 countries), not the ~89-site US live slice ("data is data"). The 100 mobile IGRA platforms
(ships + drifting ice stations, no fixed lat/lon) are NOT here: a moving platform is not a place, so
Mike split them into the new mobile_radiosonde MovingPlatformDex kind (6th family,
docs/movingplatformdex-framework.md), whose slot carries the voyage track instead of a point.
The precipitation_station kind is the second ROSTER-rather-than-deep-pull Locationdex, on the
radiosonde_station model. NOAA NCEI's Cooperative Hourly Precipitation Data (COOP-HPD v2, the
successor to the retired per-state DSI-3240 tree Mike pasted) is 2,093 fixed cooperative rain gauges,
all geolocated, records 1940-2026 across 54 states/territories. The v2 station-inventory already
carries each gauge's measured-record summary (period of record + fraction QC-passed good), which is
the place's measured footprint, so the slot catalogs identity + coordinates + that summary and
references the per-gauge hourly series (has_hourly_series + access URL) instead of embedding it;
the series deep-pull and a live edge are deferred (Mike's shape call 2026-07-01). Measured gauge
depths are all IN, no model. Mike's note that "a number of these url links from this one specific
source" all get the same judgement is why the many per-state /hourly_precip-3240/NN/ URLs collapse
into this single kind rather than being triaged one at a time.
Same discipline as every kind: scope frozen before backfill and never tuned to results; full-roster deep pull, not the thin live slice; Mike rules the load-bearing categorization calls.