Tip

For an interactive online version click here: Binder badge

Build a model from CLI#

In this example a simple SFINCS compound flood model will be made, using HydroMT’s yml-file that allows for fast model configuration. The model is situated in Northern Italy, where a small selection of topography and bathymetry data has already been made available for you to try the examples.

[1]:
# To check the version of hydromt and the hydromt_sfincs plugin, run the following command in a terminal:
!hydromt --models
model plugins:
 - sfincs (hydromt_sfincs 1.0.4.dev0)
generic models (hydromt 0.9.4):
 - grid_model
 - vector_model
 - network_model


This example shows how to build a simple SFINCS model on a regular grid, containing an elevation dep-file, offshore water level forcing and an upstream discharge input forcing. For making a more advanced model including e.g. spatially varying infiltration and roughness, see the example notebook: examples/build_from_script.ipynb

In case you want to adjust this example to build a SFINCS model anywhere else in the world, you will have to add your own datasets to HydroMT’s data catalog. For more info on that, check-out:

Steps followed in this notebook to build your SFINCS model:

  1. Build your first SFINCS model

  2. Check what files have been created

  3. Information about created files

  4. Plot current base model

  5. Explanation of HydroMT’s .yml-file

  6. Make new model including forcing

  7. Plot model including forcing

  8. Check what additional files have been created

Let’s get started!

1. Build your first SFINCS model:#

[2]:
root = r"./tmp_sfincs_base"
[3]:
!hydromt build sfincs tmp_sfincs_base --region "{'geom': 'data/region.geojson'}" -i sfincs_base_build.yml --force-overwrite -v
2024-04-24 10:07:50,242 - build - log - INFO - HydroMT version: 0.9.4
2024-04-24 10:07:50,243 - build - main - INFO - Building instance of sfincs model at /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base.
2024-04-24 10:07:50,243 - build - main - INFO - User settings:
2024-04-24 10:07:50,269 - build - model_api - INFO - Initializing sfincs model from hydromt_sfincs (v1.0.4.dev0).
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.region: {'geom': 'data/region.geojson'}
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.res: 50
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.crs: utm
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.rotated: True
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.hydrography_fn: None
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.basin_index_fn: None
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.align: False
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.dec_origin: 0
2024-04-24 10:07:50,270 - build - model_api - INFO - setup_grid_from_region.dec_rotation: 3
2024-04-24 10:07:50,366 - build - data_catalog - INFO - Reading data catalog archive artifact_data v0.0.8
2024-04-24 10:07:51,824 - build - data_catalog - INFO - Parsing data catalog from /home/runner/.hydromt_data/artifact_data/v0.0.8/data_catalog.yml
2024-04-24 10:07:51,868 - build - geodataframe - INFO - Reading  vector data from data/region.geojson
2024-04-24 10:07:51,901 - build - model_api - INFO - setup_dep.datasets_dep: [{'elevtn': 'merit_hydro', 'zmin': 0.001}, {'elevtn': 'gebco'}]
2024-04-24 10:07:51,901 - build - model_api - INFO - setup_dep.buffer_cells: 0
2024-04-24 10:07:51,901 - build - model_api - INFO - setup_dep.interp_method: linear
2024-04-24 10:07:51,916 - build - rasterdataset - INFO - Reading merit_hydro raster data from /home/runner/.hydromt_data/artifact_data/v0.0.8/merit_hydro/{variable}.tif
2024-04-24 10:07:51,947 - build - rasterdataset - INFO - Reading gebco raster data from /home/runner/.hydromt_data/artifact_data/v0.0.8/gebco.tif
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.mask: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/region.geojson
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.include_mask: None
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.exclude_mask: None
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.mask_buffer: 0
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.zmin: -5
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.zmax: None
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.fill_area: 10.0
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.drop_area: 0.0
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.connectivity: 8
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.all_touched: True
2024-04-24 10:07:52,177 - build - model_api - INFO - setup_mask_active.reset_mask: True
2024-04-24 10:07:52,179 - build - geodataframe - INFO - Reading  vector data from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/region.geojson
2024-04-24 10:07:52,209 - build - regulargrid - INFO - 4 gaps outside valid elevation range < 10.0 km2.
2024-04-24 10:07:52,210 - build - sfincs - INFO - Derive region geometry based on active cells.
2024-04-24 10:07:52,216 - build - model_api - WARNING - Replacing geom: region
2024-04-24 10:07:52,216 - build - model_api - INFO - setup_mask_bounds.btype: waterlevel
2024-04-24 10:07:52,216 - build - model_api - INFO - setup_mask_bounds.include_mask: None
2024-04-24 10:07:52,216 - build - model_api - INFO - setup_mask_bounds.exclude_mask: None
2024-04-24 10:07:52,216 - build - model_api - INFO - setup_mask_bounds.include_mask_buffer: 0
2024-04-24 10:07:52,216 - build - model_api - INFO - setup_mask_bounds.zmin: None
2024-04-24 10:07:52,217 - build - model_api - INFO - setup_mask_bounds.zmax: -1
2024-04-24 10:07:52,217 - build - model_api - INFO - setup_mask_bounds.connectivity: 8
2024-04-24 10:07:52,217 - build - model_api - INFO - setup_mask_bounds.all_touched: False
2024-04-24 10:07:52,217 - build - model_api - INFO - setup_mask_bounds.reset_bounds: False
2024-04-24 10:07:52,234 - build - sfincs - INFO - Writing model data to /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base
2024-04-24 10:07:52,236 - build - sfincs - INFO - Write raster file(s) for grid to 'gis' subfolder
2024-04-24 10:07:52,254 - build - sfincs - INFO - Write geom files
2024-04-24 10:07:52,254 - build - sfincs - INFO - Write vector file(s) for geoms to 'gis' subfolder
2024-04-24 10:07:52,260 - build - sfincs - WARNING - zsini not in states, skipping

