GRASS logo

NAME

r.hydro.hbv - HBV lumped-basin rainfall-runoff model with Monte-Carlo/GLUE calibration (OpenMP parallel). Bundles the original Karkheh basin thesis dataset and the Plumergat DICRIM flood-risk dataset as ready-to-run demonstrations.

KEYWORDS

raster, hydrology, model, HBV

SYNOPSIS

r.hydro.hbv
r.hydro.hbv --help
r.hydro.hbv [-l] [dataset=string] [precipitation=name] [temperature=name] [evapotranspiration=name] [eta_observed=name] [discharge_observed=name] [precipitation_table=name] [temperature_table=name] [evapotranspiration_table=name] [eta_observed_table=name] [discharge_observed_table=name] [table_id_column=string] [table_date_column=string] [table_value_column=string] [era5_start=string] [era5_end=string] [era5_area=north,west,south,east] [era5_cache_dir=name] [parameters=name] [basin_ids=name] [elevation=name] [outlets=name] [dem_source=string] [dem_area=north,west,south,east] [id_column=name] [threshold=integer] [snap_radius=integer] [landcover=name] [forest_cats=integer[,integer,...]] [basins_ffo=float] [basins_ffi=float] [precip_station_elevation=float] [temp_station_elevation=float] [et_station_elevation=float] [parameters_template=name] [hru_bands=integer] [basins=name] [basins_vector=name] output=name [output_tables=name] [n_basins=integer] [n_calib_steps=integer] [n_days=integer] [n_years=integer] [warmup=integer] [n_realizations=integer] [tcon=float] [ecevpfo=float] [ecalt=float] [pcalt=float] [tcalt=float] [sfcf=float] [foscf=float] [rfcf=float] [tt=float] [tti=float] [dttm=float] [cfmax=float] [focfmax=float] [cfr=float] [whc=float] [sgwmax=float] [--overwrite] [--help] [--verbose] [--quiet] [--ui]

Flags:

-l
Legacy mode: do not reset performance accumulators between Monte-Carlo realizations (bit-for-bit reproduces the original 2005 Karkheh code, including its unreset-statistics quirk)
--overwrite
Allow output files to overwrite existing files
--help
Print usage summary
--verbose
Verbose module output
--quiet
Quiet module output
--ui
Force launching GUI dialog

Parameters:

dataset=string
Bundled demonstration dataset to run (fills in any input option left unset); use 'custom' to supply your own inputs
Options: original, dicrim, custom
Default: custom
precipitation=name
CSV of observed precipitation (mm/d), rows=days, cols=basins
temperature=name
CSV of observed temperature (deg C), rows=days, cols=basins
evapotranspiration=name
CSV of potential evapotranspiration (mm/d), rows=days, cols=basins
eta_observed=name
CSV of observed actual evapotranspiration used for calibration (mm/d), rows=days, cols=basins
discharge_observed=name
CSV of observed discharge (m3/s), rows=days, cols=stations
precipitation_table=name
Long-format (station_id,date,value) DB table of observed precipitation, instead of 'precipitation'
temperature_table=name
Long-format (station_id,date,value) DB table of observed temperature, instead of 'temperature'
evapotranspiration_table=name
Long-format (station_id,date,value) DB table of potential evapotranspiration, instead of 'evapotranspiration'
eta_observed_table=name
Long-format (station_id,date,value) DB table of observed actual evapotranspiration, instead of 'eta_observed'
discharge_observed_table=name
Long-format (station_id,date,value) DB table of observed discharge, instead of 'discharge_observed'
table_id_column=string
Station-identifier column name shared by all *_table options above
Default: station_id
table_date_column=string
Date column name shared by all *_table options above
Default: date
table_value_column=string
Value column name shared by all *_table options above
Default: value
era5_start=string
Start date (YYYY-MM-DD) to fetch ERA5(-Land) precipitation/temperature/potential_evaporation via t.in.era5, instead of precipitation/temperature/evapotranspiration or their _table equivalents; requires era5_end, and basins/basins_vector (elevation/outlets or basins_vector mode)
era5_end=string
End date (YYYY-MM-DD, inclusive) for era5_start
era5_area=north,west,south,east
Bounding box in WGS84 degrees for the ERA5(-Land) request; default derived from the current region
era5_cache_dir=name
Directory to cache downloaded ERA5(-Land) NetCDF files in (default a temporary, run-scoped directory)
parameters=name
CSV of HBV parameter bounds and basin physiography (22 rows x n_basins columns)
basin_ids=name
Text file with one basin identifier per line, used to name output files (defaults to Basin01, Basin02, ...); ignored if elevation/outlets or basins_vector is given
elevation=name
Input DEM for basin delineation (requires outlets; replaces 'parameters'/'basin_ids' CSV inputs with a GRASS-native delineation via r.hydro.hbv.basins)
outlets=name
Name of input vector map
Vector points map, one point per basin outlet/station (requires elevation or dem_source)
dem_source=string
Fetch a DEM via r.in.dem instead of giving elevation= directly (requires outlets, not elevation)
Options: copernicus_glo30, copernicus_glo90
dem_area=north,west,south,east
Bounding box in WGS84 degrees for dem_source; default derived from the current region
id_column=name
Attribute column in outlets holding the basin identifier
Default: id
threshold=integer
Minimum flow accumulation (cells) for basin delineation
Default: 1000
snap_radius=integer
Maximum distance (cells) to snap outlet points onto the derived stream network
Default: 3
landcover=name
Land-cover raster used to derive forest/field fraction per basin during delineation; omit to use basins_ffo/basins_ffi
forest_cats=integer[,integer,...]
Land-cover category values considered "forest" (required if landcover is given)
basins_ffo=float
Uniform forest fraction for every basin during delineation when landcover is not given
basins_ffi=float
Uniform field fraction for every basin during delineation when landcover is not given
precip_station_elevation=float
Elevation of the precipitation station/grid reference point during delineation; omit to skip the correction term
temp_station_elevation=float
Elevation of the temperature station/grid reference point during delineation; omit to skip the correction term
et_station_elevation=float
Elevation of the evapotranspiration station/grid reference point during delineation; omit to skip the correction term
parameters_template=name
CSV of HBV parameter sampling bounds (16 rows: fc,beta,lp,alpha,kf,ks,perc,cflux low/high), 1 column (broadcast) or one per delineated basin; required when elevation/outlets are given
hru_bands=integer
Number of elevation-band HRUs per basin during delineation (1 = one lumped unit per basin, no splitting); only used with elevation/outlets
Default: 1
basins=name
Name for output delineated basins raster map (required with elevation/outlets)
basins_vector=name
Name for the basins vector map: created when elevation/outlets are given, or read as-is (from a previous r.hydro.hbv.basins run) otherwise -- either way, its attribute table is used as this run's parameters input
output=name [required]
Output directory for Output*/Basinout*/ETout*/EToutput* CSVs
Default: .
output_tables=name
Name prefix for optional long-format (station_id,day,...) GRASS DB tables <prefix>_basinout/<prefix>_etout, written in addition to (not instead of) the CSVs above
n_basins=integer
Number of sub-basins / stations
n_calib_steps=integer
Number of daily time steps used in the calibration loop
n_days=integer
Number of daily rows in the input CSVs
n_years=integer
Number of years spanned by the data
warmup=integer
Warm-up period (time steps) excluded from performance stats
n_realizations=integer
Number of Monte-Carlo parameter realizations to run
tcon=float
Unit conversion mm/d -> m3/s factor
Default: 86.4
ecevpfo=float
Forest PET correction factor
Default: 1.15
ecalt=float
PET elevation correction factor
Default: 0.1
pcalt=float
Precipitation elevation correction factor
Default: 0.2
tcalt=float
Temperature elevation correction factor
Default: 0.6
sfcf=float
Snowfall correction factor
Default: 1.0
foscf=float
Forest snow correction factor
Default: 1.0
rfcf=float
Rainfall correction factor
Default: 1.0
tt=float
Threshold temperature (deg C)
Default: -0.5
tti=float
Temperature interval snow/rain (deg C)
Default: 2.0
dttm=float
Melt threshold temperature offset
Default: 0.54391
cfmax=float
Degree-day snowmelt factor (mm/d/degC)
Default: 3.5
focfmax=float
Forest degree-day factor ratio
Default: 0.6
cfr=float
Refreezing coefficient
Default: 0.05
whc=float
Water holding capacity of snowpack
Default: 0.1
sgwmax=float
Maximum groundwater box storage (mm)
Default: 5.0

Table of contents

DESCRIPTION

r.hydro.hbv implements the HBV (Hydrologiska Byrans Vattenbalansavdelning) conceptual rainfall-runoff model over one or more lumped sub-basins, run n_realizations times with randomly sampled parameter sets (Monte-Carlo/GLUE style uncertainty analysis), and reports Nash-Sutcliffe efficiency, relative volume error and related performance criteria per realization. The simulation loop over time steps and basins is parallelized with OpenMP.

This module generalizes what were originally two hand-forked, hard-coded C programs into a single, parametrized engine:

Both are bundled as ready-to-run demonstrations via dataset=original and dataset=dicrim. Use dataset=custom (the default) to point the module at your own lumped-basin CSV inputs.

INPUTS

All time-series inputs are headerless CSV files, one row per day and one column per basin/station: parameters is a CSV with 22 rows and one column per basin: rows 0-15 are paired low/high sampling bounds for the 8 free HBV parameters (fc, beta, lp, alpha, kf, ks, perc, cflux); row 16 is basin area (km2); rows 17-18 are forest/field area fractions; rows 19-21 are elevation differences (per 100 m) between basin and station for precipitation, temperature and evapotranspiration.

basin_ids is an optional text file, one identifier per line, used to name the output files (Basin01, Basin02, ... if omitted).

GRASS-native basin delineation (instead of parameters/basin_ids)

In place of the "parameters" CSV and "basin_ids" text file, basin physiography and identifiers can come straight from a GRASS vector map instead of any file on disk:

Either way, n_basins is not needed: the basin count comes from the number of populated rows in the vector's attribute table.

dem_source (+ optional dem_area) replaces elevation entirely: given together with outlets, r.hydro.hbv spawns r.in.dem itself to fetch a real DEM (Copernicus GLO-30/GLO-90, no account/API key needed, truly global land coverage) for the current region before delineating -- so any study area on Earth can be run against real terrain with no local elevation data prepared in advance.

GRASS-native time-series I/O (instead of CSV)

Each of precipitation/temperature/evapotranspiration/ eta_observed/discharge_observed has a *_table= alternative (precipitation_table=, etc.; column names overridable via table_id_column=/table_date_column=/ table_value_column=, default station_id/date/value): a long-format DB table, e.g. one built by r.hydro.hbv.forcing from an ERA5-Land/MODIS STRDS via zonal means, instead of a CSV file. n_days isn't needed in that case either -- the day count comes from the tables' own date axis (every *_table input must resolve to exactly the same set of dates).

output_tables=prefix additionally writes the discharge/ETa results as <prefix>_basinout/<prefix>_etout GRASS DB tables (long format: station_id,day,qo,qr,po / station_id,day,eta,eto), alongside (not instead of) the CSV outputs below.

Fetching precipitation/temperature/PET directly from ERA5

era5_start/era5_end (YYYY-MM-DD, + optional era5_area/era5_cache_dir) replace precipitation/ temperature/evapotranspiration (and their *_table equivalents) entirely: given together, r.hydro.hbv spawns t.in.era5 once (fetching ERA5-Land, falling back to ERA5, for all three variables) and r.hydro.hbv.forcing three times (zonal means against basins/basins_vector, both required in this mode) to build the same long-format tables the *_table= options expect -- no manual t.in.era5/r.hydro.hbv.forcing calls needed. eta_observed/discharge_observed are calibration targets (real gauge/remote-sensing observations), not meteorological forcing, so ERA5 has no equivalent for them -- they must still be given as CSV or *_table=, exactly as in every other mode.

SEMI-DISTRIBUTED (HRU) MODE

With hru_bands > 1, each basin becomes several elevation-band HRUs (computation units, btot in the code), each independently simulated, but discharge is summed and ETa area-weighted-averaged back to the reporting station level (rtot, one per basin, matching observed data) before scoring and before writing Basinout/ETout. The Output/EToutput parameter-diagnostic files, however, only report each station's first (lowest-elevation-band) HRU as a representative draw, not every HRU individually -- a limitation of hbv_performance.c's own per-station (not per-HRU) selection-counter bookkeeping, left unchanged; see docs/raster_options.md for detail. hru_bands=1 (the default) is an exact no-op relative to the lumped, one-unit-per-basin behavior this module always had.

OUTPUTS

For every basin, four CSV files are written under output:

EXAMPLES

Run the bundled original Karkheh thesis dataset:
r.hydro.hbv dataset=original output=/tmp/hbv_original -l
(the -l legacy flag reproduces the original 2005 code's behavior exactly, including not resetting statistics accumulators between realizations)

Run the bundled Plumergat DICRIM dataset:

r.hydro.hbv dataset=dicrim output=/tmp/hbv_dicrim
Run against custom lumped-basin data:
r.hydro.hbv dataset=custom \
  precipitation=precip.csv temperature=temp.csv \
  evapotranspiration=evap.csv eta_observed=etobs.csv \
  discharge_observed=dischargeobs.csv parameters=param_sto.csv \
  n_basins=4 n_calib_steps=1000 n_days=1000 n_years=3 warmup=100 \
  n_realizations=1000 output=/tmp/hbv_custom
Run against custom data with GRASS-native basin delineation instead of a "parameters" CSV (r.hydro.hbv spawns r.hydro.hbv.basins itself):
g.region raster=dem
r.hydro.hbv dataset=custom \
  precipitation=precip.csv temperature=temp.csv \
  evapotranspiration=evap.csv eta_observed=etobs.csv \
  discharge_observed=dischargeobs.csv \
  elevation=dem outlets=outlets id_column=ID threshold=1000 \
  landcover=landcover forest_cats=1,2,3 \
  parameters_template=hbv_param_bounds_16row.csv \
  basins=basins basins_vector=basins_v \
  n_calib_steps=1000 n_days=1000 n_years=3 warmup=100 \
  n_realizations=1000 output=/tmp/hbv_custom

NOTES ON EXTENDING TO RASTER INPUTS

The current engine operates entirely on lumped, basin-averaged time series (no raster I/O). See docs/raster_options.md in the module source tree for a discussion of options to evolve toward semi-distributed or fully distributed (raster-cell-based) HBV, and a recommended incremental path.

REFERENCES

SEE ALSO

r.watershed, r.water.outlet

AUTHOR

Yann Chemin

SOURCE CODE

Available at: r.hydro.hbv source code (history)

Accessed: Monday Jul 27 12:29:28 2026


Main index | Raster index | Topics index | Keywords index | Graphical index | Full index

© 2003-2026 GRASS Development Team, GRASS 8.5.1dev Reference Manual