q06·intermediate

Is my reservoir / lake / river running low compared to historical normals?

hydrologywater-resourcesdrought Datasets: 6 15–45 min
Find the data for your area

Draw a rectangle to pick your area of interest, then see what NASA data covers it (live, here in your browser) or download a ready-to-run notebook with your AOI pre-filled. The notebook runs in any Python environment — it needs a free Earthdata Login to fetch the data.

Current AOI: -114.7, 36 → -114, 36.4 (Lake Mead, NV/AZ)

Is my reservoir / lake / river running low compared to historical normals?

What you can answer

  • Water-surface elevation time series (SWOT for rivers ≥100 m / lakes ≥250×250 m; ICESat-2 for smaller bodies)
  • Surface-area time series (HLS NDWI on cloud-free dates)
  • Total water-storage anomaly at regional scale 300+ km (GRACE-FO mascons)
  • Inflow precipitation context (GPM IMERG climatology vs current year)
  • Comparison to multi-year normal to flag drought conditions

What you can NOT answer with these alone

  • Underground storage (groundwater fluctuations need GRACE-FO + soil moisture + a land-surface model)
  • Daily-to-hourly water level during fast-changing events (storm surge, dam-release) — satellite revisit is too slow; use ground gauges or hydraulic models
  • Direct water quality (sediment, algae, salinity) without optical/hyperspectral overlays

Code template

import earthaccess
import requests

earthaccess.login(strategy="netrc")

# Lake Mead, Nevada-Arizona — drought poster child
aoi = (-114.7, 36.0, -114.0, 36.4)
window = ("2024-01-01", "2025-12-31")

# 1. SWOT lake heights via Hydrocron (much easier than raw L2)
lake_id = "7250000000"  # Hydrocron's Lake Mead ID (look up in their catalog)
hydrocron_url = (
    f"https://soto.podaac.earthdatacloud.nasa.gov/hydrocron/v1/timeseries"
    f"?feature=PriorLake&feature_id={lake_id}&start_time={window[0]}T00:00:00Z"
    f"&end_time={window[1]}T23:59:59Z&output=geojson&fields=wse,area_total,time_str"
)
swot_data = requests.get(hydrocron_url).json()

# 2. HLS for surface-area cross-check
hls = earthaccess.search_data(short_name="HLSL30", bounding_box=aoi,
                               temporal=window, cloud_cover=20)
# Compute NDWI = (Green - NIR) / (Green + NIR); threshold > 0 → water mask
# Sum water-mask pixels × 30² m² → surface area per scene

# 3. GRACE-FO mascon for regional total water storage anomaly
grace = earthaccess.search_data(short_name="GRACEFO_L3_JPL_RL06.X_M",
                                bounding_box=aoi, temporal=("2002-04-01", window[1]))
# Extract liquid water equivalent (LWE) anomaly time series

# 4. GPM IMERG for precipitation accumulation
imerg = earthaccess.search_data(short_name="GPM_3IMERGDF", bounding_box=aoi,
                                temporal=window)
# Compute monthly + annual rainfall sum

# 5. Plot: water-surface elevation, area, regional TWS, precipitation — same x-axis

Expected output

  • Multi-panel time-series: lake surface elevation (SWOT) · surface area (HLS) · regional TWS (GRACE) · monthly precipitation (IMERG)
  • Anomaly bar chart: current year vs 30-year normal for each variable
  • Map: current vs typical extent overlay

Caveats

  • SWOT 21-day revisit + 20 km nadir gap — your reservoir may be missed on a given pass
  • NDWI cloud sensitivity — cloudy scenes destroy area estimates
  • GRACE-FO at 300 km resolution can’t isolate one reservoir; it captures regional pattern
  • HLS L30/S30 calibration consistency is good but not perfect across sensor changes (Landsat 7 era vs 8/9 era)
  • Use Hydrocron, not raw L2 HR pixel-cloud for first analyses — Hydrocron pre-aggregates to feature

Cross-DAAC composition

PO.DAAC (SWOT, GRACE-FO) + LP DAAC (HLS) + GES DISC (IMERG) — three DAACs, single auth, see r01.

Sources

Datasets used

📚 Problem Finder KB

Not yet tracked in the KB.