libera_utils.footprint_matching.geometry.project_to_angular#
- libera_utils.footprint_matching.geometry.project_to_angular(cell_lats_deg: ndarray, cell_lons_deg: ndarray, *, frame: ViewingFrame | None = None, boresight_lat_deg: float | None = None, boresight_lon_deg: float | None = None, subsatellite_lat_deg: float | None = None, subsatellite_lon_deg: float | None = None, satellite_radius_km: float | None = None, cell_ecef_km: ndarray | None = None) tuple[ndarray, ndarray]#
Project ground grid cells into the radiometer’s angular frame
(delta, beta).This is the inverse of the forward rotation
_offset_ray_directionused to build the footprint bounding box, and the piece the PSF aggregation weighting needs: given where each ancillary grid cell sits on the ground, how far off the boresight is it in the along-scan (delta) and cross-scan (beta) angular directions as seen from the satellite. Those angles are exactly the coordinates the CERES PSFlibera_utils.footprint_matching.psf.psf_weight()is a function of (CERES ATBD v2.2 §4.4.2.3, Eq. 4.4-8).Pass either a precomputed single-footprint
frameor the footprint’s geolocation (all ofboresight_lat_deg,boresight_lon_deg,subsatellite_lat_deg,subsatellite_lon_degandsatellite_radius_km), from which the frame is built.Method#
The viewing frame (
compute_viewing_frames()) gives three orthonormal axes:b_hat– the boresight look direction (delta = beta = 0),c_hat– the cross-scan axis (perpendicular to the scan plane),n_hat = c_hat x b_hat– the in-scan-plane axis (b_hat’s+deltaside).
For each cell we form the unit look vector from the satellite to the cell and read off the angles by projecting onto that basis. Because
_offset_ray_directionproduces a directiond = (b_hat cos(delta) + n_hat sin(delta)) cos(beta) - c_hat sin(beta)(the beta rotation is aboutc_hat x along), the inverse is exact:beta = asin(-look . c_hat) delta = atan2(look . n_hat, look . b_hat)
The elongation of the footprint at oblique viewing is captured by projecting the actual ground cells to satellite angles, so no viewing-zenith stretch factor is needed.
- param cell_lats_deg:
Grid-cell latitudes and longitudes in degrees (any common shape). Assumed on the surface (ellipsoidal height 0).
- type cell_lats_deg:
np.ndarray
- param cell_lons_deg:
Grid-cell latitudes and longitudes in degrees (any common shape). Assumed on the surface (ellipsoidal height 0).
- type cell_lons_deg:
np.ndarray
- param frame:
A precomputed single-footprint frame, as returned by
ViewingFrame.for_index(). When given, the geolocation arguments are ignored.- type frame:
ViewingFrame, optional
- param boresight_lat_deg:
Footprint boresight centroid, degrees (
delta = beta = 0anchor).- type boresight_lat_deg:
float, optional
- param boresight_lon_deg:
Footprint boresight centroid, degrees (
delta = beta = 0anchor).- type boresight_lon_deg:
float, optional
- param subsatellite_lat_deg:
Geodetic spacecraft sub-point (L1B
Subsatellite_Latitude/Longitude), degrees.- type subsatellite_lat_deg:
float, optional
- param subsatellite_lon_deg:
Geodetic spacecraft sub-point (L1B
Subsatellite_Latitude/Longitude), degrees.- type subsatellite_lon_deg:
float, optional
- param satellite_radius_km:
Spacecraft distance from Earth’s center (L1B
Radius_of_Satellite_from_Center_of_Earth), km.- type satellite_radius_km:
float, optional
- param cell_ecef_km:
Precomputed surface ECEF (km) of the cells,
(N, 3)incell_lats_deg.ravel()order (i.e. exactlysurface_cell_ecef_km()). The cells’ geometry is independent of the viewing frame, so when several footprints see the same cells the caller can compute this once and pass it in, skipping the per-footprint closed-form geodetic->ECEF transform. When omitted it is computed from the cell coordinates; the result is identical either way.- type cell_ecef_km:
np.ndarray, optional
- returns:
(delta_deg, beta_deg)arrays, each the shape ofcell_lats_deg.- rtype:
tuple[np.ndarray, np.ndarray]
- raises ValueError:
If neither
framenor the full geolocation is given, orframedoes not hold exactly one footprint.- raises MissingGeolocationError:
If the ephemeris fields are unusable or the footprint is not visible from the satellite.
- raises OffLimbError:
If the boresight latitude or longitude is fill, non-finite or out of range.