Drought indicators — usage#
This page shows the three live transports in action.
Pick a dataset#
The catalog is sharded under src/earthlens/drought/catalog/ —
usdm.yaml, edo.yaml, gdo.yaml, speibase.yaml — plus an
_index.yaml carrying every curated dataset id. Inspect from Python:
from earthlens.drought import Catalog
cat = Catalog()
sorted(cat.datasets)[:5]
# ['edo-cdiad', 'edo-cdinx', 'edo-cdirc', 'edo-fpanv', 'edo-lfinx-lgs']
row = cat.get("usdm")
row.transport, row.output_kind, row.cadence
# ('usdm-geojson', 'vector', 'weekly')
An unknown dataset id raises ValueError with a sorted catalog and a
did-you-mean hint:
>>> Catalog().get("usdmm") # doctest: +SKIP
ValueError: 'usdmm' is not in the drought catalog. Known datasets: [...]. Did you mean 'usdm'?
USDM — weekly polygon classes (vector)#
The most common request: the latest weekly USDM polygons over a US bbox.
The four drought-facade keys (drought / usdm / edo / gdo) are
discoverability aliases — all resolve to the same backend and all
require an explicit dataset=:
from earthlens import EarthLens
facade = EarthLens(
data_source="usdm",
start="2026-06-23", end="2026-06-23",
variables=[],
lat_lim=[30.0, 40.0],
lon_lim=[-95.0, -85.0],
dataset="usdm",
)
fc = facade.download()
fc.crs.to_epsg() # 4326
sorted(fc["DM"].unique()) # [0, 1, 2, 3, 4]
fc["release_date"].iloc[0] # '2026-06-16' if queried on/before Thu 2026-06-25;
# '2026-06-23' once that Thursday release rolls out.
The result is a
pyramids.feature.collection.FeatureCollection (a GeoDataFrame) in
EPSG:4326. A multi-week range snaps to one Tuesday per week and merges
into one FeatureCollection with a release_date column so you can
trace each polygon back to its weekly valid date. The walk-back rule
fires when the snapped Tuesday's composite has not yet been released
(its release Thursday is still in the future) — historical queries
always land on the requested Tuesday.
Asking for aggregate= on USDM is rejected — drought-class polygons
have no gridded reduction:
>>> facade.download(aggregate=object()) # doctest: +SKIP
NotImplementedError: Drought.download(aggregate=...) is not supported for the USDM (vector) transport: drought-class polygons have no gridded reduction. ...
SPEIbase — global monthly raster#
Pick a SPEI timescale (1, 3, 6, 12, 24, 48 months) and a bbox; the
backend downloads the per-scale NetCDF once, slices each requested month
through pyramids.netcdf.NetCDF.subset, and writes one GeoTIFF per
month under path/.
from earthlens import EarthLens
facade = EarthLens(
data_source="drought",
dataset="speibase-12",
start="2023-01-01", end="2023-03-31",
variables=[],
lat_lim=[30.0, 40.0],
lon_lim=[-95.0, -85.0],
path="speibase_out",
)
paths = facade.download()
# [Path('speibase_out/speibase-12_202301.tif'),
# Path('speibase_out/speibase-12_202302.tif'),
# Path('speibase_out/speibase-12_202303.tif')]
The last usable month depends on the timescale — a k-month SPEI needs k
months to accumulate, so speibase-12 currently ends 2023-12. The
backend reads the axis from the file and raises a clear error for an
out-of-range month.
The downloaded NetCDF stays under path/ between runs, so a second
download() for the same dataset reuses the cached .nc without
re-hitting digital.csic.es. The cache file name embeds a hash of the
row's endpoint, so bumping the catalog row to a newer SPEIbase release
when one ships fetches the new file fresh (the stale cache is ignored) — a
pure YAML edit, no code change and no manual cache cleanup.
EDO / GDO — Copernicus drought indicators (raster)#
EDO/GDO catalog rows resolve through the same facade — dataset="edo-spaST"
for SPI ERA5 short-term, dataset="gdo-smand" for the ensemble soil-moisture
anomaly, etc. The backend builds the Copernicus GetCoverage URL by hand
(TIME + the row's SELECTED_TIMESCALE + a SUBSET=Long/Lat bbox),
streams the GeoTIFF, and opens it through pyramids.dataset.Dataset.read_file:
from earthlens import EarthLens
paths = EarthLens(
data_source="drought",
dataset="edo-spaST",
start="2025-12-21", end="2025-12-21",
variables=[],
lat_lim=[40.0, 50.0], lon_lim=[5.0, 15.0],
path="edo_out",
).download()
# [Path('edo_out/edo-spaST_20251221.tif')]
Each indicator only carries data for a limited date range; a request outside that range surfaces the Copernicus message verbatim:
>>> EarthLens( # doctest: +SKIP
... data_source="drought", dataset="edo-cdinx",
... start="2026-06-21", end="2026-06-21",
... variables=[], lat_lim=[40.0, 50.0], lon_lim=[5.0, 15.0], path="out",
... ).download()
ValueError: Copernicus EDO/GDO rejected 'edo-cdinx' (HTTP 422): Requested date ... is outside the available coverage range ...
The list of curated EDO/GDO ids lives in src/earthlens/drought/catalog/edo.yaml
and gdo.yaml. The indicator codes + the TIME / SELECTED_TIMESCALE
param shape were verified live (see planning/drought/captures/). Every
gdo-* row uses the same map=DO_WCS endpoint as the EDO rows — there is
no separate GDO_WCS map.
Aliases#
Four facade keys point at the drought backend, all of which require an
explicit dataset= kwarg:
"drought"— the canonical key."usdm"— discoverability alias; still requiresdataset="usdm"."edo"/"gdo"— namespace aliases for the European / Global indicator families; the caller names the specific indicator viadataset="edo-spaST"/dataset="gdo-twsan".
Date snapping at a glance#
from datetime import date
from earthlens.drought._helpers import snap_to_cadence
# Historical Tuesday (today is well past the release Thursday) → itself
snap_to_cadence([date(2026, 6, 23)], "weekly",
today=date(2027, 1, 1)) # [date(2026, 6, 23)]
# Same Tuesday queried on the same Tuesday (release Thursday is future) → walks back
snap_to_cadence([date(2026, 6, 23)], "weekly",
today=date(2026, 6, 23)) # [date(2026, 6, 16)]
snap_to_cadence([date(2026, 6, 15)], "10day") # [date(2026, 6, 11)] — middle dekad
snap_to_cadence([date(2026, 6, 25)], "monthly") # [date(2026, 6, 1)]
A range of dates collapses to one snapped period per release — so a
week-long USDM range yields one FeatureCollection per Tuesday valid date.
The weekly snap walks back one extra week when the same-week Tuesday's
composite has not yet been released (its release Thursday is still in
the future relative to today); historical queries always land on the
requested Tuesday.
Attributions logged on success#
Every successful download() logs the per-source attribution as a
single info line (no LicenseWarning):
- USDM: "U.S. Drought Monitor — public-domain weekly composite produced by NDMC / UNL / USDA / NOAA. Cite the National Drought Mitigation Center."
- EDO/GDO: "Copernicus European/Global Drought Observatory (EMS) — free reuse with attribution to Copernicus EMS."
- SPEIbase: "CSIC Standardised Precipitation-Evapotranspiration Index database v2.11 (Vicente-Serrano et al.), CC-BY 4.0."