Migration Guide#

HydroMT v1 introduces a component-based architecture to replace the previous inheritance model. Instead of all model functionality being defined in a single Model class, a model is now composed of modular ModelComponent classes such as GridComponent or ConfigComponent. This structure makes models more flexible, extensible, and easier to maintain. For detailed guidance, refer to the official HydroMT migration guide.

The component-based architecture of HydroMT v1 allows for better separation of functionality. Where previously all functionality was described as part of the SfincsModel class (in sfincs.py), the new architecture allows to break this down into dedicated components that each handle a specific part of the model. For example, the configuration is now handled by a SfincsConfigComponent described in components/config.py. This resulted in a mayor code restructure of HydroMT-SFINCS, but the overall functionality and API remains very similar earlier versions. In these migration guidelines, we highlight the main changes and provide guidance on how to upgrade existing HydroMT-SFINCS workflows to be compatible with HydroMT v1.

Data Catalog Format Changes#

Information#

The data catalog structure has been refactored to introduce a more modular design and clearer separation of responsibilities across several new classes (DataSource, Driver, URIResolver, and DataAdapter).

Key format changes:

  • path renamed to uri

  • filesystem or driver_kwargs moved under driver

  • unit_add, unit_mult, rename, etc. moved under data_adapter

  • crs and nodata moved under metadata (renamed from meta)

  • A single catalog entry can now reference multiple data variants or versions

For detailed information about the format changes, see this section in the HydroMT migration guide: Changes to the data catalog yaml file format

How to upgrade#

All existing pre-defined catalogs have been updated to the new format. For your own catalogs, you can upgrade easily with the HydroMT check command:

hydromt check -d /path/to/data_catalog.yml --format v0 --upgrade -v

Note

When an exclamation mark (!) is put before a command line code, the command is to be executed in a Jupyter notebook cell.

Main Changes for Users#

In HydroMT-SFINCS v2, the internal data structure and API were redesigned to improve consistency and maintainability. Most changes affect how model components (such as grid and forcing) are accessed and how model data is read and written.

Component Changes#

In earlier versions of HydroMT-SFINCS, all model functionality was encapsulated within the SfincsModel class. The data to describe the model was stored in raw data structures such as xarray.Dataset, dict, or geopandas.GeoDataFrame, and could be accessed directly via attributes of the SfincsModel instance. These attributes were grouped into config, grid, geoms, forcing, and results. The new component-based architecture allows to further separate these model parts into dedicated classes that each handle a specific part of the model. The table below summarizes the mapping from old attributes to new component names and classes.

Old Attribute

New Component Name

New Class

config

config

SfincsConfig

grid

grid elevation mask infiltration roughness storage_volume initial_conditions subgrid

SfincsGrid SfincsElevation SfincsMask SfincsInfiltration SfincsRoughness SfincsStorageVolume SfincsInitialConditions SfincsSubgridTable

geoms

observation_points cross_sections thin_dams weirs wave_makers drainage_structures

SfincsObservationPoints SfincsCrossSections SfincsThinDams SfincsWeirs SfincsWaveMakers SfincsDrainageStructures

forcing

water_level discharge_points precipitation pressure wind rivers

SfincsWaterLevel SfincsDischargePoints SfincsPrecipitation SfincsPressure SfincsWind SfincsRivers

results

output

SfincsOutput

Method Changes#

The model components are now dedicated classes rather than raw data objects (e.g., xarray, dict, or geopandas). This means that the way to access and manipulate model data has changed. Each component can be accessed via the model instance and exposes its underlying methods (e.g., read(), write(), create() and set()). The actual data is now accessed via the .data property of each component. The table below summarizes the main method changes from HydroMT-SFINCS v1.x to v2.

v1.x

v2

model.<component>

model.<component>.data

model.write_<component>()

model.<component>.write()

model.read_<component>()

model.<component>.read()

model.set_<component>()

model.<component>.set()

Probably the most significant change is the way we “create” or “update” components. In HydroMT-SFINCS v1.x, this was done via “setuo” methods on the main model class, such as model.setup_grid() or model.setup_<component>(). In HydroMT-SFINCS v2, this is now done via the create() method on each component. For a complete conversion table of method changes, see below:

Conversion Table#

v1.x

v2.x

Argument Mapping

SfincsModel.setup_grid()

SfincsModel.grid.create()

unchanged

SfincsModel.setup_grid_ from_region()

SfincsModel.grid.create_ from_region()

unchanged

SfincsModel.setup_dep()

SfincsModel.elevation. create()

datasets_dep → elevation_list

SfincsModel.setup_mask_ active()

SfincsModel.mask.create_ active()