Explanation of what is provided:

  • ! : the ‘!’ is added so you can run the command line interface (CLI) from a python notebook

  • hydromt build sfincs : HydroMT should build a SFINCS model,

  • tmp_sfincs_base : HydroMT should build the model in a folder called “tmp_sfincs_base” relative to the current working directory (you can also provide absolute paths)

  • --region "{'geom': 'data/region.geojson'}" : the area of interest for which a model is created is based on a geometry, which is already defined for you in the file “data/region.geojson”

  • -i sfincs_base_build.yml : model configuration which describes the complete pipeline to build your model, more on that later

  • --force-overwrite : even if there’s already an existing folder with the same name and SFINCS input files, HydroMT will overwrite it

  • -v : add verbosity to the logger

NOTE:

  • instead of --region, you can also type -r

  • instead of --force-overwrite, you can also type --fo

  • for extra output information of HydroMT’s logfile command, add -v

[4]:
# For more information on command line available options, type:
!hydromt build --help
Usage: hydromt build [OPTIONS] MODEL MODEL_ROOT

  Build models from scratch.

  Example usage: --------------

  To build a wflow model for a subbasin using a point coordinates snapped to
  cells with upstream area >= 50 km2 hydromt build wflow /path/to/model_root
  -i /path/to/wflow_config.yml  -r "{'subbasin': [-7.24, 62.09], 'uparea':
  50}" -d deltares_data -d /path/to/data_catalog.yml -v

  To build a sfincs model based on a bbox hydromt build sfincs
  /path/to/model_root  -i /path/to/sfincs_config.yml  -r "{'bbox':
  [4.6891,52.9750,4.9576,53.1994]}"  -d /path/to/data_catalog.yml -v

Options:
  --opt TEXT               Method specific keyword arguments, see the method
                           documentation of the specific model for more
                           information about the arguments.
  -i, --config PATH        Path to hydroMT configuration file, for the model
                           specific implementation.
  -r, --region TEXT        Set the region for which to build the model, e.g.
                           {'subbasin': [-7.24, 62.09]}
  -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
  -v, --verbose            Increase verbosity.
  -q, --quiet              Decrease verbosity.
  --help                   Show this message and exit.

2. Check what files have been created:#

[5]:
import os

