Profile
Back to NewsBack
GitHub Trending 7 min
Reader Mode
monocongo/climate_indices: Climate indices for drought monitoring

monocongo/climate_indices: Climate indices for drought monitoring

15 hours ago

!Banner Image

climate_indices

[//]: # ([![Coverage Status](https://coveralls.io/repos/github/monocongo/climate_indices/badge.svg?branch=main)](https://coveralls.io/github/monocongo/climate_indices?branch=main)) [//]: # ([![Codacy Status](https://api.codacy.com/project/badge/Grade/48563cbc37504fc6aa72100370e71f58)](https://www.codacy.com/app/monocongo/climate_indices?utm_source=github.com&utm_medium=referral&utm_content=monocongo/climate_indices&utm_campaign=Badge_Grade)) Actions Status</a> License</a> Python | 3.10-3.14</a>

Python library of indices useful for climate monitoring

This project contains Python implementations of various climate index algorithms which provide a geographical and temporal picture of the severity and duration of precipitation and temperature anomalies useful for climate monitoring and research.

The following indices are provided:

Standardized Precipitation Index, utilizing both gamma and Pearson Type III distributions Standardized Precipitation Evapotranspiration Index, utilizing both gamma and Pearson Type III distributions or Hargreaves equations Percentage of Normal Precipitation including PDSI, PHDI, PMDI, and Z-Index

This Python implementation of the above climate index algorithms is being developed with the following goals in mind:

  • to provide an open source software package to compute a suite of
climate indices commonly used for climate monitoring, with well documented code that is faithful to the relevant literature and which produces scientifically verifiable results
  • to provide a central, open location for participation and collaboration
for researchers, developers, and users of climate indices
  • to facilitate standardization and consensus on best-of-breed
climate index algorithms and corresponding compliant implementations in Python
  • to provide transparency into the operational code used for climate
monitoring activities at NCEI/NOAA, and consequent reproducibility of published datasets computed from this package
  • to incorporate modern software engineering principles and scientific programming
best practices

This is a developmental/forked version of code that was originally developed by NIDIS/NCEI/NOAA. See drought.gov.

Installation

Install the released package from PyPI:

pip install "climate-indices>=2.3"

uv users can run uv pip install "climate-indices>=2.3". The 2.3.0 floor matches the quickstart, which documents the latest release and uses the xarray API added in 2.3.0; see Supported Python Versions for interpreter support.

Developer Workflow

This project uses trunk-based development. main is the trunk and should always be releasable.

  1. Start from current trunk:
git switch main && git pull --ff-only origin main
  1. Create a short-lived branch:
git switch -c feature/
  1. Make focused changes with tests.
  2. Run validation:
uv run ruff check src/ tests/ uv run ruff format --check src/ tests/ uv run mypy src/ tests/test_type_checking.py uv run pytest
  1. Open a PR into main.
  2. The maintainer merges the PR after review and passing CI; agents never merge.
Use feature/, fix/, docs/, chore/, or hotfix/ branch names. Release branches are avoided; use maintenance branches only for approved older-version support.

Release Recipe

Releases are tag-based. The Git tag, package version, GitHub Release, and PyPI version must match.

  • Git tag: v1.2.3
  • Package version: 1.2.3
  • GitHub Release: v1.2.3
  • PyPI release: 1.2.3
  1. Prepare a release PR that updates pyproject.toml, CHANGELOG.md,
and release notes/docs; the maintainer merges it after review and passing CI.
  1. Confirm main is green.
  2. Create an annotated tag from main.
  3. Push the tag. The release workflow builds, validates, publishes to PyPI, and
creates the GitHub Release.

Tag creation and publishing require maintainer approval. See docs/release-process.md for the full checklist.

Maintainer Quick Commands

Read-only preflight:

git status --short
git branch --show-current
git log --oneline --decorate -5
uv run pytest tests/test_release_integrity.py

Safe PR branch setup:

git switch main
git pull --ff-only origin main
git switch -c chore/issue-667-release-docs

Approval-required release tag commands:

git switch main
git pull --ff-only origin main
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.Z

Supported Python Versions

| Python Version | Status | Notes | |:--------------:|:------:|:------| | 3.10 | Supported | Minimum supported version | | 3.11 | Supported | | | 3.12 | Supported | | | 3.13 | Supported | | | 3.14 | Supported | Latest supported version |

All versions are tested on Linux (ubuntu-latest). Python 3.10 and 3.14 are additionally tested on macOS. Both latest and minimum declared dependency versions are tested in CI.

Version Support Policy

This project provides 12 months notice before dropping support for a Python version. When a version approaches end-of-life, removal will be announced via the CHANGELOG and a GitHub issue, and implemented no sooner than 12 months after announcement with a version bump.

Python 3.9 support was dropped in v2.2.0 (August 2025) due to scipy>=1.15.3 requiring 3.10+.

API Stability

| API Surface | Status | Guarantee | |:------------|:------:|:----------| | NumPy array functions (indices.spi, indices.spei, indices.pet) | Stable | No breaking changes in minor versions | | xarray DataArray functions (spi(), spei(), pet_thornthwaite(), pet_hargreaves()) | Beta | No breaking changes in patch versions |

Stable API: The NumPy-based computation functions follow strict semantic versioning.

Beta API: The xarray adapter layer provides automatic parameter inference, coordinate preservation, CF metadata, and Dask support. While beta, computation results are identical to the stable NumPy API — only the interface surface (parameter names, metadata attributes, coordinate handling) may evolve. Beta features are tagged with `BetaFeatureWarning and marked in docstrings.

See docs/xarray_compatibility.md for the 3.0.0 compatibility matrix, including Dask chunking constraints, metadata behavior, and the current Palmer xarray workflow.

Validation Notes

The 3.0.0 validation status is tracked in VALIDATION.md. EDDI is validated against committed paired NOAA PSL monthly reference ET/EDDI fixtures for 1-, 3-, and 6-month Timescales (1979–2023); the maximum observed error is 2.43e-6. Palmer tests cover the committed regression fixtures for PDSI, PHDI, PMDI, and Z-Index, plus Wells-lineage reference fixtures for scPDSI's four self-calibrating outputs and fitted duration factors. These fixtures are treated as regression coverage, not independent authoritative scientific validation.

Migration Guide for v2.2.0

Breaking Change: Exception-Based Error Handling

Version 2.2.0 introduces a significant architectural improvement in error handling. The library now uses exception-based error handling instead of returning None tuples for error conditions.

What Changed

Before (v2.1.x and earlier):

# Old behavior - functions returned None tuples on failure
result = some_internal_function(data)
if result == (None, None, None, None):
    # Handle error case
    pass

After (v2.2.0+):

# New behavior - functions raise specific exceptions
try:
    result = some_internal_function(data)
except climate_indices.compute.InsufficientDataError as e:
    # Handle insufficient data case
    print(f"Not enough data: {e.non_zero_count} values found, {e.required_count} required")
except climate_indices.compute.PearsonFittingError as e:
    # Handle fitting failure case
    print(f"Fitting failed: {e}")

New Exception Hierarchy

  • DistributionFittingError (base class)
- InsufficientDataError - raised when there are too few non-zero values for statistical fitting - PearsonFittingError - raised when L-moments calculation fails for Pearson Type III distribution

Impact on Users

  • Direct API users: No changes needed - the public SPI/SPEI functions handle exceptions internally
  • Library integrators: If you were checking for None return values from internal functions, update to use try/catch blocks
  • Benefits: More informative error messages, better debugging, and automatic fallback from Pearson to Gamma distribution when appropriate

Code Quality Improvements

Version 2.2.0 also addresses floating point comparison issues (python:S1244) throughout the codebase:

Floating Point Comparisons:

# ❌ OLD: Direct equality checks (unreliable)
if values == 0.0:
    handle_zero_case()

✅ NEW: Safe comparison using numpy.isclose()

if np.isclose(values, 0.0, atol=1e-8): handle_zero_case()

Benefits:

  • Eliminates floating point precision issues in statistical parameter validation
  • Improves test reliability and numerical robustness
  • Follows scientific computing best practices for floating point arithmetic
  • See docs/floating_point_best_practices.md for comprehensive guidelines

Citation

You can cite
climate_indices` in your projects and research papers via the BibTeX entry below.
@misc {climate_indices,
    author = "James Adams",
    title  = "climate_indices, an open source Python library providing reference implementations of commonly used climate indices",
    url    = "https://github.com/monocongo/climate_indices",
    month  = "may",
    year   = "2017--"
}

Chat with me