CLI Reference#
gedih3 installs 10 command-line tools. All tools support -v (INFO) and -vv (DEBUG) verbosity, and -Q for quiet mode.
Tip: Every tool supports
--help(-h) for a complete list of flags and examples:gh3_build --help gh3_aggregate --help gh3_extract --help
Core Workflow Tools#
gh3_download#
Download GEDI data from NASA DAAC.
gh3_download -r "W,S,E,N" -l2a default -l4a default -N 8
gh3_download -r region.shp -l4a agbd -t0 2020-01-01 -t1 2021-01-01
gh3_download --s3 # Stream from NASA S3 without local download
Flag |
Description |
|---|---|
|
Spatial filter: bbox, vector file, or ISO3 code |
|
Start/end date (YYYY-MM-DD) |
|
Products to download ( |
|
GEDI data version (default: latest) |
|
S3 streaming mode |
gh3_build#
Build H3 parquet database from downloaded HDF5 files.
gh3_build -r "W,S,E,N" -l2a default -l4a default -h3r 12 -h3p 3
gh3_build -r region.shp -l4a agbd --resume
gh3_build --s3 -r region.shp -l4a agbd # Build directly from S3
Flag |
Description |
|---|---|
|
H3 index resolution (default: 12, ~25 m²) |
|
H3 partition resolution (default: 3, ~12,393 km²) |
|
Input directory where GEDI HDF5 files are stored (default: |
|
Output H3 database directory |
|
Skip the automatic |
gh3_extract#
Extract data from H3 database into simplified flat parquet files.
gh3_extract -d /path/to/database -r region.shp -l2a rh_098 -l4a agbd -y -o output/
Flag |
Description |
|---|---|
|
H3 database path |
|
Spatial filter |
|
Temporal filter |
|
Product variables |
|
Apply pre-configured quality filters |
|
Pandas-style filter string |
|
Include geometry |
|
Output directory |
EGI variant#
For square-pixel indexing instead of H3 — see EGI Indexing.
gh3_extract -d /path/to/database -egi 6 -o output/ # ~1 km EGI index
gh3_extract -d /path/to/database -egi 6:10 -o output/ # explicit index:partition
Flag |
Description |
|---|---|
|
EGI index level and optional partition level |
gh3_aggregate#
Aggregate data to a coarser spatial resolution.
gh3_aggregate -d /path/to/database -h3 6 -o output/
gh3_aggregate -d /path/to/database -h3 6 -a "['mean','std','count']" -o output/
Flag |
Description |
|---|---|
|
Aggregate to H3 level |
|
Aggregation function: |
|
Export as rasters after aggregation |
|
Output directory |
EGI variant#
gh3_aggregate -d /path/to/database -egi 6 -a mean -o output/ # ~1 km
gh3_aggregate -d /path/to/database -egi 6:10 -a mean -o output/ # explicit partition
gh3_aggregate -d /path/to/database -egi 6 -a mean -R -o output/ # aggregate + rasterize
Flag |
Description |
|---|---|
|
EGI aggregation level and optional partition level |
gh3_rasterize#
Convert pre-aggregated dataset to GeoTIFF rasters.
gh3_rasterize -d /path/to/aggregated/ -o output/ --compress LZW # tiled output
gh3_rasterize -d /path/to/aggregated/ -m -o output.tif # merged GeoTIFF
gh3_rasterize -d /path/to/aggregated/ -l agbd_l4a -o output/ # select variables
Flag |
Description |
|---|---|
|
Dataset from |
|
Variable(s) to rasterize |
|
Merge all tiles into a single GeoTIFF |
|
Compression: |
|
Output path (directory or |
Ancillary Data Tools#
gh3_from_img#
Sample raster pixel values at GEDI shot locations.
# Single raster
gh3_from_img -i /path/to/dem.tif -d /path/to/database -r region.shp -o output/
# Tile directory with band selection and window operations
gh3_from_img -i /path/to/tiles/ -B 0 2 -w 131 -d /path/to/database -o output/
# Custom band names, quality filter, include geometry
gh3_from_img -i /path/to/raster.vrt -b elevation slope -d /path/to/database -y -g -o output/
Flag |
Description |
|---|---|
|
Raster file (tif), VRT, or tile directory |
|
Band indices to sample (0-based) |
|
Custom band names |
|
Window operations (3-digit BZO format) |
|
Fill NoData value |
|
Include geometry in output |
Window spec format (-w BZO):
B= band index (0-based)Z= window size (odd, 1–9)O= operation:0=sum,1=mean,2=median,3=mode
gh3_from_polygon#
Join polygon attributes to GEDI shots via spatial join.
gh3_from_polygon -i ecoregions.shp -c ECO_NAME BIOME_NAME -d /path/to/database -o output/
gh3_from_polygon -i landcover.gpkg -x lc_ --dropna -d /path/to/database -o output/
gh3_from_polygon -i boundaries.shp -p intersects -d /path/to/database -o output/
Flag |
Description |
|---|---|
|
Polygon vector file (shapefile, GPKG, GeoJSON) |
|
Columns to include from polygon file |
|
Column name prefix (avoids conflicts) |
|
Spatial predicate: |
|
Drop shots not matched to any polygon |
|
Include geometry in output |
Utility Tools#
gh3_list_resolutions#
Display H3 and EGI resolution levels with pixel sizes.
gh3_list_resolutions # H3 levels
gh3_list_resolutions -egi # EGI levels
gh3_read_schema#
Inspect file or database schemas. Lists column names and types from parquet, feather, geopackage, HDF5 files, or H3 databases. When no path is given, reads from the default H3 database.
gh3_read_schema # default H3 database
gh3_read_schema /path/to/database/ # specific H3 database
gh3_read_schema /path/to/file.parquet # single file
gh3_read_schema /path/to/file.h5 # HDF5 file
gh3_read_schema -p L2A # filter by product
gh3_read_schema --grep agbd # grep filter
Flag |
Description |
|---|---|
|
File or directory to inspect (default: H3 database) |
|
Filter by product suffix (e.g., |
|
Filter columns by keyword (case-insensitive) |
|
HDF5 group/beam filter (e.g., |
gh3_bbox_index#
Build the _bbox_index.parquet root sidecar for an H3 database: one row per
partition year-file with the true data envelope, derived from existing parquet
row-group statistics. A footer-only scan — no data is read — so it takes
minutes even on a continental database. Once present, gh3_extract,
gh3_aggregate and every other query tool skip partition files a region or
EGI tile provably cannot touch, instead of reading and discarding them.
gh3_bbox_index # default H3 database
gh3_bbox_index -d /path/to/db -N 16 # explicit database, 16 dask workers
Flag |
Description |
|---|---|
|
H3 database directory (must be local — the index is written at the root) |
Also accepts the standard dask (-N, -T, -M, -P) and verbosity flags.
gh3_build creates or refreshes the index automatically after every
successful build (skip with --no-bbox-index), so this tool is needed for:
retrofitting databases built before the index existed, restoring it after a
gh3_doctor --fix remedy, or opting back in after a --no-bbox-index build.
Safe to re-run at any time, and self-guarding: a stale index could silently
under-select, a missing one only costs speed, so staleness is impossible by
construction — gh3_build deletes the index at merge entry (before the
first partition write, so even a killed build cannot leave one behind),
gh3_doctor --fix drops it after any applied remedy, and query tools ignore
any index older than the build log.
gh3_doctor#
Audit an H3 database or SOC tree for health problems, and optionally apply safe
remedies. Read-only by default: --fix never deletes or rewrites corrupt data,
it only applies remedies that cannot lose information. Corrupt files are always
reported rather than repaired.
gh3_doctor -i /path/to/db # audit with the default `db` group
gh3_doctor -i /db --check backfill,parquet_health
gh3_doctor -i /db --check all # every registered diagnosis
gh3_doctor -i /db --fix # apply safe remedies
gh3_doctor -i /db --fix backfill --s3 # backfill via NASA S3 streaming
gh3_doctor -i /db --online # add upstream availability + recovery commands
gh3_doctor -i /db --report report.json # machine-readable output
--check and --fix accept a diagnosis name, a comma-separated list, or a
group alias:
Alias |
Runs |
|---|---|
|
the default: |
|
|
|
every registered diagnosis |
Note
soc_health and tmp_partitions_health are not in the db group, so a
plain gh3_doctor -i /db does not run them. Ask for them by name, or use all.
Diagnosis |
Checks for |
|---|---|
|
NaN gaps in product columns |
|
leftover |
|
stuck build flags, and drift between the log and what is on disk |
|
partition JSON sidecars and the manifest |
|
corrupt files, duplicate shots, schema drift |
|
GeoParquet bbox metadata coverage |
|
invalid HDF5 files, and download-log drift |
|
post-build forensics on |
--online decorates the report with NASA upstream availability and emits
concrete gh3_download / gh3_build commands to recover what is missing.
Exit codes: 0 clean, 1 findings remain, 2 errors occurred during a
fix. tmp_partitions_health --fix refuses to act while a gh3_build is live.
gh3_update#
Add columns to an existing dataset in place, without re-extracting it. Shots are
matched by shot_number against what is already stored, so the spatial index is
never recomputed and the dataset’s partitioning is untouched.
# Pull additional GEDI variables from a source H3 database
gh3_update -d existing_dataset/ -D /path/to/h3_database -l4a agbd_se
# Merge columns from another simplified dataset
gh3_update -d existing_dataset/ -m other_dataset/
Flag |
Description |
|---|---|
|
dataset to update (required; modified in place) |
|
source H3 database to pull new variables from |
|
variables to add, per product |
|
variable list, as for |
|
another simplified dataset to merge columns from |
Also accepts the standard dask, verbosity, and remote-storage flags.
Adding variables to a full H3 database reads each source granule once and fans its shots out to every partition that contains them, so cost scales with the number of granules rather than with the number of partitions.
gh3_build_ducklake#
Build a DuckLake metadata table over an existing H3 parquet database, so it can be queried with SQL through DuckDB alongside the Python and CLI paths.
gh3_build_ducklake # default H3 database
gh3_build_ducklake -d /path/to/db
Flag |
Description |
|---|---|
|
H3 database directory (default: |
|
temporary directory for DuckLake data files |
Note
The duckdb version bound in pyproject.toml is deliberately narrow — the
DuckLake catalog format is version-locked, and a catalog built under one
version may not open under another.
Common Flags#
Flag |
Description |
|---|---|
|
Spatial filter: vector file, bbox |
|
Temporal filters (YYYY-MM-DD) |
|
Product variables (supports wildcards, e.g. |
|
Dask workers, threads, memory, dashboard port |
|
Connect to existing Dask scheduler |
|
Verbosity: INFO, DEBUG |
|
Quiet mode (errors only) |
|
EGI indexing |
|
Rasterize after aggregation ( |
Remote Storage Credentials#
All tools that accept a database path (-d) can read from remote filesystems. Pass the appropriate credential flags alongside the remote URI:
Flag |
Description |
|---|---|
|
S3 endpoint URL (e.g. |
|
S3 access key |
|
S3 secret key |
|
AWS profile name; forces the botocore credential chain (use for EC2/ECS instance roles) |
|
Anonymous S3 access (for public buckets) |
|
Username for HTTP basic auth / FTP / SFTP |
|
Password for HTTP basic auth / FTP / SFTP |
|
Bearer token for HTTP(S) auth |
|
Path to SSH/SFTP private key file |
Note
Supported protocols: s3://, http://, https://, ftp://, sftp:// (or ssh://). Credentials are passed through to fsspec — any option that fsspec accepts for a given protocol will work.
# Public S3 bucket (anonymous)
gh3_extract -d s3://my-bucket/h3_database/ --s3-anon -r region.shp -o output/
# SFTP with SSH key
gh3_aggregate -d sftp://server.example.com/data/h3/ --ssh-key ~/.ssh/id_rsa -egi 6 -o output/
Self-hosted S3 (MinIO, rclone serve s3, Ceph)#
Name the server in the URL instead of repeating it in --s3-endpoint — a bucket
name cannot contain :, so a netloc with an explicit port is unambiguously a
host. Port 443 implies https, anything else http:
# These two are equivalent
gh3_aggregate -d s3://localhost:8855/my_dataset -egi 6 -o output/
gh3_aggregate -d s3://my_dataset --s3-endpoint http://localhost:8855 -egi 6 -o output/
Access defaults to anonymous when you pass no credentials and the
standard AWS credential sources (env vars, ~/.aws/credentials) are empty —
so an unauthenticated server just works. When ambient AWS credentials exist
they are used as usual; pass --s3-anon to force anonymous access anyway, or
--s3-profile to force a specific profile (also the escape hatch for EC2/ECS
instance roles, which cannot be auto-detected). An unauthenticated S3 server
can equally be read over plain HTTP (-d http://localhost:8855/my_dataset) —
S3 GetObject is an ordinary HTTP GET, gedih3 avoids LIST on every
read path that has a _manifest.txt / root sidecar, and the HTTP backend
skips the botocore client bootstrap entirely.
Remote parquet reads transfer only the column chunks the query projects: the
fsspec read-ahead cache is disabled and pyarrow coalesces its own ranges. On a
1.8 GB partition, projecting one column moves 18 MB. Dropping geometry from a
selection matters more than any transport setting — it is 18% of a GEDI
partition against 1% for a single rh column.
Warning
rclone serve s3 answers a bucket-level ListObjectsV2 by
walking the whole tree — minutes, or worse, on a dataset with tens of thousands
of partitions. gedih3 avoids listing on every read path, but any other S3 client
you point at such a server will stall.