Skip to content

Surfaces API

Surface models are implemented in CoreRT because they form the lower boundary of the adding-doubling column.

Surface Types

vSmartMOM.CoreRT.AbstractSurfaceType Type

Abstract Type for Surface Types

source
vSmartMOM.CoreRT.LambertianSurfaceScalar Type
julia
LambertianSurfaceScalar{FT} <: AbstractSurfaceType

Isotropic 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].
source
vSmartMOM.CoreRT.LambertianSurfaceSpectrum Type
julia
LambertianSurfaceSpectrum{FT} <: AbstractSurfaceType

Isotropic 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.
source
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)

source
vSmartMOM.CoreRT.LambertianSurfaceSpline Type

Defined by a simple spline from Interpolations.jl

source
vSmartMOM.CoreRT.rpvSurfaceScalar Type
julia
rpvSurfaceScalar{FT} <: AbstractSurfaceType

Rahman-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.

source
vSmartMOM.CoreRT.RossLiSurfaceScalar Type
julia
RossLiSurfaceScalar{FT} <: AbstractSurfaceType

Ross-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 fraction

  • fgeo: Geometric LiSparse fraction

  • fiso: Isotropic reflectance fraction

source
vSmartMOM.CoreRT.CoxMunkSurface Type
julia
CoxMunkSurface{FT} <: AbstractSurfaceType

Cox-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 lookup

  • whitecap_albedo: Whitecap Lambertian albedo (Koepke 1984)

  • include_whitecaps: Include whitecap contribution

  • shadowing: Include Smith (1967) shadow masking

source
vSmartMOM.CoreRT.CanopySurface Type
julia
CanopySurface{FT} <: AbstractSurfaceType

Composite 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.

source
vSmartMOM.CoreRT.CanopySurface_from_prospect Function
julia
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: a CanopyOptics.LeafProspectProProperties (N, Ccab, Ccar, ...)

  • prospect_grid: wavelength range in nm (default 400:1:2500)

  • Remaining keyword arguments are forwarded to CanopySurface(...).

source

Surface Construction and Optics Helpers

vSmartMOM.CoreRT.create_surface_layer! Function
julia
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)
source
julia
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.

source
julia
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)
source
julia
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:

  1. Compute Z-matrices from the cached analytic stack (or coarse-grid interpolation).

  2. For each canopy sub-layer: build CoreDirectionalScatteringOpticalProperties, run elemental! (canopy kernel) + doubling!.

  3. Accumulate sub-layers via interaction!.

  4. Create soil surface layer and interact with the canopy composite.

  5. 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.

source
julia
create_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).

source
julia
create_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.

source
vSmartMOM.CoreRT.water_refractive_index Function
julia
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.
source
vSmartMOM.CoreRT.fresnel_coefficients Function
julia
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
source
vSmartMOM.CoreRT.fresnel_mueller Function
julia
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*)  ]
source
vSmartMOM.CoreRT.stokes_rotation_matrix Function
julia
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]
source