Tip

For an interactive online version click here: Binder badge

Update monitoring locations#

Once you have a DELWAQ model, you may want to update your model in order to add new emission data, add sample locations, use different hydrological 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 monitoring points and areas 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 monitoring points of the updated model. Here are the libraries to import to realize these steps.

[1]:
import numpy as np
[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
[3]:
# import hydromt
import hydromt
from hydromt_delwaq import DelwaqModel, DemissionModel
[4]:
# setup logging
from  hydromt.log import setuplog
logger = setuplog("update_model_monitoring", log_level=10)
2024-06-21 02:54:47,510 - update_model_monitoring - log - INFO - HydroMT version: 0.10.0

Locations of the monitoring points#

Adding monitoring points to your DELWAQ 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 DELWAQ model in which the locations of the Wflow basin outlets area added (from the staticgeoms/gauges.geojson). 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 examples_data/test_monpoints.csv has been prepared. Let’s have a look at it.

[5]:
fn_station = 'examples_data/test_monpoints.csv'
with open(fn_station, 'r', encoding='utf8') as f:
    txt = f.read()
print(txt)
ID,Name,x,y
1001,Gauge1,11.9594,45.8925
1002,Gauge2,12.3395,46.1492
1003,Gauge3,12.0785,46.1122

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 update API, we can update one or several components of an already existing DELWAQ model. Let’s get an overview of the available options:

[6]:
# 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 (overwrite!) landuse-landcover based maps in a Wflow model: hydromt
  update wflow /path/to/model_root -c setup_lulcmaps --opt lulc_fn=vito -d
  /path/to/data_catalog.yml -v

  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.
  -c, --components TEXT      Model methods from configuration file to run
  --opt TEXT                 Method specific keyword arguments, see the method
                             documentation of the specific model for more
                             information about the arguments.
  -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 Delwaq monitoring points#

Let’s prepare a HydroMT configuration file with new our options for monitoring points and areas. All available options are available in the docs(setup_monitoring).

[7]:
# Dictionnary with all the components and options we want to update
monitoring_options = {
    'setup_monitoring': {
        'mon_points': 'examples_data/test_monpoints.csv',
        'mon_areas': 'subcatch',
    },
}

# Save it to a hydroMT ini file
fn_yml = "delwaq_update_monitoring.yml"
hydromt.config.configwrite(fn_yml, monitoring_options)

# Open the file and visualize the content
with open(fn_yml, 'r') as f:
    txt = f.read()
print(txt)
setup_monitoring:
  mon_points: examples_data/test_monpoints.csv
  mon_areas: subcatch

[8]:
# NOTE: copy this line (without !) to your shell for more direct feedback
! hydromt update delwaq WQ_piave -o ./WQ_piave_monitoring -i delwaq_update_monitoring.yml --fo -vv
2024-06-21 02:54:51,596 - update - log - DEBUG - Writing log messages to new file /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave_monitoring/hydromt.log.
2024-06-21 02:54:51,596 - update - log - INFO - HydroMT version: 0.10.0
2024-06-21 02:54:51,597 - update - main - INFO - Updating delwaq model at /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave (r).
2024-06-21 02:54:51,597 - update - main - INFO - Output dir: /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave_monitoring
2024-06-21 02:54:51,597 - update - main - INFO - User settings:
2024-06-21 02:54:51,613 - update - log - DEBUG - Writing log messages to new file /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave/hydromt.log.
2024-06-21 02:54:51,613 - update - model_api - INFO - Initializing delwaq model from hydromt_delwaq (v0.2.2.dev0).
2024-06-21 02:54:51,613 - update - model_api - ERROR - Model config file not found at /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave/delwaq.inp
2024-06-21 02:54:51,614 - update - model_api - DEBUG - Reading model file monareas.
2024-06-21 02:54:51,639 - update - model_api - DEBUG - Reading model file staticdata.
2024-06-21 02:54:51,687 - update - model_api - DEBUG - Reading model file basins.
2024-06-21 02:54:51,693 - update - model_api - DEBUG - Reading model file monpoints.
nodata value missing for /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave/hydromodel/rivarea.tif
2024-06-21 02:54:51,822 - update - model_api - DEBUG - Reading model file staticdata.
2024-06-21 02:54:51,834 - update - model_grid - WARNING - Replacing grid map: river
2024-06-21 02:54:51,835 - update - model_grid - WARNING - Replacing grid map: slope
2024-06-21 02:54:51,836 - update - model_grid - WARNING - Replacing grid map: streamorder
2024-06-21 02:54:51,837 - update - model_grid - WARNING - Replacing grid map: manning
2024-06-21 02:54:51,838 - update - model_grid - WARNING - Replacing grid map: SoilThickness
2024-06-21 02:54:51,838 - update - model_grid - WARNING - Replacing grid map: porosity
2024-06-21 02:54:51,839 - update - model_grid - WARNING - Replacing grid map: surface
2024-06-21 02:54:51,840 - update - model_grid - WARNING - Replacing grid map: length
2024-06-21 02:54:51,841 - update - model_grid - WARNING - Replacing grid map: width
2024-06-21 02:54:51,842 - update - model_grid - WARNING - Replacing grid map: latitude_grid
2024-06-21 02:54:51,842 - update - model_grid - WARNING - Replacing grid map: bankfull_volume
2024-06-21 02:54:51,843 - update - model_grid - WARNING - Replacing grid map: monpoints
2024-06-21 02:54:51,844 - update - model_grid - WARNING - Replacing grid map: monareas
2024-06-21 02:54:51,845 - update - delwaq - INFO - Model read
2024-06-21 02:54:51,845 - update - log - DEBUG - Appending log messages to file /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave_monitoring/hydromt.log.
2024-06-21 02:54:51,853 - update - model_api - INFO - setup_monitoring.mon_points: /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/examples_data/test_monpoints.csv
2024-06-21 02:54:51,853 - update - model_api - INFO - setup_monitoring.mon_areas: subcatch
2024-06-21 02:54:51,853 - update - delwaq - INFO - Setting monitoring points and areas
2024-06-21 02:54:51,866 - update - data_catalog - INFO - Reading data catalog artifact_data latest
2024-06-21 02:54:51,866 - update - data_catalog - INFO - Parsing data catalog from /home/runner/.hydromt_data/artifact_data/v0.0.9/data_catalog.yml
2024-06-21 02:54:52,458 - update - geodataframe - INFO - Reading  csv data from /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/examples_data/test_monpoints.csv
2024-06-21 02:54:52,463 - update - geodataframe - DEBUG - Clip intersects [11.775, 45.808, 12.742, 46.692] (EPSG:4326)
2024-06-21 02:54:52,471 - update - delwaq - INFO - Gauges locations read from /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/examples_data/test_monpoints.csv
2024-06-21 02:54:52,472 - update - model_api - WARNING - Replacing geom: monpoints
2024-06-21 02:54:52,606 - update - model_api - WARNING - Replacing geom: monareas
2024-06-21 02:54:52,609 - update - delwaq - INFO - Write model data to /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave_monitoring
2024-06-21 02:54:52,645 - update - delwaq - INFO - Writing staticmap files.
2024-06-21 02:54:52,694 - update - model_api - DEBUG - Writing file geoms/monareas.geojson
2024-06-21 02:54:52,715 - update - model_api - DEBUG - Writing file geoms/basins.geojson
2024-06-21 02:54:52,721 - update - model_api - DEBUG - Writing file geoms/monpoints.geojson
2024-06-21 02:54:52,726 - update - delwaq - INFO - Writing model config to file.
2024-06-21 02:54:52,727 - update - delwaq - INFO - Writing hydromap files.
nodata value missing for /home/runner/work/hydromt_delwaq/hydromt_delwaq/docs/_examples/WQ_piave_monitoring/hydromodel/rivarea.tif
2024-06-21 02:54:52,847 - update - delwaq - DEBUG - No forcing data found, skip writing.

The example above means the following: run hydromt with:

  • update delwaq: i.e. update a delwaq model

  • WQ_piave: original model folder

  • -o ./WQ_piave_monitoring: output updated model folder

  • -i delwaq_update_monitoring.yml: hydroMT configuration file containing the components and options to update

  • -v: give some extra verbosity (2 * v) to display feedback on screen. Now debug messages are provided.

Visualization of the monitoring points#

We can now plot our newly created monitoring points.

[9]:
# Load the original and updated model with hydromt
mod0 = DelwaqModel(root='WQ_piave', mode='r')
mod1 = DelwaqModel(root='WQ_piave_monitoring', mode='r')
[10]:
# 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)

# initialize image with geoaxes
fig = plt.figure(figsize=figsize)
ax = fig.add_subplot(projection=proj)
extent = np.array(mod0.grid.raster.box.buffer(0.02).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 streamorder as background
da = mod0.grid['streamorder'].raster.mask_nodata()
da.attrs.update(long_name='streamorder', units='-')
## plot streamorder map
cmap = plt.cm.get_cmap('Blues')
kwargs = dict(cmap=cmap)
da.plot(transform=proj, ax=ax, zorder=1, cbar_kwargs=dict(aspect=30, shrink=.8), **kwargs)

# read/derive model basin boundary
gdf_bas = mod0.basins
# plot the basin boundary
gdf_bas.boundary.plot(ax=ax, color='k', linewidth=0.3)

if 'monpoints' in mod0.geoms:
    mod0.geoms['monpoints'].plot(ax=ax, marker='o', markersize=50, facecolor='red', edgecolor='k', zorder=5, label='Basin outlet')
if 'monpoints' in mod1.geoms:
    mod1.geoms['monpoints'].plot(ax=ax, marker='o', markersize=50, facecolor='yellow', edgecolor='k', zorder=5, label='Updated points')

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"Delwaq monitoring points")
legend = ax.legend(
    handles=[*ax.get_legend_handles_labels()[0]],
    title="Legend",
    loc='lower right',
    frameon=True,
    framealpha=0.7,
    edgecolor='k',
    facecolor='white'
)
../_images/_examples_update_model_monitoring_23_0.png