Surfaces API
Surface models are implemented in CoreRT because they form the lower boundary of the adding-doubling column.
Surface Types
vSmartMOM.CoreRT.LambertianSurfaceScalar Type
LambertianSurfaceScalar{FT} <: AbstractSurfaceTypeIsotropic Lambertian surface with a single scalar albedo α shared across all spectral points in a band. The BRDF is ρ = α/π, independent of viewing and illumination angles. Only the m = 0 Fourier moment is nonzero.
Supports analytical Jacobians with respect to albedo in linearized RT.
Fields
albedo::FT: hemispherical albedo ∈ [0, 1].
vSmartMOM.CoreRT.LambertianSurfaceSpectrum Type
LambertianSurfaceSpectrum{FT} <: AbstractSurfaceTypeIsotropic Lambertian surface with a per-spectral-point albedo vector. The vector length must match the number of spectral points in the band.
Fields
albedo::AbstractArray{FT,1}: spectral albedo vector, one value per grid point.
vSmartMOM.CoreRT.LambertianSurfaceLegendre Type
Defined by Legendre polynomial terms as function of spectral grid, which is scaled to [-1,1] (degree derived from length of a_coeff)
vSmartMOM.CoreRT.LambertianSurfaceSpline Type
Defined by a simple spline from Interpolations.jl
sourcevSmartMOM.CoreRT.rpvSurfaceScalar Type
rpvSurfaceScalar{FT} <: AbstractSurfaceTypeRahman-Pinty-Verstraete (1993) four-parameter empirical BRDF model. Combines a Minnaert angular shape, a Henyey-Greenstein-like hot-spot function, and a geometric bowl/bell correction. Scalar only (Stokes-I); no built-in linearization.
Fields
ρ₀: Overall reflectance level parameter (scalar)ρ_c: Hotspot function parameter (1.0 = no hotspot)k: Anisotropy shape parameter. k < 1.0 (> 1.0) corresponds to a bowl (bell) shape.Θ: Asymmetry parameter, Θ < 0.0 (> 0.0) corresponds to a predominantly backward (forward) scattering.
vSmartMOM.CoreRT.RossLiSurfaceScalar Type
RossLiSurfaceScalar{FT} <: AbstractSurfaceTypeRoss-Li kernel-based BRDF (Lucht, Schaaf & Strahler, 2000). Decomposes the surface reflectance into three semi-physical kernels: isotropic, RossThick (volumetric canopy scattering), and LiSparse (geometric mutual shadowing). Standard MODIS/RAMI parameterization. Scalar only (Stokes-I); no built-in linearization.
Fields
fvol: Volumetric RossThick fractionfgeo: Geometric LiSparse fractionfiso: Isotropic reflectance fraction
vSmartMOM.CoreRT.CoxMunkSurface Type
CoxMunkSurface{FT} <: AbstractSurfaceTypeCox-Munk (1954) ocean surface: Fresnel reflection from wind-roughened wave facets. Supports full polarization (Mueller matrix) and optional Lambertian whitecap contribution.
Isotropic slope distribution: σ² = 0.003 + 0.00512·U.
Fields
wind_speed: 10-m wind speed [m/s]n_water: Complex refractive index of water; nothing → built-in Segelstein 1981 lookupwhitecap_albedo: Whitecap Lambertian albedo (Koepke 1984)include_whitecaps: Include whitecap contributionshadowing: Include Smith (1967) shadow masking
vSmartMOM.CoreRT.CanopySurface Type
CanopySurface{FT} <: AbstractSurfaceTypeComposite lower boundary: a vegetation canopy (one or more scattering layers) backed by a soil BRDF. When used as the surface in rt_run, the canopy sub-layers are processed internally via the adding-doubling method before interacting with the soil, producing an effective canopy+soil reflectance.
Requires CanopyOptics.jl for leaf-angle distribution and scattering models.
vSmartMOM.CoreRT.CanopySurface_from_prospect Function
CanopySurface_from_prospect(leaf_prospect, prospect_grid; soil, LAI, kwargs...)Convenience constructor: compute spectral leaf R/T from PROSPECT and build a CanopySurface with the spectral leaf optics on the PROSPECT wavelength grid. If LAD is omitted, CanopySurface uses CanopyOptics.spherical_leaves().
Arguments
leaf_prospect: aCanopyOptics.LeafProspectProProperties(N, Ccab, Ccar, ...)prospect_grid: wavelength range in nm (default 400:1:2500)Remaining keyword arguments are forwarded to
CanopySurface(...).
Surface Construction and Optics Helpers
vSmartMOM.CoreRT.create_surface_layer! Function
create_surface_layer!(lambertian::LambertianSurfaceScalar{FT})Computes (in place) surface optical properties for a (scalar) lambertian albedo as AddedLayer
- `lambertian` a [`LambertianSurfaceScalar`](@ref) struct that defines albedo as scalar
- `SFI` bool if SFI is used
- `m` Fourier moment (starting at 0)
- `pol_type` Polarization type struct
- `quad_points` Quadrature points struct
- `τ_sum` total optical thickness from TOA to the surface
- `architecture` Compute architecture (GPU,CPU)create_surface_layer!(RS_type, lambertian, added_layer, added_layer_lin, iparam,
SFI, m, pol_type, quad_points, τ_sum, τ̇_sum, architecture)Compute surface reflection/transmission matrices and their derivatives for a scalar Lambertian surface.
Sets the added_layer forward matrices and added_layer_lin derivative matrices for the surface "layer", including the source function contribution from the solar beam attenuated through the full atmosphere.
Arguments
RS_type::noRS: No Raman scattering.lambertian::LambertianSurfaceScalar: Surface with scalar albedo. added_layer::AddedLayer: Output forward matrices (modified in-place).added_layer_lin::AddedLayerLin: Output linearized matrices (modified in-place).iparam::Int: Parameter index for the surface albedo derivative.SFI::Bool: Source Function Integration flag.m::Int: Fourier moment (only has nonzero surface contribution).pol_type: Polarization type.quad_points: Quadrature points and weights.τ_sum: Total optical depth from TOA to surface[nSpec].τ̇_sum: Derivative of total τ[nSpec × Nparams].architecture: CPU or GPU.
create_surface_layer!(lambertian::LambertianSurfaceScalar{FT})Computes (in place) surface optical properties for a (scalar) lambertian albedo as AddedLayer
- `lambertian` a [`LambertianSurfaceScalar`](@ref) struct that defines albedo as scalar
- `SFI` bool if SFI is used
- `m` Fourier moment (starting at 0)
- `pol_type` Polarization type struct
- `quad_points` Quadrature points struct
- `τ_sum` total optical thickness from TOA to the surface
- `architecture` Compute architecture (GPU,CPU)create_surface_layer!(canopy::CanopySurface, added_layer, SFI, m, pol_type,
quad_points, τ_sum, architecture;
spec_bands_wn=nothing, m_max=2)Compute the effective canopy+soil surface layer for Fourier moment m. m_max is the Fourier loop bound in order semantics.
When spectral leaf optics are provided, spec_bands_wn (the concatenated computation wavenumber grid) is required for initializing the spectral cache on first call.
Internally:
Compute Z-matrices from the cached analytic stack (or coarse-grid interpolation).
For each canopy sub-layer: build
CoreDirectionalScatteringOpticalProperties, runelemental!(canopy kernel) +doubling!.Accumulate sub-layers via
interaction!.Create soil surface layer and interact with the canopy composite.
Copy the resulting R⁻⁺ and J₀ into the output
added_layer.
TODO: Canopy + Raman (RRS/VS) coupling is not currently implemented. The
canopy BRDF code is noRS-only; calling rt_run with CanopySurface + RRS/VS
has undefined behavior (the inelastic ieR/ieT branches in the kernels
never see a canopy-adapted contribution and will return garbage or crash).
Future work: couple the canopy path to the inelastic path — this is a
separate project, not part of the sanghavi-unified merge.
sourcecreate_surface_layer!(RS_type, canopy::CanopySurface, added_layer, added_layer_lin,
iparam, SFI, m, pol_type, quad_points, τ_sum, τ̇_sum, F₀, architecture)Linearized surface dispatch for CanopySurface. Computes the forward canopy+soil reflectance (same as the non-linearized dispatch) and the derivative of the soil albedo parameter at iparam via finite differences.
Canopy-specific parameter derivatives (LAI, leaf R/T) are not yet implemented in the linearized path; their Jacobian slots should be populated via the hybrid AD boundary (ForwardDiff through canopy optical properties).
sourcecreate_surface_layer!(RS_type::noRS, surf::CoxMunkSurface, added_layer, added_layer_lin,
iparam, SFI, m, pol_type, quad_points, τ_sum, τ̇_sum, F₀, architecture)Compute forward + linearized surface reflection for a Cox-Munk surface.
The surface parameter is wind speed. The derivative ∂R_surf/∂U is computed analytically via the derivative chain through the slope PDF, shadow factor, and whitecap fraction — all sharing the wind-speed-independent Fresnel and geometry computations with the forward evaluation.
vSmartMOM.CoreRT.water_refractive_index Function
water_refractive_index(λ_nm)Complex refractive index of liquid water at wavelength λ_nm (in nanometers).
Uses the Segelstein (1981) tabulation with log-linear interpolation. Valid range: 200–2600 nm. Values outside are clamped to the boundary.
Returns
Complex{Float64}(n, k)where n is the real part and k the imaginary part.
vSmartMOM.CoreRT.fresnel_coefficients Function
fresnel_coefficients(n_rel, cos_θᵢ)Complex Fresnel amplitude reflection coefficients for s- and p-polarization.
Arguments
n_rel::Complex: relative refractive index (n_transmitted / n_incident)cos_θᵢ::Real: cosine of the incidence angle
Returns
(r_s, r_p): complex amplitude coefficients
vSmartMOM.CoreRT.fresnel_mueller Function
fresnel_mueller(r_s, r_p, n_stokes)Mueller matrix for Fresnel reflection given complex amplitude coefficients.
For n_stokes = 4 (IQUV):
M = [(|rs|²+|rp|²)/2 (|rs|²-|rp|²)/2 0 0 ]
[(|rs|²-|rp|²)/2 (|rs|²+|rp|²)/2 0 0 ]
[0 0 Re(rs·rp*) Im(rs·rp*) ]
[0 0 -Im(rs·rp*) Re(rs·rp*) ]vSmartMOM.CoreRT.stokes_rotation_matrix Function
stokes_rotation_matrix(φ, n_stokes)Rotation matrix L(φ) for the Stokes reference plane.
Rotates the Stokes vector reference plane by angle φ (radians). Convention matches vSmartMOM's D = [1, 1, -1, -1]:
L = [1 0 0 0]
[0 cos2φ sin2φ 0]
[0 -sin2φ cos2φ 0]
[0 0 0 1]