Skip to content

Corrections

Module: spectralbridge.corrections.

BRDF and topographic correction helpers.

Portions of this module are adapted from HyTools. The incidence-angle, Ross/Li kernel, and BRDF fitting/application lineage is detailed in HYTOOLS_PROVENANCE.md. The SCS+C implementation follows the published method of Soenen et al. (2005), DOI 10.1109/TGRS.2005.852480; it is classified separately from the adapted incidence helper.

HyTools: Hyperspectral image processing library Copyright (C) 2021 University of Wisconsin Authors named in the relevant source notices: Adam Chlus, Zhiwei Ye, Philip Townsend. License: GNU General Public License, version 3 Upstream: https://github.com/EnSpec/hytools Audited revision: 31286d64541791a9815d29443a33726fa4d54031

Modified and extended for SpectralBridge. See LICENSE, NOTICE, and HYTOOLS_PROVENANCE.md. The Ross/Li kernel equations are described by Wanner et al. (1995), DOI 10.1029/95JD02371, and Lucht et al. (2000), DOI 10.1109/36.841980.

API glossary ยท Workflow / scientific context

Signatures and documentation below are collected from the current source. Advanced objects are not newly declared stable by inclusion here.

Audience: advanced.

NDVIBinningConfig dataclass

NDVIBinningConfig(enabled: bool = False, ndvi_min: float = 0.05, ndvi_max: float = 1.0, n_bins: int = 25, perc_min: float | None = 10.0, perc_max: float | None = 95.0)

Configuration for NDVI binning used during BRDF fitting and application.

Audience: advanced.

ReferenceGeometry dataclass

ReferenceGeometry(solar_zenith_deg: float = 45.0, view_zenith_deg: float = 0.0, relative_azimuth_deg: float = 0.0)

Reference geometry (degrees) for BRDF normalization.

Audience: advanced.

BRDFKernelConfig dataclass

BRDFKernelConfig(volume_kernel: str = 'RossThick', geom_kernel: str = 'LiSparseReciprocal', b_r: float = 1.0, h_b: float = 2.0, solar_zn_type: str = 'pixel')

Kernel and geometry settings for BRDF fitting/application.

Defaults preserve the streamlined implementation's historical behaviour. Pipelines that want closer HyTools-style kernel parity should pass an explicit config.

Audience: advanced.

log_stats

log_stats(name: str, arr: ndarray, mask: ndarray | None = None) -> None

Log min/max and validity fractions for quick debugging.

Audience: advanced.

load_brdf_model

load_brdf_model(flightline_dir: Path) -> dict

Load the BRDF model JSON for flightline_dir after normalizing its name.

Audience: advanced.

compute_ndvi

compute_ndvi(cube: 'NeonCube', data_unitless: ndarray, red_target_nm: float = 665.0, nir_target_nm: float = 865.0) -> np.ndarray

Compute NDVI from unitless reflectance data.

Audience: advanced.

compute_ndvi_bins

compute_ndvi_bins(ndvi: ndarray, config: NDVIBinningConfig) -> tuple[np.ndarray, np.ndarray]

Return NDVI bin edges and bin indices.

The returned edges are the realized NDVI bin boundaries after applying the configured clipping rules. They are written to the BRDF model JSON as ndvi_edges so each coefficient row can be traced back to the NDVI stratum it was fit from. This is BRDF model metadata, not a standalone NDVI science product.

Audience: advanced.

calc_cosine_i

calc_cosine_i(solar_zn: ndarray, solar_az: ndarray, aspect: ndarray, slope: ndarray) -> np.ndarray

Adapted from hytools.topo.calc_cosine_i (GPLv3; HyTools Authors: Adam Chlus, Zhiwei Ye, Philip Townsend). Simplified for NEON use.

Compute the cosine of the solar incidence angle on a sloped surface.

Parameters:

Name Type Description Default
solar_zn ndarray

Solar zenith angle [radians], shape (Y,X)

required
solar_az ndarray

Solar azimuth angle [radians], shape (Y,X)

required
aspect ndarray

Surface aspect [radians], shape (Y,X) Aspect is typically clockwise from North.

required
slope ndarray

