mostlyright.core.schemas.satellite
mostlyright.core.schemas.satellite
Section titled “mostlyright.core.schemas.satellite”Satellite schema (schema.satellite.v1) — Phase 25 (25-01 surface).
Two surfaces live here:
validate_satellite_station
: The ICAO station-identity validation HOOK the GOES ABI L2 extractor
(mostlyright.weather._fetchers._goes_extract) calls at the
_build_record write-site (Phase 25 D2). ColumnSpec supports only
dtype/nullable/enum — NO regex (verified core/schema.py) — so the ICAO
^[A-Z]{4}$ contract cannot live as a column pattern; it is enforced via
this hook plus validate_icao_for_path at the cache-path layer.
SatelliteSchema
: The full schema.satellite.v1 shape contract — the 18 ported 2i fields
plus the SDK overlay columns source / delivery / qc_status /
as_of_time. Registered with the Validator (core/schemas/__init__.py)
and wired into the codegen exporter (scripts/export_schemas.py
_GROUP_A_SCHEMA_IDS) so schemas/json/schema.satellite.v1.json is
emitted deterministically (TS type emission is signature-forward only this
phase — the TS reader is a deferred parity ticket).
D1 source identity (Phase 25 USER-LOCKED 2026-06-18; Phase 26 W1 H1
generalization). _registered_sources is the SET of the four distinct
NATIVE-ring source identities {noaa_goes, jma_himawari, noaa_viirs, eumetsat_meteosat} — one per instrument family (a model trained on one MUST
NOT silently reconcile against another). Within a single frame the source is
homogeneous: the validator reconciles df.attrs["source"] against the SET,
and the per-row source overlay column must equal that single
df.attrs["source"] (no cross-source mixing). noaa_goes is byte-unchanged
from Phase 25 (live self-extraction AND the future paid adapter share it).
delivery (enum {live, hosted}, default "live") is INFORMATIONAL
LINEAGE ONLY and is NOT part of source identity. mirror is a transport
choice and is deliberately NOT a schema column (D9).
Module Attributes
Section titled “Module Attributes”SATELLITE_DELIVERY_VALUES | D2 informational lineage enum. |
|---|---|
SATELLITE_QC_STATUS_VALUES | qc_status values (D5 annotate-never-drop, severity-inverted). |
Functions
Section titled “Functions”validate_satellite_station(station) | Validate a satellite row’s station identity is a 4-letter ICAO code. |
|---|
Classes
Section titled “Classes”SatelliteSchema() | schema.satellite.v1 — single-pixel satellite scan rows (NATIVE ring). |
|---|
mostlyright.core.schemas.satellite.SATELLITE_DELIVERY_VALUES : tuple[str, …] = (‘live’, ‘hosted’)
Section titled “mostlyright.core.schemas.satellite.SATELLITE_DELIVERY_VALUES : tuple[str, …] = (‘live’, ‘hosted’)”D2 informational lineage enum. delivery records the delivery channel
(free local self-extraction vs the future paid adapter) WITHOUT being part of
source identity — both channels share the SAME per-source identity (e.g. GOES
live + the future GOES paid adapter both reconcile to noaa_goes).
mostlyright.core.schemas.satellite.SATELLITE_QC_STATUS_VALUES : tuple[str, …] = (‘clean’, ‘flagged’, ‘suspect’)
Section titled “mostlyright.core.schemas.satellite.SATELLITE_QC_STATUS_VALUES : tuple[str, …] = (‘clean’, ‘flagged’, ‘suspect’)”qc_status values (D5 annotate-never-drop, severity-inverted). "clean"
passed every rule; "flagged" tripped a warning-class rule; "suspect"
tripped an error-class rule (physics/structure violation — almost always an
extraction bug, so the row is KEPT rather than dropped).
class mostlyright.core.schemas.satellite.SatelliteSchema
Section titled “class mostlyright.core.schemas.satellite.SatelliteSchema”Bases: Schema
schema.satellite.v1 — single-pixel satellite scan rows (NATIVE ring).
One row per (station, satellite, product, variable, pressure_level_hpa, scan_start_utc) — the dedup key (mirror-invariant, D9). Ports the 18 2i
storage fields and adds the SDK overlay columns source / delivery /
qc_status / as_of_time.
Phase 26 W1 generalization (H1). Phase 25 was GOES-geostationary-shaped.
The native ring (GOES E/W + Himawari + VIIRS + EUMETSAT) is covered by a SET
of distinct source identities (_registered_sources) and a broadened
satellite enum, and the row contract is generalized so a polar VIIRS
SWATH row validates alongside a geostationary GOES/Himawari/SEVIRI row:
sat_lon_used is now NULLABLE (geostationary-only) and pixel_row/
pixel_col mean “native grid index OR swath line/sample index”.
COLUMNS : ClassVar[list[ColumnSpec]] = [ColumnSpec(name=‘station’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=”), ColumnSpec(name=‘satellite’, dtype=‘enum’, units=None, nullable=False, enum_values=(‘goes16’, ‘goes17’, ‘goes18’, ‘goes19’, ‘himawari8’, ‘himawari9’, ‘viirs-npp’, ‘viirs-n20’, ‘viirs-n21’, ‘meteosat-0deg’, ‘meteosat-iodc’), notes=”), ColumnSpec(name=‘product’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=”), ColumnSpec(name=‘variable’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=”), ColumnSpec(name=‘pressure_level_hpa’, dtype=‘float64’, units=‘hPa’, nullable=True, enum_values=None, notes=‘null for 2D products; populated (part of the dedup key) for 3D profiles’), ColumnSpec(name=‘scan_start_utc’, dtype=‘timestamp_utc’, units=None, nullable=False, enum_values=None, notes=“UTC scan/granule start time (event-time, D4); from the source’s filename start token (GOES/Himawari _s, VIIRS granule start, SEVIRI repeat-cycle start)”), ColumnSpec(name=‘scan_end_utc’, dtype=‘timestamp_utc’, units=None, nullable=False, enum_values=None, notes=“UTC scan/granule end time; >= scan_start_utc (the source’s filename end token; equal to start for a duration-less filename)”), ColumnSpec(name=‘pixel_value’, dtype=‘float64’, units=None, nullable=True, enum_values=None, notes=“raw-as-reported single grid cell; null ONLY on the file’s _FillValue”), ColumnSpec(name=‘pixel_dqf’, dtype=‘float64’, units=None, nullable=True, enum_values=None, notes=‘NOAA DQF integer at the cell; null for variables with no DQF’), ColumnSpec(name=‘pixel_row’, dtype=‘int64’, units=None, nullable=False, enum_values=None, notes=‘native pixel row index at the station: geostationary fixed-grid row (y) for GOES/Himawari/SEVIRI, OR the SWATH line index for a VIIRS polar granule’), ColumnSpec(name=‘pixel_col’, dtype=‘int64’, units=None, nullable=False, enum_values=None, notes=‘native pixel col index at the station: geostationary fixed-grid col (x) for GOES/Himawari/SEVIRI, OR the SWATH sample index for a VIIRS polar granule’), ColumnSpec(name=‘units’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=‘physical units from the NetCDF variable units attr’), ColumnSpec(name=‘station_lat’, dtype=‘float64’, units=‘degrees_north’, nullable=False, enum_values=None, notes=‘station latitude copied at ingest time (provenance)’), ColumnSpec(name=‘station_lon’, dtype=‘float64’, units=‘degrees_east’, nullable=False, enum_values=None, notes=‘station longitude copied at ingest time (provenance)’), ColumnSpec(name=‘sat_lon_used’, dtype=‘float64’, units=‘degrees_east’, nullable=True, enum_values=None, notes=‘sub-satellite longitude of the geostationary source (GOES goes_imager_projection / Himawari fixed-grid / SEVIRI sub-sat 0deg|45.5E); NULL for a VIIRS polar SWATH row, which has no single sub-satellite point’), ColumnSpec(name=‘source_object_key’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=‘full S3/GCS object key the row was extracted from (provenance)’), ColumnSpec(name=‘ingested_at’, dtype=‘timestamp_utc’, units=None, nullable=True, enum_values=None, notes=‘when the bytes were fetched; null for historical backfill’), ColumnSpec(name=‘source’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=“per-row source-identity overlay == df.attrs[‘source’], one of {noaa_goes, jma_himawari, noaa_viirs, eumetsat_meteosat} (D1)”), ColumnSpec(name=‘delivery’, dtype=‘enum’, units=None, nullable=False, enum_values=(‘live’, ‘hosted’), notes=‘delivery-channel lineage {live,hosted}; NOT source identity (D2)’), ColumnSpec(name=‘qc_status’, dtype=‘enum’, units=None, nullable=False, enum_values=(‘clean’, ‘flagged’, ‘suspect’), notes=‘annotate-never-drop verdict (D5 severity-inverted)’), ColumnSpec(name=‘as_of_time’, dtype=‘timestamp_utc’, units=None, nullable=True, enum_values=None, notes=‘knowledge-time stamp; nullable (D4)’)]
Section titled “COLUMNS : ClassVar[list[ColumnSpec]] = [ColumnSpec(name=‘station’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=”), ColumnSpec(name=‘satellite’, dtype=‘enum’, units=None, nullable=False, enum_values=(‘goes16’, ‘goes17’, ‘goes18’, ‘goes19’, ‘himawari8’, ‘himawari9’, ‘viirs-npp’, ‘viirs-n20’, ‘viirs-n21’, ‘meteosat-0deg’, ‘meteosat-iodc’), notes=”), ColumnSpec(name=‘product’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=”), ColumnSpec(name=‘variable’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=”), ColumnSpec(name=‘pressure_level_hpa’, dtype=‘float64’, units=‘hPa’, nullable=True, enum_values=None, notes=‘null for 2D products; populated (part of the dedup key) for 3D profiles’), ColumnSpec(name=‘scan_start_utc’, dtype=‘timestamp_utc’, units=None, nullable=False, enum_values=None, notes=“UTC scan/granule start time (event-time, D4); from the source’s filename start token (GOES/Himawari _s, VIIRS granule start, SEVIRI repeat-cycle start)”), ColumnSpec(name=‘scan_end_utc’, dtype=‘timestamp_utc’, units=None, nullable=False, enum_values=None, notes=“UTC scan/granule end time; >= scan_start_utc (the source’s filename end token; equal to start for a duration-less filename)”), ColumnSpec(name=‘pixel_value’, dtype=‘float64’, units=None, nullable=True, enum_values=None, notes=“raw-as-reported single grid cell; null ONLY on the file’s _FillValue”), ColumnSpec(name=‘pixel_dqf’, dtype=‘float64’, units=None, nullable=True, enum_values=None, notes=‘NOAA DQF integer at the cell; null for variables with no DQF’), ColumnSpec(name=‘pixel_row’, dtype=‘int64’, units=None, nullable=False, enum_values=None, notes=‘native pixel row index at the station: geostationary fixed-grid row (y) for GOES/Himawari/SEVIRI, OR the SWATH line index for a VIIRS polar granule’), ColumnSpec(name=‘pixel_col’, dtype=‘int64’, units=None, nullable=False, enum_values=None, notes=‘native pixel col index at the station: geostationary fixed-grid col (x) for GOES/Himawari/SEVIRI, OR the SWATH sample index for a VIIRS polar granule’), ColumnSpec(name=‘units’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=‘physical units from the NetCDF variable units attr’), ColumnSpec(name=‘station_lat’, dtype=‘float64’, units=‘degrees_north’, nullable=False, enum_values=None, notes=‘station latitude copied at ingest time (provenance)’), ColumnSpec(name=‘station_lon’, dtype=‘float64’, units=‘degrees_east’, nullable=False, enum_values=None, notes=‘station longitude copied at ingest time (provenance)’), ColumnSpec(name=‘sat_lon_used’, dtype=‘float64’, units=‘degrees_east’, nullable=True, enum_values=None, notes=‘sub-satellite longitude of the geostationary source (GOES goes_imager_projection / Himawari fixed-grid / SEVIRI sub-sat 0deg|45.5E); NULL for a VIIRS polar SWATH row, which has no single sub-satellite point’), ColumnSpec(name=‘source_object_key’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=‘full S3/GCS object key the row was extracted from (provenance)’), ColumnSpec(name=‘ingested_at’, dtype=‘timestamp_utc’, units=None, nullable=True, enum_values=None, notes=‘when the bytes were fetched; null for historical backfill’), ColumnSpec(name=‘source’, dtype=‘string’, units=None, nullable=False, enum_values=None, notes=“per-row source-identity overlay == df.attrs[‘source’], one of {noaa_goes, jma_himawari, noaa_viirs, eumetsat_meteosat} (D1)”), ColumnSpec(name=‘delivery’, dtype=‘enum’, units=None, nullable=False, enum_values=(‘live’, ‘hosted’), notes=‘delivery-channel lineage {live,hosted}; NOT source identity (D2)’), ColumnSpec(name=‘qc_status’, dtype=‘enum’, units=None, nullable=False, enum_values=(‘clean’, ‘flagged’, ‘suspect’), notes=‘annotate-never-drop verdict (D5 severity-inverted)’), ColumnSpec(name=‘as_of_time’, dtype=‘timestamp_utc’, units=None, nullable=True, enum_values=None, notes=‘knowledge-time stamp; nullable (D4)’)]”schema_id : ClassVar[str] = ‘schema.satellite.v1’
Section titled “schema_id : ClassVar[str] = ‘schema.satellite.v1’”mostlyright.core.schemas.satellite.validate_satellite_station(station)
Section titled “mostlyright.core.schemas.satellite.validate_satellite_station(station)”Validate a satellite row’s station identity is a 4-letter ICAO code.
Returns the station string unchanged when valid (so call sites can use it
inline). Raises SchemaValidationError for anything that is not
exactly four uppercase ASCII letters — notably the 2i 3-letter NWS codes,
which must fail loudly rather than silently produce un-joinable rows.