Tip

For an interactive online version click here: Binder badge

Clip a Wflow model#

Let’s imagine you have built and calibrated a Wflow model for a whole country or continent. And now you have a new project for a small basin belonging to your big calibrated Wflow model. Instead of re-building the smaller model from scratch with HydroMT and re-doing the calibration steps, you can easily use the clip method of HydroMT to directly extract your smaller catchment out of your already existing big calibrated model!

This notebook demonstrates how to clip a Wflow model from an already existing one using the update command line interace (CLI) and the clip method.

All lines in this notebook which start 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 these in your shell to get more direct feedback.

Clip a small sub-basin#

In order to clip a model, we need to prepare a configuration file using the clip method and specifying the region/basin to clip. Below you can see an example of such a file:

[1]:
fn_config = "wflow_clip.yml"
with open(fn_config, "r") as f:
    txt = f.read()
print(txt)
global:
  config_filename: wflow_sbm.toml # name of the config file including paths to staticmaps / forcing / states to clip
steps:
  - clip: # clip method
      region: # region to clip
        subbasin: [12.3006, 46.4324] # derive a subbasin with its outlet at the given x,y coordinates
        meta_streamorder: 4 # snapped to a river with minimum stream order (strord) of 4
      inverse_clip: false # whether to clip the region (false) or the part outside of the region (true)
      clip_states: true # whether to clip the states or not
      clip_forcing: true # whether to clipt eh forcing or not

Now let’s use the CLI to clip our model:

[2]:
# NOTE: copy this line (without !) to your shell for more direct feedback
!hydromt update wflow_sbm "wflow_piave_subbasin" -o "./wflow_test_clip" -i wflow_clip.yml -v
2025-09-17 13:34:06,895 - hydromt - log - INFO - HydroMT version: 1.2.0.dev0
2025-09-17 13:34:06,895 - hydromt.cli.main - main - INFO - Updating wflow_sbm model at /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_subbasin (r).
2025-09-17 13:34:06,896 - hydromt.cli.main - main - INFO - Output dir: /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip
2025-09-17 13:34:06,896 - hydromt.cli.main - main - INFO - User settings:
2025-09-17 13:34:06,927 - hydromt.model.root - root - INFO - setting root to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_piave_subbasin
2025-09-17 13:34:06,927 - hydromt.model.model - model - INFO - Initializing wflow_sbm model from hydromt_wflow (v1.0.0.dev0).
2025-09-17 13:34:06,927 - 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-09-17 13:34:06,956 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Supported Wflow.jl version v1+
2025-09-17 13:34:06,956 - 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-09-17 13:34:06,957 - 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-09-17 13:34:07,794 - hydromt.model.components.tables - tables - INFO - Reading model table files.
2025-09-17 13:34:07,794 - hydromt.model.root - root - INFO - setting root to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip
2025-09-17 13:34:07,796 - hydromt.model.model - model - INFO - update: clip
2025-09-17 13:34:07,796 - hydromt.model.model - model - INFO - clip.inverse_clip=False
2025-09-17 13:34:07,796 - hydromt.model.model - model - INFO - clip.clip_forcing=True
2025-09-17 13:34:07,796 - hydromt.model.model - model - INFO - clip.clip_states=True
2025-09-17 13:34:07,796 - hydromt.model.model - model - INFO - clip.crs=4326
2025-09-17 13:34:07,796 - hydromt.model.model - model - INFO - clip.region={'subbasin': [12.3006, 46.4324], 'meta_streamorder': 4}
2025-09-17 13:34:07,796 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Clipping staticmaps..
2025-09-17 13:34:10,309 - hydromt.model.processes.basin_mask - basin_mask - INFO - subbasin bbox: [12.0083, 46.3417, 12.3250, 46.6750]
2025-09-17 13:34:10,321 - hydromt.hydromt_wflow.components.staticmaps - staticmaps - INFO - No reservoirs present in the clipped model, removing them from staticmaps.
2025-09-17 13:34:11,155 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Re-generating/clipping staticgeoms..
2025-09-17 13:34:11,819 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Gauges locations set based on river outlets.
2025-09-17 13:34:11,822 - hydromt.hydromt_wflow.components.staticmaps - staticmaps - INFO - Replacing grid map: outlets
2025-09-17 13:34:11,832 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Gauges map based on catchment river outlets added.
2025-09-17 13:34:11,832 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Adding ['river_water__volume_flow_rate'] to csv section of toml.
2025-09-17 13:34:11,855 - hydromt.hydromt_wflow.components.states - states - INFO - Clipping state...
2025-09-17 13:34:11,859 - hydromt.hydromt_wflow.components.forcing - forcing - INFO - Clipping forcing...
2025-09-17 13:34:11,861 - hydromt.hydromt_wflow.wflow_sbm - wflow_sbm - INFO - Updating reservoir tables to match clipped model.
2025-09-17 13:34:11,861 - hydromt.hydromt_wflow.wflow_base - wflow_base - INFO - Write model data to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip
2025-09-17 13:34:11,861 - hydromt.model.components.grid - grid - INFO - wflow_sbm.staticmaps: Writing grid data to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/staticmaps.nc.
2025-09-17 13:34:11,902 - hydromt.model.components.spatial - spatial - INFO - wflow_sbm.staticmaps: Writing region to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/staticgeoms/region.geojson.
2025-09-17 13:34:11,914 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/staticgeoms/basins.geojson.
2025-09-17 13:34:11,916 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/staticgeoms/rivers.geojson.
2025-09-17 13:34:11,918 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/staticgeoms/outlets.geojson.
2025-09-17 13:34:11,920 - hydromt.model.components.geoms - geoms - WARNING - wflow_sbm.geoms: meta_reservoirs_simple_control is empty. Skipping...
2025-09-17 13:34:11,920 - hydromt.model.components.geoms - geoms - WARNING - wflow_sbm.geoms: reservoirs is empty. Skipping...
2025-09-17 13:34:11,920 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/staticgeoms/glaciers.geojson.
2025-09-17 13:34:11,925 - hydromt.model.components.geoms - geoms - INFO - wflow_sbm.geoms: Writing geoms to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/staticgeoms/gauges_grdc.geojson.
2025-09-17 13:34:11,927 - hydromt.model.components.geoms - geoms - WARNING - wflow_sbm.geoms: meta_reservoirs_no_control is empty. Skipping...
2025-09-17 13:34:11,927 - hydromt.hydromt_wflow.components.forcing - forcing - INFO - Write forcing file
2025-09-17 13:34:11,930 - hydromt.hydromt_wflow.components.forcing - forcing - INFO - Writing file /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/inmaps.nc
2025-09-17 13:34:11,941 - hydromt.model.components.tables - tables - INFO - wflow_sbm.tables: No tables found, skip writing.
2025-09-17 13:34:11,941 - hydromt.model.components.grid - grid - INFO - wflow_sbm.states: Writing grid data to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/instate/instates.nc.
2025-09-17 13:34:11,958 - hydromt.hydromt_wflow.components.config - config - INFO - Writing model config to /home/runner/work/hydromt_wflow/hydromt_wflow/docs/_examples/wflow_test_clip/wflow_sbm.toml.

