Skip to content

L2A — Ground Elevation & Canopy Height

Version 2 — User Guide · ATBD

Overview

GEDI L2A provides ground elevation, canopy height metrics, and relative height (RH) metrics for each GEDI footprint. Data is organized by 8 beams.

Quick Start

using SpaceLiDAR, DataFrames

g = granule("GEDI02_A_2019242104318_O04046_01_T02343_02_003_02_V002.h5")
t = table(g)
df = DataFrame(t)

Default Columns

Column HDF5 Path Type
longitude lon_lowestmode Float64
latitude lat_lowestmode Float64
height elev_lowestmode Float32
height_error elevation_bin0_error Float32
datetime delta_time DateTime
intensity energy_total Float32
sensitivity sensitivity Float32
surface surface_flag Bool
quality quality_flag Bool
nmodes num_detectedmodes UInt8
sun_angle solar_elevation Float32
height_reference digital_elevation_model Float32
strong_beam attribute

Default Tracks

SpaceLiDAR.default_tracks(g)
("BEAM0000", "BEAM0001", "BEAM0010", "BEAM0011", "BEAM0101", "BEAM0110", "BEAM1000", "BEAM1011")

Canopy Heights

Use gedi_l2a_canopy_variables() to read highest return instead of lowest mode:

t = table(g; variables=gedi_l2a_canopy_variables())

This reads elev_highestreturn / lon_highestreturn / lat_highestreturn.

Quality Filtering

df = DataFrame(t)

# Basic quality (matches quality_flag):
filter!(:quality => identity, df)

# L3-style filtering:
filter!(row -> row.quality && row.surface, df)
# For sensitivity filtering (optional):
filter!(row -> 0.9 < row.sensitivity <= 1.0, df)

For the full L3 filter (including algorithm-based zcross/toploc checks), you would need to read additional variables:

vars = [SpaceLiDAR.default_variables(g)...,
    Variable(:selected_algorithm, "selected_algorithm", UInt8),
    Variable(:rx_assess_quality_flag, "rx_assess/quality_flag", UInt8),
    Variable(:degrade_flag, "degrade_flag", UInt8),
    Variable(:stale_return_flag, "geolocation/stale_return_flag", UInt8),
    Variable(:rx_maxamp, "rx_assess/rx_maxamp", Float32),
    Variable(:sd_corrected, "rx_assess/sd_corrected", Float32),
]
t = table(g; variables=vars)
df = DataFrame(t)

# Apply L3 criteria:
filter!(df) do row
    row.rx_assess_quality_flag != 0 &&
    row.surface &&
    row.stale_return_flag == 0 &&
    row.degrade_flag == 0 &&
    row.rx_maxamp / row.sd_corrected >= 8
end