{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Hydrological modelling - Raven (lumped)\n", "\n", "`xHydro` provides a collection of functions designed to facilitate hydrological modelling, focusing on two key models: [HYDROTEL](https://github.com/INRS-Modelisation-hydrologique/hydrotel) and a suite of models emulated by the [Raven Hydrological Framework](https://raven.uwaterloo.ca/). It is important to note that Raven already possesses an extensive Python library, [RavenPy](https://github.com/CSHS-CWRA/RavenPy), which enables users to build, calibrate, and execute models. `xHydro` wraps some of these functions to support multi-model assessments with HYDROTEL, though users seeking advanced functionalities may prefer to use `RavenPy` directly. \n", "\n", "The primary contribution of `xHydro` to hydrological modelling is thus its support for HYDROTEL, a model that previously lacked a dedicated Python library. This Notebook covers `RavenPy` models, but a similar notebook for `HYDROTEL` is available [here](hydrological_modelling_hydrotel.ipynb).\n", "\n", "## Basic information" ] }, { "cell_type": "code", "execution_count": 1, "id": "1", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "from IPython.display import clear_output\n", "\n", "import xhydro as xh\n", "import xhydro.modelling as xhm\n", "\n", "clear_output(wait=False)" ] }, { "cell_type": "code", "execution_count": 2, "id": "2", "metadata": { "editable": true, "nbsphinx": "hidden", "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "import logging\n", "\n", "logger = logging.getLogger()\n", "logger.setLevel(logging.CRITICAL)" ] }, { "cell_type": "markdown", "id": "3", "metadata": {}, "source": [ "The `xHydro` modelling framework is based on a `model_config` dictionary, which is meant to contain all necessary information to execute a given hydrological model. For example, depending on the model, it can store meteorological datasets directly, paths to datasets (netCDF files or other), csv configuration files, parameters, and basically anything that is required to configure and execute an hydrological model.\n", "\n", "The list of required inputs for the dictionary can be obtained one of two ways. The first is to look at the hydrological model's class, such as `xhydro.modelling.RavenpyModel`. The second is to use the `xh.modelling.get_hydrological_model_inputs` function to get a list of the required keys for a given model, as well as the documentation." ] }, { "cell_type": "code", "execution_count": 3, "id": "4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function get_hydrological_model_inputs in module xhydro.modelling.hydrological_modelling:\n", "\n", "get_hydrological_model_inputs(model_name: str, required_only: bool = False) -> tuple[dict, str]\n", " Get the required inputs for a given hydrological model.\n", "\n", " Parameters\n", " ----------\n", " model_name : str\n", " The name of the hydrological model to use.\n", " Currently supported models are [\"HYDROTEL\", \"Blended\", \"GR4JCN\", \"HBVEC\", \"HMETS\", \"HYPR\", \"Mohyse\", \"SACSMA\"].\n", " required_only : bool\n", " If True, only the required inputs will be returned.\n", "\n", " Returns\n", " -------\n", " dict\n", " A dictionary containing the required configuration for the hydrological model.\n", " str\n", " The documentation for the hydrological model.\n", "\n" ] } ], "source": [ "help(xhm.get_hydrological_model_inputs)" ] }, { "cell_type": "code", "execution_count": 4, "id": "5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'model_name': typing.Literal['Blended', 'GR4JCN', 'HBVEC', 'HMETS', 'HYPR', 'Mohyse', 'SACSMA'] | None,\n", " 'overwrite': bool,\n", " 'workdir': str | os.PathLike | None,\n", " 'executable': str | os.PathLike | None,\n", " 'run_name': str | None,\n", " 'start_date': datetime.datetime | str | None,\n", " 'end_date': datetime.datetime | str | None,\n", " 'parameters': numpy.ndarray | list[float] | None,\n", " 'qobs_file': os.PathLike | str | None,\n", " 'alt_name_flow': str | None,\n", " 'hru': geopandas.geodataframe.GeoDataFrame | dict | os.PathLike | str | None,\n", " 'output_subbasins': typing.Literal['all', 'qobs'] | list[int] | None,\n", " 'minimum_reservoir_area': str | None,\n", " 'meteo_file': os.PathLike | str | None,\n", " 'data_type': list[str] | None,\n", " 'alt_names_meteo': dict | None,\n", " 'meteo_station_properties': dict | None,\n", " 'gridweights': str | os.PathLike | None}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# This function can be called to get a list of the keys for a given model, as well as its documentation.\n", "inputs, docs = xhm.get_hydrological_model_inputs(\"GR4JCN\", required_only=False)\n", "inputs" ] }, { "cell_type": "code", "execution_count": 5, "id": "6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Initialize the RavenPy model class.\n", "\n", "Parameters\n", "----------\n", "overwrite : bool\n", " If True, overwrite the existing project files. Default is False.\n", "workdir : str | Path | None\n", " Path to save the .rv files and model outputs. Default is None, which creates a temporary directory.\n", "executable : str | os.PathLike | None, optional\n", " Path to the Raven executable, bypassing RavenPy.\n", " If None (default), the Raven executable from your current Python environment ('raven-hydro') will be used.\n", "run_name : str, optional\n", " Name of the run, which will be used to name the project files. Defaults to \"raven\" if not provided.\n", "model_name : {\"Blended\", \"GR4JCN\", \"HBVEC\", \"HMETS\", \"HYPR\", \"Mohyse\", \"SACSMA\"}, optional\n", " The name of the RavenPy model to run. Only optional if the project files already exist.\n", "start_date : dt.datetime | str, optional\n", " The first date of the simulation. Only optional if the project files already exist.\n", "end_date : dt.datetime | str, optional\n", " The last date of the simulation. Only optional if the project files already exist.\n", "parameters : np.ndarray | list[float], optional\n", " The model parameters for simulation or calibration. Only optional if the project files already exist.\n", "qobs_file : str | Path, optional\n", " Path to the file containing the observed streamflow data.\n", " If there are multiple stations, the file should contain a 'basin_id' variable that identifies the subbasin for each time series.\n", " If a 'station_id' variable is present, it will be used to identify the station.\n", "alt_name_flow : str, optional\n", " Name of the streamflow variable in the observed data file. If not provided, it will be assumed to be \"q\".\n", "hru : gpd.GeoDataFrame | dict | os.PathLike, optional\n", " A GeoDataFrame, or dictionary containing the HRU properties. Only optional if the project files already exist.\n", " For distributed models, it should be readable by ravenpy.extractors.BasinMakerExtractor.\n", " For lumped models, should contain the following variables:\n", " - area: The watershed drainage area, in km².\n", " - elevation: The elevation of the watershed, in meters.\n", " - latitude: The latitude of the watershed centroid.\n", " - longitude: The longitude of the watershed centroid.\n", " - HRU_ID: The ID of the HRU (required for gridded data, optional for station data).\n", " If the meteorological data is gridded, the HRU dataset must also contain a SubId, DowSubId, valid geometry and crs.\n", " If the input is modified, a new shapefile will be created in the workdir/weights subdirectory.\n", "output_subbasins : {\"all\", \"qobs\"} | list[int] | None, optional\n", " If \"all\", all subbasins will be outputted. If \"qobs\", only the subbasins with observed flow will be outputted.\n", " Leave as None to use the value as defined in the HRU file ('Has_Gauge' column). Only applicable for distributed HBVEC models.\n", "minimum_reservoir_area : str, optional\n", " Quantified string (e.g. \"20 km2\") representing the minimum lake area to consider the lake explicitly as a reservoir.\n", " If not provided, all lakes with the 'HRU_IsLake' column set to 1 in the HRU file will be considered as reservoirs.\n", " Note that 'reservoirs' in Raven can also refer to natural lakes with weir-like outflows.\n", " Only applicable for distributed HBVEC models.\n", "meteo_file : str | Path, optional\n", " Path to the file containing the observed meteorological data. Only optional if the project files already exist.\n", " The meteorological data can be either station or gridded data. Use the 'xhydro.modelling.format_input' function to ensure the data\n", " is in the correct format. Unless the input is a single station accompanied by 'meteo_station_properties', the file should contain\n", " the following coordinates:\n", " - elevation: The elevation of the station / grid cell, in meters.\n", " - latitude: The latitude of the station / grid cell centroid.\n", " - longitude: The longitude of the station / grid cell centroid.\n", "data_type : list[str], optional\n", " The list of types of data provided to Raven in the meteorological file. Only optional if the project files already exist.\n", " See https://github.com/CSHS-CWRA/RavenPy/blob/master/src/ravenpy/config/conventions.py for the list of available types.\n", "alt_names_meteo : dict, optional\n", " A dictionary that allows users to link the names of meteorological variables in their dataset to Raven-compliant names.\n", " The keys should be the Raven names as listed in the data_type parameter.\n", "meteo_station_properties : dict, optional\n", " Additional properties of the weather stations providing the meteorological data. Only required if absent from the 'meteo_file'.\n", " For single stations, the format is {\"ALL\": {\"elevation\": elevation, \"latitude\": latitude, \"longitude\": longitude}}.\n", " This has not been tested for multiple stations or gridded data.\n", "gridweights : str | Path | None\n", " If using gridded meteorological data, path to a text file containing the weights linking the grid cells to the HRUs.\n", " If None, the weights will be computed using ravenpy.extractors.GridWeightExtractor and saved in a 'weights' subdirectory\n", " of the project folder, using a \"{meteo_file}_vs_{hru_file}_weights.txt\" pattern.\n", "\\*\\*kwargs : dict, optional\n", " Additional parameters to pass to the RavenPy emulator, to modify the default modules used by a given hydrological model.\n", " Typical entries include RainSnowFraction, Evaporation, GlobalParameters, etc.\n", " See https://raven.uwaterloo.ca/Downloads.html for the latest Raven documentation. Currently, model templates are listed in Appendix F.\n", "\n" ] } ], "source": [ "print(docs)" ] }, { "cell_type": "markdown", "id": "7", "metadata": {}, "source": [ "HYDROTEL and Raven vary in terms of required inputs and available functions, but an effort will be made to standardize the outputs as much as possible. Currently, all models include the following three functions:\n", "\n", "- `.run()`: Executes the model, reformats the outputs to be compatible with analysis tools in `xHydro`, and returns the simulated streamflow as a `xarray.Dataset`.\n", " - The streamflow variable will be named `q` and will have units of `m3 s-1`.\n", " - For 1D data (such as hydrometric stations), the corresponding dimension in the dataset will be identified by the `cf_role: timeseries_id` attribute.\n", " \n", "- `.get_inputs()`: Retrieves the meteorological inputs used by the model.\n", "\n", "- `.get_outputs()`: Retrieves the simulated outputs from the model.\n", " - Use `.get_outputs(\"q\")` to obtain the simulated streamflow as a `xarray.Dataset`.\n", "\n", "- `.standardize_outputs()`: Standardizes the outputs to ensure consistency across different models, facilitating comparison and analysis. This function is used by default in the `.run()` method, but can also be called separately if needed." ] }, { "cell_type": "markdown", "id": "8", "metadata": {}, "source": [ "## Initializing and running a calibrated model\n", "Raven requires several `.rv*` files to control various aspects such as meteorological inputs, watershed characteristics, and more. If the project directory already exists and contains data, `xHydro` will prepare the model for execution without overwriting existing `.rv*` files—unless the `overwrite` argument is explicitly set to `True`. To force overwriting of these files, you can thus either:\n", "\n", "- Set `overwrite=True` in the `model_config` when instantiating the model\n", "- Use the `.create_rv(overwrite=True)` method on the instantiated model.\n", "\n", "This Notebook will focus on lumped RavenPy models. For distributed models, refer to the [Raven distributed modelling notebook](pavics_notebooks/hydrological_modelling_raven_distributed.ipynb).\n", "\n", "### Acquiring HRU Data\n", "\n", "Raven relies on Hydrological Response Units (HRUs) for its hydrological simulations. For lumped models, only one HRU can be used at a time.\n", "\n", "If using station-based meteorological data, the required HRU attributes are minimal:\n", "\n", "- `area`: Watershed drainage area (km²) \n", "- `elevation`: Watershed elevation (m) \n", "- `latitude`: Latitude of the watershed centroid \n", "- `longitude`: Longitude of the watershed centroid \n", "\n", "If using gridded meteorological data, additional attributes are required, but `xHydro` will use default values for those that are not provided (except for the geometry):\n", "\n", "- `HRU_ID`: Unique identifier for the HRU (set to `1` for lumped models) \n", "- `SubId`: Subbasin ID (set to `1` for lumped models) \n", "- `DowSubId`: Downstream Subbasin ID (set to `-1` for lumped models) \n", "- A valid geometry and coordinate reference system (`crs`) \n", "\n", "HRUs can be represented as either a `geopandas.GeoDataFrame` or a Python `dict`. To assist with HRU creation, you can use the `xhydro.gis.watershed_to_raven_hru` function, which will extract the necessary information from functions described in the [GIS notebook](gis.ipynb).\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function watershed_to_raven_hru in module xhydro.gis:\n", "\n", "watershed_to_raven_hru(\n", " watershed: gpd.GeoDataFrame | tuple | str | os.PathLike,\n", " *,\n", " unique_id: str | None = None,\n", " projected_crs: int | str | None = 'NAD83',\n", " **kwargs\n", ") -> gpd.GeoDataFrame\n", " Extract the necessary properties for Raven hydrological models.\n", "\n", " Parameters\n", " ----------\n", " watershed : gpd.GeoDataFrame | tuple | str | Path\n", " The input, which is either:\n", " - A gpd.GeoDataFrame containing watershed polygons with a defined .crs attribute.\n", " - The path to such a gpd.GeoDataFrame.\n", " - Coordinates (longitude, latitude) for the location from where watershed delineation will be conducted.\n", " unique_id : str, optional\n", " The column name in the GeoDataFrame that serves as a unique identifier.\n", " Ignored if the input is a coordinate tuple.\n", " projected_crs : int | str\n", " The projected coordinate reference system (crs) to utilize for calculations, such as determining watershed area.\n", " If a string is provided, it should be a valid Geodetic CRS for the `gpd.estimate_utm_crs()` method.\n", " If None, the function will use the `gpd.estimate_utm_crs()` default (WGS 84).\n", " Default is an estimated CRS based on NAD83.\n", " \\*\\*kwargs : dict\n", " Additional keyword arguments passed to the `surface_properties` function.\n", "\n", " Returns\n", " -------\n", " gpd.GeoDataFrame\n", " Output GeoDataFrame containing the watershed properties required for Raven hydrological models.\n", "\n", " Notes\n", " -----\n", " Gridded meteorological data in RavenPy requires the `SubId` and `DowSubId` columns to be set, but this cannot currently be\n", " automatically calculated. Therefore, the function sets `SubId` to 1 and `DowSubId` to -1 by default, which is\n", " correct for lumped hydrological models, but will not be appropriate for distributed models. Until this is fixed, only a\n", " single watershed can be delineated.\n", "\n", " Furthermore, still for gridded meteorological data, RavenPy requires a shapefile with a valid geometry. Until a method\n", " is implemented to convert the geometry to something valid in xarray, the function will only return GeoDataFrames.\n", "\n" ] } ], "source": [ "help(xh.gis.watershed_to_raven_hru)" ] }, { "cell_type": "code", "execution_count": 7, "id": "10", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/rondeau/projets/xhydro/src/xhydro/gis.py:201: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", "\n", "/home/rondeau/projets/xhydro/src/xhydro/gis.py:202: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", "\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
HRU_IDarealatitudelongitudeelevationSubIdDowSubIdgeometry
07120384690755.97689645.948568-71.801471275.8222351-1POLYGON ((-71.60638 45.77973, -71.61029 45.782...
\n", "
" ], "text/plain": [ " HRU_ID area latitude longitude elevation SubId DowSubId \\\n", "0 7120384690 755.976896 45.948568 -71.801471 275.822235 1 -1 \n", "\n", " geometry \n", "0 POLYGON ((-71.60638 45.77973, -71.61029 45.782... " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hru = xh.gis.watershed_to_raven_hru((-72.0873547526953, 46.000456612402))\n", "hru" ] }, { "cell_type": "markdown", "id": "11", "metadata": {}, "source": [ "### Formatting Meteorological Data\n", "\n", "
INFO\n", "\n", "If using multiple meteorological stations, it is recommended to add the `Interpolation` argument to `model_config` or the `RavenpyModel` call to control the interpolation algorithm. Raven uses the nearest neighbour method by default, but other options are available:\n", "\n", "- `INTERP_NEAREST_NEIGHBOR` (default) — Nearest neighbor (Voronoi) method \n", "- `INTERP_INVERSE_DISTANCE` — Inverse distance weighting \n", "- `INTERP_INVERSE_DISTANCE_ELEVATION` — Inverse distance weighting with consideration of elevation \n", "- `INTERP_AVERAGE_ALL` — Averages all specified gauge readings \n", "- `INTERP_FROM_FILE [filename]` — Weights for each gauge at each HRU are specified in an external file. This method should work via `xHydro`, but it has not been fully tested.\n", "\n", "
\n", "\n", "
INFO\n", "\n", "When using gridded meteorological data, `xHydro` uses functions from `RavenPy` to compute weights for each grid cell based on the HRU's geometry. \n", "Ensure that the domain of the grid completely covers the watershed.\n", "\n", "
\n", "\n", "The acquisition of raw meteorological data is covered in the [GIS notebook](gis.ipynb) and [Use Case Example](use_case.ipynb) notebooks. Therefore, this notebook will use a test dataset." ] }, { "cell_type": "code", "execution_count": 8, "id": "12", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 132kB\n",
       "Dimensions:   (time: 6576)\n",
       "Coordinates:\n",
       "  * time      (time) datetime64[ns] 53kB 1981-12-31 1982-01-01 ... 2000-01-01\n",
       "    altitude  int64 8B 450\n",
       "    lat       int64 8B 46\n",
       "    lon       int64 8B -72\n",
       "Data variables:\n",
       "    tmin      (time) float32 26kB ...\n",
       "    tmax      (time) float32 26kB ...\n",
       "    pr        (time) float32 26kB ...\n",
       "Attributes: (12/31)\n",
       "    GRIB_NV:                                  0\n",
       "    GRIB_Nx:                                  1440\n",
       "    GRIB_Ny:                                  721\n",
       "    GRIB_cfName:                              unknown\n",
       "    GRIB_cfVarName:                           t2m\n",
       "    GRIB_dataType:                            an\n",
       "    ...                                       ...\n",
       "    GRIB_typeOfLevel:                         surface\n",
       "    GRIB_units:                               degC\n",
       "    long_name:                                2 metre temperature\n",
       "    standard_name:                            unknown\n",
       "    units:                                    degC\n",
       "    grid_mapping:                             crs
" ], "text/plain": [ " Size: 132kB\n", "Dimensions: (time: 6576)\n", "Coordinates:\n", " * time (time) datetime64[ns] 53kB 1981-12-31 1982-01-01 ... 2000-01-01\n", " altitude int64 8B 450\n", " lat int64 8B 46\n", " lon int64 8B -72\n", "Data variables:\n", " tmin (time) float32 26kB ...\n", " tmax (time) float32 26kB ...\n", " pr (time) float32 26kB ...\n", "Attributes: (12/31)\n", " GRIB_NV: 0\n", " GRIB_Nx: 1440\n", " GRIB_Ny: 721\n", " GRIB_cfName: unknown\n", " GRIB_cfVarName: t2m\n", " GRIB_dataType: an\n", " ... ...\n", " GRIB_typeOfLevel: surface\n", " GRIB_units: degC\n", " long_name: 2 metre temperature\n", " standard_name: unknown\n", " units: degC\n", " grid_mapping: crs" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import xarray as xr\n", "\n", "from xhydro.testing.helpers import ( # In-house function to get data from the xhydro-testdata repo\n", " deveraux,\n", ")\n", "\n", "D = deveraux()\n", "\n", "meteo_file = D.fetch(\"ravenpy/ERA5_Riviere_Rouge_global.nc\")\n", "ds = xr.open_dataset(meteo_file)\n", "\n", "# Add spatial information\n", "ds = ds.assign_coords({\"altitude\": 450, \"lat\": 46, \"lon\": -72})\n", "ds[\"altitude\"].attrs[\"units\"] = \"m\"\n", "ds[\"lat\"].attrs[\"units\"] = \"degrees_north\"\n", "ds[\"lon\"].attrs[\"units\"] = \"degrees_east\"\n", "ds" ] }, { "cell_type": "markdown", "id": "13", "metadata": {}, "source": [ "Every hydrological model has different requirements when it comes to their input data. In this example, the data variables have units (temperatures in `degC` and precipitation in `mm`) that would be compatible with the requirements for Raven, but this might not always be the case. For reference on default units expected by Raven, consult [this link](https://ravenpy.readthedocs.io/en/latest/_modules/ravenpy/config/defaults.html#). Furthermore, the spatial information that we added lacks attributes or names that would allow RavenPy to recognize them.\n", "\n", "The function `xh.modelling.format_input` can be used to reformat CF-compliant datasets for use in hydrological models." ] }, { "cell_type": "code", "execution_count": 9, "id": "14", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function format_input in module xhydro.modelling.hydrological_modelling:\n", "\n", "format_input(\n", " ds: xr.Dataset,\n", " model: str,\n", " convert_calendar_missing: float | str | dict | bool = nan,\n", " save_as: str | PathLike | None = None,\n", " **kwargs\n", ") -> tuple[xr.Dataset, dict]\n", " Reformat CF-compliant meteorological data for use in hydrological models. See the \"Notes\" section for important details.\n", "\n", " Parameters\n", " ----------\n", " ds : xr.Dataset\n", " A dataset containing the meteorological data. See the \"Notes\" section for more information on the expected format.\n", " model : str\n", " The name of the hydrological model to use.\n", " Currently supported models are:\n", " - \"HYDROTEL\", \"Raven\" (which is an alias for all RavenPy models), \"Blended\", \"GR4JCN\", \"HBVEC\", \"HMETS\", \"HYPR\", \"Mohyse\", \"SACSMA\".\n", " convert_calendar_missing : float | str | dict | bool, optional\n", " The value to use for missing values when converting the calendar to \"standard\".\n", " If the value is a float, it will be used as the fill value for all variables.\n", " If the value is a string \"interpolate\", the new dates will be linearly interpolated over time.\n", " A dictionary can be used to specify a different fill value for each variable.\n", " Keys should be the names of the variables as they appear in the first entry in the \"variable_name\" lists of the \"Notes\" section.\n", " If True, temperatures will be interpolated and precipitation will be filled with 0.\n", " If False, the calendar will not be converted. Only possible for \"Raven\" models.\n", " save_as : str, optional\n", " Where to save the reformatted data. If None, the data will not be saved.\n", " This can be useful when multiple files are needed for a single model run (e.g. HYDROTEL needs a configuration file).\n", " \\*\\*kwargs : dict\n", " Additional keyword arguments to pass to the save function.\n", "\n", " Returns\n", " -------\n", " xr.Dataset\n", " The reformatted dataset.\n", " dict\n", " For HYDROTEL, a dictionary containing the configuration for the meteorological data.\n", " If `save_as` is provided, the configuration will have been saved to a file with the same name as `save_as`, but with a \".nc.config\" extension.\n", " For Raven, a dictionary containing the 'data_type' and 'alt_names_meteo' keys required for the 'model_config' argument.\n", "\n", " Notes\n", " -----\n", " The input dataset should ideally be CF-compliant and follow CMIP6's Controlled Vocabulary, but this function will attempt to detect the\n", " variables based on the standard_name attribute, the cell_methods attribute, or the variable name.\n", " More information on those attributes can be found here: https://wcrp-cmip.org/cmip-model-and-experiment-documentation/, and specifically\n", " the 'CMIP6 MIP table' link provided in the 'Search for variables' section.\n", "\n", " Specifically:\n", "\n", " - If using 1D time series, the station dimension should have an attribute `cf_role` set to \"timeseries_id\".\n", " - Units don't need to be canonical, but they should be convertible to the expected units and be understood by `xclim`.\n", " - Elevation represents the altitude of the meteorological data / model grid cell, not the altitude of the ground.\n", " - Snowfall units should be in water equivalent of precipitation (e.g. mm/day or kg/m²/s), NOT height (e.g. cm of fresh snow on the ground).\n", " - The function will try to detect the variables based on the attributes and the variable name. The following attempts will be made:\n", " - Longitude:\n", " - standard_name: \"longitude\"\n", " - variable name: \"longitude\", \"lon\"\n", " - Latitude:\n", " - standard_name: \"latitude\"\n", " - variable name: \"latitude\", \"lat\"\n", " - Elevation:\n", " - standard_name: \"surface_altitude\"\n", " - variable name: \"elevation\", \"orog\", \"z\", \"altitude\", \"height\"\n", " - Precipitation:\n", " - standard_name: \"*precipitation*\" (e.g. \"lwe_thickness_of_precipitation_amount\")\n", " - variable name: \"pr\", \"precip\", \"precipitation\"\n", " - Rainfall:\n", " - standard_name: \"*rainfall*\" (e.g. \"rainfall_flux\", \"rainfall_amount\")\n", " - variable name: \"prra\", \"prlp\", \"rainfall\", \"rain\", \"precipitation_rain\"\n", " - Snowfall:\n", " - standard_name: \"*snowfall*\" (e.g. \"snowfall_flux\", \"snowfall_amount\")\n", " - variable name: \"prsn\", \"snowfall\", \"precipitation_snow\"\n", " - Maximum temperature:\n", " - standard_name: \"air_temperature\"\n", " - cell_methods: \"time: maximum\"\n", " - variable name: \"tasmax\", \"tmax\", \"t2m_max\", \"temperature_max\"\n", " - Minimum temperature:\n", " - standard_name: \"air_temperature\"\n", " - cell_methods: \"time: minimum\"\n", " - variable name: \"tasmin\", \"tmin\", \"t2m_min\", \"temperature_min\"\n", " - Mean temperature:\n", " - standard_name: \"air_temperature\"\n", " - cell_methods: \"time: mean\"\n", " - variable name: \"tas\", \"tmean\", \"t2m\", \"temperature_mean\"\n", "\n", " HYDROTEL requires the following variables: [\"longitude\", \"latitude\", \"elevation\", \"time\", \"tasmax\", \"tasmin\", \"pr\"].\n", " Raven requires the following variables: [\"longitude\", \"latitude\", \"elevation\", \"time\", \"tasmax/tasmin\" or \"tas\", \"pr\" or \"prlp/prsn\"].\n", "\n" ] } ], "source": [ "help(xh.modelling.format_input)" ] }, { "cell_type": "code", "execution_count": 10, "id": "15", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/exec/rondeau/.conda/envs/xhydro-20260311/lib/python3.14/site-packages/clisops/utils/dataset_utils.py:1772: UserWarning: For coordinate variable 'longitude' no bounds can be identified.\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 132kB\n",
       "Dimensions:     (station_id: 1, time: 6576)\n",
       "Coordinates:\n",
       "  * station_id  (station_id) <U1 4B '0'\n",
       "    elevation   (station_id) int64 8B 450\n",
       "    latitude    (station_id) int64 8B 46\n",
       "    longitude   (station_id) int64 8B -72\n",
       "  * time        (time) datetime64[ns] 53kB 1981-12-31 1982-01-01 ... 2000-01-01\n",
       "Data variables:\n",
       "    tasmin      (station_id, time) float32 26kB -14.84 -6.52 ... -26.85 -15.48\n",
       "    tasmax      (station_id, time) float32 26kB -5.316 -0.0699 ... -14.92 -15.48\n",
       "    pr          (station_id, time) float32 26kB 0.3767 9.103 ... 0.07919 0.01176\n",
       "Attributes: (12/31)\n",
       "    GRIB_NV:                                  0\n",
       "    GRIB_Nx:                                  1440\n",
       "    GRIB_Ny:                                  721\n",
       "    GRIB_cfName:                              unknown\n",
       "    GRIB_cfVarName:                           t2m\n",
       "    GRIB_dataType:                            an\n",
       "    ...                                       ...\n",
       "    GRIB_typeOfLevel:                         surface\n",
       "    GRIB_units:                               degC\n",
       "    long_name:                                2 metre temperature\n",
       "    standard_name:                            unknown\n",
       "    units:                                    degC\n",
       "    grid_mapping:                             crs
" ], "text/plain": [ " Size: 132kB\n", "Dimensions: (station_id: 1, time: 6576)\n", "Coordinates:\n", " * station_id (station_id) " ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hm = xhm.hydrological_model(model_config)\n", "hm" ] }, { "cell_type": "markdown", "id": "22", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "### Validating the Meteorological Data\n", "\n", "Before executing hydrological models, a few basic checks will be performed automatically. However, users may want to conduct more advanced health checks on the meteorological inputs (e.g., identifying unrealistic values). This can be done using `xhydro.utils.health_checks`. For the full list of available checks, refer to [the 'xscen' documentation](https://xscen.readthedocs.io/en/latest/notebooks/3_diagnostics.html#Health-checks).\n", "\n", "We can use `.get_inputs()` to automatically retrieve the meteorological data. In this example, we'll ensure there are no abnormal meteorological values or sequences of values.\n" ] }, { "cell_type": "code", "execution_count": 14, "id": "23", "metadata": {}, "outputs": [], "source": [ "health_checks = {\n", " \"raise_on\": [], # If an entry is not here, it will warn the user instead of raising an exception.\n", " \"flags\": {\n", " \"pr\": { # You can have specific flags per variable.\n", " \"negative_accumulation_values\": {},\n", " \"very_large_precipitation_events\": {},\n", " \"outside_n_standard_deviations_of_climatology\": {\"n\": 5},\n", " \"values_repeating_for_n_or_more_days\": {\"n\": 5},\n", " },\n", " \"tasmax\": {\n", " \"tasmax_below_tasmin\": {},\n", " \"temperature_extremely_low\": {},\n", " \"temperature_extremely_high\": {},\n", " \"outside_n_standard_deviations_of_climatology\": {\"n\": 5},\n", " \"values_repeating_for_n_or_more_days\": {\"n\": 5},\n", " },\n", " \"tasmin\": {\n", " \"temperature_extremely_low\": {},\n", " \"temperature_extremely_high\": {},\n", " \"outside_n_standard_deviations_of_climatology\": {\"n\": 5},\n", " \"values_repeating_for_n_or_more_days\": {\"n\": 5},\n", " },\n", " },\n", "}" ] }, { "cell_type": "code", "execution_count": 15, "id": "24", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/exec/rondeau/.conda/envs/xhydro-20260311/lib/python3.14/site-packages/xscen/diagnostics.py:291: UserWarning: The following health checks failed:\n", " - 'pr' has suspicious values according to the following flags: ['outside_5_standard_deviations_of_climatology', 'values_repeating_for_5_or_more_days'].\n" ] } ], "source": [ "from xclim.core.units import amount2rate\n", "\n", "with hm.get_inputs() as ds_in:\n", " ds_in[\"pr\"] = amount2rate(ds_in[\"pr\"]) # Precipitation in xclim needs to be a flux.\n", "\n", " xh.utils.health_checks(ds_in, **health_checks)" ] }, { "cell_type": "markdown", "id": "25", "metadata": {}, "source": [ "### Executing the Model\n", "\n", "A few basic checks are performed when the `.run()` function is called, before executing the model itself. However, since both RavenPy and Raven will perform a series of checkups themselves, they are kept at a minimum in `xHydro`. If required, a `RavenpyModel.executable` class attribute can be used to point to your own Raven executable instead of the one provided by the `raven-hydro` library in the active Python environment.\n", "\n", "Once the model is executed, `xHydro` will automatically reformat the NetCDF file to bring it closer to CF conventions, ensuring compatibility with other `xHydro` modules. Note that, at this time, only the streamflow variable is reformatted, as the modularity of Raven allows for a wide variety of outputs, and it is not yet clear how to standardize all of them. However, dimensions and coordinates will be standardized across all files." ] }, { "cell_type": "code", "execution_count": 16, "id": "26", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 12kB\n",
       "Dimensions:             (time: 730)\n",
       "Coordinates:\n",
       "  * time                (time) datetime64[ns] 6kB 1990-01-01 ... 1991-12-31\n",
       "    subbasin_id         <U1 4B ...\n",
       "    elevation           float32 4B ...\n",
       "    drainage_area       float64 8B ...\n",
       "    centroid_longitude  float64 8B ...\n",
       "    centroid_latitude   float64 8B ...\n",
       "Data variables:\n",
       "    q                   (time) float64 6kB ...\n",
       "Attributes:\n",
       "    Conventions:      CF-1.6\n",
       "    featureType:      timeSeries\n",
       "    history:          Created on 2026-04-01T12:54:24 by Raven 4.1\n",
       "    description:      Standard Output\n",
       "    references:       Craig J.R. and the Raven Development Team Raven user's ...\n",
       "    model_id:         GR4JCN\n",
       "    Raven_version:    4.1\n",
       "    RavenPy_version:  0.20.0
" ], "text/plain": [ " Size: 12kB\n", "Dimensions: (time: 730)\n", "Coordinates:\n", " * time (time) datetime64[ns] 6kB 1990-01-01 ... 1991-12-31\n", " subbasin_id ]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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ZhyAX3r4AEVaccOGDTJw4MAS56levbp64lDFnZKSompMAE8WPoSRDdGsW7dOHYchGk/Ch+esWbPk3XffVV8O2rZ161aVyv/666/N5127dq35MD5c8csYKX9/h+dRn/JMT09XGQx/Uq1aNTUEiGG+CxcuWJyGtC+eR2TbMESIFO/y5cttXg+ya9psNKO/D31JoL8PjfAeBL4P95fpfXj8+HHp0aOHytigXhPBrUuYAlhGRoZp8+bNasND8d5776nDR44cUad/9913albBwYMHTT/99JOqwh8yZIjFdXz++edqdtKBAwdMX375pZplMXbs2BIV75iRgPNha9u2relf//qXydMwOwAzWs6dO1fitOeff950+eWXm2dRtG7d2vTnn3+atm/fbhowYICpfv36ppycHJ+aDVKWmRTjx483xcXFmVasWKHu26BBg0xRUVF+N5Ni3759purVq5u6detmWr58uSkxMdG0YMECU5s2bUxNmzY1paamqvONGjXKVK9ePXV/MNMFz++cOXPUaceOHTNVqFDB9MUXX5hSUlLU+8HI70NcH64Xs4bwnGu36en7HYjvQyO+B4HvwyFOvQ+PHz+uZlT26tVLff5g9qW2lVdABzPaB4a9KaoffvihmtIaEhKiPkRefPFF8weJ5rnnnjPVqlVLnQdfIu+++66psLDQ4jz4YrnzzjvVNExsOHz27FmTpyGAuummm2yetnHjRnXfsf/4i+me+CDFh26nTp1MW7ZsMZ/Xnz5EYcSIEaahQ4eqw5g2eNttt5mio6PVlzy+yP11WmhCQoIKVvDFgNcf7s/jjz9uOn36tPk8Fy5cMD311FOm2rVrm6dm4wNH88orr6jLI6jx1tRsT70PcX22bge370mB+D406nsQ+D50/H2I16yt96Ar8ioV8I9rcjxkBCiuxFgmUtq+0iW1vFBkhvFtW03ZiHyR0d6HfA+Su7FmhgwLXwS//fab+mJAx1gi4nuQjImzmciw7r33XtVr5emnn7ZZpEZEfA+SMXCYiYiIiPwah5mIiIjIrzGYISIiIr/GYIaIiIj8GoMZIiIi8msMZojIJ2FKPdYdOnfunLd3hYh8HGczEZFPwHotl19+uXzwwQfq/1hU8syZM2pBVn9bTJGIPIt9ZojIJ2EhTKy4S0R0KRxmIiKvGzVqlFrd+8MPP1RZGGxffPGFxTAT/o/W/r/++qs0b95cIiIi5JZbbpGsrCyZOXOmNGzYUKpWrSqPP/64xUrgyPA8++yzUqdOHYmMjJTOnTurISwiMg5mZojI6xDE7Nu3T9q0aSOvvPKKOm7nzp0lznf+/HmZOnWqzJ49WzIyMmTIkCFqQ5Dz+++/y6FDh2To0KFy7bXXyrBhw9Rl7rnnHklISFCXiY+Pl3nz5qm1grZv3y5Nmzb1+H0lItdjMENEXhcTE6OGlZBt0YaW9uzZU+J8eXl5Mm3aNLnsssvU/5GZ+fLLL+XkyZMSFRUlrVq1Ugs0Ll26VAUzBw8elG+//VaOHTumAhkYN26cLFy4UGbMmCGvv/66h+8pEbkDgxki8hsIdrRABlAcjOElBDL641JSUtThTZs2iclkkmbNmllcT05OjlSrVs2De05E7sRghoj8RkhIiMX/UVNj67jCwkJ1GH+DgoJk48aN6q+ePgAiIv/GYIaIfAKGmfSFu65wxRVXqOtEpqZbt24uvW4i8h2czUREPgHDRevWrVPFuqdPnzZnV8oDw0t33nmn3H333fLjjz/K4cOHZf369fLmm2+qgmEiMgYGM0TkE1CYi6EgFPHWqFFDEhMTXXK9KPRFMPP000+rKd0DBgxQQVO9evVccv1E5H3sAExERER+jZkZIiIi8msMZoiIiMivMZghIiIiv8ZghoiIiPwagxkiIiLyawxmiIiIyK8xmCEiIiK/xmCGiIiI/BqDGSIiIvJrDGaIiIjIrzGYISIiIr/GYIaIiIjEn/0/kFg3vqH4laMAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ds_out[\"q\"].plot()" ] }, { "cell_type": "markdown", "id": "28", "metadata": {}, "source": [ "### Retrieving additional outputs\n", "\n", "By default, Raven produces multiple output files in addition to the streamflow file, which contain various state variables. The `.get_outputs()` function can be used to retrieve any of these variables as a `xarray.Dataset`." ] }, { "cell_type": "code", "execution_count": 18, "id": "29", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on method get_outputs in module xhydro.modelling._ravenpy_models:\n", "\n", "get_outputs(output: str, return_paths: bool = False, **kwargs) -> xr.Dataset | Path | list[Path] method of xhydro.modelling._ravenpy_models.RavenpyModel instance\n", " Return the outputs of the Raven model.\n", "\n", " Parameters\n", " ----------\n", " output : str\n", " \"path\" to return the output directory.\n", " \"q\" to only return the streamflow variable.\n", " Alternatively, a string matching the name of the output file to return (e.g. \"Hydrographs\", \"Storage\", \"ByHRU\", etc.).\n", " return_paths : bool\n", " If True, return the path to the output file(s) instead of the dataset. Default is False.\n", " \\*\\*kwargs : dict\n", " Keyword arguments to pass to :py:func:`xarray.open_dataset`.\n", "\n", " Returns\n", " -------\n", " xr.Dataset\n", " The requested output variable.\n", " Path\n", " The path to the output directory if output is set to \"path\".\n", " list[Path]\n", " The path to the output file(s) if return_path is True.\n", "\n" ] } ], "source": [ "help(hm.get_outputs)" ] }, { "cell_type": "code", "execution_count": 19, "id": "30", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[PosixPath('/tmp/tmp21ofasjz/gr4jcn_simulation/output/raven_Hydrographs.nc'),\n", " PosixPath('/tmp/tmp21ofasjz/gr4jcn_simulation/output/raven_WatershedStorage.nc')]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "files = hm.get_outputs(\"*\", return_paths=True)\n", "files" ] }, { "cell_type": "code", "execution_count": 20, "id": "31", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 117kB\n",
       "Dimensions:                    (time: 730)\n",
       "Coordinates:\n",
       "  * time                       (time) datetime64[ns] 6kB 1990-01-01 ... 1991-...\n",
       "    elevation                  float32 4B ...\n",
       "    drainage_area              float64 8B ...\n",
       "    centroid_longitude         float64 8B ...\n",
       "    centroid_latitude          float64 8B ...\n",
       "Data variables: (12/19)\n",
       "    rainfall                   (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    snowfall                   (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    channel_storage            (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    reservoir_storage          (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    rivulet_storage            (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    Surface Water              (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    ...                         ...\n",
       "    Convolution Storage[0]     (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    Convolution Storage[1]     (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    total                      (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    cum_input                  (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    cum_outflow                (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "    MB_error                   (time) float64 6kB dask.array<chunksize=(730,), meta=np.ndarray>\n",
       "Attributes:\n",
       "    Conventions:      CF-1.6\n",
       "    featureType:      timeSeries\n",
       "    history:          Created on 2026-04-01T12:54:24 by Raven 4.1\n",
       "    description:      Standard Output\n",
       "    references:       Craig J.R. and the Raven Development Team Raven user's ...\n",
       "    model_id:         GR4JCN\n",
       "    Raven_version:    4.1\n",
       "    RavenPy_version:  0.20.0
