libera_utils.footprint_matching.readers.base#
Abstract base classes for the ancillary data reader plugins.
A reader turns one external ancillary dataset into native samples: the source’s own pixels, footprints or grid cells, each at its own location, with no averaging, binning or interpolation applied. The PSF weigher then weights every sample where it lies and the aggregation engine reduces the weighted samples to one value per variable, so a value is transformed exactly once on its way into a FMATCH product.
Three concrete contracts#
StaticReader– the source is one body of data for the staged period: a daily composite, a yearly map, or swath data carrying a time per sample. The reader loads it once (StaticReader._load_native()) asGridSamples,PointSamples, or a native that answers box queries itself (see_BoxNative); the base class indexes a point cloud and answers every query from memory.SteppedGridReader– the source is a time series of global grids (ERA5 hourly steps). The reader lists the step times (SteppedGridReader._step_times()) and loads one step on demand (SteppedGridReader._load_step()); the base class keeps only the step nearest the footprint time in memory.PassReader– the source is swath data in hourly granules, each with a time per sample (CERES FLASHFlux, CLDPIX). The reader reads a granule’s time span (PassReader._granule_span()) and loads one granule as points (PassReader._load_granule()); the base class holds only the granules whose span lies withinMAX_TIME_OFFSETof the current footprint time.
Geographic query#
AncillaryReader.samples_in() takes a footprint’s BoundingBox and time.
A grid is sliced on its axes with searchsorted. A source whose pixels are regular
in a projection, not in latitude/longitude (IGBP’s tiles on the MODIS sinusoidal grid), is held in its
projected form and geolocates only the block a box selects (_BoxNative). A
point cloud is sorted once, at
load, into 1 degree latitude/longitude bins held as offset ranges (one permuted copy
of the data, the unsorted one released), so a box query touches only the bins the box
overlaps before applying the exact box mask. A box that crosses the antimeridian is
split into its two halves and the halves’ samples are concatenated. A box that
encloses a pole spans every longitude, as the geometry module builds it.
Time selection#
After the box query, the reader’s TimeMatch
policy selects in time: nothing for a DAILY source, the nearest step for a
NEAREST_STEP source, and the nearest pass (every sample within PASS_WINDOW of
the observation time of the sample nearest the footprint time) for a NEAREST_PASS
source. Beyond
MAX_TIME_OFFSET the query returns no samples, which the orchestrator scores as zero
coverage and flags.
Auto-registration via __init_subclass__#
Every concrete subclass of AncillaryReader is added to
ReaderRegistry._registry under its READER_KEY when its module is imported;
no manual registration call is needed. Abstract intermediates are skipped.
Functions
|
Mask of the points inside a plain (non-wrapping) box, edges included. |
|
Split an antimeridian-crossing box into its west and east halves. |
Classes
|
Abstract base class for all ancillary data readers. |
|
A reader whose source is swath data in time-spanning granules, served by time window. |
|
A reader whose source is one body of data for the staged period. |
|
A reader whose source is a time series of global grids, served one step at a time. |