mask → removed, mask_buffer → removed, include_mask → include_polygon, extra_option1 → include_zmin, extra_option2 → include_zmax, exclude_mask → exclude_polygon, extra_option3 → exclude_zmin, extra_option4 → exclude_zmax

SfincsModel.setup_mask_ bounds()

SfincsModel.mask.create_ boundary()

include_mask → include_polygon, extra_option1 → include_zmin, extra_option2 → include_zmax, exclude_mask → exclude_polygon, extra_option3 → exclude_zmin, extra_option4 → exclude_zmax

SfincsModel.setup_subgrid()

SfincsModel.subgrid. create()

datasets_dep → elevation_list, datasets_rgh → roughness_list, datasets_riv → river_list, nr_levels → nlevels

SfincsModel.setup_river_ inflow()

SfincsModel.river.create_ inflow()

unchanged

SfincsModel.setup_river_ outflow()

TODO()

unchanged

SfincsModel.setup_ constant_infiltration()

SfincsModel.infiltration. create_constant()

unchanged

SfincsModel.setup_cn_ infiltration()

SfincsModel.infiltration. create_cn()

unchanged

SfincsModel.setup_cn_ infiltration_with_ks()

SfincsModel.infiltration. create_cn_with_recovery()

unchanged

SfincsModel.setup_manning _roughness()

SfincsModel.roughness. create()

datasets_rgh → roughness_list

SfincsModel.setup_ observation_points()

SfincsModel.observation_ points.create()

unchanged

SfincsModel.setup_ observation_lines()

SfincsModel.cross_ sections.create()

unchanged

SfincsModel.setup_ structures()

SfincsModel.weirs.create()

structures → locations, stype → removed

SfincsModel.setup_ structures()

SfincsModel.thin_dams. create()

structures → locations, stype → removed

SfincsModel.setup_ drainage_structures()

SfincsModel.drainage_ structures.create()

structures → locations

SfincsModel.setup_storage _volume()

SfincsModel.storage_ volume.create()

unchanged

SfincsModel.setup_ waterlevel_forcing()

SfincsModel.water_level. create()

unchanged

SfincsModel.setup_ waterlevel_bnd_from_mask()

SfincsModel.water_level. create_boundary_points_ from_mask()

distance → bnd_dist, new_option → min_dist

SficnsModel.setup_ discharge_forcing()

SfincsModel.discharge_ points.create()

unchanged

SfincsModel.setup_ discharge_forcing_from_ grid()

TODO()

unchanged

SfincsModel.setup_precip_ forcing_from_grid()

SfincsModel.precipitation .create()

unchanged

SfincsModel.setup_precip_ forcing()

SfincsModel.precipitation .create_uniform()

unchanged

SficsModel.setup_pressure _forcing_from_grid()

SfincsModel.pressure. create()

unchanged

SfincsModel.setup_wind_ forcing_from_grid()

SfincsModel.wind.create()

unchanged

SfincsModel.setup_wind_ forcing()

SfincsModel.wind.create_ uniform()

unchanged

SfincsModel.setup_config()

SfincsModel.config.update()

unchanged

SfincsModel.plot_basemap()

SfincsModel.plot_basemap()

unchanged

SfincsModel.plot_forcing()

SfincsModel.plot_forcing()

unchanged

Example: Accessing Component Data#

Each component provides structured access to its data via the .data property.

from hydromt_sfincs import SfincsModel

model = SfincsModel(root="path/to/model", mode="r")

# Access xarray.Dataset of the grid component
grid = model.grid.data

# Access geometries (GeoDataFrames), such as the observation points
observation_points = model.observation_points.data

# Access forcing data (xarray.Dataset), such as water level time series
water_level = model.water_level.data

Example: Writing Components#

Read and write operations are now handled at the component level.

# Write configuration file
model.config.write()

# Write updated grid to disk
model.grid.write()

These changes provide a clearer and more modular interface, making it easier to manipulate model components independently.

YAML Configuration Changes#

The HydroMT model configuration format has been overhauled and the ini format is not supported anymore. The root YAML file now includes three main keys: modeltype, global, and steps.

  • modeltype (optional): Defines which model plugin is being used (e.g. sfincs).

  • global: Defines model-wide configuration, including data catalog(s), name of the model configuration toml file etc.

  • steps: Replaces the old numbered dictionary format with a sequential list of function calls.

Some of the functions (component specific read and write) are now explicitly mapped to model or component methods using the <component>.<method> syntax.

For a complete example of the new configuration format, see the SFINCS v1 YAML template: sfincs_build.yml.

For more information on the format changes, see this section in the HydroMT migration guide: Changes to the yaml HydroMT configuration file format.