From a9d980e8893cec46cab3fa376221910286fa8fcb Mon Sep 17 00:00:00 2001 From: roeldegoede Date: Wed, 5 Jul 2023 17:07:53 +0200 Subject: [PATCH 1/4] Create constant infiltration rates based on lulc and reclass_table --- docs/changelog.rst | 1 + hydromt_sfincs/sfincs.py | 43 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 7497a84d..7bf4b9ca 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -21,6 +21,7 @@ New - `SfincsModel.setup_cn_infiltration_with_kr` to setup three layers related to the curve number (maximum and effective infiltration capacity; seff and smax) and recovery rate (kr). PR#87 - `SfincsModelsetup_drainage_structures` to setup drainage structures (pumps,culverts) from a geodataframe. PR#90 - Added `SfincsModel.setup_wind_forcing`, `SfincsModel.setup_wind_forcing_from_grid` and `SfincsModel.setup_pressure_forcing_from_grid` methods to easily add wind and pressure forcing. PR #92 +- Added the option to use landuse/landcover data combined with a reclass table to `SfincsModel.setup_constant_infiltration`. v1.0 (17 April 2023) ==================== diff --git a/hydromt_sfincs/sfincs.py b/hydromt_sfincs/sfincs.py index 8025ac91..531fe0e2 100644 --- a/hydromt_sfincs/sfincs.py +++ b/hydromt_sfincs/sfincs.py @@ -939,7 +939,13 @@ def setup_river_outflow( self.set_geoms(gdf_riv, name="rivers_outflow") # Function to create constant spatially varying infiltration - def setup_constant_infiltration(self, qinf, reproj_method="average"): + def setup_constant_infiltration( + self, + qinf=None, + lulc=None, + reclass_table=None, + reproj_method="average", + ): """Setup spatially varying constant infiltration rate (qinffile). Adds model layers: @@ -950,14 +956,45 @@ def setup_constant_infiltration(self, qinf, reproj_method="average"): ---------- qinf : str, Path, or RasterDataset Spatially varying infiltration rates [mm/hr] + lulc: str, Path, or RasterDataset + Landuse/landcover data set + reclass_table: str, Path, or pd.DataFrame + Reclassification table to convert landuse/landcover to infiltration rates [mm/hr] reproj_method : str, optional Resampling method for reprojecting the infiltration data to the model grid. By default 'average'. For more information see, :py:meth:`hydromt.raster.RasterDataArray.reproject_like` """ # get infiltration data - da_inf = self.data_catalog.get_rasterdataset(qinf, geom=self.region, buffer=10) - da_inf = da_inf.raster.mask_nodata() # set nodata to nan + if qinf is not None: + da_inf = self.data_catalog.get_rasterdataset( + qinf, + bbox=self.mask.raster.transform_bounds(4326), + buffer=10, + ) + da_inf = da_inf.raster.mask_nodata() # set nodata to nan + elif lulc is not None: + # landuse/landcover should always be combined with mapping + if reclass_table is None and isinstance(lulc, str): + reclass_table = join(DATADIR, "qinf", f"{lulc}_mapping.csv") + if ( + not os.path.isfile(reclass_table) + and reclass_table not in self.data_catalog + ): + raise IOError(f"Infiltration mapping file not found: {reclass_table}") + da_lulc = self.data_catalog.get_rasterdataset( + lulc, + bbox=self.mask.raster.transform_bounds(4326), + buffer=10, + variables=["lulc"], + ) + df_map = self.data_catalog.get_dataframe(reclass_table, index_col=0) + # reclassify + da_inf = da_lulc.raster.reclassify(df_map[["qinf"]])["qinf"] + else: + raise ValueError( + "Either qinf or lulc must be provided when setting up constant infiltration." + ) # reproject infiltration data to model grid da_inf = da_inf.raster.reproject_like(self.mask, method=reproj_method) From 9ab8b6fd4aefd6ba7d1b44ac5ddaa27868980aea Mon Sep 17 00:00:00 2001 From: roeldegoede Date: Wed, 5 Jul 2023 17:11:19 +0200 Subject: [PATCH 2/4] add pull-request nr to changelog --- docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 7bf4b9ca..fcf945f8 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -21,7 +21,7 @@ New - `SfincsModel.setup_cn_infiltration_with_kr` to setup three layers related to the curve number (maximum and effective infiltration capacity; seff and smax) and recovery rate (kr). PR#87 - `SfincsModelsetup_drainage_structures` to setup drainage structures (pumps,culverts) from a geodataframe. PR#90 - Added `SfincsModel.setup_wind_forcing`, `SfincsModel.setup_wind_forcing_from_grid` and `SfincsModel.setup_pressure_forcing_from_grid` methods to easily add wind and pressure forcing. PR #92 -- Added the option to use landuse/landcover data combined with a reclass table to `SfincsModel.setup_constant_infiltration`. +- Added the option to use landuse/landcover data combined with a reclass table to `SfincsModel.setup_constant_infiltration`. PR #103 v1.0 (17 April 2023) ==================== From 990cdea58994278d31ba6f29ab714526153d76bb Mon Sep 17 00:00:00 2001 From: Dirk Eilander Date: Sun, 9 Jul 2023 16:08:11 +0200 Subject: [PATCH 3/4] small fixes --- hydromt_sfincs/sfincs.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/hydromt_sfincs/sfincs.py b/hydromt_sfincs/sfincs.py index 531fe0e2..8ab2b2e3 100644 --- a/hydromt_sfincs/sfincs.py +++ b/hydromt_sfincs/sfincs.py @@ -972,31 +972,34 @@ def setup_constant_infiltration( bbox=self.mask.raster.transform_bounds(4326), buffer=10, ) - da_inf = da_inf.raster.mask_nodata() # set nodata to nan elif lulc is not None: # landuse/landcover should always be combined with mapping if reclass_table is None and isinstance(lulc, str): - reclass_table = join(DATADIR, "qinf", f"{lulc}_mapping.csv") - if ( - not os.path.isfile(reclass_table) - and reclass_table not in self.data_catalog - ): - raise IOError(f"Infiltration mapping file not found: {reclass_table}") + reclass_table = join(DATADIR, "lulc", f"{lulc}_mapping.csv") + if reclass_table is None: + raise IOError( + f"Infiltration mapping file should be provided for {lulc}" + ) da_lulc = self.data_catalog.get_rasterdataset( lulc, bbox=self.mask.raster.transform_bounds(4326), buffer=10, variables=["lulc"], ) - df_map = self.data_catalog.get_dataframe(reclass_table, index_col=0) + df_map = self.data_catalog.get_dataframe( + reclass_table, + variables=["qinf"], + index_col=0, # driver kwargs + ) # reclassify - da_inf = da_lulc.raster.reclassify(df_map[["qinf"]])["qinf"] + da_inf = da_lulc.raster.reclassify(df_map)["qinf"] else: raise ValueError( "Either qinf or lulc must be provided when setting up constant infiltration." ) # reproject infiltration data to model grid + da_inf = da_inf.raster.mask_nodata() # set nodata to nan da_inf = da_inf.raster.reproject_like(self.mask, method=reproj_method) # check on nan values From 98ccc28008bc7b6abb55eb26448ce9fbf864608d Mon Sep 17 00:00:00 2001 From: roeldegoede Date: Wed, 12 Jul 2023 10:15:21 +0200 Subject: [PATCH 4/4] reclass table should always be provided for infiltration --- hydromt_sfincs/sfincs.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/hydromt_sfincs/sfincs.py b/hydromt_sfincs/sfincs.py index 8ab2b2e3..037fa671 100644 --- a/hydromt_sfincs/sfincs.py +++ b/hydromt_sfincs/sfincs.py @@ -974,8 +974,6 @@ def setup_constant_infiltration( ) elif lulc is not None: # landuse/landcover should always be combined with mapping - if reclass_table is None and isinstance(lulc, str): - reclass_table = join(DATADIR, "lulc", f"{lulc}_mapping.csv") if reclass_table is None: raise IOError( f"Infiltration mapping file should be provided for {lulc}"