libera_utils.footprint_matching.geometry#

Coordinate geometry for footprint matching: L1B viewing geometry -> lat/lon box.

Purpose#

Given a footprint’s geolocation and viewing geometry from an L1B file, compute the geographic (latitude/longitude) bounding box of the patch of Earth the radiometer is sensing. Downstream, that box selects the ancillary-data samples the readers serve for this footprint. The box is therefore a safe superset: it must always enclose the footprint, and over-covering slightly is fine (a few extra samples) while under-covering is not (dropped data). We deliberately round outward for this reason.

The footprint is not a fixed shape – at large viewing zenith angles it stretches dramatically along the scan direction (tens of km at nadir, hundreds of km near the limb), because a fixed angular offset at the satellite projects to a much larger ground distance when looking toward the horizon. This module handles that, plus the hard edge cases: Earth curvature, dateline crossings, footprints that enclose a pole, and viewing geometry that runs off the limb of the Earth – including the case where the boresight is on Earth but the limb-ward corner of the box is not (severe- angle truncation), which raises PartialFootprintError.

Earth model: WGS84 ellipsoid (ECEF ray-trace)#

The footprint is anchored at the reported L1B footprint latitude/longitude (the box center). The satellite is placed in Earth-Centered-Earth-Fixed (ECEF) coordinates from the L1B subsatellite point and Radius_of_Satellite_from_Center_of_Earth, and the line from it to the footprint is the boresight. We rotate the boresight by the PSF’s angular half-extents and intersect each resulting ray with the WGS84 ellipsoid. The intersection points, converted back to geodetic latitude/longitude, give the box. Because the model is the true ellipsoid:

  • flattening (equatorial 6378.137 km vs polar 6356.752 km) is exact, and

  • geodetic latitude is honored exactly – the local vertical at each point is the ellipsoid normal, not the geocentric radial direction.

Off-limb handling falls out of the ray-trace: rays that miss the ellipsoid are off the Earth. A boresight with no Earth intersection (L1B writes NaN latitude/longitude for a space or calibration view) raises OffLimbError; a boresight on Earth whose box corner rays miss the ellipsoid is partial coverage (truncated/flagged, or raised as PartialFootprintError). Unusable ephemeris fields, or a footprint the satellite could not have seen, raise MissingGeolocationError.

The geodetic<->ECEF transforms and the ray-ellipsoid intersection are curryer’s (curryer.compute.spatial); pyproj is used only for the surface distances in the pole-enclosure test (pyproj.Geod).

References

Functions

bounding_box_from_points(center_lat_deg, ...)

Build the lat/lon bounding box of one footprint from its boundary points.

bounding_box_from_points_batch(...)

Build one lat/lon bounding box per footprint from its boundary points.

compute_footprint_bounding_box(...[, ...])

Compute the lat/lon bounding box of one radiometer footprint on the surface.

compute_footprint_bounding_boxes(...[, ...])

Compute the lat/lon bounding box of each of N radiometer footprints on the surface.

compute_viewing_frames(boresight_lat_deg, ...)

Build every footprint's viewing frame in one batched call.

project_to_angular(cell_lats_deg, ...[, ...])

Project ground grid cells into the radiometer's angular frame (delta, beta).

psf_ground_radius_km(satellite_radius_km, ...)

Project the PSF angular half-extent to an isotropic ground radius, in km.

slant_range_km(satellite_radius_km, ...)

Distance from the satellite to the ground point seen at a viewing zenith, in km.

surface_cell_ecef_km(cell_lats_deg, ...)

ECEF (km) of surface grid cells, raveled to (N, 3) in the input's row-major order.

Classes

ViewingFrame(satellite, b_hat, c_hat, n_hat)

Radiometer viewing frames of N footprints.

Exceptions

GeometryError

Base class for geometry errors raised by this module.

MissingGeolocationError

Raised when the spacecraft geolocation needed to build the viewing geometry is unusable.

OffLimbError

Raised when the boresight does not intersect the Earth's surface.

PartialFootprintError

Raised when the boresight is on Earth but part of the bounding box is not.