libera_utils.footprint_matching.product.compute_derived_viewing_geometry#

libera_utils.footprint_matching.product.compute_derived_viewing_geometry(solar_zenith_angle: ndarray, viewing_zenith_angle: ndarray, relative_azimuth_angle: ndarray) → dict[str, ndarray]#

Compute derived viewing-geometry variables from the geolocation angles.

Produces the Sunglint_Angle column every FMATCH product definition declares: the angle between the sensor view direction and the specular reflection of the solar beam, in degrees. Small values indicate potential sun glint contamination.

Parameters:
  • solar_zenith_angle (np.ndarray) – Per-footprint geolocation angles in degrees.

  • viewing_zenith_angle (np.ndarray) – Per-footprint geolocation angles in degrees.

  • relative_azimuth_angle (np.ndarray) – Per-footprint geolocation angles in degrees.

Returns:

{"Sunglint_Angle": ...}, a 1-D array of glint angles in degrees ([0, 180]) indexed by footprint. NaN propagates wherever any input angle is NaN.

Return type:

dict[str, np.ndarray]

Notes

The sun-glint angle is the angle between the sensor view direction and the specular (mirror) reflection of the solar beam off a horizontal surface. Writing the view and specular directions as unit vectors in the local horizontal frame and taking their dot product gives, with all angles in degrees,

cos(glint) = cos(SZA)*cos(VZA) + sin(SZA)*sin(VZA)*cos(RAA).

The sign of the third term follows the relative azimuth convention of the L1B Relative_Azimuth_Surface input, the CERES BDS R3V4 origin as curryer computes it (curryer.compute.spatial.relative_azimuth): mod(view_az - sun_az + 180, 360), with both azimuths taken at the surface point, clockwise from North, toward the spacecraft and the Sun. The Sun therefore sits at RAA == 180, the backscatter hot spot, where glint is SZA + VZA; the specular direction is RAA == 0, where glint falls to zero when VZA == SZA.