Machine-learning reconstruction of the June 2013 Kedarnath disaster from satellite and climate-reanalysis data, built entirely in Google Earth Engine.
Central question: the June 2013 Kedarnath flood killed thousands and is popularly attributed to the Chorabari glacial lake outburst. Was the water actually glacial in origin, or was the lake breach a secondary effect of an extreme rainfall event?
Answer: the flood was overwhelmingly meteorological. A catchment water budget over 14–18 June 2013 puts rainfall volume orders of magnitude above the Chorabari Lake release, and a rainfall-runoff model trained on years of pre-event data reproduces the 17 June peak without needing a glacial term. The lake burst is real and detectable, but it is a secondary contributor visible in post-event drainage residuals — not the cause.
| Basin | Mandakini river upstream of Kedarnath |
| Area | 47.4 km² |
| Elevation range | 3,500 – 6,940 m |
| Glaciated fraction | 27.7% |
| Glaciers | 12 (RGI 7.0), dominant: Chorabari, 4.56 km² |
| Delineation | SRTM 30 m void-filled, PCRaster D8 flow accumulation |
| Pour point | On the Mandakini channel below Kedarnath, not at the temple |
The pour point placement matters. Snapping to the temple coordinates puts the outlet off the channel and produces a catchment that cuts across glacier fields instead of following ridge lines.
SRTM DEM ──► PCRaster D8 ──► Catchment (47.4 km²)
│
┌───────────────────────────┼───────────────────────────┐
│ │ │
▼ ▼ ▼
GLIMS 2008 Landsat / Sentinel-2 ERA5-Land
│ │ + CHIRPS + MODIS
▼ ▼ │
Glacier RF classifier Water-body detection ▼
(2000–2023 series) (NEGATIVE RESULT — Annual features
lakes sub-pixel) + 2013 water budget
│ │
└────────► Flood labels ◄────┘
(A ∪ B)
│
▼
Susceptibility training CSV
Twelve Earth Engine scripts, each with a header explaining its method, inputs, outputs, and known caveats.
Empty. The catchment was delineated in PCRaster outside Earth Engine and uploaded as an asset — see Reproducing this below.
| Script | Purpose |
|---|---|
glims_2008_baseline.js |
Extracts the GLIMS 2008 ground-truth polygons. Run first. |
glims_inventory_clipped.js |
Full glacier inventory, clipped to basin (not merely intersecting). |
glacier_rf_classifier.js |
Supervised: RF on 9 features, GLIMS truth, applied 2000–2023. |
glacier_area_change_2001_2020.js |
Unsupervised: fixed NDSI threshold, stable/lost/gained decomposition. |
The supervised and unsupervised scripts are both kept deliberately. The contrast between them — the threshold method's inability to separate glacier ice from seasonal snow — is the argument for the classifier.
| Script | Purpose |
|---|---|
waterbodies_multiyear_symbols.js |
Proportional-symbol map, 2005–2023, with interactive year selector. |
| Script | Purpose |
|---|---|
era5_annual_features.js |
31-year annual feature table, 2013 held out. Exports daily CSV too. |
water_budget_2013.js |
Key script. Partitions flood water into rainfall / snowmelt / lake breach. |
| Script | Purpose |
|---|---|
label_A_landsat_change.js |
Automated flood footprint via pre/post NDVI + brightness change. |
label_B_martha2015.js |
Damage zones digitised from Martha et al. (2015). |
Two independent labels, built from unrelated evidence. Agreement between them is a validity check that neither provides alone.
| Script | Purpose |
|---|---|
flood_training_export.js |
Labels ∪ 13 conditioning factors → stratified CSV. |
susceptibility_training_v2.js |
Self-contained v2: rebuilt label, 17 features, 5,000 px/class. |
debris_flow_susceptibility.js |
Rule-based weighted-overlay baseline (no ML, no labels). |
Glacier classifier — Random Forest, 100 trees, 9 features, GLIMS 2008 truth, 70/30 split:
| Metric | Value |
|---|---|
| Overall accuracy | 86.5% |
| Cohen's kappa | 0.73 (substantial agreement) |
| Precision / Recall / F1 | 84.8% / 88.9% / 0.87 |
| Top features | NDSI, elevation, SWIR1 |
Rainfall-runoff reconstruction — RF trained on pre-event ERA5-Land forcings, R² = 0.97. Flood week:
| Date | Precip (mm) | Actual runoff | Predicted | Residual |
|---|---|---|---|---|
| Jun 15 | 37 | 0.020 | 0.024 | −0.004 |
| Jun 16 | 130 | 0.075 | 0.085 | −0.010 |
| Jun 17 | 125 | 0.083 | 0.081 | +0.002 |
| Jun 18 | 2 | 0.008 | 0.009 | −0.001 |
| Jun 19 | 0 | 0.007 | 0.007 | +0.0005 |
| Jun 20 | 0 | 0.007 | 0.003 | +0.004 |
Two rows carry the argument. 17 June is predicted within 2% from rainfall alone — the flood was a precipitation anomaly, not a runoff anomaly. 20 June shows the model expecting near-zero runoff after rain stops, while the catchment is still draining 4 mm more than rainfall explains. That residual, with no rain to account for it, is the Chorabari signature.
Negative result — lake detection. Chorabari Lake before the breach was ~0.013 km², roughly 15 Landsat pixels. NDWI, MNDWI, and manual Sentinel-2 inspection all failed to yield a usable time series. Lakes were dropped from the predictor stack rather than tuned until a signal appeared. Published analyses of this event use commercial high-resolution imagery for the same reason.
- Delineate the catchment. SRTM 30 m + PCRaster D8, pour point on the Mandakini channel below Kedarnath (~30.7346°N, 79.0669°E, snapped to the channel). Upload the result as a GEE asset.
- Update the asset paths. Every script references
projects/rock-groove-418708/assets/.... Replacerock-groove-418708with your own Cloud project throughout. - Run in dependency order:
05_labels→06_susceptibility(the training export reads the label assets). Everything under02_glacier,03_water_bodies, and04_climateis independent. - Redraw the Label B geometries.
label_B_martha2015.jsdepends on two hand-drawn polygons stored in the Code Editor's Imports panel, which is not part of saved script source. See that file's header. - Collect exports from the
GEE_exportsDrive folder for downstream Python work.
All freely available; nothing proprietary.
| Dataset | Used for |
|---|---|
SRTM 30 m (USGS/SRTMGL1_003) |
Catchment delineation, terrain features |
| Landsat 5/7/8/9 Collection 2 L2 | Glacier mapping, flood change detection |
| Sentinel-2 SR Harmonized | Post-2016 water bodies, NDVI |
| ERA5-Land Daily Aggregated | Climate forcings, runoff target |
| CHIRPS Daily | Rainfall, water budget |
| MODIS MOD10A1 | Snow cover masking |
| GLIMS | Glacier ground truth |
| ESA WorldCover v100/v200 | Land cover |
| HydroSHEDS | Flow accumulation |
- ERA5-Land is 11 km. The catchment is 47 km² — roughly one grid cell. Local cloudburst intensity is smoothed, which likely understates the rainfall extreme.
- No gauge validation. GRFR discharge data was not accessible; the runoff target is
ERA5's modelled
runoff_sum, itself a land-surface model output. - Glacial lakes are sub-pixel in optical imagery at this scale.
dist_roadis a placeholder inflood_training_export.js— it duplicatesdist_stream. Seedocs/NOTES.md.- Optical sensors cannot see the event. Monsoon cloud means no usable Landsat scene exists for the flood week itself. Everything is inferred from before and after.
- Allen, S.K., Rastner, P., Arora, M., Huggel, C., Stoffel, M. (2016). Lake outburst and debris flow disaster at Kedarnath, June 2013: hydrometeorological triggering and topographic predisposition. Natural Hazards, 84, 1741–1763.
- Dobhal, D.P., Gupta, A.K., Mehta, M., Khandelwal, D.D. (2013). Kedarnath disaster: facts and plausible causes. Current Science, 105(2), 171–174.
- Martha, T.R., Roy, P., Govindharaj, K.B., Kumar, K.V., Diwakar, P.G., Dadhwal, V.K. (2015). Landslides triggered by the June 2013 extreme rainfall event in parts of Uttarakhand state, India. Landslides, 12, 135–146.
- Rafiq, M., Romshoo, S.A., Mishra, A.K., Jalal, F. (2019). Modelling Chorabari Lake outburst flood, Kedarnath, India. Journal of Mountain Science, 16(1), 64–76.
MIT — see LICENSE.