Skip to content

Repository files navigation

climate-shift — Glacier Toolkit

CI CodeQL License: MIT Python 3.10+ Code style: ruff pre-commit

A scientific Python toolkit for downloading and analysing global mountain-glacier area change from satellite imagery. It pulls glacier outlines, multi-decadal Landsat surface-reflectance imagery, and reanalysis climate fields from open archives; classifies glacier ice with the Normalised-Difference Snow Index (NDSI); builds per-glacier area time series; couples those trends to local temperature and precipitation; validates them against published reference areas and an independent DEM-differencing mass-balance dataset; and exposes a suite of statistical methods (trend fitting, bootstrap confidence intervals, robustness sweeps, and critical-slowing-down / autocorrelation diagnostics) together with vector figure builders. This repository is the code-only distribution: it ships the methods and pipelines, not the (large, separately-licensed) raw datasets.


What this is

  • Data acquisition — server- and client-side Google Earth Engine workflows for Landsat 5/7/8/9 Collection-2 Level-2 imagery, GLIMS glacier outlines (single glacier, whole RGI region, or full database), ERA5-Land monthly climate, plus loaders for the Hugonnet (2021) mass-balance archive and the RGI v6.2 metadata table.
  • NDSI ice classification — sensor harmonisation, cloud masking, seasonal median compositing, NDSI/NDWI computation, slope masking, and pixel-count area estimation with boundary-pixel uncertainty.
  • Area-change analysis — multi-temporal area time series, OLS trends with bootstrap CIs and Mann–Kendall tests, and acceleration tests.
  • Climate coupling — local CRU TS temperature and precipitation extraction, warming/wetting trends, cross-glacier warming-vs-retreat regression (OLS and Theil–Sen), and confounder control via partial correlation, multivariate regression, mediation decomposition, and interval / fixed-effects panel estimators.
  • Validation — comparison of NDSI-derived areas against published reference areas, and cross-validation of area trends against the independent Hugonnet (2021) mass-balance dataset.
  • Resilience diagnostics — a critical-slowing-down (CSD) toolkit implementing AR(1), variance and skewness estimators (point and rolling), Pettitt change-point detection, the Kendall-tau-on-rolling-AR(1) fingerprint, and surrogate/null machinery, applied to both glacier area and mass-balance series.
  • Reproducible pipelines & figures — console entry points that chain the above into end-to-end runs, a library of vector (PDF) figure builders, and numbered analysis work-packages.

Note. A manuscript that uses this toolkit is in preparation. This README documents the code and methods only; no scientific results are reported here.


Repository layout

Path Role
glacier_toolkit/ Installable Python package (glacier-toolkit).
  acquire/ Data-acquisition layer (Landsat, GLIMS, ERA5-Land via Earth Engine; loaders for Hugonnet 2021 mass balance and RGI v6.2).
  analyze/ Statistical core: NDSI classification, area-change pipeline, climate/precipitation coupling, confounder control, interval analysis, and the CSD/resilience toolkit.
  validate/ Validation against published reference areas and the Hugonnet (2021) mass-balance dataset.
  visualize/ Vector figure builders (white-background, 300 DPI, PDF) for the analysis outputs.
  pipelines/ End-to-end CLI pipelines exposed as glacier-* console scripts.
  config.py Central paths, stats defaults (bootstrap N / seed / CI), and a registry of notable glaciers.
scripts/ Download/extraction helpers, numbered analysis work-packages (wp*.py), figure builders (make_*.py), and shell orchestration for the long-running Earth Engine extraction chain.
tests/ pytest suite covering config, NDSI, area, statistics, correlation, multivariate, interval, resilience, validation, and more.
paper/figures/ Gitignored output directory for generated figure PDFs (only .gitkeep is tracked). Figure scripts write here.

Computed products (glacier_data/, glacier_outputs/) and generated figures (paper/figures/) are gitignored and not part of the repository.


Installation

Requires Python 3.10–3.12.

git clone https://github.com/bijanf/climate-shift.git
cd climate-shift
python -m pip install -e .            # core install
python -m pip install -e ".[all]"     # everything (recommended for full pipelines)

The core install pulls numpy, pandas, matplotlib, scipy, xarray, scikit-image, Pillow, tqdm and requests. Heavier capabilities are split into optional extras:

Extra pip install -e ".[extra]" adds Needed for
geo rasterio, rioxarray, geopandas, shapely, fiona, pyproj, cartopy, netCDF4 Reading GeoTIFFs/shapefiles, equal-area computation, CRU/ERA5 netCDF, and cartopy maps.
gee earthengine-api Google Earth Engine acquisition (Landsat, GLIMS, ERA5-Land).
paper statsmodels LOESS detrending in analyze/resilience_mass.py and the statistical work-packages (scripts/wp*.py).
dev ruff, mypy, pre-commit, pytest, pytest-cov, pytest-xdist Linting, typing, hooks, and the test suite.
all glacier-toolkit[geo,gee,paper,dev] Combined extras.

