Using HydroMT in Python#

As HydroMT’s architecture is modular, it is possible to use HydroMT as a python library without using the command line interface (CLI). Using the libary, you have more of HydroMTs functionalities at your disposal. This can be useful if you want to for example:

  • build / update / clip models, check configurations or export data in Python instead of the CLI

  • analyse model inputs or results

  • analyse and compare input data without connecting to a specific model

  • process input data for another reason than building a model

  • create your own HydroMT plugin

So first, let’s go deeper into the API of HydroMT. You have all available functions and their documentation in the API reference.

HydroMT is here to read and harmonize input data, and to process it via its methods and workflows in order to prepare ready to run models. So HydroMT’s methods are organized around these main objects.

Input data#

Most classes around the finding, reading and transforming input data have implementations for the five different data_types in HydroMT. The main objects to work with input data are:

  • The DataCatalog is the most high-level class and leverages the

    next few classes to find, read and transform the data coming from its configuration. The methods used to do this are called get_<data_type>, for example get_rasterdataset().

  • The URIResolver is responsible for finding the

    data based on a single uri. This class is generic for all data_types. An implementation that finds data based on naming conventions is the ConventionResolver.

  • The Driver has different subclasses based on

    the data_type, for example RasterDatasetDriver, which then has different implementations, for example a driver for reading raster data using rasterio: RasterioDriver. which reads raster data.

  • The DataAdapter has subclasses

    that transform data, like renaming, reprojecting etc. These subclasses are for example: RasterDatasetAdapter.

So let’s say you would like to read data in HydroMT, you can do this by creating a DataCatalog instance and using the get_<data_type> methods to read the data. This is a short example:

import hydromt
# create a data catalog from a local data_catalog file
cat = hydromt.DataCatalog("data_catalog.yml")
# read a raster dataset ("dem" source in the data catalog)
dem = cat.get_rasterdataset("dem")
# read a vector dataset ("catchments" source in the data catalog)
catchments = cat.get_geodataframe("catchments")
# read a geodataset with some time and space slicing
qobs = cat.get_geodataset(
  "qobs",
  time_range = ("2000-01-01", "2010-12-31"),
  bbox = [5.0, 50.0, 6.0, 51.0]
)

You can find more detailed examples on using the DataCatalog and DataAdapter in Python in:

Xarray Accessors#

Some powerful functionality that HydroMT uses is exposed in the gis module. In this module xarray accessors are located. These allow for powerful new methods on top of xarray Dataset and DataArray classes. There is the raster API, such as functionality to repoject, resample, transform, interpolate nodata or zonal statistics. There is also the GeoDataset API to work with geodataset data (N-dim point/line/polygon geometry). For example, reprojecting, transform, update geometry or convert to geopandas.GeoDataFrame to access further GIS methods.

FlowPy Wrappers:#

PyFlwDir <https://deltares.github.io/pyflwdir/latest/index.html> contains a series of methods to work with gridded DEM and flow direction datasets. The gis.flw module builds on top of this and provides hydrological methods for raster DEM data. For example, calculate flow direction, flow accumulation, stream network, catchments, or reproject hydrography.

Stats:#

The stats module has statistical methods including skills to compute skill scores of models (e.g. NSE, KGE, bias and many more) and extremes to analyse extreme events (extract peaks or compute return values).

The model module has a processes submodule. This module contains some functions to work with different kinds of model in- and ouput.

  • grid: generic workflows to prepare regular gridded data.

    Used with the GridComponent. For example to prepare regular grid data from constant, from RasterDataset (with or without reclassification) or from GeoDataFrame.

  • mesh: generic workflows to prepare unstructured mesh

    data. Used with the MeshComponent. For example to create a mesh grid or prepare unstructured mesh data from RasterDataset.

  • basin_mask: workflows to prepare a basin mask based on

    different region definitions (bounding box, point coordinates, polygon etc.)

  • rivers: workflows to prepare river profile data like

    width and depth.

  • temp: workflows to prepare meteorological forcing

    data. For example to prepare precipitation, temperature, or compute evapotranspiration data. Advanced downscaling methods are also available within these workflows.

You can find a couple of detailed examples of how to use HydroMT methods and workflows in Python:

Models#

You can also use HydroMT and its Model and ModelComponent classes to do some analysis on your model inputs or results. HydroMT views a model as a combination of different components to represent the different type of inputs of a model, like config for the model run configuration file, forcing for the dynamic forcing data of the model etc. For each component, there are methods to set_<component> (update or add a new data layer), read_<component> and write_<component>.

Here is a small example of how to use the Model class in python to plot or analyse your model:

import hydromt
# create a GridModel instance for an existing grid model saved in "grid_model" folder
model = hydromt.GridModel(root="grid_model", mode="r")
# read/get the grid data
forcing = model.grid
# plot the DEM
grid["dem"].plot()

# read the model results
results = model.results
# Get the simulated discharge
qsim = results["qsim"]
# Read observations using a local data catalog
cat = hydromt.DataCatalog("data_catalog.yml")
qobs = cat.get_geodataset("qobs")
# Compute some skill scores like NSE
nse = hydromt.stats.nashsutcliffe(qobs, qsim)

You can find more detailed examples on using the Model class in Python in:

And feel free to visit some of the plugins documentation to find even more examples!