dir_list = os.listdir(root)
print(dir_list)
['gis', 'hydromt_data.yml', 'sfincs.inp', 'sfincs.dep', 'sfincs.msk', 'sfincs.ind', 'hydromt.log']

3. Information about created files:#

SFINCS native input files:

Check-out the SFINCS manual (see links) in case you want to have more information about each file

HydroMT output:

  • folder 'gis' : contains tiff- and geojson-files of the input files of SFINCS, for you to easily check in your favourite GIS application

  • folder 'subgrid' : contains tiff-files of the subgrid input which can be used for downscaling later

  • hydromt.log : log-file with feedback of HydroMT during building your model

4. Plot current base model#

[6]:
from hydromt_sfincs import SfincsModel

# read the model with hydromt methods
sf = SfincsModel(root=root, mode="r")
sf.read()

Here in the plot you see the following: - Background geoimage of the region - Spatial colourplot of the elevation (dep) - In the red line of ‘waterlevel bnd’ the boundary cells along which SFINCS will later force input water levels

[7]:
# plot the model with satelite basemap (see hydromt_sfincs.plot_basemap for more options)
_ = sf.plot_basemap(shaded=False, bmap="sat", zoomlevel=12)
../_images/_examples_build_from_cli_19_0.png

5. Explanation of HydroMT’s .yml-file:#

This model was made using HydroMT’s yaml-file, in this case ‘sfincs_base_build.yml’, that contains:

[8]:
fn = "sfincs_base_build.yml"
with open(fn, "r") as f:
    txt = f.read()
print(txt)
global:
  data_libs: []                # add optional paths to data_catalog yml files

setup_config:
  tref: 20100201 000000
  tstart: 20100201 000000
  tstop: 20100202 000000

setup_grid_from_region:
  res: 50                      # model resolution
  crs: utm                     # model CRS (must be UTM zone)
  rotated: True                # allow a rotated grid

setup_dep:
  datasets_dep:
  - elevtn: merit_hydro        # 1st elevation dataset
    zmin: 0.001                # only use where values > 0.001
  - elevtn: gebco              # 2nd eleveation dataset (to be merged with the first)

setup_mask_active:
  mask: data//region.geojson   # Note that this is local data and only valid for this example
  zmin: -5                     # set cells below zmin to inactive

setup_mask_bounds:
  btype: waterlevel            # Set waterlevel boundaries
  zmax: -1                     # only cells below zmax can be waterlevel boundaries

[9]:
# in case you want to see how hydromt interprets the config file, you can use the following:
from hydromt.config import configread

config = configread(fn)
config
[9]:
{'global': {'data_libs': []},
 'setup_config': {'tref': '20100201 000000',
  'tstart': '20100201 000000',
  'tstop': '20100202 000000'},
 'setup_grid_from_region': {'res': 50, 'crs': 'utm', 'rotated': True},
 'setup_dep': {'datasets_dep': [{'elevtn': 'merit_hydro', 'zmin': 0.001},
   {'elevtn': 'gebco'}]},
 'setup_mask_active': {'mask': 'data//region.geojson', 'zmin': -5},
 'setup_mask_bounds': {'btype': 'waterlevel', 'zmax': -1}}

You can see the following sections:

  • setup_config: arguments are forwarded to the SFINCS model configuration file sfincs.inp, in this case the reference time ‘tref’, model start time ‘tstart’ and end time ‘tstop’

  • setup_grid_from_region: used to create a model grid covering the region you provided;

    • using a grid resolution of 50 meters (res = 50)

    • using the closest UTM zone (crs = utm) to the model domain as the Coordinate Reference System (also a specific CRS or epsg-code can be provided)

    • using a rotation that results in a minimum rectangle around your region (if rotation=True)

  • setup_dep: adds topography and bathymetry data to the model domain. If using local data sources, these should be described in a data_catalog.yml. At least one dataset is required.

    • Additional data sources are merged with the first elevation dataset using merge argements (e.g. zmin, zmax, offset, mask) if provided.

  • setup_mask_active: set valid model cells based on an input region file (more options available).

  • setup_mask_bounds: set cells at the model domain edge with a maxmimum elevation of -5 meters (zmax = -5) to waterlevel boundary cells.

