Skip to main content

Composite Drought Index via GEE + COG output + climate-science plots

Project description

drought-monitoring v0.1.0

A lightweight Python package for computing the Composite Drought Index (CDI) over 20–30 year monitoring periods using Google Earth Engine data, writing outputs as Cloud Optimized GeoTIFFs, and producing publication-quality climate science visualisations.


Package structure

drought_cdi/
└── drought_monitoring/
    └── core.py     CDI mathematics on pd.Series
    └── spatial.py  pixel-wise computation on xr.DataArray
    └── gee.py      GEE authentication + ERA5-Land / MODIS data fetching
    └── io.py       Cloud Optimized GeoTIFF (COG) export and import
    └── plot.py     publication-quality climate science figures
└── tests/
    └── test_core.py
pyproject.toml
README.md

Installation

# Core only (numpy, pandas, xarray)
uv pip install -e .

# Full workflow (GEE + COG + plots)
uv pip install -e ".[all]"

Monitoring period

Default Minimum Maximum
20 years 20 years 30 years

An error is raised if the requested period is outside 20–30 years.


Typical Jupyter notebook workflow

# ── 1. Authenticate GEE ──────────────────────────────────────────────────────
from drought_cdi.gee import authenticate
authenticate(project="my-gee-project")   # opens browser on first use

# ── 2. Define your study area ────────────────────────────────────────────────
aoi = [38.0, 3.5, 42.5, 7.0]   # [lon_min, lat_min, lon_max, lat_max]
                                 # Borena region, Southern Ethiopia

# ── 3. Fetch 20-year monthly time series ────────────────────────────────────
from drought_cdi.gee import fetch_era5_precip, fetch_era5_temp, fetch_modis_ndvi

precip = fetch_era5_precip(aoi, start_year=2000, end_year=2020)  # mm/month
temp   = fetch_era5_temp(aoi,   start_year=2000, end_year=2020)  # °C
ndvi   = fetch_modis_ndvi(aoi,  start_year=2000, end_year=2020)  # [-1,1]

# ── 4. Compute CDI ───────────────────────────────────────────────────────────
from drought_cdi import compute_all

df = compute_all(precip, temp, ndvi, window=3)
# Returns pd.DataFrame with columns: PDI, TDI, VDI, CDI

# ── 5. Visualise ─────────────────────────────────────────────────────────────
from drought_cdi.plot import plot_timeseries, plot_anomaly_bars, plot_seasonal_cycle

fig = plot_timeseries(
    df,
    title="Composite Drought Index — Borena Region",
    subtitle="ERA5-Land + MODIS MOD09GQ  |  2000–2020",
)
fig.savefig("CDI_Borena_timeseries.png", dpi=300, bbox_inches="tight")

fig2 = plot_anomaly_bars(df, freq="Y", title="Annual Mean CDI Anomaly")
fig2.savefig("CDI_Borena_annual.png", dpi=300, bbox_inches="tight")

fig3 = plot_seasonal_cycle(df)
fig3.savefig("CDI_Borena_seasonal.png", dpi=300, bbox_inches="tight")

# ── 6. Export Cloud Optimized GeoTIFFs ──────────────────────────────────────
# Option A: from spatial xr.Dataset (pixel-wise)
from drought_cdi.gee import fetch_era5_precip_cube, fetch_era5_temp_cube
from drought_cdi.spatial import spatial_cdi
from drought_cdi.io import cdi_stack_to_cog

precip_cube = fetch_era5_precip_cube(aoi, start_year=2000, end_year=2020)
temp_cube   = fetch_era5_temp_cube(aoi,   start_year=2000, end_year=2020)
# (fetch ndvi cube similarly, or resample your time series)

ds = spatial_cdi(precip_cube, temp_cube, ndvi_cube)
paths = cdi_stack_to_cog(ds, output_dir="outputs/", prefix="Borena_2000_2020")
# → outputs/Borena_2000_2020_PDI.tif
# → outputs/Borena_2000_2020_TDI.tif
# → outputs/Borena_2000_2020_VDI.tif
# → outputs/Borena_2000_2020_CDI.tif

# Option B: broadcast area-averaged time series onto a spatial template
from drought_cdi.io import series_to_cog

paths = series_to_cog(df, spatial_ds=precip_cube, output_dir="outputs/",
                      prefix="Borena_2000_2020")

# ── 7. Visualise COGs in leafmap ─────────────────────────────────────────────
import leafmap
m = leafmap.Map(center=[5.0, 40.0], zoom=6)
m.add_raster(str(paths["CDI"]), colormap="RdBu", vmin=-3, vmax=3,
             layer_name="CDI 2020-12")
m

Data sources

Variable GEE collection Band Units
Precipitation ECMWF/ERA5_LAND/MONTHLY_AGGR total_precipitation_sum mm month⁻¹
Temperature ECMWF/ERA5_LAND/MONTHLY_AGGR temperature_2m °C
NDVI MODIS/061/MOD09GQ derived from b01+b02

CDI formula

DI = (IP − LTM) / LTM  +  run / LTM_run
CDI = (PDI + TDI + VDI) / 3   [default equal weights]
Symbol Meaning
IP Interest-period value (3-month trailing rolling mean)
LTM Long-term mean for that calendar month
run Consecutive months where the anomaly condition is active
LTM_run Long-term mean of run lengths

PDI & VDI use deficit streaks (IP < LTM). TDI uses excess streaks (IP > LTM).


CDI severity classes

CDI value Class
< −2.0 Extreme drought
−2.0 – −1.5 Severe drought
−1.5 – −1.0 Moderate drought
−1.0 – −0.5 Mild drought
−0.5 – +0.5 Near normal
+0.5 – +1.0 Mild wet
+1.0 – +1.5 Moderately wet
> +1.5 Very wet

COG structure

Each output GeoTIFF contains one band per month. Band descriptions are ISO-8601 date strings (YYYY-MM), so every file is self-documenting and can be range-requested from cloud storage (S3, GCS, Azure Blob) by leafmap, QGIS, or any GDAL tool.


Running tests

pytest drought_cdi/tests/ -v

Reference

Based on: Burchard-Levine, V. et al. (2024). pyCDI: a Python implementation of the composite drought index. EO-Africa R&D, ESA. https://github.com/VicenteBurchard/pyCDI

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drought_monitoring-0.1.0.tar.gz (28.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

drought_monitoring-0.1.0-py3-none-any.whl (25.8 kB view details)

Uploaded Python 3

File details

Details for the file drought_monitoring-0.1.0.tar.gz.

File metadata

  • Download URL: drought_monitoring-0.1.0.tar.gz
  • Upload date:
  • Size: 28.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for drought_monitoring-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ca80b6b2d991cc10528b79dfa8ae24e2eab814e2e57838c303e213d9ecf6c5d3
MD5 9e645c2c3720f2e9b4f10724a14ba384
BLAKE2b-256 98eb2249c315670bb64fd2c10b8d74a1ada83d5d21dc42986eeda690e3f51822

See more details on using hashes here.

File details

Details for the file drought_monitoring-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: drought_monitoring-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for drought_monitoring-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b4f9d52527e266f2a2224251c5c4cd65487e40d48e9edfb843925aa8b2cb1e6b
MD5 f8a90a5c7cffb098a7f729b0f594ea46
BLAKE2b-256 09f4ff86a754d2ec4f3d1529011db10f1ed2f3efa2f7d97c8b275f8ad35ea324

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page