Update a Wflow model: gauging stations#
Once you have a Wflow model, you may want to update your model in order to use a new landuse map, change a parameter value, add sample locations, use different forcing data, create and run different scenarios etc.
With HydroMT, you can easily read your model and update one or several components of your model using the update function of the command line interface (CLI). Here are the steps and some examples on how to update/add gauging stations to your model.
All lines in this notebook which starts with ! are executed from the command line. Within the notebook environment the logging messages are shown after completion. You can also copy these lines and paste them in your shell to get more feedback.
Import packages#
In this notebook, we will use some functions of HydroMT to plot the new gauging stations of the updated model. Here are the libraries to import to realize these steps.
[1]:
import numpy as np
import geopandas as gpd
from shapely.geometry import box
[2]:
# for plotting
import matplotlib.pyplot as plt
import cartopy.io.img_tiles as cimgt
import cartopy.crs as ccrs
proj = ccrs.PlateCarree() # plot projection
Locations of the gauging stations#
Adding gauging stations to your Wflow model can be quite useful. It allows you to directly extract model outputs at specific locations. For example for model validation, calibration, you can then directly compare model results to available observations.
In our previous notebook, we built a wflow model in which the locations of the available GRDC stations are including. If you have other observation data available, you can easily add them to your model using HydroMT. One way to do it is to prepare a csv table containing the ID, latitude and longitude of the available stations. An example test_stations.csv has been prepared. Let’s have a look at it.
[3]:
fn_station = "test_stations.csv"
with open(fn_station, "r", encoding="utf8") as f:
txt = f.read()
print(txt)
ID,Name,x,y,uparea
1001,Gauge1,11.9594,45.8925,3642
1002,Gauge2,12.3395,46.1492,2
1003,Gauge3,12.0785,46.1122,837
Here we can see that we have defined three stations with an ID and the longitude (x) and latitude (y) coordinates, in the same EPSG system as our model (EPSG 4326). We can now add them to our model.
HydroMT CLI update interface#
Using the HydroMT build API, we can update one or several components of an already existing Wflow model. Let’s get an overview of the available options:
[4]:
# Print the options available from the update command
! hydromt update --help
Usage: hydromt update [OPTIONS] MODEL MODEL_ROOT
Update a specific component of a model.
Set an output directory to copy the edited model to a new folder, otherwise
maps are overwritten.
Example usage: --------------
Update Wflow model components outlined in an .yml configuration file and
write the model to a directory: hydromt update wflow /path/to/model_root -o
/path/to/model_out -i /path/to/wflow_config.yml -d
/path/to/data_catalog.yml -v
Options:
-o, --model-out DIRECTORY Output model folder. Maps in MODEL_ROOT are
overwritten if left empty.
-i, --config PATH Path to hydroMT configuration file, for the model
specific implementation. [required]
-d, --data TEXT Path to local yaml data catalog file OR name of
predefined data catalog.
--dd, --deltares-data Flag: Shortcut to add the "deltares_data" catalog
--fo, --force-overwrite Flag: If provided overwrite existing model files
--cache Flag: If provided cache tiled rasterdatasets
-q, --quiet Decrease verbosity.
-v, --verbose Increase verbosity.
--help Show this message and exit.
Update Wflow gauging stations#
Let’s open the example configuration file (wflow_update_gauges.yml) from the model repository [examples folder] and have a look at the setup_gauges step.
[5]:
fn_config = "wflow_update_gauges.yml"
with open(fn_config, "r") as f:
txt = f.read()
print(txt)
steps:
- setup_gauges:
gauges_fn : test_stations.csv
basename: test-flow
Here, you see the step for updating the gauges with our test_stations.csv and giving it the name test-flow. Let’s update the model with the following CLI command:
[6]:
# NOTE: copy this line (without !) to your shell for more direct feedback
! hydromt update wflow_sbm wflow_piave_subbasin -o ./wflow_piave_gauges -i wflow_update_gauges.yml -v
2025-10-10 08:01:47,870 - hydromt - log - INFO - HydroMT version: 1.3.0-rc1
2025-10-10 08:01:47,870 - hydromt.cli.main - main - INFO - Updating wflow_sbm model at /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_subbasin (r).
2025-10-10 08:01:47,870 - hydromt.cli.main - main - INFO - Output dir: /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges
2025-10-10 08:01:47,870 - hydromt.cli.main - main - INFO - User settings:
2025-10-10 08:01:47,900 - hydromt.model.root - root - INFO - setting root to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_subbasin
2025-10-10 08:01:47,900 - hydromt.model.model - model - INFO - Initializing wflow_sbm model from hydromt_wflow (v1.0.0.dev0).
2025-10-10 08:01:47,901 - hydromt.data_catalog.data_catalog - data_catalog - INFO - Parsing data catalog from /home/runner/work/hydromt_wflow/hydromt_wflow/hydromt_wflow/data/parameters_data.yml
2025-10-10 08:01:47,929 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Supported Wflow.jl version v1+
2025-10-10 08:01:47,929 - hydromt.hydromt_wflow.components.config - config - INFO - Reading model config file from /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_subbasin/wflow_sbm.toml.
2025-10-10 08:01:47,930 - hydromt.hydromt_wflow.components.config - config - INFO - Reading model config file from /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_subbasin/wflow_sbm.toml.
2025-10-10 08:01:49,078 - hydromt.model.components.tables - tables - INFO - Reading model table files.
2025-10-10 08:01:49,079 - hydromt.model.root - root - INFO - setting root to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges
2025-10-10 08:01:49,081 - hydromt.model.model - model - INFO - update: setup_gauges
2025-10-10 08:01:49,081 - hydromt.model.model - model - INFO - setup_gauges.index_col=None
2025-10-10 08:01:49,081 - hydromt.model.model - model - INFO - setup_gauges.snap_to_river=True
2025-10-10 08:01:49,081 - hydromt.model.model - model - INFO - setup_gauges.mask=None
2025-10-10 08:01:49,081 - hydromt.model.model - model - INFO - setup_gauges.snap_uparea=False
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.max_dist=10000.0
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.wdw=3
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.rel_error=0.05
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.abs_error=50.0
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.fillna=False
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.derive_subcatch=False
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.basename=test-flow
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.toml_output=csv
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.gauge_toml_header=['river_q', 'precip']
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.gauge_toml_param=['river_water__volume_flow_rate', 'atmosphere_water__precipitation_volume_flux']
2025-10-10 08:01:49,082 - hydromt.model.model - model - INFO - setup_gauges.gauges_fn=test_stations.csv
2025-10-10 08:01:49,089 - hydromt.data_catalog.sources.data_source - data_source - INFO - Reading test_stations.csv GeoDataFrame data from /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/test_stations.csv
2025-10-10 08:01:49,093 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - 3 test-flow gauge locations found within domain
2025-10-10 08:01:50,418 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Adding ['river_water__volume_flow_rate', 'atmosphere_water__precipitation_volume_flux'] to csv section of toml.
2025-10-10 08:01:50,418 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Write model data to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges
2025-10-10 08:01:50,419 - hydromt.model.components.grid - grid - INFO - wflow_sbm.staticmaps: Writing grid data to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticmaps.nc.
2025-10-10 08:01:50,688 - hydromt.model.components.spatial - spatial - INFO - wflow_sbm.staticmaps: Writing region to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/region.geojson.
2025-10-10 08:01:50,716 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/region.geojson.
2025-10-10 08:01:50,717 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/basins.geojson.
2025-10-10 08:01:50,719 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/gauges_grdc.geojson.
2025-10-10 08:01:50,722 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/basins_highres.geojson.
2025-10-10 08:01:50,739 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/outlets.geojson.
2025-10-10 08:01:50,740 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/glaciers.geojson.
2025-10-10 08:01:50,775 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/rivers.geojson.
2025-10-10 08:01:50,778 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/meta_reservoirs_no_control.geojson.
2025-10-10 08:01:50,781 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/reservoirs.geojson.
2025-10-10 08:01:50,783 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/meta_reservoirs_simple_control.geojson.
2025-10-10 08:01:50,786 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticgeoms/gauges_test-flow.geojson.
2025-10-10 08:01:50,788 - hydromt.hydromt_wflow.components.forcing - forcing - INFO - Write forcing file
2025-10-10 08:01:50,795 - hydromt.hydromt_wflow.components.forcing - forcing - INFO - Writing file /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/inmaps.nc
2025-10-10 08:01:50,835 - hydromt.model.components.tables - tables - INFO - wflow_sbm.tables: No tables found, skip writing.
2025-10-10 08:01:50,835 - hydromt.model.components.grid - grid - INFO - wflow_sbm.states: Writing grid data to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/instate/instates.nc.
2025-10-10 08:01:50,940 - hydromt.hydromt_wflow.components.config - config - INFO - Writing model config to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/wflow_sbm.toml.
The example above means the following: run hydromt with:
update wflow
: i.e. update a wflow modelwflow_piave_subbasin
: original model folder-o ./wflow_piave_gauges
: output updated model folder-i wflow_update_gauges.yml
: path to the update configuration file.v
: give some extra verbosity (2 * v) to display feedback on screen. Now debug messages are provided.
Other available options are available in the docs (setup gauges).
Update Wflow gauging stations without snapping#
By default, the setup_gauges of HydroMT Wflow will assume that gauges are for flow sampling and will therefore snap the gauges locations to the river. If your observations are used to compare rainfall data, then you do not want HydroMT to move the location of your gauges. This is done by setting snap_to_river: False
.
By default, HydroMT Wflow will update the TOML in order to save both river discharge and precipitation at the new gauges locations. With our rainfall stations, we only need to save the precipitation. We can set this with hydroMT using the options:
gauge_toml_header: ['P-station']
: set the column name in the outputcsv file of the Wflow run in the TOML configurationgauge_toml_param: ['atmosphere_water__precipitation_volume_flux']
: set the Wflow variable to save in the corresponding outputcsv file column of Wflow run in the TOML configuration
[7]:
fn_config = "wflow_update_gauges_without_snapping.yml"
with open(fn_config, "r") as f:
txt = f.read()
print(txt)
steps:
- setup_gauges:
gauges_fn : test_stations.csv
basename: test-rain
snap_to_river: False
gauge_toml_header: ['P-station']
gauge_toml_param : ['atmosphere_water__precipitation_volume_flux']
[8]:
# NOTE: copy this line (without !) to your shell for more direct feedback
! hydromt update wflow_sbm wflow_piave_gauges -i wflow_update_gauges_without_snapping.yml -v
2025-10-10 08:01:54,592 - hydromt - log - INFO - HydroMT version: 1.3.0-rc1
2025-10-10 08:01:54,592 - hydromt.cli.main - main - INFO - Updating wflow_sbm model at /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges (r+).
2025-10-10 08:01:54,592 - hydromt.cli.main - main - INFO - Output dir: /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges
2025-10-10 08:01:54,592 - hydromt.cli.main - main - INFO - User settings:
2025-10-10 08:01:54,625 - hydromt.model.root - root - INFO - setting root to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges
2025-10-10 08:01:54,625 - hydromt.model.model - model - INFO - Initializing wflow_sbm model from hydromt_wflow (v1.0.0.dev0).
2025-10-10 08:01:54,626 - hydromt.data_catalog.data_catalog - data_catalog - INFO - Parsing data catalog from /home/runner/work/hydromt_wflow/hydromt_wflow/hydromt_wflow/data/parameters_data.yml
2025-10-10 08:01:54,654 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Supported Wflow.jl version v1+
2025-10-10 08:01:54,654 - hydromt.hydromt_wflow.components.config - config - INFO - Reading model config file from /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/wflow_sbm.toml.
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - update: setup_gauges
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.index_col=None
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.snap_to_river=False
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.mask=None
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.snap_uparea=False
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.max_dist=10000.0
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.wdw=3
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.rel_error=0.05
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.abs_error=50.0
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.fillna=False
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.derive_subcatch=False
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.basename=test-rain
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.toml_output=csv
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.gauge_toml_header=['P-station']
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.gauge_toml_param=['atmosphere_water__precipitation_volume_flux']
2025-10-10 08:01:55,669 - hydromt.model.model - model - INFO - setup_gauges.gauges_fn=test_stations.csv
2025-10-10 08:01:55,750 - hydromt.data_catalog.sources.data_source - data_source - INFO - Reading test_stations.csv GeoDataFrame data from /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/test_stations.csv
2025-10-10 08:01:55,754 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - 3 test-rain gauge locations found within domain
2025-10-10 08:01:56,391 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Adding ['atmosphere_water__precipitation_volume_flux'] to csv section of toml.
2025-10-10 08:01:56,392 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Write model data to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges
2025-10-10 08:01:56,392 - hydromt.data_catalog.data_catalog - data_catalog - INFO - Parsing data catalog from /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/hydromt_data.yml
2025-10-10 08:01:56,394 - hydromt.model.components.grid - grid - INFO - wflow_sbm.staticmaps: Writing grid data to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticmaps.nc.
2025-10-10 08:01:56,402 - hydromt.cli.main - main - ERROR - Unable to synchronously create file (unable to truncate a file which is already open)
Traceback (most recent call last):
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/file_manager.py", line 219, in _acquire_with_cache_info
file = self._cache[self._key]
~~~~~~~~~~~^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/lru_cache.py", line 56, in __getitem__
value = self._cache[key]
~~~~~~~~~~~^^^^^
KeyError: [<class 'h5netcdf.core.File'>, ('/home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticmaps.nc',), 'a', (('decode_vlen_strings', True), ('driver', None), ('invalid_netcdf', None)), 'b5bdf55e-9657-42f2-8012-284deae9a29b']
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/hydromt/cli/main.py", line 349, in update
mod.update(model_out=model_out, steps=steps, forceful_overwrite=fo)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/hydromt/model/model.py", line 371, in update
self.write()
~~~~~~~~~~^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/hydromt_wflow/wflow_base.py", line 1745, in write
self.write_grid(filename=grid_filename)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/hydromt_wflow/wflow_base.py", line 1873, in write_grid
self.staticmaps.write(filename=filename, **kwargs)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/hydromt_wflow/components/staticmaps.py", line 129, in write
super().write(
~~~~~~~~~~~~~^
str(p_input),
^^^^^^^^^^^^^
...<3 lines>...
**kwargs,
^^^^^^^^^
)
^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/hydromt/model/components/grid.py", line 186, in write
close_handle = write_nc(
self.data,
...<5 lines>...
**kwargs,
)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/hydromt/io/writers.py", line 143, in write_nc
ds.to_netcdf(file_path, **kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/core/dataset.py", line 2104, in to_netcdf
return to_netcdf( # type: ignore[return-value] # mypy cannot resolve the overloads:(
self,
...<10 lines>...
auto_complex=auto_complex,
)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/writers.py", line 422, in to_netcdf
store = get_writable_netcdf_store(
target,
...<5 lines>...
auto_complex=auto_complex,
)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/writers.py", line 78, in get_writable_netcdf_store
return store_open(target, mode=mode, format=format, **kwargs)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/h5netcdf_.py", line 226, in open
return cls(manager, group=group, mode=mode, lock=lock, autoclose=autoclose)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/h5netcdf_.py", line 149, in __init__
self._filename = find_root_and_group(self.ds)[0].filename
^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/h5netcdf_.py", line 237, in ds
return self._acquire()
~~~~~~~~~~~~~^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/h5netcdf_.py", line 229, in _acquire
with self._manager.acquire_context(needs_lock) as root:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/contextlib.py", line 141, in __enter__
return next(self.gen)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/file_manager.py", line 207, in acquire_context
file, cached = self._acquire_with_cache_info(needs_lock)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/file_manager.py", line 225, in _acquire_with_cache_info
file = self._opener(*self._args, **kwargs)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/h5netcdf/core.py", line 1552, in __init__
self.__h5file = self._h5py.File(
~~~~~~~~~~~~~~~^
path, mode, track_order=track_order, **kwargs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/h5py/_hl/files.py", line 564, in __init__
fid = make_fid(name, mode, userblock_size, fapl, fcpl, swmr=swmr)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/h5py/_hl/files.py", line 244, in make_fid
fid = h5f.create(name, h5f.ACC_TRUNC, fapl=fapl, fcpl=fcpl)
File "h5py/_objects.pyx", line 56, in h5py._objects.with_phil.wrapper
File "h5py/_objects.pyx", line 57, in h5py._objects.with_phil.wrapper
File "h5py/h5f.pyx", line 122, in h5py.h5f.create
OSError: Unable to synchronously create file (unable to truncate a file which is already open)
Traceback (most recent call last):
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/file_manager.py", line 219, in _acquire_with_cache_info
file = self._cache[self._key]
~~~~~~~~~~~^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/lru_cache.py", line 56, in __getitem__
value = self._cache[key]
~~~~~~~~~~~^^^^^
KeyError: [<class 'h5netcdf.core.File'>, ('/home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_gauges/staticmaps.nc',), 'a', (('decode_vlen_strings', True), ('driver', None), ('invalid_netcdf', None)), 'b5bdf55e-9657-42f2-8012-284deae9a29b']
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/bin/hydromt", line 10, in <module>
sys.exit(main())
~~~~^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/click/core.py", line 1462, in __call__
return self.main(*args, **kwargs)
~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/click/core.py", line 1383, in main
rv = self.invoke(ctx)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/click/core.py", line 1850, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/click/core.py", line 1246, in invoke
return ctx.invoke(self.callback, **ctx.params)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/click/core.py", line 814, in invoke
return callback(*args, **kwargs)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/click/decorators.py", line 34, in new_func
return f(get_current_context(), *args, **kwargs)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/hydromt/cli/main.py", line 349, in update
mod.update(model_out=model_out, steps=steps, forceful_overwrite=fo)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/hydromt/model/model.py", line 371, in update
self.write()
~~~~~~~~~~^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/hydromt_wflow/wflow_base.py", line 1745, in write
self.write_grid(filename=grid_filename)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/hydromt_wflow/wflow_base.py", line 1873, in write_grid
self.staticmaps.write(filename=filename, **kwargs)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/hydromt_wflow/components/staticmaps.py", line 129, in write
super().write(
~~~~~~~~~~~~~^
str(p_input),
^^^^^^^^^^^^^
...<3 lines>...
**kwargs,
^^^^^^^^^
)
^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/hydromt/model/components/grid.py", line 186, in write
close_handle = write_nc(
self.data,
...<5 lines>...
**kwargs,
)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/hydromt/io/writers.py", line 143, in write_nc
ds.to_netcdf(file_path, **kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/core/dataset.py", line 2104, in to_netcdf
return to_netcdf( # type: ignore[return-value] # mypy cannot resolve the overloads:(
self,
...<10 lines>...
auto_complex=auto_complex,
)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/writers.py", line 422, in to_netcdf
store = get_writable_netcdf_store(
target,
...<5 lines>...
auto_complex=auto_complex,
)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/writers.py", line 78, in get_writable_netcdf_store
return store_open(target, mode=mode, format=format, **kwargs)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/h5netcdf_.py", line 226, in open
return cls(manager, group=group, mode=mode, lock=lock, autoclose=autoclose)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/h5netcdf_.py", line 149, in __init__
self._filename = find_root_and_group(self.ds)[0].filename
^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/h5netcdf_.py", line 237, in ds
return self._acquire()
~~~~~~~~~~~~~^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/h5netcdf_.py", line 229, in _acquire
with self._manager.acquire_context(needs_lock) as root:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/contextlib.py", line 141, in __enter__
return next(self.gen)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/file_manager.py", line 207, in acquire_context
file, cached = self._acquire_with_cache_info(needs_lock)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/xarray/backends/file_manager.py", line 225, in _acquire_with_cache_info
file = self._opener(*self._args, **kwargs)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/h5netcdf/core.py", line 1552, in __init__
self.__h5file = self._h5py.File(
~~~~~~~~~~~~~~~^
path, mode, track_order=track_order, **kwargs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/h5py/_hl/files.py", line 564, in __init__
fid = make_fid(name, mode, userblock_size, fapl, fcpl, swmr=swmr)
File "/home/runner/work/hydromt_wflow/hydromt_wflow/.pixi/envs/docs/lib/python3.13/site-packages/h5py/_hl/files.py", line 244, in make_fid
fid = h5f.create(name, h5f.ACC_TRUNC, fapl=fapl, fcpl=fcpl)
File "h5py/_objects.pyx", line 56, in h5py._objects.with_phil.wrapper
File "h5py/_objects.pyx", line 57, in h5py._objects.with_phil.wrapper
File "h5py/h5f.pyx", line 122, in h5py.h5f.create
OSError: Unable to synchronously create file (unable to truncate a file which is already open)
The example above means the following: run hydromt with:
update wflow
: i.e. update a wflow modelwflow_piave_gauges
: model folder to update (here we save our updates in the same model folder)-i wflow_update_gauges_without_snapping.yml
: the config yaml containing the additional options.v
: give some extra verbosity (2 * v) to display feedback on screen. Now debug messages are provided.
Other available options are available in the docs (setup gauges).
Visualization of the gauges#
We can now plot our newly created gauges stations maps and check the differences between the flow and rain maps.
[9]:
# Load the updated model with hydromt
from hydromt_wflow import WflowSbmModel
mod = WflowSbmModel(root="wflow_piave_gauges", mode="r")
[10]:
# read/derive river geometries
gdf_riv = mod.rivers
# read/derive model basin boundary
gdf_bas = mod.basins
[11]:
# Plot
# we assume the model maps are in the geographic CRS EPSG:4326
proj = ccrs.PlateCarree()
# adjust zoomlevel and figure size to your basis size & aspect
zoom_level = 10
figsize = (10, 8)
shaded = False
# initialize image with geoaxes
fig = plt.figure(figsize=figsize)
ax = fig.add_subplot(projection=proj)
bounds = mod.region.total_bounds
bbox = gpd.GeoDataFrame(geometry=[box(*bounds)], crs=mod.crs).to_crs(3857).buffer(5e3)
extent = np.array(bbox.to_crs(mod.crs).total_bounds)[[0, 2, 1, 3]]
ax.set_extent(extent, crs=proj)
# add sat background image
ax.add_image(cimgt.QuadtreeTiles(), zoom_level, alpha=0.5)
# plot rivers with increasing width with stream order
gdf_riv.plot(ax=ax, lw=gdf_riv["strord"] / 2, color="blue", zorder=3, label="river")
# plot the basin boundary
gdf_bas.boundary.plot(ax=ax, color="k", linewidth=0.5)
if "gauges" in mod.geoms.data:
mod.geoms.get("gauges").plot(
ax=ax, marker="d", markersize=25, facecolor="k", zorder=5, label="outlet"
)
if "gauges_grdc" in mod.geoms.data:
mod.geoms.get("gauges_grdc").plot(
ax=ax,
marker="d",
markersize=25,
facecolor="purple",
zorder=5,
label="Gauges GRDC",
)
if "gauges_test-flow" in mod.geoms.data:
mod.geoms.get("gauges_test-flow").plot(
ax=ax, marker="d", markersize=25, facecolor="red", zorder=5, label="Gauges Flow"
)
if "gauges_test-rain" in mod.geoms.data:
mod.geoms.get("gauges_test-rain").plot(
ax=ax,
marker="d",
markersize=25,
facecolor="green",
zorder=5,
label="Gauges Rain",
)
ax.xaxis.set_visible(True)
ax.yaxis.set_visible(True)
ax.set_ylabel(f"latitude [degree north]")
ax.set_xlabel(f"longitude [degree east]")
_ = ax.set_title(f"wflow base map")
legend = ax.legend(
handles=[*ax.get_legend_handles_labels()[0]],
title="Legend",
loc="lower right",
frameon=True,
framealpha=0.7,
edgecolor="k",
facecolor="white",
)