System requirements

  • GIS system libraries for the geo extra: GDAL, GEOS and PROJ must be present. On Debian/Ubuntu:
    sudo apt-get install -y libgdal-dev gdal-bin libgeos-dev libproj-dev proj-bin proj-data
    (CI installs exactly these before pip install -e ".[geo,dev]".)
  • Google Earth Engine account + authenticated earthengine-api for any acquisition that hits GEE (Landsat, GLIMS, ERA5-Land). The GEE-backed modules run ee.Authenticate() lazily on first use.
  • Copernicus CDS account if you obtain ERA5-Land outside of the GEE path.
  • Local disk for the gitignored cache: full-region Landsat/GLIMS extractions and the Hugonnet/RGI archives are large (the GLIMS bulk shapefile alone is ~500 MB).

Downloading data

Raw datasets are not redistributed in this repository — only the code that fetches them. Acquisition writes into a local, gitignored cache (default glacier_data/) so that downloads are reused across runs.

The glacier_toolkit/acquire/ modules and the scripts/ download helpers obtain:

  • Landsat NDSI / imageryacquire/landsat.py exports per-glacier NDSI/RGB GeoTIFFs from Landsat C2 L2 via Earth Engine; acquire/landsat_batch.py is the server-side batch variant that returns per-glacier-per-year ice area (km²) without downloading rasters, with payload/feature-limit handling and CSV resume caching. scripts/download_all_glaciers.py drives a resumable per-glacier run.
  • Glacier outlines (GLIMS / RGI)acquire/glims_gee.py (single glaciers) and acquire/glims_regions.py (whole RGI O1 regions) fetch from the GEE GLIMS/current collection and cache GeoJSON; acquire/glims.py is a heavier fallback that downloads the full GLIMS shapefile directly. acquire/rgi_stats.py loads the RGI v6.2 metadata table and provides the RGIId↔GLIMSId join.
  • Climateacquire/era5.py extracts ERA5-Land monthly fields per glacier from GEE; scripts/extract_annual_cru_per_glacier.py extracts annual CRU TS temperature and precipitation at glacier locations.
  • Independent mass balanceacquire/hugonnet.py is a loader for the Hugonnet et al. (2021) per-glacier mass-balance archive: download the per-RGI TAR files manually from the data DOI (SEDOO/Theia) into glacier_data/hugonnet/ and the module auto-extracts and joins them. scripts/fetch_dussaillant2025.py prepares the Dussaillant (2025) surface-mass-balance series.

Manual prerequisites (cannot be fetched programmatically):

  • Hugonnet (2021) per-region TAR files in glacier_data/hugonnet/.
  • rgi62_stats.csv (RGI v6.2 metadata) placed alongside the Hugonnet download.
  • CRU TS netCDF grids (temperature tmx, precipitation pre) under data/.

Analysis pipeline

The pipelines communicate through CSV/parquet caches written under glacier_outputs/ (gitignored), not through direct function calls, so they are run in sequence. Each is exposed as a console script (installed by pip install -e .):

Command Module Purpose
glacier-paper pipelines/run_paper.py Per-registry-glacier run: NDSI area series + trends, local warming, climate sensitivity, reference-area validation, terminus-stratified cross-glacier regression, tables and figures.
glacier-global pipelines/run_global.py Scale-out run over whole RGI regions: GLIMS fetch/dedup, batched GEE ice-area computation, coverage/length filtering, cross-glacier regression, RGI enrichment, region + combined result CSVs.
glacier-refit-with-coverage-filter pipelines/refit_with_coverage_filter.py Maintenance refit: drop low-coverage glacier-years, re-fit per-glacier slopes, back up raw CSVs, overwrite region/combined results.
glacier-nc-paper pipelines/run_nc_paper.py Cross-region regressions, Hugonnet cross-validation, multivariate regression + partial correlation + per-stratum coupling, scale-aware figures.
glacier-interval-analysis pipelines/run_interval_analysis.py Fixed-interval panel decomposition with within-glacier fixed-effects and first-difference estimators.
glacier-multipathway-analysis pipelines/run_multipathway_analysis.py Direct vs precipitation-mediated decomposition (bivariate T+P, partial Spearman, mediation).
glacier-sign-flip-validation pipelines/run_sign_flip_validation.py Per-region comparison of the area-trend coupling sign against the Hugonnet mass-balance coupling sign.
glacier-era5-seb-analysis pipelines/run_era5_seb_analysis.py Extends the multipathway controls with ERA5-Land surface-energy-balance proxies (temperature, humidity, shortwave).
glacier-sensitivity pipelines/run_sensitivity.py Robustness sweep over NDSI threshold, smoothing window, time range and estimator; reports stability and renders a forest plot.