From here on, we’re going to extend the model with some forcing of water level and river discharge, so that actually something interesting will happen when you run the created SFINCS model later. Also, we’re adding some observations points so we can inspect this. We do this with the additional yml-file sfincs_base_update.yml containing what we want to add:

6. Update the model to include forcing:#

[10]:
!hydromt update sfincs tmp_sfincs_base -i sfincs_base_update.yml -v
2024-04-24 10:08:01,310 - update - log - INFO - HydroMT version: 0.9.4
2024-04-24 10:08:01,310 - update - main - INFO - Updating sfincs model at /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base (r+).
2024-04-24 10:08:01,310 - update - main - INFO - Output dir: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base
2024-04-24 10:08:01,310 - update - main - INFO - User settings:
2024-04-24 10:08:01,335 - update - model_api - WARNING - Model dir already exists and files might be overwritten: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base/gis.
2024-04-24 10:08:01,335 - update - model_api - INFO - Initializing sfincs model from hydromt_sfincs (v1.0.4.dev0).
2024-04-24 10:08:01,363 - update - model_api - INFO - setup_observation_points.locations: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_example_observation_points.geojson
2024-04-24 10:08:01,363 - update - model_api - INFO - setup_observation_points.merge: True
2024-04-24 10:08:01,397 - update - data_catalog - INFO - Reading data catalog archive artifact_data v0.0.8
2024-04-24 10:08:01,397 - update - data_catalog - INFO - Parsing data catalog from /home/runner/.hydromt_data/artifact_data/v0.0.8/data_catalog.yml
2024-04-24 10:08:01,442 - update - geodataframe - INFO - Reading  vector data from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_example_observation_points.geojson
2024-04-24 10:08:01,453 - update - model_api - INFO - setup_waterlevel_forcing.geodataset: gtsmv3_eu_era5
2024-04-24 10:08:01,453 - update - model_api - INFO - setup_waterlevel_forcing.timeseries: None
2024-04-24 10:08:01,453 - update - model_api - INFO - setup_waterlevel_forcing.locations: None
2024-04-24 10:08:01,453 - update - model_api - INFO - setup_waterlevel_forcing.offset: None
2024-04-24 10:08:01,453 - update - model_api - INFO - setup_waterlevel_forcing.buffer: 2000
2024-04-24 10:08:01,453 - update - model_api - INFO - setup_waterlevel_forcing.merge: True
2024-04-24 10:08:01,825 - update - model_api - INFO - setup_discharge_forcing.geodataset: None
2024-04-24 10:08:01,825 - update - model_api - INFO - setup_discharge_forcing.timeseries: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_dis_timeseries.csv
2024-04-24 10:08:01,825 - update - model_api - INFO - setup_discharge_forcing.locations: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_src_locations.geojson
2024-04-24 10:08:01,825 - update - model_api - INFO - setup_discharge_forcing.merge: True
2024-04-24 10:08:01,825 - update - model_api - INFO - setup_discharge_forcing.buffer: None
2024-04-24 10:08:01,826 - update - dataframe - INFO - Reading  csv data from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_dis_timeseries.csv
2024-04-24 10:08:01,829 - update - geodataframe - INFO - Reading  vector data from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_src_locations.geojson
2024-04-24 10:08:01,837 - update - sfincs - INFO - Setting gdf_locs index to ID
2024-04-24 10:08:01,842 - update - sfincs - INFO - Writing model data to /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base
2024-04-24 10:08:01,845 - update - sfincs - INFO - Write raster file(s) for grid to 'gis' subfolder
2024-04-24 10:08:01,871 - update - sfincs - INFO - Write geom files
2024-04-24 10:08:01,873 - update - sfincs - INFO - Write vector file(s) for geoms to 'gis' subfolder
2024-04-24 10:08:01,882 - update - sfincs - INFO - Write forcing files
2024-04-24 10:08:01,891 - update - sfincs - INFO - Write vector file(s) for forcing.bzs to 'gis' subfolder
2024-04-24 10:08:01,918 - update - sfincs - INFO - Write vector file(s) for forcing.dis to 'gis' subfolder
2024-04-24 10:08:01,938 - update - sfincs - WARNING - zsini not in states, skipping
2024-04-24 10:08:01,938 - update - data_catalog - INFO - Parsing data catalog from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base/hydromt_data.yml

