Skip to main content

Differentiable conceptual hydrological models (GR6J, HBV) in JAX with gradient and evolutionary calibration

Project description

hydrologeez

Differentiable conceptual hydrological models in JAX.

PyPI version Python versions License: MIT

hydrologeez implements conceptual rainfall-runoff models (GR6J, HBV) as Equinox modules on top of JAX. Every model is a PyTree whose fields are its parameters, so a full simulation is end-to-end differentiable: jax.grad flows through the entire lax.scan over your forcing series. That makes both gradient-based and evolutionary parameter calibration first-class.

Installation

# uv (recommended)
uv add hydrologeez

# pip
pip install hydrologeez

GPU (CUDA 12) wheels of JAX via the cuda extra:

uv add "hydrologeez[cuda]"
# or
pip install "hydrologeez[cuda]"

Requirement: 64-bit precision (JAX_ENABLE_X64=1)

hydrologeez requires JAX 64-bit (float64) precision. It does not flip this for you. You must enable x64 before importing jax or hydrologeez, otherwise the import raises RuntimeError.

Enable it either by exporting the environment variable before running Python:

export JAX_ENABLE_X64=1

or, in code, as the very first thing your program does:

import os
os.environ["JAX_ENABLE_X64"] = "1"  # must run before any jax/hydrologeez import

Quick Start

A minimal forward run: build a GR6J model from explicit parameters, feed it a short synthetic daily forcing series, and read out simulated streamflow. No data files needed.

import os

os.environ["JAX_ENABLE_X64"] = "1"  # must be set before importing jax/hydrologeez

import jax.numpy as jnp

from hydrologeez.models.gr6j import GR6J, GR6JForcing

# GR6J's six parameters (x1..x6), each a scalar JAX array.
model = GR6J(
    x1=jnp.asarray(350.0),  # production store capacity [mm]
    x2=jnp.asarray(0.0),    # groundwater exchange coefficient
    x3=jnp.asarray(90.0),   # routing store capacity [mm]
    x4=jnp.asarray(1.7),    # unit-hydrograph time base [days]
    x5=jnp.asarray(0.3),    # inter-catchment exchange threshold
    x6=jnp.asarray(5.0),    # exponential store depth [mm]
)

# Daily forcing; the leading axis is time. Precipitation and PET in mm/day.
precip = jnp.asarray([0.0, 5.0, 12.0, 8.0, 0.0, 0.0, 3.0, 20.0, 1.0, 0.0])
pet = jnp.asarray([1.0, 1.2, 1.1, 0.9, 1.0, 1.3, 1.1, 0.8, 1.0, 1.2])
forcing = GR6JForcing(precip=precip, pet=pet)

# Forward run -> simulated streamflow timeseries, shape (T,), dtype float64.
streamflow = model.run(forcing)
print(streamflow)

For full internal fluxes, pass return_fluxes=True: observable, fluxes, final_state = model.run(forcing, return_fluxes=True).

Gradient-based and evolutionary calibration (using ctrl-freak's ga / nsga2 with the evaluate_batch hook) are covered in the documentation.

Features

  • GR6J and HBV conceptual rainfall-runoff models, ready to run.
  • Fully differentiable in JAX: each model is an Equinox PyTree, so jax.grad and jax.value_and_grad flow through the whole lax.scan simulation.
  • Two calibration paths: gradient descent (e.g. optax) and evolutionary search (ga / nsga2 from ctrl-freak, with a batched evaluate_batch hook).
  • Validated numerics: streamflow matches the retired Rust pydrology oracle to ~1e-4 relative error.
  • Batched simulation via batch_run (vmap over a leading batch axis).
  • 64-bit by default: import-time x64 enforcement keeps long store recurrences and metric reductions numerically stable.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hydrologeez-0.1.0.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hydrologeez-0.1.0-py3-none-any.whl (27.7 kB view details)

Uploaded Python 3

File details

Details for the file hydrologeez-0.1.0.tar.gz.

File metadata

  • Download URL: hydrologeez-0.1.0.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.0

File hashes

Hashes for hydrologeez-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a22689aa2e61b2a6991a22c17e1d58e87c7b0bb44992d241b158f1df6bb276fc
MD5 a66f0c0b96494522758dccaddb768a11
BLAKE2b-256 9d1a162404aa0eeaddff1ac0d4886bc1b6890cedc6a0aaa24642024d00c5ddb8

See more details on using hashes here.

File details

Details for the file hydrologeez-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for hydrologeez-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 776db994dc14036b6e334c4e8b558bb2b52c6001c40a4170cf35f3a81a091f0f
MD5 66a89c0544fcbc7b40376c893f2ebf7a
BLAKE2b-256 6e7ea5481862b748813e64a12d7c2d234aba2c366ee42ea1a2d04025c12c659d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page