canvod-vod¶
Purpose¶
The canvod-vod package implements vegetation optical depth (VOD) estimation from GNSS signal-to-noise ratio (SNR) data. It provides the core scientific algorithms for the canVODpy analysis pipeline.
Physical Background¶
Tau-Omega Radiative Transfer Model
canvod-vod implements the zeroth-order tau-omega model for GNSS-Transmissometry, following Humphrey & Frankenberg (2022).
A reference receiver in open sky and a canopy receiver beneath vegetation observe the same satellite at polar angle θ. The SNR difference encodes the two-way canopy attenuation:
Assumptions: - Single-scattering approximation (no multiple canopy reflections) - Plane-parallel canopy layer - Attenuation proportional to path length through canopy
Usage¶
from canvod.vod import TauOmegaZerothOrder
calculator = TauOmegaZerothOrder(canopy_ds=canopy_ds, sky_ds=sky_ds)
vod_result = calculator.calculate_vod()
from canvod.vod import TauOmegaZerothOrder
vod_result = TauOmegaZerothOrder.from_datasets(
canopy_ds=canopy_ds,
sky_ds=sky_ds,
align=True, # auto-align epochs before differencing
)
from canvod.vod import TauOmegaZerothOrder
vod_result = TauOmegaZerothOrder.from_icechunkstore(
icechunk_store_pth="path/to/store",
canopy_group="canopy_01",
sky_group="reference_01",
)
Input requirements
Both datasets must contain an SNR data variable.
Both should be augmented with spherical coordinates (θ, φ) from canvod-auxiliary
and assigned to grid cells by canvod-grids.
Output¶
calculate_vod() returns an xr.Dataset containing:
| Variable | Description |
|---|---|
VOD |
Vegetation optical depth |
phi |
Azimuth angles (from canopy dataset) |
theta |
Polar angles (from canopy dataset) |
Multi-Receiver SCS Expansion¶
When a single reference receiver serves multiple canopy positions, satellite geometry must be recomputed relative to each canopy location. The scs_from configuration in sites.yaml drives this expansion.
flowchart TD
subgraph FIELD["Field Setup"]
C1["`**Canopy 1**
NE position`"]
C2["`**Canopy 2**
SW position`"]
R1["`**Reference**
open sky`"]
end
subgraph STORE["RINEX Store Groups"]
SG1["canopy_01"]
SG2["canopy_02"]
SG3["`**reference_01_canopy_01**
geometry at canopy_01 pos.`"]
SG4["`**reference_01_canopy_02**
geometry at canopy_02 pos.`"]
end
subgraph VOD["VOD Analysis Pairs"]
VP1["canopy_01 vs reference_01_canopy_01"]
VP2["canopy_02 vs reference_01_canopy_02"]
end
C1 --> SG1
C2 --> SG2
R1 --> SG3
R1 --> SG4
SG1 --> VP1
SG3 --> VP1
SG2 --> VP2
SG4 --> VP2
VP1 --> V1["VOD @ canopy_01"]
VP2 --> V2["VOD @ canopy_02"]
Configuration
# config/sites.yaml
receivers:
reference_01:
type: reference
scs_from:
- canopy_01 # recompute geometry at canopy_01 position
- canopy_02 # recompute geometry at canopy_02 position
References¶
Humphrey, V. and Frankenberg, C. (2022). GNSS-transmissometry: A new approach for vegetation optical depth estimation. Remote Sensing of Environment.