The example above means the following: run hydromt clip with:

  • wflow_sbm : i.e. clip a wflow SBM model

  • wflow_piave_subbasin: original model to clip

  • -o ./wflow_test_clip : output model folder

  • -i wflow_clip.yml : configuration file with settings for clipping (including the region).

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

NOTE: Compared to build, you may notice here that the streamorder argument is called ‘meta_streamorder’. As we are clipping a wflow model, the name here should correspond to the name of the stream order map inside of your wflow model staticmaps.

Visualize and/or inspect model schematization#

The wflow plot example notebook contains scripts to visualize your model.

Here we will just simply plot the region of the different model (original and clipped) to check the differences between them.

[3]:
# Import plot packages
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.img_tiles as cimgt

# import descartes  # used under the hood to plot polygons
[4]:
import numpy as np
from hydromt_wflow import WflowSbmModel
[5]:
# Load both models with hydromt
mod0 = WflowSbmModel(root="wflow_piave_subbasin", mode="r")
mod1 = WflowSbmModel(root="wflow_test_clip", mode="r")
[6]:
# read/derive river geometries
gdf_riv0 = mod0.rivers
gdf_riv1 = mod1.rivers
# read/derive model basin boundary
gdf_bas0 = mod0.basins
gdf_bas1 = mod1.basins
[7]:
# 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 = mod0.staticmaps.data.raster.box.to_crs(3847).buffer(2000).to_crs(4326).total_bounds
extent = np.array(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_riv0.plot(ax=ax, lw=gdf_riv0["strord"] / 2, color="blue", zorder=3, label="river")
gdf_riv1.plot(
    ax=ax, lw=gdf_riv1["strord"] / 2, color="purple", zorder=3, label="river clip"
)
# plot the basin boundary
gdf_bas0.boundary.plot(ax=ax, color="k", linewidth=0.8, label="basin original")
gdf_bas1.boundary.plot(ax=ax, color="r", linewidth=0.8, label="basin clip")

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",
)
../_images/_examples_clip_model_15_0.png