Source code for hydroflows.methods.sfincs.sfincs_postprocess

"""Postprocess SFINCS netcdf maximum water level (zsmax) output to a regular grid geotiff file."""

from pathlib import Path
from typing import Optional

from hydromt_sfincs import SfincsModel

from hydroflows._typing import OutputDirPath
from hydroflows.workflow.method import Method
from hydroflows.workflow.method_parameters import Parameters

__all__ = ["SfincsPostprocess", "Input", "Output", "Params"]


[docs] class Input(Parameters): """Input parameters for the :py:class:`SfincsPostprocess` method.""" sfincs_map: Path """The path to the SFINCS model output sfincs_map.nc file."""
[docs] class Output(Parameters): """Output parameters for the :py:class:`SfincsPostprocess` method.""" sfincs_zsmax: Path """The path to the output zsmax netcdf file."""
[docs] class Params(Parameters): """Parameters for the :py:class:`SfincsPostprocess` method.""" output_root: Optional[OutputDirPath] = None """The output directory where the hazard output files are saved.""" event_name: str """The name of the event, used to create the output filename."""
[docs] class SfincsPostprocess(Method): """Postprocess SFINCS netcdf maximum water level (zsmax) output to a regular grid geotiff file. output nc file is saved to {output_root}/zsmax_{event_name}.nc Parameters ---------- sfincs_map : Path The path to the SFINCS model output sfincs_map.nc file. event_name : str The name of the event, used to create the output filename. output_root : Optional[Path], optional The output directory where the hazard output files are saved. By default the output is saved in the same directory as the input. See Also -------- :py:class:`sfincs_downscale Input <hydroflows.methods.sfincs.sfincs_downscale.Input>` :py:class:`sfincs_downscale Output <hydroflows.methods.sfincs.sfincs_downscale.Output>` :py:class:`sfincs_downscale Params <hydroflows.methods.sfincs.sfincs_downscale.Params>` """ name: str = "sfincs_postprocess" _test_kwargs = { "sfincs_map": Path("tests_event/sfincs_map.nc"), } def __init__( self, sfincs_map: Path, event_name: Optional[str] = None, output_root: Optional[Path] = None, ) -> None: self.input: Input = Input(sfincs_map=sfincs_map) if output_root is None: output_root = self.input.sfincs_map.parent if event_name is None: # parent folder equals event name event_name = self.input.sfincs_map.parent.name self.params: Params = Params(output_root=output_root, event_name=event_name) # NOTE: unique output file name are required by HydroMT-FIAT hazard self.output: Output = Output( sfincs_zsmax=self.params.output_root / f"zsmax_{event_name}.nc" ) def _run(self): """Run the postprocessing.""" # unpack input, output and params root = self.input.sfincs_map.parent sf = SfincsModel(root, mode="r", write_gis=False) # Read the model results sf.read_results() if "zsmax" not in sf.results: raise KeyError(f"zsmax is missing in results of {self.input.sfincs_map}") # get zsmax and save to file witt "water_level" as variable name zsmax = sf.results["zsmax"].max(dim="timemax").rename("water_level") zsmax = zsmax.fillna(-9999.0) zsmax.raster.set_nodata(-9999.0) zsmax.attrs["units"] = "m" zsmax.to_netcdf( self.output.sfincs_zsmax, encoding={"water_level": {"zlib": True, "complevel": 4}}, ) del sf