" ], "text/plain": [ " Size: 117kB\n", "Dimensions: (time: 730)\n", "Coordinates:\n", " * time (time) datetime64[ns] 6kB 1990-01-01 ... 1991-...\n", " elevation float32 4B ...\n", " drainage_area float64 8B ...\n", " centroid_longitude float64 8B ...\n", " centroid_latitude float64 8B ...\n", "Data variables: (12/19)\n", " rainfall (time) float64 6kB dask.array\n", " snowfall (time) float64 6kB dask.array\n", " channel_storage (time) float64 6kB dask.array\n", " reservoir_storage (time) float64 6kB dask.array\n", " rivulet_storage (time) float64 6kB dask.array\n", " Surface Water (time) float64 6kB dask.array\n", " ... ...\n", " Convolution Storage[0] (time) float64 6kB dask.array\n", " Convolution Storage[1] (time) float64 6kB dask.array\n", " total (time) float64 6kB dask.array\n", " cum_input (time) float64 6kB dask.array\n", " cum_outflow (time) float64 6kB dask.array\n", " MB_error (time) float64 6kB dask.array\n", "Attributes:\n", " Conventions: CF-1.6\n", " featureType: timeSeries\n", " history: Created on 2026-04-01T12:54:24 by Raven 4.1\n", " description: Standard Output\n", " references: Craig J.R. and the Raven Development Team Raven user's ...\n", " model_id: GR4JCN\n", " Raven_version: 4.1\n", " RavenPy_version: 0.20.0" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "storage = hm.get_outputs(\"Storage\")\n", "storage" ] }, { "cell_type": "code", "execution_count": 21, "id": "32", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "storage[\"Soil Water[0]\"].plot()" ] }, { "cell_type": "markdown", "id": "33", "metadata": {}, "source": [ "## Updating the rv* files\n", "\n", "Currently, `RavenPy` provides no straightforward way to open and modify the Raven `.rv*` files. For instance, changing simulation dates or meteorological data directly through the files is not yet supported. Until this feature is added, some basic functions have been integrated into `xHydro`, but should be used with care.\n", "\n", "The basic information, such as `start_date`, `end_date`, and `parameters`, are stored directly in the `RavenpyModel` class and can be manually updated. Similarly, if additional arguments had been given to the model during initialization, they are stored within a dictionary under `RavenpyModel.kwargs`, which can be accessed and modified as needed.\n", "\n", "The observed streamflow, HRU characteristics and meteorological data are stored under the `.qobs`, `.hru` and `.meteo` attributes respectively, but can be much trickier to update, since the associated `RavenPy` commands must be reconstructed again. Therefore, it is strongly recommended to use the `.update_data` method to update these. This function calls upon a subset of the same arguments used when initializing a Raven model:\n" ] }, { "cell_type": "code", "execution_count": 22, "id": "34", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on method update_data in module xhydro.modelling._ravenpy_models:\n", "\n", "update_data(\n", " *,\n", " qobs_file: os.PathLike | str | None = None,\n", " alt_name_flow: str | None = 'q',\n", " hru: gpd.GeoDataFrame | dict | os.PathLike | str | None = None,\n", " output_subbasins: Literal['all', 'qobs'] | list[int] | None = None,\n", " minimum_reservoir_area: str | None = None,\n", " meteo_file: os.PathLike | str | None = None,\n", " data_type: list[str] | None = None,\n", " alt_names_meteo: dict | None = None,\n", " meteo_station_properties: dict | None = None,\n", " gridweights: str | os.PathLike | None = None\n", ") method of xhydro.modelling._ravenpy_models.RavenpyModel instance\n", " Update the model configuration with new observed data (self.qobs), HRU properties (self.hru), or meteorological data (self.meteo).\n", "\n", " Parameters\n", " ----------\n", " qobs_file : os.PathLike | str\n", " Path to the NetCDF file containing the observed streamflow data.\n", " If there are multiple stations, the file should contain a 'basin_id' variable that identifies the subbasin for each time series.\n", " If a 'station_id' variable is present, it will be used to identify the station.\n", " alt_name_flow : str, optional\n", " Alternative name for the streamflow variable in the observed data.\n", " hru : gpd.GeoDataFrame | dict | os.PathLike | str\n", " A GeoDataFrame, or dictionary containing the HRU properties. Alternatively, a path to a shapefile containing the HRU properties.\n", " For distributed models, it should be readable by ravenpy.extractors.BasinMakerExtractor.\n", " For lumped models, should contain the following variables:\n", " - area: The watershed drainage area, in km².\n", " - elevation: The elevation of the watershed, in meters.\n", " - latitude: The latitude of the watershed centroid.\n", " - longitude: The longitude of the watershed centroid.\n", " - HRU_ID: The ID of the HRU (required for gridded data, optional for station data).\n", " If the meteorological data is gridded, the HRU dataset must also contain a SubId, DowSubId, valid geometry and crs.\n", " If the input is modified, a new shapefile will be created in the workdir/weights subdirectory.\n", " output_subbasins : {\"all\", \"qobs\"} | list[int] | None, optional\n", " If \"all\", all subbasins will be outputted.\n", " If \"qobs\", subbasins with observed flow will be outputted, as defined by the basin IDs in the observed streamflow data.\n", " If a list of integers is provided, it should contain the basin IDs to output.\n", " Leave as None to use the value as defined in the HRU file ('Has_Gauge' column).\n", " minimum_reservoir_area : str, optional\n", " Quantified string (e.g. \"20 km2\") representing the minimum lake area to consider the lake explicitly as a reservoir.\n", " If not provided, all lakes with the 'HRU_IsLake' column set to 1 in the HRU file will be considered as reservoirs.\n", " Note that 'reservoirs' in Raven can also refer to natural lakes with weir-like outflows.\n", " Only applicable for distributed HBVEC models.\n", " meteo_file : str | Path, optional\n", " Path to the file containing the observed meteorological data. Only optional if the project files already exist.\n", " The meteorological data can be either station or gridded data. Use the 'xhydro.modelling.format_input' function to ensure the data\n", " is in the correct format. Unless the input is a single station accompanied by 'meteo_station_properties', the file should contain\n", " the following coordinates:\n", " - elevation: The elevation of the station / grid cell, in meters.\n", " - latitude: The latitude of the station / grid cell centroid.\n", " - longitude: The longitude of the station / grid cell centroid.\n", " data_type : list[str], optional\n", " The list of types of data provided to Raven in the meteorological file. Only optional if the project files already exist.\n", " See https://github.com/CSHS-CWRA/RavenPy/blob/master/src/ravenpy/config/conventions.py for the list of available types.\n", " alt_names_meteo : dict, optional\n", " A dictionary that allows users to link the names of meteorological variables in their dataset to Raven-compliant names.\n", " The keys should be the Raven names as listed in the data_type parameter.\n", " meteo_station_properties : dict, optional\n", " Additional properties of the weather stations providing the meteorological data. Only required if absent from the 'meteo_file'.\n", " For single stations, the format is {\"ALL\": {\"elevation\": elevation, \"latitude\": latitude, \"longitude\": longitude}}.\n", " This has not been tested for multiple stations or gridded data.\n", " gridweights : str | Path | None\n", " If using gridded meteorological data, path to a text file containing the weights linking the grid cells to the HRUs.\n", " If None, the weights will be computed using ravenpy.extractors.GridWeightExtractor and saved in a 'weights' subdirectory\n", " of the project folder, using a \"{meteo_file}_vs_{hru_file}_weights.txt\" pattern.\n", "\n", " Notes\n", " -----\n", " If the meteorological data is gridded, new weights will be computed using the HRU file in the RavenpyModel instance and saved\n", " in a 'weights' subdirectory of the project folder, under the name 'meteo-name_vs_hru-name.txt'.\n", "\n" ] } ], "source": [ "help(hm.update_data)" ] }, { "cell_type": "markdown", "id": "35", "metadata": {}, "source": [ "That function will only update the `RavenpyModel` class itself, not the files. If possible, it is strongly recommended to use the `create_rv` function to overwrite the existing `.rv*` files with the updated information.\n", "\n", "If this is not possible, some aspects of the model can still be updated using the `.update_config` method:" ] }, { "cell_type": "code", "execution_count": 23, "id": "36", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on method update_config in module xhydro.modelling._ravenpy_models:\n", "\n", "update_config(\n", " *,\n", " rvi_dates: bool = False,\n", " rvi_commands: list[str] | None = None,\n", " rvt: bool = False,\n", " rvh: bool = False\n", ") -> None method of xhydro.modelling._ravenpy_models.RavenpyModel instance\n", " Manually update some aspects of the configuration of the RavenPy model.\n", "\n", " Parameters\n", " ----------\n", " rvi_dates : bool\n", " If True, update the .rvi file with the 'start_date' and 'end_date' defined in the model.\n", " rvi_commands : list[str] | None\n", " A list of commands to include in the .rvi file. If None, no additional commands will be added.\n", " Warning: These commands will be added at the end of the .rvi file, with no checks. Use with caution.\n", " rvt : bool\n", " If True, update the .rvt file with the meteorological data and observed streamflow data defined in the model.\n", " rvh : bool\n", " If True, update the .rvh file with the list of subbasins to output. Nothing else will be changed in that file.\n", "\n", " Notes\n", " -----\n", " Ideally, users should favor using the `update_data` method to update the model configuration, then call the `create_rv`\n", " method to recreate the project files from scratch. This method assumes that the changes brought to the model configuration\n", " are minimal, such as wanting to change the meteorological data or the simulation start and end dates.\n", "\n", " Be aware that:\n", " - The .rvh will be rewritten entirely. If multiple sources of data were mentioned, such as both meteorological and observed streamflow data,\n", " all of them must be included in the RavenpyModel instance.\n", " - If the meteorological data is gridded, new weights will be computed using the HRU file in the RavenpyModel instance. If that HRU\n", " file is different from the one used to create the original .rvh file, it may lead to inconsistencies or errors.\n", " - Similarly, only the list of subbasins to output will be modified in the new .rvh file. Any additional changes to the HRU or\n", " other components might also lead to inconsistencies or errors.\n", "\n", " A backup of the original files will be created before any modifications are made.\n", "\n" ] } ], "source": [ "help(hm.update_config)" ] }, { "cell_type": "markdown", "id": "37", "metadata": {}, "source": [ "Be very aware that not all updates will be reflected in the `.rv*` files. The last two options especially should be used with caution, as HRU characteristics, such as the subbasin IDs, will *not* be updated. If the HRU within the model has changed, there is currently no way to modify existing files. They should be deleted and recreated using the `.create_rv()` method." ] }, { "cell_type": "markdown", "id": "38", "metadata": {}, "source": [ "## Model Calibration\n", "\n", "When building a model from scratch, a calibration step is necessary to find the optimal set of parameters. Model calibration involves a loop of several iterations, where: model parameters are selected, the model is run, and the results are compared to observed data. In `xHydro`, the calibration function utilizes `SPOTPY` to carry out the optimization process.\n", "\n", "The calibration function still uses the `model_config` dictionary created earlier, but now within the `xh.modelling.perform_calibration` function.\n" ] }, { "cell_type": "code", "execution_count": 24, "id": "39", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function perform_calibration in module xhydro.modelling.calibration:\n", "\n", "perform_calibration(\n", " model_config: dict,\n", " obj_func: str,\n", " bounds_high: np.ndarray | list[float | int],\n", " bounds_low: np.ndarray | list[float | int],\n", " evaluations: int,\n", " qobs: os.PathLike | np.ndarray | xr.Dataset | xr.DataArray,\n", " algorithm: str = 'DDS',\n", " mask: np.ndarray | list[float | int] | None = None,\n", " transform: str | None = None,\n", " epsilon: float = 0.01,\n", " sampler_kwargs: dict | None = None\n", ")\n", " Perform calibration using SPOTPY.\n", "\n", " This is the entrypoint for the model calibration. After setting-up the\n", " model_config object and other arguments, calling \"perform_calibration\" will\n", " return the optimal parameter set, objective function value and simulated\n", " flows on the calibration period.\n", "\n", " Parameters\n", " ----------\n", " model_config : dict\n", " The model configuration object that contains all info to run the model.\n", " The model function called to run this model should always use this object and read-in data it requires.\n", " It will be up to the user to provide the data that the model requires.\n", " obj_func : str\n", " The objective function used for calibrating. Can be any one of these:\n", "\n", " - \"abs_bias\": Absolute value of the \"bias\" metric\n", " - \"abs_pbias\": Absolute value of the \"pbias\" metric\n", " - \"abs_volume_error\": Absolute value of the volume_error metric\n", " - \"agreement_index\": Index of agreement\n", " - \"correlation_coeff\": Correlation coefficient\n", " - \"high_flow_rel_error\": High flow relative error\n", " - \"kge\": Kling Gupta Efficiency metric (2009 version)\n", " - \"kge_mod\": Kling Gupta Efficiency metric (2012 version)\n", " - \"kge_2021\": Kling Gupta Efficiency metric (2021 version)\n", " - \"lce\": Least-squares combined efficiency\n", " - \"low_flow_rel_error\": Low flow relative error\n", " - \"mae\": Mean Absolute Error metric\n", " - \"mare\": Mean Absolute Relative Error metric\n", " - \"mse\": Mean Square Error metric\n", " - \"nse\": Nash-Sutcliffe Efficiency metric\n", " - \"persistence_index\": Persistence index\n", " - \"r2\": r-squared, i.e. square of correlation_coeff.\n", " - \"rmse\": Root Mean Square Error\n", " - \"rrmse\": Relative Root Mean Square Error (RMSE-to-mean ratio)\n", " - \"rsr\": Ratio of RMSE to standard deviation.\n", " - \"volumetric_efficiency\": Volumetric efficiency\n", "\n", " bounds_high : np.array\n", " High bounds for the model parameters to be calibrated. SPOTPY will sample parameter sets from\n", " within these bounds. The size must be equal to the number of parameters to calibrate.\n", " bounds_low : np.array\n", " Low bounds for the model parameters to be calibrated. SPOTPY will sample parameter sets from\n", " within these bounds. The size must be equal to the number of parameters to calibrate.\n", " evaluations : int\n", " Maximum number of model evaluations (calibration budget) to perform before stopping the calibration process.\n", " qobs : os.PathLike or np.ndarray or xr.Dataset or xr.DataArray\n", " Observed streamflow dataset (or path to it), used to compute the objective function.\n", " If using a dataset, it must contain a \"streamflow\" variable.\n", " algorithm : str\n", " The optimization algorithm to use. Currently, \"DDS\" and \"SCEUA\" are available, but more can be easily added.\n", " mask : np.array, optional\n", " A vector indicating which values to preserve/remove from the objective function computation. 0=remove, 1=preserve.\n", " transform : str, optional\n", " The method to transform streamflow prior to computing the objective function. Can be one of:\n", " Square root ('sqrt'), inverse ('inv'), or logarithmic ('log') transformation.\n", " epsilon : scalar float\n", " Used to add a small delta to observations for log and inverse transforms, to eliminate errors\n", " caused by zero flow days (1/0 and log(0)). The added perturbation is equal to the mean observed streamflow\n", " times this value of epsilon.\n", " sampler_kwargs : dict\n", " Contains the keywords and hyperparameter values for the optimization algorithm.\n", " Keywords depend on the algorithm choice. Currently, SCEUA and DDS are supported with\n", " the following default values:\n", " - SCEUA: dict(ngs=7, kstop=3, peps=0.1, pcento=0.1)\n", " - DDS: dict(trials=1)\n", "\n", " Returns\n", " -------\n", " best_parameters : array_like\n", " The optimized parameter set.\n", " qsim : xr.Dataset\n", " Simulated streamflow using the optimized parameter set.\n", " bestobjf : float\n", " The best objective function value.\n", "\n" ] } ], "source": [ "help(xh.modelling.perform_calibration)" ] }, { "cell_type": "markdown", "id": "40", "metadata": {}, "source": [ "We can prepare the additional arguments required by the calibration function. A good calibration process should always exclude some data from the computation of the objective function to ensure a validation period. This can be achieved using the `mask` argument, which uses an array of 0 and 1. \n", "\n", "This example will only use 10 evaluations to cut on computing time, but a real calibration should rely on at least 500 iterations with simple models such as GR4JCN." ] }, { "cell_type": "code", "execution_count": 25, "id": "41", "metadata": {}, "outputs": [], "source": [ "qobs_file = D.fetch(\"ravenpy/Debit_Riviere_Rouge.nc\")\n", "ds_obs = xr.open_dataset(qobs_file)\n", "\n", "# Reformat the data\n", "ds_obs = ds_obs.rename({\"qobs\": \"q\"}).sel(time=slice(\"1990\", \"1991\"))\n", "\n", "# Create the mask\n", "mask = xr.where(ds_obs.time.dt.year.isin([1990]), 0, 1)" ] }, { "cell_type": "code", "execution_count": 26, "id": "42", "metadata": {}, "outputs": [], "source": [ "# Parameter bounds for GR4JCN\n", "bounds_low = [0.01, -15.0, 10.0, 0.0, 1.0, 0.0]\n", "bounds_high = [2.5, 10.0, 700.0, 7.0, 30.0, 1.0]" ] }, { "cell_type": "code", "execution_count": 27, "id": "43", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Initializing the Dynamically Dimensioned Search (DDS) algorithm with 10 repetitions\n", "The objective function will be maximized\n", "Starting the DDS algorithm with 10 repetitions...\n", "Finding best starting point for trial 1 using 5 random samples.\n", "Initialize database...\n", "['csv', 'hdf5', 'ram', 'sql', 'custom', 'noData']\n", "4 of 10, maximal objective function=-0.00696254, time remaining: 00:00:02\n", "8 of 10, maximal objective function=0.0445682, time remaining: 00:00:00\n", "Best solution found has obj function value of 0.044568158083302944 at 5\n", "\n", "\n", "\n", "*** Final SPOTPY summary ***\n", "Total Duration: 5.4 seconds\n", "Total Repetitions: 10\n", "Maximal objective value: 0.0445682\n", "Corresponding parameter setting:\n", "param0: 0.01001\n", "param1: 7.93032\n", "param2: 108.521\n", "param3: 0.276909\n", "param4: 17.0447\n", "param5: 0.351842\n", "******************************\n", "\n", "Best parameter set:\n", "param0=0.01001, param1=7.93031661557087, param2=108.52104320487612, param3=0.27690868006760194, param4=17.04469471095574, param5=0.35184151716991\n", "Run number 6 has the highest objectivefunction with: 0.0446\n" ] } ], "source": [ "model_config[\"overwrite\"] = True\n", "\n", "# Run the calibration\n", "best_parameters, best_simulation, best_objfun = xhm.perform_calibration(\n", " model_config,\n", " obj_func=\"kge\",\n", " bounds_low=bounds_low,\n", " bounds_high=bounds_high,\n", " qobs=ds_obs,\n", " evaluations=10,\n", " algorithm=\"DDS\",\n", " mask=mask,\n", " sampler_kwargs={\"trials\": 1},\n", ")" ] }, { "cell_type": "code", "execution_count": 28, "id": "44", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[np.float64(0.01001),\n", " np.float64(7.93031661557087),\n", " np.float64(108.52104320487612),\n", " np.float64(0.27690868006760194),\n", " np.float64(17.04469471095574),\n", " np.float64(0.35184151716991)]" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The first output corresponds to the best set of parameters\n", "best_parameters" ] }, { "cell_type": "code", "execution_count": 29, "id": "45", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 12kB\n",
       "Dimensions:             (time: 730)\n",
       "Coordinates:\n",
       "  * time                (time) datetime64[ns] 6kB 1990-01-01 ... 1991-12-31\n",
       "    subbasin_id         <U1 4B ...\n",
       "    elevation           float32 4B ...\n",
       "    drainage_area       float64 8B ...\n",
       "    centroid_longitude  float64 8B ...\n",
       "    centroid_latitude   float64 8B ...\n",
       "Data variables:\n",
       "    q                   (time) float64 6kB ...\n",
       "Attributes:\n",
       "    Conventions:      CF-1.6\n",
       "    featureType:      timeSeries\n",
       "    history:          Created on 2026-04-01T12:54:33 by Raven 4.1\n",
       "    description:      Standard Output\n",
       "    references:       Craig J.R. and the Raven Development Team Raven user's ...\n",
       "    model_id:         GR4JCN\n",
       "    Raven_version:    4.1\n",
       "    RavenPy_version:  0.20.0
" ], "text/plain": [ " Size: 12kB\n", "Dimensions: (time: 730)\n", "Coordinates:\n", " * time (time) datetime64[ns] 6kB 1990-01-01 ... 1991-12-31\n", " subbasin_id