This repository contains the codebase and analytical workflows for the paper:
Monitoring Agricultural Canals from Space Reveals Global Patterns of Human Water Redistribution
Sarath Suresh¹,Mridul Sharma¹, Faisal Hossain¹*, Tamlin Pavelsky²
¹ Department of Civil and Environmental Engineering, University of Washington, Seattle, WA 98195, USA
² Department of Earth, Marine and Environmental Sciences, University of North Carolina, Chapel Hill, NC 27599, USA
Agricultural canals redistribute surface water, yet their global behavior has been difficult to track due to the paucity of in-situ measurements. Using the vantage of space, surface water in nearly 1.5 million kilometers of agricultural canals was tracked in this study. Most canals were found to carry water downhill significantly faster than nearby rivers, effectively accelerating the delivery of freshwater to farms. Distinct seasonal patterns of redistribution were also identified: many of the world's major breadbaskets increase canal water delivery during dry periods when crops need it most, while others maintain steady flows year-round. By showing, for the first time, how humanity has deliberately redirected water across the Earth’s agricultural landscapes, the research highlights the global extent of irrigation canals in modifying Earth's freshwater cycle.
The repository is organized into two primary folders:
scripts/: Python modules for data preprocessing, raster sampling, climatology masking, and spatial indexing.notebook/: Jupyter Notebooks for main workflows, river comparisons, sub-basin aggregations, statistics, and plotting.
SWOT-GRAIN_Global_Patterns/
├── README.md
├── .gitignore
├── scripts/
│ ├── GRC_terrain_classifier.py
│ ├── SWORDRivers_creatingSpatialIndexes.py
│ ├── canal_assign_precipClimatology.py
│ ├── canal_seasonalWSE.py
│ ├── cogFile_creator.py
│ ├── dryWetMonths_bitmask_creator.py
│ └── swotFile_forGrain_lookupTable_creator.py
└── notebook/
├── canal_comparison_with_sword_slope.ipynb
├── canal_confidenceScore.ipynb
├── canal_hydrobasins_level_wse_analysis.ipynb
└── canal_terrain_classification.ipynb
-
dryWetMonths_bitmask_creator.py
-
Purpose: Processes daily IMERG precipitation rasters over a year-range to calculate monthly averages. It utilizes a fast, vectorized 1D K-Means clustering algorithm (
$K=2$ ) per pixel to partition the 12 months of the year into wet (rainy) and dry regimes, encoding the results as bitmasks to output GeoTIFF files (rainy_month_bitmask_*_kmeans.tif, etc.).
-
Purpose: Processes daily IMERG precipitation rasters over a year-range to calculate monthly averages. It utilizes a fast, vectorized 1D K-Means clustering algorithm (
-
canal_assign_precipClimatology.py
- Purpose: Matches GRAIN canal segments to SWOT observability metadata, filters by confidence levels, samples the IMERG climatology bitmasks at each canal's representative point, and decodes the bitmasks into lists of active wet and dry calendar months. Outputs country-specific parquet files.
-
canal_seasonalWSE.py
-
Purpose: Processes daily SWOT water level datasets. It calculates Mean Sea Level (MSL) water surface elevation (WSE) values, filters outliers daily using the Interquartile Range (IQR) method, aggregates daily averages, and computes seasonal mean elevation values to evaluate the seasonal difference (
$\Delta\text{WSE} = \text{Rainy} - \text{Dry}$ ).
-
Purpose: Processes daily SWOT water level datasets. It calculates Mean Sea Level (MSL) water surface elevation (WSE) values, filters outliers daily using the Interquartile Range (IQR) method, aggregates daily averages, and computes seasonal mean elevation values to evaluate the seasonal difference (
-
swotFile_forGrain_lookupTable_creator.py
-
Purpose: Traverses raw SWOT observation directories and creates a global parquet lookup table mapping each canal segment (
grain_id) to its corresponding raw SWOT parquet file.
-
Purpose: Traverses raw SWOT observation directories and creates a global parquet lookup table mapping each canal segment (
-
SWORDRivers_creatingSpatialIndexes.py
- Purpose: Reads SWORD (Shallow Water Obstruction Database) river reach parquets and indexes their geographic bounding boxes (xmin, ymin, xmax, ymax) and reach counts to enable fast spatial overlap queries.
-
GRC_terrain_classifier.py
- Purpose: Classifies canal segments into standard topography/terrain classes (Plains, Hills, Mountains) by sampling global elevation tiles.
-
cogFile_creator.py
- Purpose: A utility script converting standard raster GeoTIFF files into Cloud-Optimized GeoTIFFs (COGs) for fast tile-based access.
- canal_comparison_with_sword_slope.ipynb
- Purpose: Matches GRAIN canals to nearby SWORD river reaches using spatial buffering. It evaluates slope ratios and differences only between canals and rivers sharing the same topography class, helping compare human-engineered slope gradients to natural river systems.
- canal_hydrobasins_level_wse_analysis.ipynb
- Purpose: Aggregates canal seasonal operational regimes (dry-dominant, perennial, rainy-dominant) to HydroBASINS Level 6 sub-basins globally. Prepares spatial parquet summary files and generates global choropleth maps and dominance distributions.
- canal_confidenceScore.ipynb
- Purpose: Evaluates and derives canal Confidence Level A (CL_A) metrics based on slope signal-to-noise ratios (SNR), observation coverage, and data dispersion.
- canal_terrain_classification.ipynb
- Purpose: Contains workflows for setting up and testing topographic classifications of GRAIN canal segments.