Source code for sen2nbar.kernels

from typing import Any, Union

import numpy as np
import xarray as xr


[docs] def kgeo( sun_zenith: Any, view_zenith: Any, relative_azimuth: Any, br: Union[float, int] = 1.0, hb: Union[float, int] = 2.0, ) -> Any: """Computes the Geometric Kernel (Kgeo). The mathematical formulation of Kgeo, also known as LiSparse-R Kernel (KLSR), can be found in Equation 39 of Lucht et al., 2000 [1]_. Parameters ---------- sun_zenith : Any Sun Zenith angles in degrees. view_zenith : Any Sensor Zenith angles in degrees. relative_azimuth : Any Relative Azimuth angles in degrees. br : float | int, default = 1.0 Crown relative height (Br) parameter. hb : float | int, default = 2.0 Shape (Hb) parameter. Returns ------- Any Geometric Kernel (Kgeo). References ---------- .. [1] https://doi.org/10.1109/36.841980 """ # Convert to radians theta_i = np.deg2rad(sun_zenith) theta_v = np.deg2rad(view_zenith) phi = np.deg2rad(relative_azimuth) # Equation 44 in Lucht et al., 2000 theta_i_dev = np.arctan(br * np.tan(theta_i)) theta_v_dev = np.arctan(br * np.tan(theta_v)) # Equation 43 in Lucht et al., 2000 cos_xi_dev = np.cos(theta_i_dev) * np.cos(theta_v_dev) + np.sin( theta_i_dev ) * np.sin(theta_v_dev) * np.cos(phi) # Equation 42 in Lucht et al., 2000 D = np.sqrt( (np.tan(theta_i_dev) ** 2.0) + (np.tan(theta_v_dev) ** 2.0) - (2.0 * np.tan(theta_i_dev) * np.tan(theta_v_dev) * np.cos(phi)) ) # Compute the cost term cos(t) # Equation 41 in Lucht et al., 2000 cos_t = ( hb * np.sqrt( (D ** 2.0) + ((np.tan(theta_i_dev) * np.tan(theta_v_dev) * np.sin(phi)) ** 2.0) ) / ((1.0 / np.cos(theta_i_dev)) + (1.0 / np.cos(theta_v_dev))) ) # cos(t) should be constrained to [-1,1] # Page 981 in Lucht et al., 2000 cos_t = cos_t.where(lambda x: x <= 1.0, other=1.0) cos_t = cos_t.where(lambda x: x >= -1.0, other=-1.0) t = np.arccos(cos_t) # Compute the overlap area between the view and solar shadows (O) # Equation 40 in Lucht et al., 2000 O = ( (1.0 / np.pi) * (t - np.sin(t) * cos_t) * ((1.0 / np.cos(theta_i_dev)) + (1.0 / np.cos(theta_v_dev))) ) return ( O - (1.0 / np.cos(theta_i_dev)) - (1.0 / np.cos(theta_v_dev)) + 0.5 * (1.0 + cos_xi_dev) * (1.0 / np.cos(theta_i_dev)) * (1.0 / np.cos(theta_v_dev)) )
[docs] def kvol(sun_zenith: Any, view_zenith: Any, relative_azimuth: Any) -> Any: """Computes the Volumetric Kernel (Kvol). The mathematical formulation of Kvol, also known as RossThick Kernel (KRT), can be found in Equation 38 of Lucht et al., 2000 [1]_. Parameters ---------- sun_zenith : Any Sun Zenith angles in degrees. view_zenith : Any Sensor Zenith angles in degrees. relative_azimuth : Any Relative Azimuth angles in degrees. Returns ------- Any Volumeric Kernel (Kvol). References ---------- .. [1] https://doi.org/10.1109/36.841980 """ # Convert to radians theta_i = np.deg2rad(sun_zenith) theta_v = np.deg2rad(view_zenith) phi = np.deg2rad(relative_azimuth) # Compute the phase angle cos_xi = np.cos(theta_i) * np.cos(theta_v) + np.sin(theta_i) * np.sin( theta_v ) * np.cos(phi) xi = np.arccos(cos_xi) return ( (((np.pi / 2.0) - xi) * cos_xi + np.sin(xi)) / (np.cos(theta_i) + np.cos(theta_v)) ) - (np.pi / 4.0)