A typical scale-out order is: glacier-globalglacier-refit-with-coverage-filter{ glacier-nc-paper, glacier-interval-analysis, glacier-multipathway-analysis, glacier-sign-flip-validation, glacier-era5-seb-analysis }.

The numbered work-packages in scripts/wp*.py (wp4wp26) implement additional CSD/resilience, null/surrogate, FDR, power and robustness analyses (for example wp4_pettitt_l5sensitivity.py, wp5_spatial_coherence.py, wp8_dual_metric_csd.py, wp11_mass_csd_robustness.py). Shell scripts such as scripts/launch_global_extraction_chain.sh, scripts/watchdog_extraction_chain.sh and scripts/run_paper_full.sh orchestrate the long-running, interruptible Earth Engine extraction chain. All outputs land under glacier_outputs/ (gitignored).

Many pipelines and scripts require the upstream cache to exist first; on a clean checkout they will fetch/recompute their inputs (the global extraction chain is long-running and Earth-Engine-bound) rather than read pre-shipped products.


Figures

Figure builders live in scripts/ (make_fig*.py, make_supp*.py, make_figS*.py) and in glacier_toolkit/visualize/. They render vector PDFs (sans-serif, RGB, editable text) from the analysis outputs and write them into paper/figures/, which is gitignored except for .gitkeep. After a run, scripts/freeze_paper_figures.sh collects the curated figure PDFs from that directory. The visualize/ modules use an explicit white-background, 300-DPI publication style; scripts/verify_greyscale_colorblind.py provides figure QC.


Testing & development

The repository is set up for standard Python tooling.

python -m pip install -e ".[dev]"

python -m pytest            # run the test suite (175 tests collected)
ruff check .                # lint
ruff format --check .       # formatting check
mypy glacier_toolkit        # static typing (informational)
pre-commit install          # enable git hooks
pre-commit run --all-files  # run all hooks
  • pytest — 15 test_*.py files (175 tests collected) covering config, correlation, area, NDSI, statistics, multivariate, interval analysis, resilience (area and mass), coverage refit, RGI stats, and validation. Markers slow, integration and gee are configured.
  • ruff — line length 100, target Python 3.10, rule sets E/W/F/I/B/C4/UP/SIM/RUF; used for both linting and formatting.
  • mypy — configured in pyproject.toml (informational in CI).
  • pre-commit — whitespace/EOF/merge/large-file hooks, ruff (--fix) + ruff-format, and mypy on glacier_toolkit/.
  • Continuous integration.github/workflows/ci.yml runs lint, typecheck (non-blocking), a test matrix across Python 3.10 / 3.11 / 3.12 (with GDAL/ GEOS/PROJ apt deps and coverage), and a build/twine-check job. .github/workflows/codeql.yml runs CodeQL security scanning (public repos).

Data sources

This toolkit consumes the following open datasets. Each is obtained under its own terms; please cite the original providers when you use them.

Dataset Module(s) License / terms Citation
Landsat 5/7/8/9 Collection-2 Level-2 acquire/landsat.py, acquire/landsat_batch.py USGS — public domain USGS / NASA Landsat; Roy et al. (2016) sensor harmonisation.
GLIMS glacier outlines acquire/glims*.py NSIDC / GLIMS data-use policy GLIMS & NSIDC (glims.org).
Randolph Glacier Inventory (RGI v6.2) acquire/rgi_stats.py NSIDC / RGI use policy RGI Consortium (2017).
Hugonnet et al. (2021) mass balance acquire/hugonnet.py, validate/hugonnet_validation.py SEDOO/Theia data-use terms Hugonnet et al. (2021), Nature; data DOI 10.6096/13.
Dussaillant (2025) surface mass balance analyze/resilience_mass.py, scripts/fetch_dussaillant2025.py Provider terms Dussaillant et al. (2025).
ERA5-Land monthly reanalysis acquire/era5.py Copernicus / ECMWF licence Muñoz-Sabater et al. (2021), ERA5-Land.
CRU TS v4.x (tmx, pre) analyze/climate_link.py, analyze/precipitation_link.py CEDA / CRU open licence Harris et al. (2020), CRU TS.

Citation

If you use this toolkit, please cite the software:

@software{fallah_climate_shift_2026,
  author  = {Fallah, Bijan},
  title    = {{climate-shift}: a toolkit for downloading and analysing
              global mountain-glacier area change from satellite imagery},
  year     = {2026},
  version  = {0.1.0},
  url      = {https://github.com/bijanf/climate-shift}
}

A manuscript using this toolkit is in preparation; a reference will be added here on publication.


License

Released under the MIT License. Copyright © 2026 Bijan Fallah.

Author

Bijan Fallahbijan.fallah01@gmail.com GitHub: github.com/bijanf/climate-shift

About

Global climate shift analysis: European temperature/precipitation + worldwide glacier retreat monitoring toolkit

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages