# GEDI L3 Tutorial¶

## GEDI Instrument¶

GEDI produces the first high resolution layer ranging observations of 3D structure of earth with precise measurements of forest canopy height, canopy vertical structure and surface elevation. GEDI is attached to the International Space Station (ISS) and collects data globally between 51.6° N and 51.6° S latitudes at the highest resolution and densest sampling of any light detection and ranging (lidar) instrument in orbit to date.

GEDI L3 data products are gridded by spatially interpolating Level 2 footprint estimates of canopy cover, canopy height, Leaf Area Index (LAI), vertical foliage profile and their uncertainties. Level 2 data contains terrain elevation, canopy height, RH metrics and Leaf Area Index (LAI). The raw waveforms are collected by GEDI system and processed to provide canopy height and profile metrics. These metrics provide easy to use and interpret information about the vertical distribution of canopy material.

Figure: Sample of GEDI lidar waveform (Left). The light brown area under the curve represents the return energy from the canopy, while the dark brown area signifies the return from the underlying typography. The black line is cumulative return energey, starting from the bottom of the ground return (normalized to 0) to the top of canopy (normalized to 1). The diagram on the right shows the distribution of trees that produced the waveform.

## [Optional] Install Python Packages¶

This tutorial assumes you’ve all packages installed. If you haven’t already, uncomment the following lines to install these packages.

[1]:

# !pip install geopandas
# !pip install contextily
# !pip install backoff
# !pip install folium
# !pip install geojsoncontour

[5]:

from maap.maap import MAAP
import pandas as pd
import folium
from rasterio.plot import show
import rasterio
import boto3
import os


After importing necessary packages, the next step is to initialize MAAP constructor using api.ops.maap-project.org as maap_host argument.

[6]:

maap = MAAP(maap_host="api.ops.maap-project.org")


## Dataset¶

GEDI L3 Gridded Land Surface Metrics, Version 2

This dataset provides Global Ecosystem Dynamics Investigation (GEDI) Level 3 (L3) gridded mean canopy height, standard deviation of canopy height, mean ground elevation, standard deviation of ground elevation, and counts of laser footprints per 1-km x 1-km grid cells globally within -52 and 52 degrees latitude.

Now, the next step is to seach granules from MAAP CMR. To generate following query, you can use EarthData search feature from MAAP ADE. Refer to this tutorial for more info.

[7]:

# generated from this EDSC search: https://ade.ops.maap-project.org:30052/search?p=!C1201702030-NASA_MAAP&pg[1][v]=t&pg[1][qt]=2015-01-01T00%3A00%3A00.000Z%2C2020-12-31T23%3A59%3A59.999Z&q=L3%20GEDI
results=maap.searchGranule(cmr_host='cmr.maap-project.org',concept_id="C1201702030-NASA_MAAP", limit=1000)


The above query gives 1000 results by default. The number of necessary results can be changed using limit argument. We can view the GranuleUR from results using:

[8]:

[result['Granule']['GranuleUR'] for result in results]

[8]:

['GEDI_L3_LandSurface_Metrics_V2.GEDI03_elev_lowestmode_stddev_2019108_2020287_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_counts_2019108_2021104_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_elev_lowestmode_stddev_2019108_2021104_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_elev_lowestmode_mean_2019108_2020287_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_elev_lowestmode_mean_2019108_2021104_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_rh100_stddev_2019108_2021104_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_counts_2019108_2020287_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_rh100_mean_2019108_2021104_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_rh100_mean_2019108_2020287_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_rh100_stddev_2019108_2020287_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_counts_2019108_2021216_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_rh100_mean_2019108_2021216_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_elev_lowestmode_stddev_2019108_2021216_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_elev_lowestmode_mean_2019108_2021216_002_02.tif',
'GEDI_L3_LandSurface_Metrics_V2.GEDI03_rh100_stddev_2019108_2021216_002_02.tif']


Before downloading a particular tif, let’s catch the collection and file name for first item in results:

[9]:

granule_ur=results[0]['Granule']['GranuleUR'].split(".")
collection_name=granule_ur[0]
file_name=granule_ur[1]

[10]:

print(f"collection name: {collection_name} | file_name: {file_name}")

collection name: GEDI_L3_LandSurface_Metrics_V2 | file_name: GEDI03_elev_lowestmode_stddev_2019108_2020287_002_02


To download the file from the source, temporary s3 credentials are required for maap package. You can explicitly request s3_cred_endpoint for the credentials. The code below wraps that request to get credentials and download the file to your workspace.

[14]:

def get_s3_creds(url):
return maap.aws.earthdata_s3_credentials(url)

def get_s3_client(s3_cred_endpoint):
creds=get_s3_creds(s3_cred_endpoint)
boto3_session = boto3.Session(
aws_access_key_id=creds['accessKeyId'],
aws_secret_access_key=creds['secretAccessKey'],
aws_session_token=creds['sessionToken']
)
return boto3_session.client("s3")

os.makedirs("/projects/gedi_l3", exist_ok=True) # create directories, as necessary

[15]:

s3_cred_endpoint= 'https://data.ornldaac.earthdata.nasa.gov/s3credentials'
s3=get_s3_client(s3_cred_endpoint)

[16]:

bucket="ornl-cumulus-prod-protected"

[16]:

'/projects/gedi_l3/GEDI03_elev_lowestmode_stddev_2019108_2020287_002_02.tif'


Now, we have the file in our local workspace. It’s time to visualize it using rasterio package

## [Optional] Visualization using Rasterio¶

The downloaded file is too big to read and visualize directly so we might need to scale it down and view it as a small thumbnail.

[2]:

def show_thumbnail(path):
src=rasterio.open(path)
oview = src.overviews(1)[0]
thumbnail = src.read(1, out_shape=(1, int(src.height // oview), int(src.width // oview)))
show(thumbnail)

[ ]:

show_thumbnail(download_path)


## [Optional] Overlay raster layer on top of folium map¶

To properly visualize the canopy heights, we need to display the TIF image on the map. The TIF image file may be too memory and compute-intensive for the kernel causing the process to exit.

[31]:

# tif=rasterio.open(download_path)

[32]:

# x1,y1,x2,y2=bounds