From 0aa44d4ec450c352694eda0dbb41b11c344c98fb Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 07:56:10 +0200 Subject: [PATCH 01/23] first steps to hydromt v1 --- hydromt_delft3dfm/data/parameters_data.yml | 91 +++--- hydromt_delft3dfm/dflowfm.py | 76 +++-- hydromt_delft3dfm/workflows/boundaries.py | 1 - hydromt_delft3dfm/workflows/branches.py | 4 +- hydromt_delft3dfm/workflows/dem.py | 11 +- hydromt_delft3dfm/workflows/manholes.py | 4 +- hydromt_delft3dfm/workflows/region.py | 4 +- pyproject.toml | 2 +- tests/data/dflowfm_build.yml | 4 +- tests/data/test_data.yaml | 317 ++++++++++++--------- tests/test_dflowfm.py | 6 +- tests/test_hydromt.py | 14 +- 12 files changed, 313 insertions(+), 221 deletions(-) diff --git a/hydromt_delft3dfm/data/parameters_data.yml b/hydromt_delft3dfm/data/parameters_data.yml index 2efdc823..c0eebc43 100644 --- a/hydromt_delft3dfm/data/parameters_data.yml +++ b/hydromt_delft3dfm/data/parameters_data.yml @@ -1,65 +1,78 @@ ---- rivers_defaults: data_type: DataFrame - driver: csv - path: branches/rivers_defaults.csv - meta: + uri: branches/rivers_defaults.csv + driver: + name: pandas + options: {} + metadata: notes: default river parameters. channels_defaults: data_type: DataFrame - driver: csv - path: branches/channels_defaults.csv - meta: + uri: branches/channels_defaults.csv + driver: + name: pandas + options: {} + metadata: notes: default channel parameters. pipes_defaults: data_type: DataFrame - driver: csv - path: branches/pipes_defaults.csv - meta: + uri: branches/pipes_defaults.csv + driver: + name: pandas + options: {} + metadata: notes: default pipe parameters. manholes_defaults: data_type: DataFrame - driver: csv - path: storages/manholes_defaults.csv - meta: + uri: storages/manholes_defaults.csv + driver: + name: pandas + options: {} + metadata: notes: default manhole parameters. 1D_bridges_defaults: data_type: DataFrame - driver: csv - path: structures/bridges_defaults.csv - meta: + uri: structures/bridges_defaults.csv + driver: + name: pandas + options: {} + metadata: notes: default bridge parameters. 1D_culverts_defaults: data_type: DataFrame - driver: csv - path: structures/culverts_defaults.csv - meta: + uri: structures/culverts_defaults.csv + driver: + name: pandas + options: {} + metadata: notes: default culvert parameters. vito_mapping: data_type: DataFrame - driver: csv - kwargs: - index_col: 0 - nodata: - landuse: 0 - roughness_manning: -999.0 - infiltcap: -999.0 - meta: + uri: landuse/vito_mapping.csv + driver: + name: pandas + options: + index_col: 0 + metadata: category: landuse - source_info: landuse parameters based on vito classification (https://land.copernicus.eu/global/products/lc) source_version: 1.0 - path: landuse/vito_mapping.csv + info: landuse parameters based on vito classification (https://land.copernicus.eu/global/products/lc) + nodata: + landuse: 0 + roughness_manning: -999.0 + infiltcap: -999.0 corine_mapping: data_type: DataFrame - driver: csv - kwargs: - index_col: 0 - nodata: - landuse: 0 - roughness_manning: -999.0 - infiltcap: -999.0 - meta: + uri: landuse/corine_mapping.csv + driver: + name: pandas + options: + index_col: 0 + metadata: category: landuse - source_info: landuse parameters based on corine classification (https://land.copernicus.eu/pan-european/corine-land-cover/clc2018) source_version: 1.0 - path: landuse/corine_mapping.csv + info: landuse parameters based on corine classification (https://land.copernicus.eu/pan-european/corine-land-cover/clc2018) + nodata: + landuse: 0 + roughness_manning: -999.0 + infiltcap: -999.0 diff --git a/hydromt_delft3dfm/dflowfm.py b/hydromt_delft3dfm/dflowfm.py index ae6a41b5..2ca7335e 100644 --- a/hydromt_delft3dfm/dflowfm.py +++ b/hydromt_delft3dfm/dflowfm.py @@ -16,8 +16,9 @@ import xugrid as xu from hydrolib.core.dflowfm import FMModel, IniFieldModel from hydrolib.core.dimr import DIMR, FMComponent, Start -from hydromt.models import MeshModel -from hydromt.workflows import create_mesh2d +from hydromt.model import Model +from hydromt.model.components import MeshComponent, GeomsComponent +from hydromt.model.processes.mesh import create_mesh2d_from_region from pyproj import CRS from shapely.geometry import box @@ -27,7 +28,7 @@ logger = logging.getLogger(__name__) -class DFlowFMModel(MeshModel): +class DFlowFMModel(Model): """API for Delft3D-FM models in HydroMT.""" _NAME = "dflowfm" @@ -110,6 +111,7 @@ class DFlowFMModel(MeshModel): _FOLDERS = ["dflowfm", "geoms", "maps"] _CLI_ARGS = {"region": "setup_region"} _CATALOGS = join(_DATADIR, "parameters_data.yml") + __hydromt_eps__ = [] def __init__( self, @@ -162,12 +164,17 @@ def __init__( if not isinstance(root, (str, Path)): raise ValueError("The 'root' parameter should be a of str or Path.") + components = {"mesh":{"type":"MeshComponent"}, + "geoms":{"type":"GeomsComponent"}, + } super().__init__( root=root, + components=components, mode=mode, - config_fn=config_fn, + # config_fn=config_fn, data_libs=data_libs, - logger=logger, + # logger=logger, + region_component="mesh", ) # model specific @@ -180,7 +187,7 @@ def __init__( ) # FIXME Xiaohan config needs to be derived from dimr_fn if dimr_fn exsit self.data_catalog.from_yml(self._CATALOGS) - self.config + # self.config # Global options for generation of the mesh1d network self._network_snap_offset = network_snap_offset @@ -2101,7 +2108,7 @@ def setup_mesh2d( """ # noqa: E501 # Create the 2dmesh - mesh2d = create_mesh2d( + mesh2d = create_mesh2d_from_region( region=region, res=res, crs=self.crs, @@ -3402,29 +3409,36 @@ def bounds(self) -> Tuple: """Return model mesh bounds.""" return self.region.total_bounds - @property - def region(self) -> gpd.GeoDataFrame: - """Return geometry of region of the model area of interest.""" - # First tries in geoms - if "region" in self.geoms: - region = self.geoms["region"] - # Else derives from mesh or branches - else: - if self.mesh is not None: - bounds = self.mesh.ugrid.total_bounds - crs = self.crs - elif not self.branches.empty: - bounds = self.branches.total_bounds - crs = self.branches.crs - else: - # Finally raise error assuming model is empty - raise ValueError( - "Could not derive region from geoms, or mesh. Model may be empty." - ) - region = gpd.GeoDataFrame(geometry=[box(*bounds)], crs=crs) - self.set_geoms(region, "region") - - return region + # @property + # def region(self) -> gpd.GeoDataFrame: + # """Return geometry of region of the model area of interest.""" + # # First tries in geoms + # # TODO: TypeError: argument of type 'GeomsComponent' is not iterable + # # self has geoms component if we add GeomsComponent do DflowFMModel + # # self.geoms has region attribute (not always), but it is sometimes None + # # if present and not None, it behaves different than legacy region + # # so it seems quite complex to update this part of the code + # # self.region does also exist, but `TypeError: argument of type 'GeomsComponent' is not iterable` + # # and `RecursionError: maximum recursion depth exceeded`, probably because we redefine region here + # if "region" in self.geoms: + # region = self.geoms["region"] + # # Else derives from mesh or branches + # else: + # if self.mesh is not None: + # bounds = self.mesh.ugrid.total_bounds + # crs = self.crs + # elif not self.branches.empty: + # bounds = self.branches.total_bounds + # crs = self.branches.crs + # else: + # # Finally raise error assuming model is empty + # raise ValueError( + # "Could not derive region from geoms, or mesh. Model may be empty." + # ) + # region = gpd.GeoDataFrame(geometry=[box(*bounds)], crs=crs) + # self.set_geoms(region, "region") + + # return region @property def dfmmodel(self): @@ -3736,7 +3750,7 @@ def _model_has_1d(self): def _check_crs(self): """Check if model crs is defined.""" if self.crs is None: - if self._read: + if self._read: # TODO: `KeyError: '_read'` self.logger.warning( "Could not derive CRS from reading the mesh file." "Please define the CRS in the [global] init attributes before" diff --git a/hydromt_delft3dfm/workflows/boundaries.py b/hydromt_delft3dfm/workflows/boundaries.py index dc5be3fb..f54dd45b 100644 --- a/hydromt_delft3dfm/workflows/boundaries.py +++ b/hydromt_delft3dfm/workflows/boundaries.py @@ -4,7 +4,6 @@ from pathlib import Path import geopandas as gpd -import hydromt.io import numpy as np import pandas as pd import xarray as xr diff --git a/hydromt_delft3dfm/workflows/branches.py b/hydromt_delft3dfm/workflows/branches.py index 65ec6310..9aa410b0 100644 --- a/hydromt_delft3dfm/workflows/branches.py +++ b/hydromt_delft3dfm/workflows/branches.py @@ -8,7 +8,7 @@ import pandas as pd import pyproj import shapely -from hydromt import gis_utils +from hydromt.gis._vector_utils import _nearest_merge from scipy.spatial import distance from shapely.geometry import LineString, MultiLineString, Point @@ -211,7 +211,7 @@ def _get_possible_unsnappednodes(newbranches): def _snap_unsnappednodes_to_nodes( unsnapped_nodes: gpd.GeoDataFrame, nodes: gpd.GeoDataFrame, snap_offset: float ) -> gpd.GeoDataFrame: - snapped_nodes = gis_utils.nearest_merge( + snapped_nodes = _nearest_merge( unsnapped_nodes, nodes, max_dist=snap_offset, overwrite=False ) snapped_nodes = snapped_nodes[snapped_nodes.index_right != -1] # drop not snapped diff --git a/hydromt_delft3dfm/workflows/dem.py b/hydromt_delft3dfm/workflows/dem.py index 4abafe91..0476593d 100644 --- a/hydromt_delft3dfm/workflows/dem.py +++ b/hydromt_delft3dfm/workflows/dem.py @@ -7,8 +7,9 @@ import numpy as np import pyflwdir import xarray as xr -from hydromt.gis_utils import nearest, nearest_merge, spread2d -from hydromt.workflows import rivers +from hydromt.gis._vector_utils import _nearest, _nearest_merge +from hydromt.gis._raster_utils import _spread2d +from hydromt.model.processes import rivers from scipy import ndimage from shapely.geometry import Point @@ -123,7 +124,7 @@ def get_rivbank_dz( ) da_mask.raster.set_crs(da_hnd.raster.crs) # find nearest stream segment for all river bank cells - segid_spread = spread2d(da_obs=segid, da_mask=da_mask) + segid_spread = _spread2d(da_obs=segid, da_mask=da_mask) # get edge of riv mask -> riv banks da_bnk_mask = np.logical_and(da_hnd > 0, np.logical_xor(da_mask, _mask)) da_riv_mask = np.logical_and( @@ -249,7 +250,7 @@ def get_river_bathymetry( # merge gdf_riv with gdf_stream if gdf_riv is not None: cols = [c for c in ["rivwth", "qbankfull"] if c in gdf_riv] - gdf_riv = nearest_merge(gdf_stream, gdf_riv, columns=cols, max_dist=max_dist) + gdf_riv = _nearest_merge(gdf_stream, gdf_riv, columns=cols, max_dist=max_dist) gdf_riv["rivlen"] = gdf_riv["rivdst"] - flw.downstream(gdf_riv["rivdst"]) else: gdf_riv = gdf_stream @@ -257,7 +258,7 @@ def get_river_bathymetry( if gdf_qbf is not None and "qbankfull" in gdf_qbf.columns: if "qbankfull" in gdf_riv: gdf_riv = gdf_riv.drop(colums="qbankfull") - idx_nn, dists = nearest(gdf_qbf, gdf_riv) + idx_nn, dists = _nearest(gdf_qbf, gdf_riv) valid = dists < max_dist gdf_riv.loc[idx_nn[valid], "qbankfull"] = gdf_qbf["qbankfull"].values[valid] logger.info(f"{sum(valid)}/{len(idx_nn)} qbankfull boundary points set.") diff --git a/hydromt_delft3dfm/workflows/manholes.py b/hydromt_delft3dfm/workflows/manholes.py index d96e8fc3..6fcb1e73 100644 --- a/hydromt_delft3dfm/workflows/manholes.py +++ b/hydromt_delft3dfm/workflows/manholes.py @@ -4,7 +4,7 @@ import geopandas as gpd import pandas as pd -from hydromt import gis_utils +from hydromt.gis._vector_utils import _nearest_merge from shapely.geometry import Point logger = logging.getLogger(__name__) @@ -141,7 +141,7 @@ def generate_manholes_on_branches( ) if len(_nodes_channels) > 0: nodes_channels = gpd.GeoDataFrame(_nodes_channels, crs=branches.crs) - nodes_to_remove = gis_utils.nearest_merge( + nodes_to_remove = _nearest_merge( nodes_pipes, nodes_channels, max_dist=0.001, overwrite=True ) nodes_pipes = nodes_pipes.loc[nodes_to_remove.index_right == -1] diff --git a/hydromt_delft3dfm/workflows/region.py b/hydromt_delft3dfm/workflows/region.py index 0d843c92..b4aa768d 100644 --- a/hydromt_delft3dfm/workflows/region.py +++ b/hydromt_delft3dfm/workflows/region.py @@ -3,7 +3,7 @@ import logging import geopandas as gpd -from hydromt.workflows import parse_region +from hydromt.model.processes.region import parse_region_geom from pyproj.crs import CRS from shapely.geometry import box @@ -20,7 +20,7 @@ def parse_region_geometry( logger: logging.Logger = logger, ): """Parse hydromt stype region argument into region geometry.""" - kind, region = parse_region(region, logger=logger) + kind, region = parse_region_geom(region, logger=logger) if kind == "bbox": bbox = region["bbox"] geom = gpd.GeoDataFrame(geometry=[box(*bbox)], crs=4326) diff --git a/pyproject.toml b/pyproject.toml index 5903eb67..987c0a93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ authors = [ { name = "Jelmer Veenstra", email = "jelmer.veenstra@deltares.nl" }, ] dependencies = [ - "hydromt>=0.10.0, <1", # TODO: move to hydromt>=1: https://github.com/Deltares/hydromt_delft3dfm/issues/137 + "hydromt>=1.0.0", "geopandas>=0.10, <1", # TODO: remove upper bound: https://github.com/Deltares/hydromt_delft3dfm/issues/135 "numpy", "pandas>=2.0.0", diff --git a/tests/data/dflowfm_build.yml b/tests/data/dflowfm_build.yml index 36190b64..8e1ccd9f 100644 --- a/tests/data/dflowfm_build.yml +++ b/tests/data/dflowfm_build.yml @@ -2,7 +2,7 @@ setup_rivers_from_dem: region: bbox: [12.4331, 46.4661, 12.5212, 46.5369] hydrography_fn: merit_hydro - river_geom_fn: hydro_rivers_lin + river_geom_fn: rivers_lin2019_v1 rivdph_method: gvf rivwth_method: geom river_upa: 25.0 @@ -48,7 +48,7 @@ setup_maps_from_rasterdataset: split_dataset: True setup_maps_from_raster_reclass: - raster_fn: vito_2015 + raster_fn: vito reclass_table_fn: vito_mapping reclass_variables: ['roughness_manning', 'infiltcap'] interpolation_method: triangulation diff --git a/tests/data/test_data.yaml b/tests/data/test_data.yaml index 81aba620..7a83a6a6 100644 --- a/tests/data/test_data.yaml +++ b/tests/data/test_data.yaml @@ -1,172 +1,235 @@ 1D_branches: data_type: GeoDataFrame - driver: vector - path: local_data/1D_rivers.geojson - crs: 32647 - rename: - BRANCH_ID: branchid - BR_TYPE: branchtype + uri: local_data/1D_rivers.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + BRANCH_ID: branchid + BR_TYPE: branchtype 1D_rivers_xyzcrosssections: data_type: GeoDataFrame - driver: vector - path: local_data/1D_rivers_xyzcrosssections.geojson - crs: 32647 - rename: - ORDER: order - CRS_ID: crsid - Z: z + uri: local_data/1D_rivers_xyzcrosssections.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + ORDER: order + CRS_ID: crsid + Z: z 1D_rivers_pointcrosssections: data_type: GeoDataFrame - driver: vector - path: local_data/1D_rivers_pointcrosssections.geojson - crs: 32647 - rename: - id: crsid - TYPE: shape - WIDTH: width - HEIGHT: height - BEDLEVEL: shift + uri: local_data/1D_rivers_pointcrosssections.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + id: crsid + TYPE: shape + WIDTH: width + HEIGHT: height + BEDLEVEL: shift 1d_manholes: data_type: GeoDataFrame - driver: vector - path: local_data/manholes.geojson - crs: 32647 - rename: - ID: manholeid - AREA: area - STR_AREA: streetArea + uri: local_data/manholes.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + ID: manholeid + AREA: area + STR_AREA: streetArea 1d_bridges: data_type: GeoDataFrame - driver: vector - path: local_data/bridges.geojson - crs: 32647 - rename: - STRUC_ID: structure_id - STRUC_TYPE: structure_type - SHAPE: shape - WIDTH: width - HEIGHT: height - CLOSED: closed - BEDLEV: shift - LENGTH: length - FLOW_DIR: allowedflowdir - IN_LOSS: inletlosscoeff - OUT_LOSS: outletlosscoeff + uri: local_data/bridges.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + STRUC_ID: structure_id + STRUC_TYPE: structure_type + SHAPE: shape + WIDTH: width + HEIGHT: height + CLOSED: closed + BEDLEV: shift + LENGTH: length + FLOW_DIR: allowedflowdir + IN_LOSS: inletlosscoeff + OUT_LOSS: outletlosscoeff 1d_culverts: data_type: GeoDataFrame - driver: vector - path: local_data/culverts.geojson - crs: 32647 - rename: - STRUC_ID: structure_id - STRUC_TYPE: structure_type - SHAPE: shape - WIDTH: width - HEIGHT: height - CLOSED: closed - INVLEV_UP: leftlevel - INVLEV_DN: rightlevel - FLOW_DIR: allowedflowdir + uri: local_data/culverts.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + STRUC_ID: structure_id + STRUC_TYPE: structure_type + SHAPE: shape + WIDTH: width + HEIGHT: height + CLOSED: closed + INVLEV_UP: leftlevel + INVLEV_DN: rightlevel + FLOW_DIR: allowedflowdir 1D_boundaries: data_type: GeoDataFrame - driver: vector - path: local_data/boundaries.geojson - crs: 32647 + uri: local_data/boundaries.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 1D_boundaries_timeseries: - path: local_data/boundaries.geojson data_type: GeoDataset - driver: vector - crs: 32647 - kwargs: - fn_data: local_data/boundaries_series.csv + uri: local_data/boundaries.geojson + driver: + name: geodataset_vector + options: + fn_data: local_data/boundaries_series.csv + metadata: + crs: 32647 1D_laterals_points: data_type: GeoDataFrame - driver: vector - path: local_data/laterals_points.geojson - crs: 32647 + uri: local_data/laterals_points.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 1D_laterals_timeseries: - path: local_data/laterals_points.geojson data_type: GeoDataset - driver: vector - crs: 32647 - rename: - 1D_laterals_timeseries: lateral_discharge - kwargs: - fn_data: local_data/laterals_series.csv + uri: local_data/laterals_points.geojson + driver: + name: geodataset_vector + options: + fn_data: local_data/laterals_series.csv + metadata: + crs: 32647 + data_adapter: + rename: + 1D_laterals_timeseries: lateral_discharge 1D_laterals_polygons: data_type: GeoDataFrame - driver: vector - path: local_data/laterals_polygons.geojson - crs: 32647 + uri: local_data/laterals_polygons.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 1D_laterals_polygons_timeseries: - path: local_data/laterals_polygons.geojson data_type: GeoDataset - driver: vector - crs: 32647 - rename: - 1D_laterals_polygons_timeseries: lateral_discharge - kwargs: - fn_data: local_data/laterals_series.csv - assert_gtype: Polygon + uri: local_data/laterals_polygons.geojson + driver: + name: geodataset_vector + options: + fn_data: local_data/laterals_series.csv + assert_gtype: Polygon + metadata: + crs: 32647 + data_adapter: + rename: + 1D_laterals_polygons_timeseries: lateral_discharge roads: - path: local_data/roads.tiff data_type: RasterDataset - crs: 32647 - rename: - roads: steps + uri: local_data/roads.tiff + driver: + name: rasterio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + roads: steps 2D_boundary: data_type: GeoDataFrame - driver: vector - path: local_data/2d_boundary.geojson - crs: 32647 - meta: - notes: created by buffer the extent by aqrt(2) * res. Must contain boundary_id if timeseries is specified + uri: local_data/2d_boundary.geojson + driver: + name: pyogrio + options: {} + metadata: + notes: created by buffer the extent by aqrt(2) * res. Must contain boundary_id + if timeseries is specified + crs: 32647 2D_boundary_timeseries: data_type: DataFrame - driver: csv - path: local_data/2dboundaries_series.csv - kwargs: + uri: local_data/2dboundaries_series.csv + driver: + name: pandas + options: index_col: time parse_dates: true dayfirst: true - meta: - notes: time series data for the 2D boundary, must contain time as index and boundary_id as columns + metadata: + notes: time series data for the 2D boundary, must contain time as index and boundary_id + as columns meteo_timeseries_T2: - path: local_data/rainfall_series.csv data_type: DataFrame - driver: csv - rename: - T2_mm/day: precip - kwargs: - index_col: 0 - parse_dates: True - meta: + uri: local_data/rainfall_series.csv + driver: + name: pandas + options: + index_col: 0 + parse_dates: true + metadata: unit: mm day-1 + data_adapter: + rename: + T2_mm/day: precip meteo_timeseries_T5: - path: local_data/rainfall_series.csv data_type: DataFrame - driver: csv - rename: - T5_mm/day: precip - kwargs: - index_col: 0 - parse_dates: True - meta: + uri: local_data/rainfall_series.csv + driver: + name: pandas + options: + index_col: 0 + parse_dates: true + metadata: unit: mm day-1 + data_adapter: + rename: + T5_mm/day: precip dem: - path: local_data/dem.tif data_type: RasterDataset - crs: 4326 - rename: - dem: elevtn - meta: + uri: local_data/dem.tif + driver: + name: rasterio + options: {} + metadata: category: dem history: temporary dem within model extent + crs: 4326 + data_adapter: + rename: + dem: elevtn roughness_manning: - path: local_data/frictioncoefficient.tif data_type: RasterDataset - crs: 32647 - rename: - frictioncoefficient: roughness_manning - meta: - category: roughness_manning \ No newline at end of file + uri: local_data/frictioncoefficient.tif + driver: + name: rasterio + options: {} + metadata: + category: roughness_manning + crs: 32647 + data_adapter: + rename: + frictioncoefficient: roughness_manning diff --git a/tests/test_dflowfm.py b/tests/test_dflowfm.py index 2f8d168e..d9551536 100644 --- a/tests/test_dflowfm.py +++ b/tests/test_dflowfm.py @@ -49,8 +49,7 @@ def test_setup_mesh2d_refine(tmpdir): mesh1d = model.get_mesh('mesh1d') assert mesh1d.edge_coordinates.shape == (1732, 2) - -def test_setup_channels(tmpdir): +def test_setup_channels():#tmpdir): # Instantiate a dummy model model = DFlowFMModel( root=join(EXAMPLEDIR, "dflowfm_local"), @@ -58,7 +57,7 @@ def test_setup_channels(tmpdir): data_libs=[join(TESTDATADIR, "test_data.yaml")] ) model.read() - model.set_root(tmpdir, mode="w") + # model.set_root(tmpdir, mode="w") # setup_channels region = {'geom': join(TESTDATADIR, "local_data","1D_extent.geojson")} @@ -69,6 +68,7 @@ def test_setup_channels(tmpdir): crosssections_fn=crosssections_fn, crosssections_type='point' ) +# test_setup_channels() def test_write_structures(tmpdir): diff --git a/tests/test_hydromt.py b/tests/test_hydromt.py index 27f3dd60..64776c44 100644 --- a/tests/test_hydromt.py +++ b/tests/test_hydromt.py @@ -4,8 +4,8 @@ from os.path import abspath, dirname, join import pytest -from hydromt.cli.cli_utils import parse_config -from hydromt.log import setuplog +from hydromt.cli._utils import parse_config +# from hydromt._utils.log import setuplog from hydromt_delft3dfm import DFlowFMModel @@ -17,7 +17,7 @@ "example": "dflowfm_piave", "ini": "dflowfm_build.yml", "model": DFlowFMModel, - "data": "artifact_data", + "data": "artifact_data=v0.0.6", "snap_offset": 25, "crs": 3857, # global section needs to be passed to build as arguments }, @@ -51,7 +51,9 @@ def test_model_build(tmpdir, model): # test build method # compare results with model from examples folder root = str(tmpdir.join(model)) - logger = setuplog(__name__, join(root, "hydromt.log"), log_level=10) + # TODO: passing the logger does not seem to be necessary anymore according to + # https://github.com/Deltares/hydromt/blob/main/docs/guides/plugin_dev/migrating_to_v1.rst#logging + # logger = setuplog(__name__, join(root, "hydromt.log"), log_level=10) mod1 = _model["model"]( root=root, mode="w", @@ -59,7 +61,7 @@ def test_model_build(tmpdir, model): network_snap_offset=_model["snap_offset"], crs=_model["crs"], openwater_computation_node_distance=40, - logger=logger, + # logger=logger, ) # Build method options config = join(TESTDATADIR, _model["ini"]) @@ -72,7 +74,7 @@ def test_model_build(tmpdir, model): # Compare with model from examples folder # (need to read it again for proper geoms check) - mod1 = _model["model"](root=root, mode="r", logger=logger) + mod1 = _model["model"](root=root, mode="r") #, logger=logger) mod1.read() root = join(EXAMPLEDIR, _model["example"]) mod0 = _model["model"](root=root, mode="r") From 9dbe60606dd1b75dd923297ac3eb68c0df5af223 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 08:01:45 +0200 Subject: [PATCH 02/23] minimized diff --- tests/test_hydromt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_hydromt.py b/tests/test_hydromt.py index 64776c44..65f1897b 100644 --- a/tests/test_hydromt.py +++ b/tests/test_hydromt.py @@ -17,7 +17,7 @@ "example": "dflowfm_piave", "ini": "dflowfm_build.yml", "model": DFlowFMModel, - "data": "artifact_data=v0.0.6", + "data": "artifact_data", "snap_offset": 25, "crs": 3857, # global section needs to be passed to build as arguments }, From c8ca8463656730f35a6a03ccd22a8e44761e2b37 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 08:03:05 +0200 Subject: [PATCH 03/23] minimized diff --- tests/data/dflowfm_build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/data/dflowfm_build.yml b/tests/data/dflowfm_build.yml index 8e1ccd9f..36190b64 100644 --- a/tests/data/dflowfm_build.yml +++ b/tests/data/dflowfm_build.yml @@ -2,7 +2,7 @@ setup_rivers_from_dem: region: bbox: [12.4331, 46.4661, 12.5212, 46.5369] hydrography_fn: merit_hydro - river_geom_fn: rivers_lin2019_v1 + river_geom_fn: hydro_rivers_lin rivdph_method: gvf rivwth_method: geom river_upa: 25.0 @@ -48,7 +48,7 @@ setup_maps_from_rasterdataset: split_dataset: True setup_maps_from_raster_reclass: - raster_fn: vito + raster_fn: vito_2015 reclass_table_fn: vito_mapping reclass_variables: ['roughness_manning', 'infiltcap'] interpolation_method: triangulation From 2dbe4cef7ed52def6937a78fcfc18711401fca43 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 08:05:32 +0200 Subject: [PATCH 04/23] minimized diff --- tests/test_dflowfm.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_dflowfm.py b/tests/test_dflowfm.py index d9551536..a1fd14d1 100644 --- a/tests/test_dflowfm.py +++ b/tests/test_dflowfm.py @@ -49,6 +49,7 @@ def test_setup_mesh2d_refine(tmpdir): mesh1d = model.get_mesh('mesh1d') assert mesh1d.edge_coordinates.shape == (1732, 2) + def test_setup_channels():#tmpdir): # Instantiate a dummy model model = DFlowFMModel( From b42d53193d01729eab5c55ded88c0a8dad090eff Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 09:03:22 +0200 Subject: [PATCH 05/23] commented logger --- tests/test_hydromt.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_hydromt.py b/tests/test_hydromt.py index 8005197d..72c5a9b5 100644 --- a/tests/test_hydromt.py +++ b/tests/test_hydromt.py @@ -93,7 +93,7 @@ def test_model_build_local_code(tmp_path): This test can be removed once the entire hydromt_delft3dfm is properly covered by unittests. """ - logger = setuplog(__name__, join(tmp_path, "hydromt.log"), log_level=10) + # logger = setuplog(__name__, join(tmp_path, "hydromt.log"), log_level=10) _model = _models["local"] model = DFlowFMModel( root=tmp_path, @@ -102,7 +102,7 @@ def test_model_build_local_code(tmp_path): network_snap_offset=_model["snap_offset"], crs=_model["crs"], openwater_computation_node_distance=40, - logger=logger + # logger=logger ) config = join(TESTDATADIR, _model["ini"]) @@ -128,7 +128,7 @@ def test_model_build_piave_code(tmp_path): This test can be removed once the entire hydromt_delft3dfm is properly covered by unittests. """ - logger = setuplog(__name__, join(tmp_path, "hydromt.log"), log_level=10) + # logger = setuplog(__name__, join(tmp_path, "hydromt.log"), log_level=10) _model = _models["piave"] model = DFlowFMModel( root=tmp_path, @@ -137,7 +137,7 @@ def test_model_build_piave_code(tmp_path): network_snap_offset=_model["snap_offset"], crs=_model["crs"], openwater_computation_node_distance=40, - logger=logger + # logger=logger ) config = join(TESTDATADIR, _model["ini"]) From 86bc4a71214880fc669da36c4192d2dd69e74cff Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 09:08:43 +0200 Subject: [PATCH 06/23] linting --- hydromt_delft3dfm/dflowfm.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hydromt_delft3dfm/dflowfm.py b/hydromt_delft3dfm/dflowfm.py index ee6aa641..bd1711cd 100644 --- a/hydromt_delft3dfm/dflowfm.py +++ b/hydromt_delft3dfm/dflowfm.py @@ -17,10 +17,8 @@ from hydrolib.core.dflowfm import FMModel, IniFieldModel from hydrolib.core.dimr import DIMR, FMComponent, Start from hydromt.model import Model -from hydromt.model.components import MeshComponent, GeomsComponent from hydromt.model.processes.mesh import create_mesh2d_from_region from pyproj import CRS -from shapely.geometry import box from . import DATADIR, gis_utils, mesh_utils, utils, workflows @@ -164,9 +162,10 @@ def __init__( if not isinstance(root, (str, Path)): raise ValueError("The 'root' parameter should be a of str or Path.") - components = {"mesh":{"type":"MeshComponent"}, - "geoms":{"type":"GeomsComponent"}, - } + components = { + "mesh": {"type": "MeshComponent"}, + "geoms": {"type": "GeomsComponent"}, + } super().__init__( root=root, components=components, @@ -3421,8 +3420,9 @@ def bounds(self) -> Tuple: # # self.geoms has region attribute (not always), but it is sometimes None # # if present and not None, it behaves different than legacy region # # so it seems quite complex to update this part of the code - # # self.region does also exist, but `TypeError: argument of type 'GeomsComponent' is not iterable` - # # and `RecursionError: maximum recursion depth exceeded`, probably because we redefine region here + # # self.region does also exist, but `TypeError: argument of + # # type 'GeomsComponent' is not iterable` and `RecursionError: maximum + # # recursion depth exceeded`, probably because we redefine region here # if "region" in self.geoms: # region = self.geoms["region"] # # Else derives from mesh or branches @@ -3753,7 +3753,7 @@ def _model_has_1d(self): def _check_crs(self): """Check if model crs is defined.""" if self.crs is None: - if self._read: # TODO: `KeyError: '_read'` + if self._read: # TODO: `KeyError: '_read'` self.logger.warning( "Could not derive CRS from reading the mesh file." "Please define the CRS in the [global] init attributes before" From 85578612c9beb4582b742861831d91bf78608c3b Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 09:12:41 +0200 Subject: [PATCH 07/23] linting --- hydromt_delft3dfm/workflows/dem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hydromt_delft3dfm/workflows/dem.py b/hydromt_delft3dfm/workflows/dem.py index 0476593d..9a0b33d1 100644 --- a/hydromt_delft3dfm/workflows/dem.py +++ b/hydromt_delft3dfm/workflows/dem.py @@ -7,8 +7,8 @@ import numpy as np import pyflwdir import xarray as xr -from hydromt.gis._vector_utils import _nearest, _nearest_merge from hydromt.gis._raster_utils import _spread2d +from hydromt.gis._vector_utils import _nearest, _nearest_merge from hydromt.model.processes import rivers from scipy import ndimage from shapely.geometry import Point From 1a704b5acd85784cc1351c6465f7ac293de5ed50 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 09:15:45 +0200 Subject: [PATCH 08/23] linting --- hydromt_delft3dfm/data/parameters_data.yml | 1 + hydromt_delft3dfm/workflows/boundaries.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hydromt_delft3dfm/data/parameters_data.yml b/hydromt_delft3dfm/data/parameters_data.yml index c0eebc43..9e1bfc59 100644 --- a/hydromt_delft3dfm/data/parameters_data.yml +++ b/hydromt_delft3dfm/data/parameters_data.yml @@ -1,3 +1,4 @@ +--- rivers_defaults: data_type: DataFrame uri: branches/rivers_defaults.csv diff --git a/hydromt_delft3dfm/workflows/boundaries.py b/hydromt_delft3dfm/workflows/boundaries.py index f54dd45b..792a6b06 100644 --- a/hydromt_delft3dfm/workflows/boundaries.py +++ b/hydromt_delft3dfm/workflows/boundaries.py @@ -7,6 +7,7 @@ import numpy as np import pandas as pd import xarray as xr +from hydromt.gis._vector_utils import _nearest_merge from hydromt_delft3dfm import graph_utils @@ -51,7 +52,7 @@ def get_boundaries_with_nodeid( # generate all possible and allowed boundary locations _boundaries = graph_utils.get_endnodes_from_lines(branches, where="both") - boundaries = hydromt.gis_utils.nearest_merge( + boundaries = _nearest_merge( _boundaries, network1d_nodes, max_dist=0.1, overwrite=False ) return boundaries @@ -207,7 +208,7 @@ def compute_boundary_values( gdf_bnd = da_bnd.vector.to_gdf() gdf_bnd.crs = boundaries.crs # TODO remove after hydromt release>0.9.0 - gdf_bnd = hydromt.gis_utils.nearest_merge( + gdf_bnd = _nearest_merge( gdf_bnd, boundaries, max_dist=snap_offset, From c467dc6c407215d452ffa8f037e724517ce20e2f Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 11:00:10 +0200 Subject: [PATCH 09/23] read instead of _read --- envs/hydromt-delft3dfm-min.yml | 2 +- envs/hydromt-delft3dfm.yml | 2 +- hydromt_delft3dfm/dflowfm.py | 9 ++++----- pyproject.toml | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/envs/hydromt-delft3dfm-min.yml b/envs/hydromt-delft3dfm-min.yml index 61619095..c2cf0090 100644 --- a/envs/hydromt-delft3dfm-min.yml +++ b/envs/hydromt-delft3dfm-min.yml @@ -8,7 +8,7 @@ channels: dependencies: - flit>=3.4 - geopandas<1 - - hydromt>=0.10.0,<1.0.0a0 + - hydromt>=1.0.0 - numpy - pandas>=2.0.0 - pip diff --git a/envs/hydromt-delft3dfm.yml b/envs/hydromt-delft3dfm.yml index bc6cf2db..a6e8c82e 100644 --- a/envs/hydromt-delft3dfm.yml +++ b/envs/hydromt-delft3dfm.yml @@ -12,7 +12,7 @@ dependencies: - geopandas<1 - jupyter # to run examples - matplotlib # to run examples - - hydromt>=0.10.0,<1.0.0a0 # To avoid getting v1 alpha + - hydromt>=1.0.0 - nbsphinx # docs notebook examples - numpy - pandas>=2.0.0 diff --git a/hydromt_delft3dfm/dflowfm.py b/hydromt_delft3dfm/dflowfm.py index bd1711cd..77f8cb8f 100644 --- a/hydromt_delft3dfm/dflowfm.py +++ b/hydromt_delft3dfm/dflowfm.py @@ -1,7 +1,6 @@ """Implement Delft3D-FM hydromt plugin model class.""" import itertools -import logging import os from datetime import datetime, timedelta from os.path import basename, dirname, isfile, join @@ -23,7 +22,7 @@ from . import DATADIR, gis_utils, mesh_utils, utils, workflows __all__ = ["DFlowFMModel"] -logger = logging.getLogger(__name__) +# logger = logging.getLogger(__name__) class DFlowFMModel(Model): @@ -122,7 +121,7 @@ def __init__( network_snap_offset=25, snap_newbranches_to_branches_at_snapnodes=True, openwater_computation_node_distance=40, - logger=logger, + # logger=logger, ): """Initialize the DFlowFMModel. @@ -2161,7 +2160,7 @@ def setup_mesh2d_refine( """ if "mesh2d" not in self.mesh_names: - logger.error( + self.logger.error( "2d mesh is not available, use setup_mesh2d before refinement." ) return @@ -3753,7 +3752,7 @@ def _model_has_1d(self): def _check_crs(self): """Check if model crs is defined.""" if self.crs is None: - if self._read: # TODO: `KeyError: '_read'` + if self.read: self.logger.warning( "Could not derive CRS from reading the mesh file." "Please define the CRS in the [global] init attributes before" diff --git a/pyproject.toml b/pyproject.toml index 8a2bddbb..987c0a93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ authors = [ ] dependencies = [ "hydromt>=1.0.0", - "geopandas>=0.10, !=1.0.0", # gpd 1.0.0 has sjoin bug: https://github.com/geopandas/geopandas/issues/352 + "geopandas>=0.10, <1", # TODO: remove upper bound: https://github.com/Deltares/hydromt_delft3dfm/issues/135 "numpy", "pandas>=2.0.0", "xarray", From dbecb61cd4a22d1ce002dca96cc144564b283d07 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Mon, 30 Sep 2024 11:02:45 +0200 Subject: [PATCH 10/23] minimized diff --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 987c0a93..8a2bddbb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ authors = [ ] dependencies = [ "hydromt>=1.0.0", - "geopandas>=0.10, <1", # TODO: remove upper bound: https://github.com/Deltares/hydromt_delft3dfm/issues/135 + "geopandas>=0.10, !=1.0.0", # gpd 1.0.0 has sjoin bug: https://github.com/geopandas/geopandas/issues/352 "numpy", "pandas>=2.0.0", "xarray", From 8fafec584b74bca8d9686bf7c0b4804cbb19ef79 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Fri, 18 Oct 2024 14:02:10 +0200 Subject: [PATCH 11/23] minimized diff --- envs/hydromt-delft3dfm-min.yml | 2 +- envs/hydromt-delft3dfm.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/envs/hydromt-delft3dfm-min.yml b/envs/hydromt-delft3dfm-min.yml index c2cf0090..61619095 100644 --- a/envs/hydromt-delft3dfm-min.yml +++ b/envs/hydromt-delft3dfm-min.yml @@ -8,7 +8,7 @@ channels: dependencies: - flit>=3.4 - geopandas<1 - - hydromt>=1.0.0 + - hydromt>=0.10.0,<1.0.0a0 - numpy - pandas>=2.0.0 - pip diff --git a/envs/hydromt-delft3dfm.yml b/envs/hydromt-delft3dfm.yml index a6e8c82e..bc6cf2db 100644 --- a/envs/hydromt-delft3dfm.yml +++ b/envs/hydromt-delft3dfm.yml @@ -12,7 +12,7 @@ dependencies: - geopandas<1 - jupyter # to run examples - matplotlib # to run examples - - hydromt>=1.0.0 + - hydromt>=0.10.0,<1.0.0a0 # To avoid getting v1 alpha - nbsphinx # docs notebook examples - numpy - pandas>=2.0.0 From 06dd9669438c7dc0a7d5e210794fd8af0fc3f009 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Fri, 18 Oct 2024 14:02:57 +0200 Subject: [PATCH 12/23] minimized diff --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c2bd9b2a..3e21387b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ authors = [ { name = "Sebastian Hartgring", email = "sebastian.hartgring@deltares.nl" }, ] dependencies = [ - "hydromt>=1.0.0", + "hydromt>=0.10.0, <1", # TODO: move to hydromt>=1: https://github.com/Deltares/hydromt_delft3dfm/issues/137 "geopandas>=0.10, !=1.0.0", # gpd 1.0.0 has sjoin bug: https://github.com/geopandas/geopandas/issues/352 "numpy", "pandas>=2.0.0", From 675ebe8d0345d144181e53996d5d4b61714e9f7d Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Fri, 18 Oct 2024 14:03:48 +0200 Subject: [PATCH 13/23] minimized diff --- pyproject.toml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3e21387b..9672a9c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,19 +13,19 @@ authors = [ ] dependencies = [ "hydromt>=0.10.0, <1", # TODO: move to hydromt>=1: https://github.com/Deltares/hydromt_delft3dfm/issues/137 - "geopandas>=0.10, !=1.0.0", # gpd 1.0.0 has sjoin bug: https://github.com/geopandas/geopandas/issues/352 - "numpy", - "pandas>=2.0.0", - "xarray", - "hydrolib-core>=0.8.0", - "xugrid>=0.9.0", - "meshkernel>=4.3.0", - "pyproj", - "shapely>=2.0.0", - "scipy", - "universal_pathlib>=0.2", # provides path compatibility between different filesystems - "pyflwdir>=0.5.4", - "networkx", + "geopandas>=0.10, !=1.0.0", # gpd 1.0.0 has sjoin bug: https://github.com/geopandas/geopandas/issues/352 + "numpy", + "pandas>=2.0.0", + "xarray", + "hydrolib-core>=0.8.0", + "xugrid>=0.9.0", + "meshkernel>=4.3.0", + "pyproj", + "shapely>=2.0.0", + "scipy", + "universal_pathlib>=0.2", # provides path compatibility between different filesystems + "pyflwdir>=0.5.4", + "networkx", ] requires-python = ">=3.9" readme = "README.rst" From 189b180f5c64e94693a7e0111edab4271e0f57ed Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Fri, 18 Oct 2024 14:04:27 +0200 Subject: [PATCH 14/23] minimized diff --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9672a9c2..a1b6a258 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,6 @@ dependencies = [ "pyproj", "shapely>=2.0.0", "scipy", - "universal_pathlib>=0.2", # provides path compatibility between different filesystems "pyflwdir>=0.5.4", "networkx", ] From 1b1c438439d16a045f82d949e97f9636c119f8c5 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Fri, 18 Oct 2024 14:05:28 +0200 Subject: [PATCH 15/23] re-updated hydromt dependency version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7013cc52..d256d209 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ authors = [ { name = "Sebastian Hartgring", email = "sebastian.hartgring@deltares.nl" }, ] dependencies = [ - "hydromt>=0.10.0, <1", # TODO: move to hydromt>=1: https://github.com/Deltares/hydromt_delft3dfm/issues/137 + "hydromt>=1.0.0", "geopandas>=0.10, !=1.0.0", # gpd 1.0.0 has sjoin bug: https://github.com/geopandas/geopandas/issues/352 "numpy", "pandas>=2.0.0", From fa65bb59e119ad660f103b31f52b5bec4a03da14 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Wed, 23 Oct 2024 14:46:16 +0200 Subject: [PATCH 16/23] replaced logger by hydromt --- hydromt_delft3dfm/dflowfm.py | 200 ++++++++++------------ hydromt_delft3dfm/workflows/boundaries.py | 18 -- hydromt_delft3dfm/workflows/branches.py | 29 +--- hydromt_delft3dfm/workflows/dem.py | 1 - hydromt_delft3dfm/workflows/region.py | 2 +- hydromt_delft3dfm/workflows/structures.py | 3 +- tests/test_hydromt.py | 16 +- 7 files changed, 102 insertions(+), 167 deletions(-) diff --git a/hydromt_delft3dfm/dflowfm.py b/hydromt_delft3dfm/dflowfm.py index 1c9285eb..c06764eb 100644 --- a/hydromt_delft3dfm/dflowfm.py +++ b/hydromt_delft3dfm/dflowfm.py @@ -1,6 +1,7 @@ """Implement Delft3D-FM hydromt plugin model class.""" import itertools +import logging import os from datetime import datetime, timedelta from os.path import basename, dirname, isfile, join @@ -22,7 +23,7 @@ from . import DATADIR, gis_utils, mesh_utils, utils, workflows __all__ = ["DFlowFMModel"] -# logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") class DFlowFMModel(Model): @@ -121,7 +122,6 @@ def __init__( network_snap_offset=25, snap_newbranches_to_branches_at_snapnodes=True, openwater_computation_node_distance=40, - # logger=logger, ): """Initialize the DFlowFMModel. @@ -155,8 +155,6 @@ def __init__( openwater_computation_node_distance: float, optional Global option for generation of the mesh1d network. Distance to generate mesh1d nodes for open water system (rivers, channels). By default 40 m. - logger - The logger used to log messages. """ if not isinstance(root, (str, Path)): raise ValueError("The 'root' parameter should be a of str or Path.") @@ -171,7 +169,6 @@ def __init__( mode=mode, # config_fn=config_fn, data_libs=data_libs, - # logger=logger, region_component="mesh", ) @@ -293,7 +290,7 @@ def setup_channels( -------- dflowfm._setup_branches """ - self.logger.info("Preparing 1D channels.") + logger.info("Preparing 1D channels.") # filter for allowed columns br_type = "channel" @@ -333,7 +330,6 @@ def setup_channels( snap_offset=snap_offset, allow_intersection_snapping=allow_intersection_snapping, allowed_columns=_allowed_columns, - logger=self.logger, ) # Prepare friction and crosssections channels = workflows.prepare_default_friction_and_crosssection( @@ -341,7 +337,6 @@ def setup_channels( br_type=br_type, friction_type=friction_type, friction_value=friction_value, - logger=self.logger, ) # setup crosssections @@ -358,14 +353,14 @@ def setup_channels( ) # add crosssections to exisiting ones and update geoms - self.logger.debug("Adding crosssections vector to geoms.") + logger.debug("Adding crosssections vector to geoms.") crosssections = workflows.add_crosssections( self.geoms.get("crosssections"), crosssections ) self.set_geoms(crosssections, "crosssections") # setup geoms - self.logger.debug("Adding branches and branch_nodes vector to geoms.") + logger.debug("Adding branches and branch_nodes vector to geoms.") self.set_geoms(channels, "channels") self.set_geoms(channel_nodes, "channel_nodes") @@ -517,7 +512,7 @@ def setup_rivers_from_dem( ValueError """ - self.logger.info("Preparing river shape from hydrography data.") + logger.info("Preparing river shape from hydrography data.") # parse region argument region = workflows.parse_region_geometry(region, self.crs) @@ -577,7 +572,6 @@ def setup_rivers_from_dem( smooth_length=smooth_length, constrain_estuary=constrain_estuary, constrain_rivbed=constrain_rivbed, - logger=self.logger, **kwargs, ) # Rename river properties column and reproject @@ -617,7 +611,6 @@ def setup_rivers_from_dem( dst_crs=self.crs, id_start=len(self.branches) + 1, allowed_columns=_allowed_columns, - logger=self.logger, ) # Prepare friction branches = workflows.prepare_default_friction_and_crosssection( @@ -625,7 +618,6 @@ def setup_rivers_from_dem( br_type=br_type, friction_type=friction_type, friction_value=friction_value, - logger=self.logger, ) # setup crosssections @@ -636,14 +628,14 @@ def setup_rivers_from_dem( ) # add crosssections to exisiting ones and update geoms - self.logger.debug("Adding crosssections vector to geoms.") + logger.debug("Adding crosssections vector to geoms.") crosssections = workflows.add_crosssections( self.geoms.get("crosssections"), crosssections ) self.set_geoms(crosssections, "crosssections") # setup geoms #TODO do we still need channels? - self.logger.debug("Adding rivers and river_nodes vector to geoms.") + logger.debug("Adding rivers and river_nodes vector to geoms.") self.set_geoms(rivers, "rivers") self.set_geoms(river_nodes, "rivers_nodes") @@ -769,7 +761,7 @@ def setup_rivers( dflowfm._setup_branches dflowfm._setup_crosssections """ - self.logger.info("Preparing 1D rivers.") + logger.info("Preparing 1D rivers.") # filter for allowed columns br_type = "river" _allowed_columns = [ @@ -806,7 +798,6 @@ def setup_rivers( snap_offset=snap_offset, allow_intersection_snapping=allow_intersection_snapping, allowed_columns=_allowed_columns, - logger=self.logger, ) # Prepare friction and crosssections rivers = workflows.prepare_default_friction_and_crosssection( @@ -814,7 +805,6 @@ def setup_rivers( br_type=br_type, friction_type=friction_type, friction_value=friction_value, - logger=self.logger, ) # setup crosssections @@ -848,7 +838,7 @@ def setup_rivers( ] = -1 # setup geoms for rivers and river_nodes - self.logger.debug("Adding rivers and river_nodes vector to geoms.") + logger.debug("Adding rivers and river_nodes vector to geoms.") self.set_geoms(rivers, "rivers") self.set_geoms(river_nodes, "rivers_nodes") @@ -996,7 +986,7 @@ def setup_pipes( dflowfm._setup_branches dflowfm._setup_crosssections """ - self.logger.info("Preparing 1D pipes.") + logger.info("Preparing 1D pipes.") # filter for allowed columns br_type = "pipe" @@ -1036,7 +1026,6 @@ def setup_pipes( snap_offset=snap_offset, allow_intersection_snapping=allow_intersection_snapping, allowed_columns=_allowed_columns, - logger=self.logger, ) # Prepare friction and crosssections pipes = workflows.prepare_default_friction_and_crosssection( @@ -1046,7 +1035,6 @@ def setup_pipes( friction_value=friction_value, crosssections_shape=crosssections_shape, crosssections_value=crosssections_value, - logger=self.logger, ) # filter extra time for geting clipped pipes within the region (better match) # remove the index name to avoid "ValueError: cannot insert branchid, @@ -1061,7 +1049,7 @@ def setup_pipes( inv = pipes[["invlev_up", "invlev_dn"]] if inv.isnull().sum().sum() > 0: # nodata values in pipes for invert levels fill_invlev = True - self.logger.info( + logger.info( f"{pipes_fn} data has {inv.isnull().sum().sum()} no data values" "for invert levels. Will be filled using dem_fn or" f"default value {pipes_invlev}" @@ -1070,7 +1058,7 @@ def setup_pipes( fill_invlev = False else: fill_invlev = True - self.logger.info( + logger.info( f"{pipes_fn} does not have columns [invlev_up, invlev_dn]." "Invert levels will be generated from dem_fn or" f"default value {pipes_invlev}" @@ -1092,7 +1080,7 @@ def setup_pipes( fill_invlev = False # 3. filling use pipes_invlev if fill_invlev and pipes_invlev is not None: - self.logger.warning( + logger.warning( "!Using a constant up and down invert levels for all pipes." "May cause issues when running the delft3dfm model.!" ) @@ -1117,14 +1105,14 @@ def setup_pipes( midpoint=False, ) # add crosssections to exisiting ones and update geoms - self.logger.debug("Adding crosssections vector to geoms.") + logger.debug("Adding crosssections vector to geoms.") crosssections = workflows.add_crosssections( self.geoms.get("crosssections"), crosssections ) self.set_geoms(crosssections, "crosssections") # setup geoms - self.logger.debug("Adding pipes and pipe_nodes vector to geoms.") + logger.debug("Adding pipes and pipe_nodes vector to geoms.") self.set_geoms(pipes, "pipes") self.set_geoms(pipe_nodes, "pipe_nodes") # TODO: for manholes @@ -1236,7 +1224,7 @@ def _setup_crosssections( # might require upstream/downstream # TODO: check for required columns # read crosssection from branches - self.logger.info("Preparing crossections from branch.") + logger.info("Preparing crossections from branch.") gdf_cs = workflows.set_branch_crosssections(branches, midpoint=midpoint) elif crosssections_type == "xyz": @@ -1250,7 +1238,7 @@ def _setup_crosssections( # check if feature valid if len(gdf_cs) == 0: - self.logger.warning( + logger.warning( f"No {crosssections_fn} 1D xyz crosssections found within domain" ) return None @@ -1258,7 +1246,7 @@ def _setup_crosssections( gdf_cs, required_columns=["crsid", "order", "z"] ) if not valid_attributes: - self.logger.error( + logger.error( "Required attributes [crsid, order, z] in xyz crosssections" "do not exist" ) @@ -1273,7 +1261,7 @@ def _setup_crosssections( gdf_cs.to_crs(self.crs) # set crsloc and crsdef attributes to crosssections - self.logger.info(f"Preparing 1D xyz crossections from {crosssections_fn}") + logger.info(f"Preparing 1D xyz crossections from {crosssections_fn}") gdf_cs = workflows.set_xyz_crosssections(branches, gdf_cs) elif crosssections_type == "point": @@ -1287,7 +1275,7 @@ def _setup_crosssections( # check if feature valid if len(gdf_cs) == 0: - self.logger.warning( + logger.warning( f"No {crosssections_fn} 1D point crosssections found within domain" ) return None @@ -1295,7 +1283,7 @@ def _setup_crosssections( gdf_cs, required_columns=["crsid", "shape", "shift"] ) if not valid_attributes: - self.logger.error( + logger.error( "Required attributes [crsid, shape, shift] in point crosssections" "do not exist" ) @@ -1310,7 +1298,7 @@ def _setup_crosssections( gdf_cs.to_crs(self.crs) # set crsloc and crsdef attributes to crosssections - self.logger.info(f"Preparing 1D point crossections from {crosssections_fn}") + logger.info(f"Preparing 1D point crossections from {crosssections_fn}") gdf_cs = workflows.set_point_crosssections( branches, gdf_cs, maxdist=maxdist ) @@ -1405,14 +1393,13 @@ def setup_manholes( ] # generate manhole locations and bedlevels - self.logger.info("generating manholes locations and bedlevels. ") + logger.info("generating manholes locations and bedlevels. ") manholes, branches = workflows.generate_manholes_on_branches( self.branches, bedlevel_shift=bedlevel_shift, use_branch_variables=["diameter", "width"], id_prefix="manhole_", id_suffix="_generated", - logger=self.logger, ) # FIXME Xiaohan: why do we need set_branches here? Because of branches.gui # --> add a high level write_gui files same level as write_mesh @@ -1426,7 +1413,7 @@ def setup_manholes( # read user manhole if manholes_fn: - self.logger.info(f"reading manholes street level from file {manholes_fn}. ") + logger.info(f"reading manholes street level from file {manholes_fn}. ") # read gdf_manhole = self.data_catalog.get_geodataframe( manholes_fn, @@ -1439,21 +1426,19 @@ def setup_manholes( gdf_manhole = gdf_manhole.to_crs(self.crs) # filter for allowed columns allowed_columns = set(_allowed_columns).intersection(gdf_manhole.columns) - self.logger.debug( - f'filtering for allowed columns:{",".join(allowed_columns)}' - ) + logger.debug(f'filtering for allowed columns:{",".join(allowed_columns)}') gdf_manhole = gpd.GeoDataFrame( gdf_manhole[list(allowed_columns)], crs=gdf_manhole.crs ) # replace generated manhole using user manholes - self.logger.debug("overwriting generated manholes using user manholes.") + logger.debug("overwriting generated manholes using user manholes.") manholes = hydromt.gis_utils.nearest_merge( manholes, gdf_manhole, max_dist=snap_offset, overwrite=True ) # generate manhole streetlevels from dem if dem_fn is not None: - self.logger.info("overwriting manholes street level from dem. ") + logger.info("overwriting manholes street level from dem. ") dem = self.data_catalog.get_rasterdataset( dem_fn, geom=self.region, @@ -1464,13 +1449,11 @@ def setup_manholes( manholes["_streetlevel_dem"] = dem.raster.sample(manholes).values manholes["_streetlevel_dem"].fillna(manholes["streetlevel"], inplace=True) manholes["streetlevel"] = manholes["_streetlevel_dem"] - self.logger.debug( - f'street level mean is {np.mean(manholes["streetlevel"])}' - ) + logger.debug(f'street level mean is {np.mean(manholes["streetlevel"])}') # internal administration # drop duplicated manholeid - self.logger.debug("dropping duplicated manholeid") + logger.debug("dropping duplicated manholeid") manholes.drop_duplicates(subset="manholeid") # add nodeid to manholes network1d_nodes = mesh_utils.network1d_nodes_geodataframe( @@ -1488,13 +1471,13 @@ def setup_manholes( # validate if manholes[_allowed_columns].isna().any().any(): - self.logger.error( + logger.error( "manholes contain no data." "Use manholes_defaults_fn to apply no data filling." ) # setup geoms - self.logger.debug("Adding manholes vector to geoms.") + logger.debug("Adding manholes vector to geoms.") self.set_geoms(manholes, "manholes") def setup_1dboundary( @@ -1581,7 +1564,7 @@ def setup_1dboundary( network nodes. By default 0.1, a small snapping is applied to avoid precision errors. """ - self.logger.info(f"Preparing 1D {boundary_type} boundaries for {branch_type}.") + logger.info(f"Preparing 1D {boundary_type} boundaries for {branch_type}.") # 1. get potential boundary locations based on branch_type and boundary_type boundaries_branch_type = workflows.select_boundary_type( @@ -1602,7 +1585,6 @@ def setup_1dboundary( boundary_type=boundary_type, boundary_unit=boundary_unit, snap_offset=snap_offset, - logger=self.logger, ) # 4. set boundaries @@ -1636,7 +1618,7 @@ def _read_forcing_geodataset( ): pass else: - self.logger.error( + logger.error( "Forcing has different start and end time." + " Please check the forcing file. Support yyyy-mm-dd HH:MM:SS. " ) @@ -1710,7 +1692,7 @@ def setup_1dlateral_from_points( If None, all branches are used. By defalt None. """ - self.logger.info(f"Preparing 1D laterals for {branch_type}.") + logger.info(f"Preparing 1D laterals for {branch_type}.") network_by_branchtype = self.staticgeoms[f"{branch_type}s"] # 1. read lateral geodataset and snap to network @@ -1735,7 +1717,6 @@ def setup_1dlateral_from_points( forcing_value=lateral_value, forcing_type="lateral_discharge", forcing_unit="m3/s", - logger=self.logger, ) # 3. set laterals @@ -1776,7 +1757,7 @@ def setup_1dlateral_from_polygons( or for filling in missing data. By default 0 [m3/s]. """ - self.logger.info("Preparing 1D laterals for polygons.") + logger.info("Preparing 1D laterals for polygons.") # 1. read lateral geodataset gdf_laterals, da_lat = self._read_forcing_geodataset( @@ -1793,7 +1774,6 @@ def setup_1dlateral_from_polygons( forcing_value=lateral_value, forcing_type="lateral_discharge", forcing_unit="m3/s", - logger=self.logger, ) # 3. set laterals @@ -2176,13 +2156,13 @@ def setup_mesh2d_refine( """ if "mesh2d" not in self.mesh_names: - self.logger.error( + logger.error( "2d mesh is not available, use setup_mesh2d before refinement." ) return if polygon_fn is not None: - self.logger.info(f"reading geometry from file {polygon_fn}. ") + logger.info(f"reading geometry from file {polygon_fn}. ") # read gdf = self.data_catalog.get_geodataframe( polygon_fn, geom=self.region, buffer=0, predicate="contains" @@ -2192,7 +2172,7 @@ def setup_mesh2d_refine( gdf = gdf.to_crs(self.crs) elif sample_fn is not None: - self.logger.info(f"reading samples from file {sample_fn}. ") + logger.info(f"reading samples from file {sample_fn}. ") # read da = self.data_catalog.get_rasterdataset( sample_fn, @@ -2206,7 +2186,7 @@ def setup_mesh2d_refine( ) # float64 is needed by mesh kernel to convert into c double # reproject if da.raster.crs != self.crs: - self.logger.warning( + logger.warning( "Sample grid has a different resolution than model." "Reprojecting with nearest but some information might be lost." ) @@ -2219,7 +2199,6 @@ def setup_mesh2d_refine( gdf_polygon=gdf if polygon_fn is not None else None, da_sample=da if sample_fn is not None else None, steps=steps, - logger=self.logger, ) # set mesh2d @@ -2290,7 +2269,7 @@ def setup_link1d2d( """ # check existing network if "mesh1d" not in self.mesh_names or "mesh2d" not in self.mesh_names: - self.logger.error( + logger.error( "cannot setup link1d2d: either mesh1d or mesh2d or both do not exist" ) return None @@ -2303,7 +2282,7 @@ def setup_link1d2d( # check input if polygon_fn is not None: within = self.data_catalog.get_geodataframe(polygon_fn).geometry - self.logger.info(f"adding 1d2d links only within polygon {polygon_fn}") + logger.info(f"adding 1d2d links only within polygon {polygon_fn}") else: within = None @@ -2311,16 +2290,16 @@ def setup_link1d2d( branchids = self.branches[ self.branches.branchtype == branch_type ].branchid.to_list() # use selective branches - self.logger.info(f"adding 1d2d links for {branch_type} branches.") + logger.info(f"adding 1d2d links for {branch_type} branches.") else: branchids = None # use all branches - self.logger.warning( + logger.warning( "adding 1d2d links for all branches at non boundary locations." ) # setup 1d2d links if link_direction == "1d_to_2d": - self.logger.info("setting up 1d_to_2d links.") + logger.info("setting up 1d_to_2d links.") # recompute max_length based on the diagonal distance of the max mesh area max_length = np.sqrt(self.mesh_grids["mesh2d"].area.max()) * np.sqrt(2) link1d2d = workflows.links1d2d_add_links_1d_to_2d( @@ -2329,13 +2308,13 @@ def setup_link1d2d( elif link_direction == "2d_to_1d": if link_type == "embedded": - self.logger.info("setting up 2d_to_1d embedded links.") + logger.info("setting up 2d_to_1d embedded links.") link1d2d = workflows.links1d2d_add_links_2d_to_1d_embedded( self.mesh, branchids=branchids, within=within ) elif link_type == "lateral": - self.logger.info("setting up 2d_to_1d lateral links.") + logger.info("setting up 2d_to_1d lateral links.") link1d2d = workflows.links1d2d_add_links_2d_to_1d_lateral( self.mesh, branchids=branchids, @@ -2344,14 +2323,14 @@ def setup_link1d2d( dist_factor=dist_factor, ) else: - self.logger.error(f"link_type {link_type} is not recognised.") + logger.error(f"link_type {link_type} is not recognised.") else: - self.logger.error(f"link_direction {link_direction} is not recognised.") + logger.error(f"link_direction {link_direction} is not recognised.") # Add link1d2d to xu Ugrid mesh if len(link1d2d["link1d2d"]) == 0: - self.logger.warning("No 1d2d links were generated.") + logger.warning("No 1d2d links were generated.") else: self.set_link1d2d(link1d2d) @@ -2412,7 +2391,7 @@ def setup_maps_from_rasterdataset( """ # check for name when split_dataset is False if split_dataset is False and name is None: - self.logger.error("name must be specified when split_dataset = False") + logger.error("name must be specified when split_dataset = False") # Call super method variables = super().setup_maps_from_rasterdataset( @@ -2521,7 +2500,7 @@ def setup_maps_from_raster_reclass( """ # check for name when split_dataset is False if split_dataset is False and name is None: - self.logger.error("name must be specified when split_dataset = False") + logger.error("name must be specified when split_dataset = False") # Call super method reclass_variables = super().setup_maps_from_raster_reclass( @@ -2645,7 +2624,7 @@ def setup_2dboundary( ``boundaries_timeseries_fn``. """ - self.logger.info("Preparing 2D boundaries.") + logger.info("Preparing 2D boundaries.") if boundary_type == "waterlevel": boundary_unit = "m" @@ -2675,7 +2654,7 @@ def setup_2dboundary( predicate="contains", ) if len(gdf_bnd) == 0: - self.logger.error( + logger.error( "Boundaries are not found. Check if the boundary are outside of" "recognisable boundary region (cell size * tolerance to the mesh)." ) @@ -2692,7 +2671,7 @@ def setup_2dboundary( gdf_bnd = None # 2. read timeseries boundaries if boundaries_timeseries_fn is not None: - self.logger.info("reading timeseries boundaries") + logger.info("reading timeseries boundaries") df_bnd = self.data_catalog.get_dataframe( boundaries_timeseries_fn, time_tuple=(tstart, tstop) ) # could not use open_geodataset due to line geometry @@ -2736,7 +2715,6 @@ def setup_2dboundary( boundary_value=boundary_value, boundary_type=boundary_type, boundary_unit=boundary_unit, - logger=self.logger, ) # 5. set boundaries @@ -2762,7 +2740,7 @@ def setup_rainfall_from_constant( constant_value: float Constant value for the rainfall_rate timeseries in mm/day. """ - self.logger.info("Preparing rainfall meteo forcing from uniform timeseries.") + logger.info("Preparing rainfall meteo forcing from uniform timeseries.") refdate, tstart, tstop = self.get_model_time() # time slice meteo_location = ( @@ -2785,7 +2763,6 @@ def setup_rainfall_from_constant( fill_value=constant_value, is_rate=True, meteo_location=meteo_location, - logger=self.logger, ) # 4. set meteo forcing @@ -2835,7 +2812,7 @@ def setup_rainfall_from_uniform_timeseries( Note that Delft3DFM 1D2D Suite 2022.04 supports only "rainfall_rate". """ - self.logger.info("Preparing rainfall meteo forcing from uniform timeseries.") + logger.info("Preparing rainfall meteo forcing from uniform timeseries.") refdate, tstart, tstop = self.get_model_time() # time slice meteo_location = ( @@ -2855,7 +2832,7 @@ def setup_rainfall_from_uniform_timeseries( "function arguments (eg pandas.read_csv for csv driver)." ) if (df_meteo.index[-1] - df_meteo.index[0]) < (tstop - tstart): - self.logger.warning( + logger.warning( "Time in meteo_timeseries_fn were shorter than model simulation time. " "Will fill in using fill_value." ) @@ -2870,7 +2847,6 @@ def setup_rainfall_from_uniform_timeseries( fill_value=fill_value, is_rate=is_rate, meteo_location=meteo_location, - logger=self.logger, ) # 4. set meteo forcing @@ -2886,7 +2862,7 @@ def read(self): # FIXME: where to read crs?. """ - self.logger.info(f"Reading model data from {self.root}") + logger.info(f"Reading model data from {self.root}") self.read_dimr() self.read_config() self.read_mesh() @@ -2897,10 +2873,10 @@ def read(self): def write(self): # complete model """Write the complete model schematization and configuration to file.""" - self.logger.info(f"Writing model data to {self.root}") + logger.info(f"Writing model data to {self.root}") # if in r, r+ mode, only write updated components if not self._write: - self.logger.warning("Cannot write in read-only mode") + logger.warning("Cannot write in read-only mode") return if self._maps: @@ -3029,14 +3005,14 @@ def read_maps(self) -> Dict[str, Union[xr.Dataset, xr.DataArray]]: def write_maps(self) -> None: """Write maps as tif files in maps folder and update initial fields.""" if len(self._maps) == 0: - self.logger.debug("No maps data found, skip writing.") + logger.debug("No maps data found, skip writing.") return self._assert_write_mode() # Global parameters mapsroot = join(self.root, "maps") inilist = [] paramlist = [] - self.logger.info(f"Writing maps files to {mapsroot}") + logger.info(f"Writing maps files to {mapsroot}") def _prepare_inifields(da_dict, da): # Write tif files @@ -3139,17 +3115,17 @@ def read_geoms(self) -> None: # FIXME: gives an error when only 2D model. # Add crosssections properties, should be done before friction # Branches are needed do derive locations, # self.branches should start the read if not done yet - self.logger.info("Reading cross-sections files") + logger.info("Reading cross-sections files") crosssections = utils.read_crosssections(self.branches, self.dfmmodel) # Add friction properties from roughness files - # self.logger.info("Reading friction files") + # logger.info("Reading friction files") crosssections = utils.read_friction(crosssections, self.dfmmodel) self.set_geoms(crosssections, "crosssections") # Read manholes if self.dfmmodel.geometry.storagenodefile is not None: - self.logger.info("Reading manholes file") + logger.info("Reading manholes file") network1d_nodes = mesh_utils.network1d_nodes_geodataframe( self.mesh_datasets["network1d"] ) @@ -3158,7 +3134,7 @@ def read_geoms(self) -> None: # FIXME: gives an error when only 2D model. # Read structures if self.dfmmodel.geometry.structurefile is not None: - self.logger.info("Reading structures file") + logger.info("Reading structures file") structures = utils.read_structures(self.branches, self.dfmmodel) for st_type in structures["type"].unique(): self.set_geoms(structures[structures["type"] == st_type], f"{st_type}s") @@ -3183,20 +3159,20 @@ def write_geoms(self, write_mesh_gdf=True) -> None: if "crosssections" in self._geoms: # Crosssections gdf_crs = self.geoms["crosssections"] - self.logger.info("Writting cross-sections files crsdef and crsloc") + logger.info("Writting cross-sections files crsdef and crsloc") crsdef_fn, crsloc_fn = utils.write_crosssections(gdf_crs, savedir) self.set_config("geometry.crossdeffile", crsdef_fn) self.set_config("geometry.crosslocfile", crsloc_fn) # Friction - self.logger.info("Writting friction file(s)") + logger.info("Writting friction file(s)") friction_fns = utils.write_friction(gdf_crs, savedir) self.set_config("geometry.frictfile", ";".join(friction_fns)) # Write structures # Manholes if "manholes" in self._geoms: - self.logger.info("Writting manholes file.") + logger.info("Writting manholes file.") storage_fn = utils.write_manholes( self.geoms["manholes"], savedir, @@ -3213,7 +3189,7 @@ def write_geoms(self, write_mesh_gdf=True) -> None: structures = list(itertools.chain.from_iterable(structures)) structures = pd.DataFrame(structures).replace(np.nan, None) # write - self.logger.info("Writting structures file.") + logger.info("Writting structures file.") structures_fn = utils.write_structures( structures, savedir, @@ -3308,10 +3284,10 @@ def read_forcing( def write_forcing(self) -> None: """Write forcing into hydrolib-core ext and forcing models.""" if len(self._forcing) == 0: - self.logger.debug("No forcing data found, skip writing.") + logger.debug("No forcing data found, skip writing.") else: self._assert_write_mode() - self.logger.info("Writting forcing files.") + logger.info("Writting forcing files.") savedir = dirname(join(self.root, self._config_fn)) # create new external forcing file ext_fn = "bnd.ext" @@ -3361,7 +3337,7 @@ def read_mesh(self): # https://github.com/Deltares/HYDROLIB-core/issues/561 # Add branchtype, properties from branches.gui file - self.logger.info("Reading branches GUI file") + logger.info("Reading branches GUI file") branches = utils.read_branches_gui(branches, self.dfmmodel) # Set branches @@ -3392,7 +3368,7 @@ def write_mesh(self, write_gui=True): # other mesh1d related geometry TODO update if "mesh1d" in self.mesh_names and write_gui: - self.logger.info("Writting branches.gui file") + logger.info("Writting branches.gui file") if "manholes" in self.geoms: utils.write_branches_gui(self.branches, savedir) @@ -3474,11 +3450,11 @@ def init_dfmmodel(self): # create a new MDU-Model mdu_fn = Path(join(self.root, self._config_fn)) if isfile(mdu_fn) and self._read: - self.logger.info(f"Reading mdu file at {mdu_fn}") + logger.info(f"Reading mdu file at {mdu_fn}") self._dfmmodel = FMModel(filepath=mdu_fn) else: # use hydrolib template self._assert_write_mode() - self.logger.info("Initialising empty mdu file") + logger.info("Initialising empty mdu file") self._dfmmodel = FMModel() self._dfmmodel.filepath = mdu_fn @@ -3495,12 +3471,12 @@ def read_dimr(self, dimr_fn: Optional[str] = None) -> None: dimr_fn = join(self.root, self._dimr_fn) # if file exist, read if isfile(dimr_fn) and self._read: - self.logger.info(f"Reading dimr file at {dimr_fn}") + logger.info(f"Reading dimr file at {dimr_fn}") dimr = DIMR(filepath=Path(dimr_fn)) # else initialise else: self._assert_write_mode() - self.logger.info("Initialising empty dimr file") + logger.info("Initialising empty dimr file") dimr = DIMR() self._dimr = dimr @@ -3518,7 +3494,7 @@ def write_dimr(self, dimr_fn: Optional[str] = None): if not self._read: # Updates the dimr file first before writing - self.logger.info("Adding dflowfm component to dimr config") + logger.info("Adding dflowfm component to dimr config") # update component components = self._dimr.component @@ -3541,7 +3517,7 @@ def write_dimr(self, dimr_fn: Optional[str] = None): self._dimr.control = control # write - self.logger.info(f"Writing model dimr file to {self._dimr.filepath}") + logger.info(f"Writing model dimr file to {self._dimr.filepath}") self.dimr.save(recurse=False) @property @@ -3563,7 +3539,7 @@ def set_branches(self, branches: gpd.GeoDataFrame): if "branchtype" in branches.columns: self._branches = branches else: - self.logger.error( + logger.error( "'branchtype' column absent from the new branches, could not update." ) @@ -3573,10 +3549,10 @@ def set_branches(self, branches: gpd.GeoDataFrame): _ = self.set_branches_component(name="pipe") # update geom - self.logger.debug("Adding branches vector to geoms.") + logger.debug("Adding branches vector to geoms.") self.set_geoms(branches, "branches") - self.logger.debug("Updating branches in network.") + logger.debug("Updating branches in network.") def set_branches_component(self, name: str): """Extract component name from branches and add it to geoms.""" @@ -3705,7 +3681,7 @@ def set_mesh( if overwrite_grid and "link1d2d" in self.mesh.data_vars: if grid_name == "mesh1d" or grid_name == "mesh2d": # TODO check if warning is enough or if we should remove to be sure? - self.logger.warning( + logger.warning( f"{grid_name} grid was updated in self.mesh. " "Re-run setup_link1d2d method to update the model 1D2D links." ) @@ -3742,7 +3718,7 @@ def set_link1d2d( # FIXME current implementation of below does not support updating partial # 1d2d links. Either document or adapt. #1 if "link1d2d" in self.mesh.data_vars: - self.logger.info("Overwriting existing link1d2d in self.mesh.") + logger.info("Overwriting existing link1d2d in self.mesh.") self._mesh = self._mesh.drop_vars( [ "link1d2d", @@ -3773,7 +3749,7 @@ def _check_crs(self): """Check if model crs is defined.""" if self.crs is None: if self.read: - self.logger.warning( + logger.warning( "Could not derive CRS from reading the mesh file." "Please define the CRS in the [global] init attributes before" "setting up the model." @@ -3784,4 +3760,4 @@ def _check_crs(self): "attributes before setting up the model." ) else: - self.logger.info(f"project crs: {self.crs.to_epsg()}") + logger.info(f"project crs: {self.crs.to_epsg()}") diff --git a/hydromt_delft3dfm/workflows/boundaries.py b/hydromt_delft3dfm/workflows/boundaries.py index e34a0975..47c11e4f 100644 --- a/hydromt_delft3dfm/workflows/boundaries.py +++ b/hydromt_delft3dfm/workflows/boundaries.py @@ -63,7 +63,6 @@ def select_boundary_type( branch_type: str, boundary_type: str, boundary_locs: str, - logger=logger, ) -> pd.DataFrame: """Select boundary location per branch type and boundary type. @@ -78,8 +77,6 @@ def select_boundary_type( For pipes 'waterlevel' is supported. boundary_locs : {'both', 'upstream', 'downstream'} The boundary location to use. - logger - The logger to log messages with. Returns ------- @@ -165,7 +162,6 @@ def compute_boundary_values( boundary_type: str = "waterlevel", boundary_unit: str = "m", snap_offset: float = 0.1, - logger=logger, ): """ Compute 1d boundary values. @@ -197,8 +193,6 @@ def compute_boundary_values( Snapping tolerance to automatically applying boundaries at the correct network nodes. By default 0.1, a small snapping is applied to avoid precision errors. - logger - Logger to log messages. """ # Timeseries boundary values if da_bnd is not None: @@ -280,7 +274,6 @@ def compute_2dboundary_values( boundary_value: float = 0.0, boundary_type: str = "waterlevel", boundary_unit: str = "m", - logger=logger, ): """ Compute 2d boundary timeseries. @@ -313,8 +306,6 @@ def compute_2dboundary_values( if ''boundary_type`` = "discharge": Allowed unit is [m3/s] By default m. - logger : - Logger to log messages. Raises ------ @@ -471,7 +462,6 @@ def compute_meteo_forcings( fill_value: float = 0.0, is_rate: bool = True, meteo_location: tuple = None, - logger=logger, ) -> xr.DataArray: """ Compute meteo forcings. @@ -493,8 +483,6 @@ def compute_meteo_forcings( If rate, unit is expected to be in mm/day and else mm. meteo_location : tuple Global location for meteo timeseries - logger - Logger to log messages. Returns ------- @@ -592,7 +580,6 @@ def compute_forcing_values_points( forcing_value: float = 0.0, forcing_type: str = "lateral_discharge", forcing_unit: str = "m3/s", - logger=logger, ): """ Compute 1d forcing values. @@ -622,8 +609,6 @@ def compute_forcing_values_points( forcing_unit : {'m3/s'} Unit corresponding to ``forcing_type``. By default 'm3/s' - logger - Logger to log messages. """ # TODO: harmonize for other point forcing #21 # first process data based on either timeseries or constant @@ -744,7 +729,6 @@ def compute_forcing_values_polygon( forcing_value: float = 0.0, forcing_type: str = "waterlevelbnd", forcing_unit: str = "m", - logger=logger, ): """ Compute 1d forcing values. @@ -774,8 +758,6 @@ def compute_forcing_values_polygon( forcing_unit : {'m3/s'} Unit corresponding to ``forcing_type``. By default 'm3/s' - logger - Logger to log messages. """ # default dims, coords and attris for polygon geometry type _dims_defaults = ["index", "numcoordinates"] diff --git a/hydromt_delft3dfm/workflows/branches.py b/hydromt_delft3dfm/workflows/branches.py index 1d0cf305..1afd3780 100644 --- a/hydromt_delft3dfm/workflows/branches.py +++ b/hydromt_delft3dfm/workflows/branches.py @@ -131,7 +131,6 @@ def prepare_branches( snap_offset=snap_offset, allow_intersection_snapping=allow_intersection_snapping, smooth_branches=br_type == "pipe", - logger=logger, ) logger.info("Validating branches") validate_branches(branches) @@ -278,7 +277,6 @@ def update_data_columns_attribute_from_query( branches: gpd.GeoDataFrame, attribute: pd.DataFrame, attribute_name: str, - logger=logger, ): """ Update an attribute column of branches. @@ -360,7 +358,6 @@ def process_branches( snap_offset: float = 0.01, allow_intersection_snapping: bool = True, smooth_branches: bool = False, - logger=logger, ): """Process the branches. @@ -381,8 +378,6 @@ def process_branches( smooth_branches: bool, optional whether to return branches that are smoothed (straightend), needed for pipes Default to False. - logger - The logger to log messages with. Returns ------- @@ -400,16 +395,15 @@ def process_branches( id_col=id_col, snap_offset=snap_offset, allow_intersection_snapping=allow_intersection_snapping, - logger=logger, ) logger.debug("Splitting branches based on spacing") # TODO: add check, if spacing is used, # then in branch cross section cannot be setup later - branches = space_branches(branches, smooth_branches=smooth_branches, logger=logger) + branches = space_branches(branches, smooth_branches=smooth_branches) logger.debug("Generating branchnodes") - branch_nodes = generate_branchnodes(branches, id_col, logger=logger) + branch_nodes = generate_branchnodes(branches, id_col) return branches, branch_nodes @@ -419,7 +413,6 @@ def cleanup_branches( id_col: str = "branchid", snap_offset: float = 0.01, allow_intersection_snapping: bool = True, - logger=logger, ): """Clean up the branches. @@ -445,8 +438,6 @@ def cleanup_branches( allow_intersection_snapping : bool, optional Allow snapping at all branch ends, including intersections. Defaults to True. - logger - The logger to log messages with. Returns ------- @@ -559,7 +550,6 @@ def space_branches( branches: gpd.GeoDataFrame, spacing_col: str = "spacing", smooth_branches: bool = False, - logger=logger, ): """ Space the branches based on the spacing_col on the branch. @@ -575,8 +565,6 @@ def space_branches( The branches to clean up. spacing_col : str, optional The branch id column name. Defaults to 'spacing'. - logger - The logger to log messages with. Returns ------- @@ -598,7 +586,6 @@ def space_branches( def generate_branchnodes( branches: gpd.GeoDataFrame, id_col: str = None, - logger=logger, ): """Generate branch nodes at the branch ends. @@ -608,8 +595,6 @@ def generate_branchnodes( The branches to generate the end nodes for. id_col : str, optional The branch id column name. Defaults to None. - logger - The logger to log messages with. Returns ------- @@ -652,9 +637,8 @@ def generate_branchnodes( return nodes -def validate_branches( - branches: gpd.GeoDataFrame, logger=logger -): # TODO: add more content and maybe make a seperate module +# TODO: add more content and maybe make a seperate module +def validate_branches(branches: gpd.GeoDataFrame): """Validate the branches. Logs an error when one or more branches have a length of 0 meter. @@ -663,8 +647,6 @@ def validate_branches( ---------- branches : gpd.GeoDataFrame The branches to validate. - logger - The logger to log messages with. """ # validate pipe geometry if sum(branches.geometry.length <= 0) == 0: @@ -683,7 +665,6 @@ def split_branches( spacing_const: float = float("inf"), spacing_col: str = None, smooth_branches: bool = False, - logger=logger, ): """ Split branches based on a given spacing. @@ -707,8 +688,6 @@ def split_branches( Default to None. smooth_branches: bool, optional Switch to split branches into straight lines. By default False. - logger - The logger to log messages with. Returns ------- diff --git a/hydromt_delft3dfm/workflows/dem.py b/hydromt_delft3dfm/workflows/dem.py index 9a0b33d1..d79a7af1 100644 --- a/hydromt_delft3dfm/workflows/dem.py +++ b/hydromt_delft3dfm/workflows/dem.py @@ -165,7 +165,6 @@ def get_river_bathymetry( elevtn_name: str = "elevtn", uparea_name: str = "uparea", rivmsk_name: str = "rivmsk", - logger=logger, **kwargs, ) -> Tuple[gpd.GeoDataFrame, xr.DataArray]: """Estimate river bedlevel zb. diff --git a/hydromt_delft3dfm/workflows/region.py b/hydromt_delft3dfm/workflows/region.py index b4aa768d..0d67aaca 100644 --- a/hydromt_delft3dfm/workflows/region.py +++ b/hydromt_delft3dfm/workflows/region.py @@ -20,7 +20,7 @@ def parse_region_geometry( logger: logging.Logger = logger, ): """Parse hydromt stype region argument into region geometry.""" - kind, region = parse_region_geom(region, logger=logger) + kind, region = parse_region_geom(region) if kind == "bbox": bbox = region["bbox"] geom = gpd.GeoDataFrame(geometry=[box(*bbox)], crs=4326) diff --git a/hydromt_delft3dfm/workflows/structures.py b/hydromt_delft3dfm/workflows/structures.py index 5d4ee240..2462328d 100644 --- a/hydromt_delft3dfm/workflows/structures.py +++ b/hydromt_delft3dfm/workflows/structures.py @@ -11,7 +11,7 @@ from .branches import find_nearest_branch from .crosssections import set_point_crosssections -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = [ @@ -27,7 +27,6 @@ def prepare_1dstructures( id_start: int = 1, filter: str = None, snap_offset: float = 0.0, - logger: logging.Logger = logger, ) -> gpd.GeoDataFrame: """Prepare 1D structures from geodataframe. diff --git a/tests/test_hydromt.py b/tests/test_hydromt.py index 3efab902..56e4c227 100644 --- a/tests/test_hydromt.py +++ b/tests/test_hydromt.py @@ -1,11 +1,11 @@ """Test for hydromt plugin model class DFlowFMModel""" +import logging import pdb from os.path import abspath, dirname, join import pytest from hydromt.cli._utils import parse_config -# from hydromt._utils.log import setuplog from hydromt_delft3dfm import DFlowFMModel @@ -52,7 +52,8 @@ def test_model_build(tmpdir, modelname): # test build method # compare results with model from examples folder root = join(tmpdir, f"dflowfm_{modelname}") - # logger = setuplog(__name__, join(root, "hydromt.log"), log_level=10) + logger = logging.getLogger("hydromt") + logger.setLevel(10) mod1 = DFlowFMModel( root=root, mode="w", @@ -60,7 +61,6 @@ def test_model_build(tmpdir, modelname): network_snap_offset=network_snap_offset, crs=crs, openwater_computation_node_distance=openwater_computation_node_distance, - # logger=logger, ) # Build model (now excludes global section because of pop) mod1.build(opt=opt) @@ -70,7 +70,7 @@ def test_model_build(tmpdir, modelname): # Compare with model from examples folder # (need to read it again for proper geoms check) - mod1 = DFlowFMModel(root=root, mode="r") #, logger=logger) + mod1 = DFlowFMModel(root=root, mode="r")) mod1.read() root = join(EXAMPLEDIR, f"dflowfm_{modelname}") mod0 = DFlowFMModel(root=root, mode="r") @@ -102,7 +102,8 @@ def test_model_build_local_code(tmp_path): network_snap_offset = global_sect['network_snap_offset'] openwater_computation_node_distance = global_sect['openwater_computation_node_distance'] # initialize model - # logger = setuplog(__name__, join(tmp_path, "hydromt.log"), log_level=10) + logger = logging.getLogger("hydromt") + logger.setLevel(10) model = DFlowFMModel( root=tmp_path, mode="w", @@ -110,7 +111,6 @@ def test_model_build_local_code(tmp_path): network_snap_offset=network_snap_offset, crs=crs, openwater_computation_node_distance=openwater_computation_node_distance, - # logger=logger ) # build model via steps corresponding to yml order model.setup_rivers(**opt['setup_rivers']) @@ -146,7 +146,8 @@ def test_model_build_piave_code(tmp_path): network_snap_offset = global_sect['network_snap_offset'] openwater_computation_node_distance = global_sect['openwater_computation_node_distance'] # initialize model - # logger = setuplog(__name__, join(tmp_path, "hydromt.log"), log_level=10) + logger = logging.getLogger("hydromt") + logger.setLevel(10) model = DFlowFMModel( root=tmp_path, mode="w", @@ -154,7 +155,6 @@ def test_model_build_piave_code(tmp_path): network_snap_offset=network_snap_offset, crs=crs, openwater_computation_node_distance=openwater_computation_node_distance, - # logger=logger ) # build model via steps corresponding to yml order model.setup_rivers_from_dem(**opt['setup_rivers_from_dem']) From 41dea00128466eecb12e72a4834d8943fadfb8af Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Wed, 23 Oct 2024 14:49:29 +0200 Subject: [PATCH 17/23] replaced logger by hydromt --- hydromt_delft3dfm/gis_utils.py | 2 +- hydromt_delft3dfm/graph_utils.py | 2 +- hydromt_delft3dfm/mesh_utils.py | 2 +- hydromt_delft3dfm/workflows/boundaries.py | 2 +- hydromt_delft3dfm/workflows/branches.py | 2 +- hydromt_delft3dfm/workflows/crosssections.py | 2 +- hydromt_delft3dfm/workflows/dem.py | 2 +- hydromt_delft3dfm/workflows/manholes.py | 2 +- hydromt_delft3dfm/workflows/mesh.py | 2 +- hydromt_delft3dfm/workflows/region.py | 2 +- hydromt_delft3dfm/workflows/roughness.py | 2 +- tests/test_hydromt.py | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/hydromt_delft3dfm/gis_utils.py b/hydromt_delft3dfm/gis_utils.py index b7c4124b..587e5d9f 100644 --- a/hydromt_delft3dfm/gis_utils.py +++ b/hydromt_delft3dfm/gis_utils.py @@ -11,7 +11,7 @@ ) from shapely.ops import snap, split -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = [ diff --git a/hydromt_delft3dfm/graph_utils.py b/hydromt_delft3dfm/graph_utils.py index 6018d111..703b8aa8 100644 --- a/hydromt_delft3dfm/graph_utils.py +++ b/hydromt_delft3dfm/graph_utils.py @@ -7,7 +7,7 @@ import pandas as pd from shapely.geometry import Point -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = ["gpd_to_digraph", "get_endnodes_from_lines"] diff --git a/hydromt_delft3dfm/mesh_utils.py b/hydromt_delft3dfm/mesh_utils.py index 60d6cdb2..ffe13961 100644 --- a/hydromt_delft3dfm/mesh_utils.py +++ b/hydromt_delft3dfm/mesh_utils.py @@ -13,7 +13,7 @@ # TODO: maybe move this function here instead of under workflows? from hydromt_delft3dfm.workflows.mesh import _set_link1d2d -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = [ diff --git a/hydromt_delft3dfm/workflows/boundaries.py b/hydromt_delft3dfm/workflows/boundaries.py index 47c11e4f..fc62c192 100644 --- a/hydromt_delft3dfm/workflows/boundaries.py +++ b/hydromt_delft3dfm/workflows/boundaries.py @@ -11,7 +11,7 @@ from hydromt_delft3dfm import graph_utils -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = [ "get_boundaries_with_nodeid", diff --git a/hydromt_delft3dfm/workflows/branches.py b/hydromt_delft3dfm/workflows/branches.py index 1afd3780..d726e120 100644 --- a/hydromt_delft3dfm/workflows/branches.py +++ b/hydromt_delft3dfm/workflows/branches.py @@ -16,7 +16,7 @@ from ..gis_utils import cut_pieces, split_lines -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = [ diff --git a/hydromt_delft3dfm/workflows/crosssections.py b/hydromt_delft3dfm/workflows/crosssections.py index c4964dd4..9ce7d48d 100644 --- a/hydromt_delft3dfm/workflows/crosssections.py +++ b/hydromt_delft3dfm/workflows/crosssections.py @@ -12,7 +12,7 @@ from ..gis_utils import check_gpd_attributes from .branches import find_nearest_branch, update_data_columns_attributes -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = [ diff --git a/hydromt_delft3dfm/workflows/dem.py b/hydromt_delft3dfm/workflows/dem.py index d79a7af1..2951c4a7 100644 --- a/hydromt_delft3dfm/workflows/dem.py +++ b/hydromt_delft3dfm/workflows/dem.py @@ -13,7 +13,7 @@ from scipy import ndimage from shapely.geometry import Point -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = ["invert_levels_from_dem", "get_river_bathymetry"] diff --git a/hydromt_delft3dfm/workflows/manholes.py b/hydromt_delft3dfm/workflows/manholes.py index 6fcb1e73..f029efee 100644 --- a/hydromt_delft3dfm/workflows/manholes.py +++ b/hydromt_delft3dfm/workflows/manholes.py @@ -7,7 +7,7 @@ from hydromt.gis._vector_utils import _nearest_merge from shapely.geometry import Point -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = [ diff --git a/hydromt_delft3dfm/workflows/mesh.py b/hydromt_delft3dfm/workflows/mesh.py index 89e1aaf6..dea035c2 100644 --- a/hydromt_delft3dfm/workflows/mesh.py +++ b/hydromt_delft3dfm/workflows/mesh.py @@ -24,7 +24,7 @@ from .. import mesh_utils as mutils -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = [ diff --git a/hydromt_delft3dfm/workflows/region.py b/hydromt_delft3dfm/workflows/region.py index 0d67aaca..1746be8a 100644 --- a/hydromt_delft3dfm/workflows/region.py +++ b/hydromt_delft3dfm/workflows/region.py @@ -11,7 +11,7 @@ "parse_region_geometry", ] -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") def parse_region_geometry( diff --git a/hydromt_delft3dfm/workflows/roughness.py b/hydromt_delft3dfm/workflows/roughness.py index 95a10597..cbe53d9c 100644 --- a/hydromt_delft3dfm/workflows/roughness.py +++ b/hydromt_delft3dfm/workflows/roughness.py @@ -4,7 +4,7 @@ import geopandas as gpd -logger = logging.getLogger(__name__) +logger = logging.getLogger("hydromt") __all__ = ["generate_roughness"] diff --git a/tests/test_hydromt.py b/tests/test_hydromt.py index 56e4c227..6c1c3405 100644 --- a/tests/test_hydromt.py +++ b/tests/test_hydromt.py @@ -70,7 +70,7 @@ def test_model_build(tmpdir, modelname): # Compare with model from examples folder # (need to read it again for proper geoms check) - mod1 = DFlowFMModel(root=root, mode="r")) + mod1 = DFlowFMModel(root=root, mode="r") mod1.read() root = join(EXAMPLEDIR, f"dflowfm_{modelname}") mod0 = DFlowFMModel(root=root, mode="r") From 59c0fcec9ffb29245b3f5956d27307c2270a31ef Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Wed, 23 Oct 2024 14:54:36 +0200 Subject: [PATCH 18/23] replaced logger by hydromt --- hydromt_delft3dfm/workflows/branches.py | 3 --- hydromt_delft3dfm/workflows/crosssections.py | 3 --- hydromt_delft3dfm/workflows/manholes.py | 1 - hydromt_delft3dfm/workflows/mesh.py | 1 - hydromt_delft3dfm/workflows/region.py | 4 ---- hydromt_delft3dfm/workflows/roughness.py | 5 ----- hydromt_delft3dfm/workflows/structures.py | 2 -- 7 files changed, 19 deletions(-) diff --git a/hydromt_delft3dfm/workflows/branches.py b/hydromt_delft3dfm/workflows/branches.py index d726e120..2503aaab 100644 --- a/hydromt_delft3dfm/workflows/branches.py +++ b/hydromt_delft3dfm/workflows/branches.py @@ -43,7 +43,6 @@ def prepare_branches( snap_offset: float = 0.0, allow_intersection_snapping: bool = False, allowed_columns: List[str] = [], - logger: logging.Logger = logger, ) -> Tuple[gpd.GeoDataFrame, gpd.GeoDataFrame]: """ Set all common steps to add branches type of objects. @@ -80,8 +79,6 @@ def prepare_branches( By default True. allowed_columns: list, optional List of columns to filter in branches GeoDataFrame - logger: logging.Logger, optional - Logger. Returns ------- diff --git a/hydromt_delft3dfm/workflows/crosssections.py b/hydromt_delft3dfm/workflows/crosssections.py index 9ce7d48d..991799ed 100644 --- a/hydromt_delft3dfm/workflows/crosssections.py +++ b/hydromt_delft3dfm/workflows/crosssections.py @@ -32,7 +32,6 @@ def prepare_default_friction_and_crosssection( friction_value: float = 0.023, crosssections_shape: Literal["rectangle", "circle"] = None, crosssections_value: Union[List[float], float] = None, - logger: logging.Logger = logger, ): """ Prepare the default uniform friction and crosssection for branches. @@ -60,8 +59,6 @@ def prepare_default_friction_and_crosssection( used for br_type == "pipe". If ``crosssections_shape`` = "rectangle", expects a list with [width, height] (e.g. [1.0, 1.0]) [m]. used for br_type == "river" or "channel". - logger: Logger, optional - Logger. Return ------ branches: gpd.GeoDataFrame diff --git a/hydromt_delft3dfm/workflows/manholes.py b/hydromt_delft3dfm/workflows/manholes.py index f029efee..b2a51ebb 100644 --- a/hydromt_delft3dfm/workflows/manholes.py +++ b/hydromt_delft3dfm/workflows/manholes.py @@ -21,7 +21,6 @@ def generate_manholes_on_branches( bedlevel_shift: float = 0.0, id_prefix: str = "", id_suffix: str = "", - logger=logging, ): """Generate manhole location and bedlevel from branches. diff --git a/hydromt_delft3dfm/workflows/mesh.py b/hydromt_delft3dfm/workflows/mesh.py index dea035c2..0cf7d508 100644 --- a/hydromt_delft3dfm/workflows/mesh.py +++ b/hydromt_delft3dfm/workflows/mesh.py @@ -164,7 +164,6 @@ def mesh2d_refine( gdf_polygon: gpd.GeoDataFrame = None, da_sample: xr.DataArray = None, steps: int = 1, - logger: logging.Logger = logger, ) -> Tuple[Union[xu.UgridDataArray, xu.UgridDataset], float]: """Refine mesh2d by adding new nodes and faces. diff --git a/hydromt_delft3dfm/workflows/region.py b/hydromt_delft3dfm/workflows/region.py index 1746be8a..828e6573 100644 --- a/hydromt_delft3dfm/workflows/region.py +++ b/hydromt_delft3dfm/workflows/region.py @@ -1,6 +1,5 @@ """Workflows to parse region for Delft3D-FM model.""" -import logging import geopandas as gpd from hydromt.model.processes.region import parse_region_geom @@ -11,13 +10,10 @@ "parse_region_geometry", ] -logger = logging.getLogger("hydromt") - def parse_region_geometry( region: dict, crs: CRS, - logger: logging.Logger = logger, ): """Parse hydromt stype region argument into region geometry.""" kind, region = parse_region_geom(region) diff --git a/hydromt_delft3dfm/workflows/roughness.py b/hydromt_delft3dfm/workflows/roughness.py index cbe53d9c..e4480d49 100644 --- a/hydromt_delft3dfm/workflows/roughness.py +++ b/hydromt_delft3dfm/workflows/roughness.py @@ -1,12 +1,7 @@ """Workflows to prepare roughness for Delft3D-FM model.""" -import logging - import geopandas as gpd -logger = logging.getLogger("hydromt") - - __all__ = ["generate_roughness"] diff --git a/hydromt_delft3dfm/workflows/structures.py b/hydromt_delft3dfm/workflows/structures.py index 2462328d..1af8e437 100644 --- a/hydromt_delft3dfm/workflows/structures.py +++ b/hydromt_delft3dfm/workflows/structures.py @@ -55,8 +55,6 @@ def prepare_1dstructures( snap_offset: float, optional Snapping tolerance to automatically snapping to branch. By default 0.0, no snapping is applied. - logger: logging.Logger, optional - Logger. Returns ------- From 8de2dfe3a420f209eebc1195a3b468755f10dc5b Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Wed, 23 Oct 2024 14:55:31 +0200 Subject: [PATCH 19/23] minimized diff --- tests/test_dflowfm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_dflowfm.py b/tests/test_dflowfm.py index a1fd14d1..5f629f92 100644 --- a/tests/test_dflowfm.py +++ b/tests/test_dflowfm.py @@ -50,7 +50,7 @@ def test_setup_mesh2d_refine(tmpdir): assert mesh1d.edge_coordinates.shape == (1732, 2) -def test_setup_channels():#tmpdir): +def test_setup_channels(tmpdir): # Instantiate a dummy model model = DFlowFMModel( root=join(EXAMPLEDIR, "dflowfm_local"), From 3dab7c68564fd2b76a2cf374d2d5e5ee915b907d Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Wed, 23 Oct 2024 14:56:22 +0200 Subject: [PATCH 20/23] minimized diff --- tests/test_dflowfm.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_dflowfm.py b/tests/test_dflowfm.py index 5f629f92..2f8d168e 100644 --- a/tests/test_dflowfm.py +++ b/tests/test_dflowfm.py @@ -58,7 +58,7 @@ def test_setup_channels(tmpdir): data_libs=[join(TESTDATADIR, "test_data.yaml")] ) model.read() - # model.set_root(tmpdir, mode="w") + model.set_root(tmpdir, mode="w") # setup_channels region = {'geom': join(TESTDATADIR, "local_data","1D_extent.geojson")} @@ -69,7 +69,6 @@ def test_setup_channels(tmpdir): crosssections_fn=crosssections_fn, crosssections_type='point' ) -# test_setup_channels() def test_write_structures(tmpdir): From 4c5ae23fa93b9659087d6bc3a68631982e5ac588 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Thu, 24 Oct 2024 17:17:41 +0200 Subject: [PATCH 21/23] renamed file --- tests/data/test_data.yaml | 235 -------------------------------------- 1 file changed, 235 deletions(-) delete mode 100644 tests/data/test_data.yaml diff --git a/tests/data/test_data.yaml b/tests/data/test_data.yaml deleted file mode 100644 index 7a83a6a6..00000000 --- a/tests/data/test_data.yaml +++ /dev/null @@ -1,235 +0,0 @@ -1D_branches: - data_type: GeoDataFrame - uri: local_data/1D_rivers.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 - data_adapter: - rename: - BRANCH_ID: branchid - BR_TYPE: branchtype -1D_rivers_xyzcrosssections: - data_type: GeoDataFrame - uri: local_data/1D_rivers_xyzcrosssections.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 - data_adapter: - rename: - ORDER: order - CRS_ID: crsid - Z: z -1D_rivers_pointcrosssections: - data_type: GeoDataFrame - uri: local_data/1D_rivers_pointcrosssections.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 - data_adapter: - rename: - id: crsid - TYPE: shape - WIDTH: width - HEIGHT: height - BEDLEVEL: shift -1d_manholes: - data_type: GeoDataFrame - uri: local_data/manholes.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 - data_adapter: - rename: - ID: manholeid - AREA: area - STR_AREA: streetArea -1d_bridges: - data_type: GeoDataFrame - uri: local_data/bridges.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 - data_adapter: - rename: - STRUC_ID: structure_id - STRUC_TYPE: structure_type - SHAPE: shape - WIDTH: width - HEIGHT: height - CLOSED: closed - BEDLEV: shift - LENGTH: length - FLOW_DIR: allowedflowdir - IN_LOSS: inletlosscoeff - OUT_LOSS: outletlosscoeff -1d_culverts: - data_type: GeoDataFrame - uri: local_data/culverts.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 - data_adapter: - rename: - STRUC_ID: structure_id - STRUC_TYPE: structure_type - SHAPE: shape - WIDTH: width - HEIGHT: height - CLOSED: closed - INVLEV_UP: leftlevel - INVLEV_DN: rightlevel - FLOW_DIR: allowedflowdir -1D_boundaries: - data_type: GeoDataFrame - uri: local_data/boundaries.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 -1D_boundaries_timeseries: - data_type: GeoDataset - uri: local_data/boundaries.geojson - driver: - name: geodataset_vector - options: - fn_data: local_data/boundaries_series.csv - metadata: - crs: 32647 -1D_laterals_points: - data_type: GeoDataFrame - uri: local_data/laterals_points.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 -1D_laterals_timeseries: - data_type: GeoDataset - uri: local_data/laterals_points.geojson - driver: - name: geodataset_vector - options: - fn_data: local_data/laterals_series.csv - metadata: - crs: 32647 - data_adapter: - rename: - 1D_laterals_timeseries: lateral_discharge -1D_laterals_polygons: - data_type: GeoDataFrame - uri: local_data/laterals_polygons.geojson - driver: - name: pyogrio - options: {} - metadata: - crs: 32647 -1D_laterals_polygons_timeseries: - data_type: GeoDataset - uri: local_data/laterals_polygons.geojson - driver: - name: geodataset_vector - options: - fn_data: local_data/laterals_series.csv - assert_gtype: Polygon - metadata: - crs: 32647 - data_adapter: - rename: - 1D_laterals_polygons_timeseries: lateral_discharge -roads: - data_type: RasterDataset - uri: local_data/roads.tiff - driver: - name: rasterio - options: {} - metadata: - crs: 32647 - data_adapter: - rename: - roads: steps -2D_boundary: - data_type: GeoDataFrame - uri: local_data/2d_boundary.geojson - driver: - name: pyogrio - options: {} - metadata: - notes: created by buffer the extent by aqrt(2) * res. Must contain boundary_id - if timeseries is specified - crs: 32647 -2D_boundary_timeseries: - data_type: DataFrame - uri: local_data/2dboundaries_series.csv - driver: - name: pandas - options: - index_col: time - parse_dates: true - dayfirst: true - metadata: - notes: time series data for the 2D boundary, must contain time as index and boundary_id - as columns -meteo_timeseries_T2: - data_type: DataFrame - uri: local_data/rainfall_series.csv - driver: - name: pandas - options: - index_col: 0 - parse_dates: true - metadata: - unit: mm day-1 - data_adapter: - rename: - T2_mm/day: precip -meteo_timeseries_T5: - data_type: DataFrame - uri: local_data/rainfall_series.csv - driver: - name: pandas - options: - index_col: 0 - parse_dates: true - metadata: - unit: mm day-1 - data_adapter: - rename: - T5_mm/day: precip -dem: - data_type: RasterDataset - uri: local_data/dem.tif - driver: - name: rasterio - options: {} - metadata: - category: dem - history: temporary dem within model extent - crs: 4326 - data_adapter: - rename: - dem: elevtn -roughness_manning: - data_type: RasterDataset - uri: local_data/frictioncoefficient.tif - driver: - name: rasterio - options: {} - metadata: - category: roughness_manning - crs: 32647 - data_adapter: - rename: - frictioncoefficient: roughness_manning From 83ea0cfa2232a221984d3f65646cf72b2ba9e081 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Thu, 24 Oct 2024 17:19:15 +0200 Subject: [PATCH 22/23] updated catalog again --- tests/data/data_catalog_local.yaml | 317 +++++++++++++++++------------ 1 file changed, 190 insertions(+), 127 deletions(-) diff --git a/tests/data/data_catalog_local.yaml b/tests/data/data_catalog_local.yaml index 81aba620..7a83a6a6 100644 --- a/tests/data/data_catalog_local.yaml +++ b/tests/data/data_catalog_local.yaml @@ -1,172 +1,235 @@ 1D_branches: data_type: GeoDataFrame - driver: vector - path: local_data/1D_rivers.geojson - crs: 32647 - rename: - BRANCH_ID: branchid - BR_TYPE: branchtype + uri: local_data/1D_rivers.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + BRANCH_ID: branchid + BR_TYPE: branchtype 1D_rivers_xyzcrosssections: data_type: GeoDataFrame - driver: vector - path: local_data/1D_rivers_xyzcrosssections.geojson - crs: 32647 - rename: - ORDER: order - CRS_ID: crsid - Z: z + uri: local_data/1D_rivers_xyzcrosssections.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + ORDER: order + CRS_ID: crsid + Z: z 1D_rivers_pointcrosssections: data_type: GeoDataFrame - driver: vector - path: local_data/1D_rivers_pointcrosssections.geojson - crs: 32647 - rename: - id: crsid - TYPE: shape - WIDTH: width - HEIGHT: height - BEDLEVEL: shift + uri: local_data/1D_rivers_pointcrosssections.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + id: crsid + TYPE: shape + WIDTH: width + HEIGHT: height + BEDLEVEL: shift 1d_manholes: data_type: GeoDataFrame - driver: vector - path: local_data/manholes.geojson - crs: 32647 - rename: - ID: manholeid - AREA: area - STR_AREA: streetArea + uri: local_data/manholes.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + ID: manholeid + AREA: area + STR_AREA: streetArea 1d_bridges: data_type: GeoDataFrame - driver: vector - path: local_data/bridges.geojson - crs: 32647 - rename: - STRUC_ID: structure_id - STRUC_TYPE: structure_type - SHAPE: shape - WIDTH: width - HEIGHT: height - CLOSED: closed - BEDLEV: shift - LENGTH: length - FLOW_DIR: allowedflowdir - IN_LOSS: inletlosscoeff - OUT_LOSS: outletlosscoeff + uri: local_data/bridges.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + STRUC_ID: structure_id + STRUC_TYPE: structure_type + SHAPE: shape + WIDTH: width + HEIGHT: height + CLOSED: closed + BEDLEV: shift + LENGTH: length + FLOW_DIR: allowedflowdir + IN_LOSS: inletlosscoeff + OUT_LOSS: outletlosscoeff 1d_culverts: data_type: GeoDataFrame - driver: vector - path: local_data/culverts.geojson - crs: 32647 - rename: - STRUC_ID: structure_id - STRUC_TYPE: structure_type - SHAPE: shape - WIDTH: width - HEIGHT: height - CLOSED: closed - INVLEV_UP: leftlevel - INVLEV_DN: rightlevel - FLOW_DIR: allowedflowdir + uri: local_data/culverts.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + STRUC_ID: structure_id + STRUC_TYPE: structure_type + SHAPE: shape + WIDTH: width + HEIGHT: height + CLOSED: closed + INVLEV_UP: leftlevel + INVLEV_DN: rightlevel + FLOW_DIR: allowedflowdir 1D_boundaries: data_type: GeoDataFrame - driver: vector - path: local_data/boundaries.geojson - crs: 32647 + uri: local_data/boundaries.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 1D_boundaries_timeseries: - path: local_data/boundaries.geojson data_type: GeoDataset - driver: vector - crs: 32647 - kwargs: - fn_data: local_data/boundaries_series.csv + uri: local_data/boundaries.geojson + driver: + name: geodataset_vector + options: + fn_data: local_data/boundaries_series.csv + metadata: + crs: 32647 1D_laterals_points: data_type: GeoDataFrame - driver: vector - path: local_data/laterals_points.geojson - crs: 32647 + uri: local_data/laterals_points.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 1D_laterals_timeseries: - path: local_data/laterals_points.geojson data_type: GeoDataset - driver: vector - crs: 32647 - rename: - 1D_laterals_timeseries: lateral_discharge - kwargs: - fn_data: local_data/laterals_series.csv + uri: local_data/laterals_points.geojson + driver: + name: geodataset_vector + options: + fn_data: local_data/laterals_series.csv + metadata: + crs: 32647 + data_adapter: + rename: + 1D_laterals_timeseries: lateral_discharge 1D_laterals_polygons: data_type: GeoDataFrame - driver: vector - path: local_data/laterals_polygons.geojson - crs: 32647 + uri: local_data/laterals_polygons.geojson + driver: + name: pyogrio + options: {} + metadata: + crs: 32647 1D_laterals_polygons_timeseries: - path: local_data/laterals_polygons.geojson data_type: GeoDataset - driver: vector - crs: 32647 - rename: - 1D_laterals_polygons_timeseries: lateral_discharge - kwargs: - fn_data: local_data/laterals_series.csv - assert_gtype: Polygon + uri: local_data/laterals_polygons.geojson + driver: + name: geodataset_vector + options: + fn_data: local_data/laterals_series.csv + assert_gtype: Polygon + metadata: + crs: 32647 + data_adapter: + rename: + 1D_laterals_polygons_timeseries: lateral_discharge roads: - path: local_data/roads.tiff data_type: RasterDataset - crs: 32647 - rename: - roads: steps + uri: local_data/roads.tiff + driver: + name: rasterio + options: {} + metadata: + crs: 32647 + data_adapter: + rename: + roads: steps 2D_boundary: data_type: GeoDataFrame - driver: vector - path: local_data/2d_boundary.geojson - crs: 32647 - meta: - notes: created by buffer the extent by aqrt(2) * res. Must contain boundary_id if timeseries is specified + uri: local_data/2d_boundary.geojson + driver: + name: pyogrio + options: {} + metadata: + notes: created by buffer the extent by aqrt(2) * res. Must contain boundary_id + if timeseries is specified + crs: 32647 2D_boundary_timeseries: data_type: DataFrame - driver: csv - path: local_data/2dboundaries_series.csv - kwargs: + uri: local_data/2dboundaries_series.csv + driver: + name: pandas + options: index_col: time parse_dates: true dayfirst: true - meta: - notes: time series data for the 2D boundary, must contain time as index and boundary_id as columns + metadata: + notes: time series data for the 2D boundary, must contain time as index and boundary_id + as columns meteo_timeseries_T2: - path: local_data/rainfall_series.csv data_type: DataFrame - driver: csv - rename: - T2_mm/day: precip - kwargs: - index_col: 0 - parse_dates: True - meta: + uri: local_data/rainfall_series.csv + driver: + name: pandas + options: + index_col: 0 + parse_dates: true + metadata: unit: mm day-1 + data_adapter: + rename: + T2_mm/day: precip meteo_timeseries_T5: - path: local_data/rainfall_series.csv data_type: DataFrame - driver: csv - rename: - T5_mm/day: precip - kwargs: - index_col: 0 - parse_dates: True - meta: + uri: local_data/rainfall_series.csv + driver: + name: pandas + options: + index_col: 0 + parse_dates: true + metadata: unit: mm day-1 + data_adapter: + rename: + T5_mm/day: precip dem: - path: local_data/dem.tif data_type: RasterDataset - crs: 4326 - rename: - dem: elevtn - meta: + uri: local_data/dem.tif + driver: + name: rasterio + options: {} + metadata: category: dem history: temporary dem within model extent + crs: 4326 + data_adapter: + rename: + dem: elevtn roughness_manning: - path: local_data/frictioncoefficient.tif data_type: RasterDataset - crs: 32647 - rename: - frictioncoefficient: roughness_manning - meta: - category: roughness_manning \ No newline at end of file + uri: local_data/frictioncoefficient.tif + driver: + name: rasterio + options: {} + metadata: + category: roughness_manning + crs: 32647 + data_adapter: + rename: + frictioncoefficient: roughness_manning From f067867a5b31b997351c6fa67f02e93ba079a3b9 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Thu, 24 Oct 2024 18:20:37 +0200 Subject: [PATCH 23/23] resolved some simple bugs --- hydromt_delft3dfm/dflowfm.py | 36 +++++++++++++++++++++++------------- tests/test_dflowfm.py | 4 ++-- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/hydromt_delft3dfm/dflowfm.py b/hydromt_delft3dfm/dflowfm.py index c06764eb..38707d8c 100644 --- a/hydromt_delft3dfm/dflowfm.py +++ b/hydromt_delft3dfm/dflowfm.py @@ -196,6 +196,16 @@ def __init__( self._crs = CRS.from_user_input(crs) if crs else None self._check_crs() + # TODO: three class functions that were deprecated in hydromt v1 + def _read(self): + return self.root.is_reading_mode() + + def _assert_read_mode(self): + assert self.root.is_reading_mode() + + def _assert_write_mode(self): + assert self.root.is_writing_mode() + def setup_region(self, region): """HYDROMT CORE METHOD NOT USED FOR DFlowFMModel.""" raise ValueError( @@ -2927,7 +2937,7 @@ def write_config(self) -> None: cf_dict = self._config.copy() # Need to switch to dflowfm folder for files to be found and properly added mdu_fn = cf_dict.pop("filepath", None) - mdu_fn = Path(join(self.root, self._config_fn)) + mdu_fn = Path(join(self.root.path, self._config_fn)) cwd = os.getcwd() os.chdir(dirname(mdu_fn)) mdu = FMModel(**cf_dict) @@ -2972,7 +2982,7 @@ def read_maps(self) -> Dict[str, Union[xr.Dataset, xr.DataArray]]: # does not parse correclty the relative path # For now re-update manually.... if not isfile(_fn): - _fn = join(self.root, "maps", _fn.name) + _fn = join(self.root.path, "maps", _fn.name) inimap = hydromt.io.open_raster(_fn) name = inidict.quantity # Need to get branchid from config @@ -3009,7 +3019,7 @@ def write_maps(self) -> None: return self._assert_write_mode() # Global parameters - mapsroot = join(self.root, "maps") + mapsroot = join(self.root.path, "maps") inilist = [] paramlist = [] logger.info(f"Writing maps files to {mapsroot}") @@ -3091,7 +3101,7 @@ def _prepare_inifields(da_dict, da): inifield_model.parameter[i].datafile.filepath = path # Write inifield file inifield_model_filename = inifield_model._filename() + ".ini" - fm_dir = dirname(join(self.root, self._config_fn)) + fm_dir = dirname(join(self.root.path, self._config_fn)) inifield_model.save( join(fm_dir, inifield_model_filename), recurse=False, @@ -3153,7 +3163,7 @@ def write_geoms(self, write_mesh_gdf=True) -> None: super().write_geoms(fn="geoms/{name}.geojson") # Write dfm files - savedir = dirname(join(self.root, self._config_fn)) + savedir = dirname(join(self.root.path, self._config_fn)) # Write cross-sections (inc. friction) if "crosssections" in self._geoms: @@ -3288,7 +3298,7 @@ def write_forcing(self) -> None: else: self._assert_write_mode() logger.info("Writting forcing files.") - savedir = dirname(join(self.root, self._config_fn)) + savedir = dirname(join(self.root.path, self._config_fn)) # create new external forcing file ext_fn = "bnd.ext" Path(join(savedir, ext_fn)).unlink(missing_ok=True) @@ -3309,7 +3319,7 @@ def read_mesh(self): # FIXME: crs info is not available in dfmmodel, so get it from region.geojson # Cannot use read_geoms yet because for some some geoms # (crosssections, manholes) mesh needs to be read first... - region_fn = join(self.root, "geoms", "region.geojson") + region_fn = join(self.root.path, "geoms", "region.geojson") if (not self._crs) and isfile(region_fn): crs = gpd.read_file(region_fn).crs self._crs = crs @@ -3346,7 +3356,7 @@ def read_mesh(self): def write_mesh(self, write_gui=True): """Write 1D branches and 2D mesh at .""" self._assert_write_mode() - savedir = join(self.root, "dflowfm") + savedir = join(self.root.path, "dflowfm") mesh_filename = "fm_net.nc" # write mesh @@ -3448,8 +3458,8 @@ def dfmmodel(self): def init_dfmmodel(self): """Initialise the hydrolib-core FMModel object.""" # create a new MDU-Model - mdu_fn = Path(join(self.root, self._config_fn)) - if isfile(mdu_fn) and self._read: + mdu_fn = Path(join(self.root.path, self._config_fn)) + if isfile(mdu_fn) and self._read(): logger.info(f"Reading mdu file at {mdu_fn}") self._dfmmodel = FMModel(filepath=mdu_fn) else: # use hydrolib template @@ -3468,7 +3478,7 @@ def dimr(self): def read_dimr(self, dimr_fn: Optional[str] = None) -> None: """Read DIMR from file and else create from hydrolib-core.""" if dimr_fn is None: - dimr_fn = join(self.root, self._dimr_fn) + dimr_fn = join(self.root.path, self._dimr_fn) # if file exist, read if isfile(dimr_fn) and self._read: logger.info(f"Reading dimr file at {dimr_fn}") @@ -3488,9 +3498,9 @@ def write_dimr(self, dimr_fn: Optional[str] = None): # force read self.dimr if dimr_fn is not None: - self._dimr.filepath = join(self.root, dimr_fn) + self._dimr.filepath = join(self.root.path, dimr_fn) else: - self._dimr.filepath = join(self.root, self._dimr_fn) + self._dimr.filepath = join(self.root.path, self._dimr_fn) if not self._read: # Updates the dimr file first before writing diff --git a/tests/test_dflowfm.py b/tests/test_dflowfm.py index 36130a10..7319f509 100644 --- a/tests/test_dflowfm.py +++ b/tests/test_dflowfm.py @@ -18,7 +18,7 @@ def test_read_write_config_empty_paths(tmpdir): model.read_config() # Check whether the path is an emtpy string # TODO: we temporarly put . in the example mdu, so this is now also here - assert model.config["output"]["outputdir"] == Path(".") + assert model._config["output"]["outputdir"] == Path(".") # write the mdu to read again model.write_config() @@ -29,7 +29,7 @@ def test_read_write_config_empty_paths(tmpdir): # Check whether the path is an emtpy string # TODO: should be an empty string: https://github.com/Deltares/HYDROLIB-core/issues/703 # then update this test: https://github.com/Deltares/hydromt_delft3dfm/issues/148 - assert model2.config["output"]["outputdir"] == Path(".") + assert model2._config["output"]["outputdir"] == Path(".") def test_setup_mesh2d_refine(tmpdir):