The example above means the following: run hydromt with:

  • update sfincs: i.e. update a SFINCS model.

  • tmp_sfincs_base: original model folder. Here we update the model inplace. Add -o <output folder> to store the udpated model in another directory.

  • -i sfincs_base_update.yml: configuration file containing the components to update and their different options.

[11]:
# Let's see what is in the yml-file:

fn = "sfincs_base_update.yml"
with open(fn, "r") as f:
    txt = f.read()
print(txt)
setup_observation_points:
  locations: data//compound_example_observation_points.geojson       # Note that this is local data and only valid for this example

setup_waterlevel_forcing:
  geodataset: gtsmv3_eu_era5
  buffer: 2000                                                        # [m] find points within 2 km of waterlevel boundary

setup_discharge_forcing:
  timeseries: data/compound_dis_timeseries.csv
  locations: data/compound_src_locations.geojson                     # Note that this is local data and only valid for this example

You can see the following sections:

  • setup_observation_points: add 3 observation points based on the locations given in the shapefile “data//compound_example_observation_points.shp”

  • setup_waterlevel_forcing: add water level forcing, in this case water levels from a GTSM run, with 4 output points found in the SFINCS model domain. Timeseries are clipped automatically to the earlier provided start and stop time of the SFINCS model (in setup_config)

  • setup_discharge_forcing: add an upstream river discharge input point, in this case from a csv file (timeseries) and a geojson (locations)

7. Plot model including forcing:#

[12]:
from hydromt_sfincs import SfincsModel

# read the model with hydromt methods
sf = SfincsModel(root=root, mode="r")
sf.read()

In the forcing plot you see the following:

  • Water level time-series based on GTSM input for the model period. For each of the 4 stations within the SFINCS domain, these time-series are interpolated to the ‘waterlevel’ boundary cells (bnd) using the two nearest stations.

  • Discharge time series from the local file input. These timeseries are forced at the ‘discharge src’ points

[13]:
# Plot time-series:
_ = sf.plot_forcing(fn_out="forcing.png")
../_images/_examples_build_from_cli_34_0.png

In the basemap plot you see the following:

  • Background geoimage of the region

  • Spatial colourplot of the elevation (dep)

  • In the red line of ‘waterlevel bnd’ the boundary cells along which SFINCS will later force input water levels

  • Specified observation points ‘obs’ in red diamond to get a ‘sfincs_his.nc’ output file

  • Discharge ‘src’ and waterlevel ‘bnd’ point locations.

[14]:
# plot the model basemaps
# Note the added obs and forcing points

_ = sf.plot_basemap(fn_out="basemap.png", bmap="sat", zoomlevel=12)
../_images/_examples_build_from_cli_36_0.png

8. Check what additional files have been created:#

[15]:
dir_list = os.listdir(root)
print(dir_list)
['gis', 'hydromt_data.yml', 'sfincs.inp', 'sfincs.dep', 'sfincs.msk', 'sfincs.bnd', 'sfincs.dis', 'sfincs.src', 'sfincs.bzs', 'sfincs.ind', 'hydromt.log', 'sfincs.obs', 'figs']

SFINCS native input files:

Click on Read more in case you want to have more information about what each file means!

In case you want to add other types of forcing, check-out:

Now you have made a model, you can progress to the notebooks:

  • examples/run_sfincs_model.ipynb

  • examples/analyse_sfincs_model.ipynb

This notebook provides you a simple SFINCS model on a regular grid. A more advanced example is provided in see examples/build_from_script.ipynb. In addition, an overview of all available options in HydroMT-SFINCS can be found here.

NOTE: HydroMT can build even more models for you, like the Hydrological model Wflow, to provide for instance upstream boundary conditions for your SFINCS model! See e.g: https://deltares.github.io/hydromt/latest/plugins.html