libera_utils.footprint_matching.product#

FMATCH data product assembly and writing.

This module is the seam between the footprint-matching engine (readers, PSF aggregation, geometry) and the Libera data-product machinery (LiberaDataProductDefinition / write_libera_data_product). It owns the FMATCH product definitions and the flow that turns matched footprints into a conformant NetCDF file, for all four operational modes.

What the product carries#

Assembly and writing are wired for every operational mode, and each declared variable is filled by one of three routes:

  • Input pass-through - the geolocation and viewing angles come straight from the L1B Daily inputs (L1B_PASSTHROUGH_VARIABLES for the radiometer modes) or from the camera pseudo-footprints (real_columns in _assemble_camtime_dataset). Each footprint’s PSF bounding box (PSF_Bbox_*) comes from its ray-traced box.

  • Computed - the derived viewing geometry (Sunglint_Angle, via compute_derived_viewing_geometry()) is always calculated, and the external aggregated variables (aggregate_external_variables()) plus the coverage/QA columns (PSF_Coverage_Fraction / Quality_Flag) are calculated whenever staged ancillary inputs are supplied - the PSF aggregation of each source’s native samples.

  • Placeholders - a declared variable no input produced, when the caller opts in with allow_placeholders=True: the external columns when no ancillary data is staged, a reader’s columns when its source is not supplied, and Cloud_Fraction_Camera when it is omitted for a CAM mode. Without the opt-in, assembly raises.

Variable names#

Assembly fills each column under the name the product definition declares (Sunglint_Angle, Quality_Flag, <READER_KEY>_<spec_name> such as ERA5_Surface_Wind_U10), so nothing is renamed on the way to the file. The L1B input dict is keyed by the L1B RAD-4CH variable names (Latitude, Subsatellite_Latitude, Cone_Angle_Rate) plus the RADIOMETER_TIME coordinate; the pass-through names are also the product names, since the L1B names follow CERES BDS.

A placeholder is structurally correct (declared dtype, shape and attributes) but numerically meaningless. Floating-point placeholders are filled with NaN and integer placeholders with their declared _FillValue (FMATCH_INTEGER_FILL_VALUE, -1), or 0 for a bitmask; see _fill_placeholder_variables.

Why a thin seam here#

The product definitions (libera_utils/data/product_definitions/fmatch_*.yml) are the contract every downstream consumer (Scene ID, Camera Cloud Fraction, ADM binning) reads against. Keeping the loaders next to the writers means there is a single place that knows how a FMATCH file is produced, while the reader plugins stay decoupled from product I/O.

Functions

aggregate_external_variables(mode, footprints)

Aggregate every active reader's native samples to one value per footprint.

assemble_fmatch_dataset(mode, inputs, *[, ...])

Assemble a conformant FMATCH xarray.Dataset for an operational mode.

build_radiometer_footprints(l1b_inputs)

Build one RadiometerFootprint per L1B pass-through record.

compute_derived_viewing_geometry(...)

Compute derived viewing-geometry variables from the geolocation angles.

fmatch_time_variable(mode)

Return the per-footprint time coordinate name for an operational mode.

is_camera_timescale_mode(mode)

Return whether a mode indexes its footprints by camera image time.

load_fmatch_definition(mode)

Load and validate the FMATCH product definition for an operational mode.

write_fmatch_product(mode, inputs, ...[, ...])

Assemble and write one FMATCH NetCDF product for an operational mode.