Surface slope [radians], shape (Y,X)

required

Returns:

Type Description
ndarray

cos(i), shape (Y,X), float32

Notes

HyTools uses this quantity in topographic correction. This is basically: cos_i = cos(solar_zn)cos(slope) + sin(solar_zn)sin(slope)*cos(solar_az - aspect)

Audience: advanced.

calc_volume_kernel

calc_volume_kernel(solar_az: ndarray, solar_zn: ndarray, sensor_az: ndarray, sensor_zn: ndarray, kernel_type: str) -> np.ndarray

Adapted from hytools.brdf.kernels.calc_volume_kernel (GPLv3; HyTools Authors: Adam Chlus, Zhiwei Ye, Philip Townsend). Simplified for NEON use.

Compute the BRDF volume scattering kernel for each pixel.

Audience: advanced.

calc_geom_kernel

calc_geom_kernel(solar_az: ndarray, solar_zn: ndarray, sensor_az: ndarray, sensor_zn: ndarray, kernel_type: str, b_r: float = 1.0, h_b: float = 2.0) -> np.ndarray

Adapted from hytools.brdf.kernels.calc_geom_kernel (GPLv3; HyTools Authors: Adam Chlus, Zhiwei Ye, Philip Townsend). Simplified for NEON use.

Compute the BRDF geometric scattering kernel for each pixel.

Audience: advanced.

fit_scs_c_coefficients

fit_scs_c_coefficients(cube, *, chunk_y: int = 500, chunk_x: int | None = None) -> np.ndarray

Fit per-band SCS+C C parameters over a full NeonCube footprint.

Implements the method of Soenen et al. (2005), DOI 10.1109/TGRS.2005.852480. The audit found no material source match between this fitting/application code and HyTools' SCS+C implementation.

Streams reflectance tiles and accumulates ordinary-least-squares sufficient statistics so scene-wide topographic fits do not require holding a second full corrected cube in memory.

Audience: advanced.

apply_topo_correct

apply_topo_correct(cube, chunk_array: ndarray, ys: int, ye: int, xs: int, xe: int, use_scs_c: bool = True, scs_c: ndarray | None = None) -> np.ndarray

Topographic (illumination) correction on a hyperspectral chunk.

The SCS+C branch implements Soenen et al. (2005), DOI 10.1109/TGRS.2005.852480. calc_cosine_i, used here, has separately documented HyTools implementation lineage.

Parameters:

Name Type Description Default
scs_c ndarray | None

Optional per-band SCS+C C values (length bands). When provided, the tile uses these coefficients instead of fitting locally. Pass scene fits from :func:fit_scs_c_coefficients for HyTools-style behaviour without loading the full flightline as one correction chunk.

None

Audience: advanced.

apply_brdf_correct

apply_brdf_correct(cube: 'NeonCube', chunk_array: ndarray, ys: int, ye: int, xs: int, xe: int, coeff_path: Path | None = None, ndvi_config: NDVIBinningConfig | None = None, reference_geometry: ReferenceGeometry | None = None, brdf_kernel_config: BRDFKernelConfig | None = None) -> np.ndarray

Perform BRDF normalization on a hyperspectral chunk using FlexBRDF ratio.

Audience: advanced.

apply_glint_correct

apply_glint_correct(*args, **kwargs)

Placeholder for sunglint correction.

In hytools.glint.apply_glint_correct (GPLv3), sunglint correction is used for aquatic environments. We are not supporting that right now.

Audience: advanced.

fit_and_save_brdf_model

fit_and_save_brdf_model(cube: 'NeonCube', out_dir: Path, ndvi_config: NDVIBinningConfig | None = None, brdf_kernel_config: BRDFKernelConfig | None = None, rho_min: float = 0.0, rho_max: float | None = 2.0) -> Path

Estimate and persist BRDF coefficients for a NEON flightline.

Parameters:

Name Type Description Default
cube NeonCube

Loaded NEON hyperspectral cube providing reflectance and ancillary angles.

required
out_dir Path

Directory where the fitted BRDF coefficient JSON should be stored.

required

Returns:

Type Description
Path

Path to the JSON file containing the BRDF model coefficients.