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.0)
generic models (hydromt 0.7.1):
- grid_model
- lumped_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:
Build your first SFINCS model
Check what files have been created
Information about created files
Plot current base model
Explanation of HydroMT’s .yml-file
Make new model including forcing
Plot model including forcing
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
2023-04-17 16:03:44,699 - build - log - INFO - HydroMT version: 0.7.1
2023-04-17 16:03:44,699 - build - main - INFO - Building instance of sfincs model at /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base.
2023-04-17 16:03:44,699 - build - main - INFO - User settings:
2023-04-17 16:03:44,732 - build - model_api - INFO - Initializing sfincs model from hydromt_sfincs (v1.0.0).
2023-04-17 16:03:44,732 - build - model_api - INFO - setup_grid_from_region.region: {'geom': 'data/region.geojson'}
2023-04-17 16:03:44,732 - build - model_api - INFO - setup_grid_from_region.res: 50
2023-04-17 16:03:44,732 - build - model_api - INFO - setup_grid_from_region.crs: utm
2023-04-17 16:03:44,732 - build - model_api - INFO - setup_grid_from_region.rotated: True
2023-04-17 16:03:44,732 - build - model_api - INFO - setup_grid_from_region.hydrography_fn: None
2023-04-17 16:03:44,732 - build - model_api - INFO - setup_grid_from_region.basin_index_fn: None
2023-04-17 16:03:44,732 - build - model_api - INFO - setup_grid_from_region.dec_origin: 0
2023-04-17 16:03:44,732 - build - model_api - INFO - setup_grid_from_region.dec_rotation: 3
2023-04-17 16:03:44,781 - build - model_api - INFO - setup_dep.datasets_dep: [{'elevtn': 'merit_hydro', 'zmin': 0.001}, {'elevtn': 'gebco'}]
2023-04-17 16:03:44,781 - build - model_api - INFO - setup_dep.buffer_cells: 0
2023-04-17 16:03:44,781 - build - model_api - INFO - setup_dep.interp_method: linear
2023-04-17 16:03:44,883 - build - data_catalog - INFO - Reading data catalog artifact_data v0.0.8 from archive
2023-04-17 16:03:46,169 - build - data_catalog - INFO - Parsing data catalog from /home/runner/.hydromt_data/artifact_data/v0.0.8/data_catalog.yml
2023-04-17 16:03:46,233 - build - data_catalog - INFO - DataCatalog: Getting merit_hydro RasterDataset raster data from /home/runner/.hydromt_data/artifact_data/v0.0.8/merit_hydro/{variable}.tif
2023-04-17 16:03:46,300 - build - data_catalog - INFO - DataCatalog: Getting gebco RasterDataset raster data from /home/runner/.hydromt_data/artifact_data/v0.0.8/gebco.tif
2023-04-17 16:03:46,797 - build - sfincs - WARNING - Interpolate data at 0 cells
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.mask: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/region.geojson
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.include_mask: None
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.exclude_mask: None
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.mask_buffer: 0
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.zmin: -5
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.zmax: None
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.fill_area: 10.0
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.drop_area: 0.0
2023-04-17 16:03:46,799 - build - model_api - INFO - setup_mask_active.connectivity: 8
2023-04-17 16:03:46,800 - build - model_api - INFO - setup_mask_active.all_touched: True
2023-04-17 16:03:46,800 - build - model_api - INFO - setup_mask_active.reset_mask: False
2023-04-17 16:03:46,804 - build - data_catalog - INFO - DataCatalog: Getting region GeoDataFrame vector data from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/region.geojson
2023-04-17 16:03:46,808 - build - geodataframe - INFO - GeoDataFrame: Read vector data and clip to bbox (epsg:4326) [12.646, 45.490, 12.820, 45.586].
2023-04-17 16:03:46,841 - build - regulargrid - INFO - 3 gaps outside valid elevation range < 10.0 km2.
2023-04-17 16:03:46,844 - build - sfincs - INFO - Derive region geometry based on active cells.
2023-04-17 16:03:46,850 - build - model_api - WARNING - Replacing geom: region
2023-04-17 16:03:46,851 - build - model_api - INFO - setup_mask_bounds.btype: waterlevel
2023-04-17 16:03:46,851 - build - model_api - INFO - setup_mask_bounds.include_mask: None
2023-04-17 16:03:46,851 - build - model_api - INFO - setup_mask_bounds.exclude_mask: None
2023-04-17 16:03:46,851 - build - model_api - INFO - setup_mask_bounds.zmin: None
2023-04-17 16:03:46,851 - build - model_api - INFO - setup_mask_bounds.zmax: -1
2023-04-17 16:03:46,851 - build - model_api - INFO - setup_mask_bounds.connectivity: 8
2023-04-17 16:03:46,851 - build - model_api - INFO - setup_mask_bounds.all_touched: False
2023-04-17 16:03:46,851 - build - model_api - INFO - setup_mask_bounds.reset_bounds: False
2023-04-17 16:03:46,878 - build - sfincs - INFO - Writing model data to /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base
2023-04-17 16:03:46,880 - build - sfincs - INFO - Write raster file(s) for grid to 'gis' subfolder
2023-04-17 16:03:46,967 - build - sfincs - INFO - Write geom files
2023-04-17 16:03:46,968 - build - sfincs - INFO - Write vector file(s) for geoms to 'gis' subfolder
2023-04-17 16:03:46,976 - 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 notebookhydromt 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 and point coordinates snapped to cells with stream order >= 4
hydromt build wflow /path/to/model_root -i /path/to/wflow_config.ini -r "{'subbasin': [-7.24, 62.09], 'strord': 4}" -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.ini -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', 'sfincs.dep', 'sfincs.inp', 'sfincs.ind', 'sfincs.msk', 'hydromt.log']
3. Information about created files:#
SFINCS native input files:
SFINCS configuration
: sfincs.inp (Read more)which includes the grid definition (Read more)
depfile
: sfincs.dep (Read more)mskfile
: sfincs.msk (Read more)indfile
: sfincs.ind (Read more)
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 applicationfolder 'subgrid'
: contains tiff-files of the subgrid input which can be used for downscaling laterhydromt.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)
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 bounddaries
[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 adata_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
2023-04-17 16:03:55,347 - update - log - INFO - HydroMT version: 0.7.1
2023-04-17 16:03:55,347 - update - main - INFO - Updating sfincs model at /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base (r+).
2023-04-17 16:03:55,347 - update - main - INFO - Output dir: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base
2023-04-17 16:03:55,347 - update - main - INFO - User settings:
2023-04-17 16:03:55,378 - 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.
2023-04-17 16:03:55,378 - update - model_api - INFO - Initializing sfincs model from hydromt_sfincs (v1.0.0).
2023-04-17 16:03:55,410 - update - model_api - INFO - setup_observation_points.locations: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_example_observation_points.geojson
2023-04-17 16:03:55,410 - update - model_api - INFO - setup_observation_points.merge: True
2023-04-17 16:03:55,440 - update - data_catalog - INFO - Reading data catalog artifact_data v0.0.8 from archive
2023-04-17 16:03:55,440 - update - data_catalog - INFO - Parsing data catalog from /home/runner/.hydromt_data/artifact_data/v0.0.8/data_catalog.yml
2023-04-17 16:03:55,505 - update - data_catalog - INFO - DataCatalog: Getting compound_example_observation_points GeoDataFrame vector data from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_example_observation_points.geojson
2023-04-17 16:03:55,507 - update - geodataframe - INFO - GeoDataFrame: Read vector data and clip to geom (epsg:32633) [316221.151, 5041336.510, 329106.596, 5050441.766].
2023-04-17 16:03:55,519 - update - model_api - INFO - setup_waterlevel_forcing.geodataset: gtsmv3_eu_era5
2023-04-17 16:03:55,519 - update - model_api - INFO - setup_waterlevel_forcing.timeseries: None
2023-04-17 16:03:55,519 - update - model_api - INFO - setup_waterlevel_forcing.locations: None
2023-04-17 16:03:55,519 - update - model_api - INFO - setup_waterlevel_forcing.offset: None
2023-04-17 16:03:55,519 - update - model_api - INFO - setup_waterlevel_forcing.buffer: 2000
2023-04-17 16:03:55,519 - update - model_api - INFO - setup_waterlevel_forcing.merge: True
2023-04-17 16:03:55,535 - update - data_catalog - INFO - DataCatalog: Getting gtsmv3_eu_era5 GeoDataset netcdf data from /home/runner/.hydromt_data/artifact_data/v0.0.8/gtsmv3_eu_era5.nc
2023-04-17 16:03:55,567 - update - geodataset - INFO - GeoDataset: Read netcdf data and clip to geom (epsg:32633) [315583.508, 5039336.895, 331106.210, 5049946.562].
2023-04-17 16:03:55,846 - update - model_api - INFO - setup_discharge_forcing.geodataset: None
2023-04-17 16:03:55,850 - update - model_api - INFO - setup_discharge_forcing.timeseries: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_dis_timeseries.csv
2023-04-17 16:03:55,850 - update - model_api - INFO - setup_discharge_forcing.locations: /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_src_locations.geojson
2023-04-17 16:03:55,850 - update - model_api - INFO - setup_discharge_forcing.merge: True
2023-04-17 16:03:55,850 - update - data_catalog - INFO - DataCatalog: Getting compound_dis_timeseries DataFrame csv data from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_dis_timeseries.csv
2023-04-17 16:03:55,850 - update - dataframe - INFO - DataFrame: Read csv data.
2023-04-17 16:03:55,855 - update - data_catalog - INFO - DataCatalog: Getting compound_src_locations GeoDataFrame vector data from /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/data/compound_src_locations.geojson
2023-04-17 16:03:55,856 - update - geodataframe - INFO - GeoDataFrame: Read vector data and clip to geom (epsg:32633) [316221.151, 5041336.510, 329106.596, 5050441.766].
2023-04-17 16:03:55,867 - update - sfincs - INFO - Setting gdf_locs index to ID
2023-04-17 16:03:55,868 - update - sfincs - INFO - No matching index column found in gdf_locs; assuming the order is correct
2023-04-17 16:03:55,875 - update - sfincs - INFO - Writing model data to /home/runner/work/hydromt_sfincs/hydromt_sfincs/docs/_examples/tmp_sfincs_base
2023-04-17 16:03:55,878 - update - sfincs - INFO - Write raster file(s) for grid to 'gis' subfolder
2023-04-17 16:03:55,975 - update - sfincs - INFO - Write geom files
2023-04-17 16:03:55,978 - update - sfincs - INFO - Write vector file(s) for geoms to 'gis' subfolder
2023-04-17 16:03:55,995 - update - sfincs - INFO - Write forcing files
2023-04-17 16:03:56,005 - update - sfincs - INFO - Write vector file(s) for forcing.bzs to 'gis' subfolder
2023-04-17 16:03:56,039 - update - sfincs - INFO - Write vector file(s) for forcing.dis to 'gis' subfolder
2023-04-17 16:03:56,064 - update - sfincs - WARNING - zsini not in states, skipping
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()
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(bmap="sat", zoomlevel=12)
8. Check what additional files have been created:#
[15]:
dir_list = os.listdir(root)
print(dir_list)
['sfincs.dis', 'gis', 'sfincs.bnd', 'sfincs.dep', 'sfincs.inp', 'sfincs.obs', 'sfincs.ind', 'sfincs.src', 'sfincs.msk', 'hydromt.log', 'sfincs.bzs']
SFINCS native input files:
obsfile
: sfincs.obs (Read more)bndfile
: sfincs.bnd (Read more)bzsfile
: sfincs.bzs (Read more)srcfile
: sfincs.src (Read more)disfile
: sfincs.dis (Read more)
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