Source code for hydroflows.methods.fiat.fiat_run

"""Method for running a FIAT model."""

import subprocess
from pathlib import Path
from typing import Literal, Optional

from pydantic import model_validator

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


[docs] class Input(Parameters): """Input parameters. This class represents the input data required for the :py:class:`FIATRun` method. """ # fiat_hazard: Path # """The path to the FIAT hazard or risk (NetCDF) file.""" fiat_cfg: FileDirPath """The file path to the FIAT configuration (toml) file from the FIAT model that needs to be run."""
[docs] class Output(Parameters): """Output parameters. This class represents the output data generated by the :py:class:`FIATRun` method. """ fiat_out_gpkg: FileDirPath """The resulting spatial file from the fiat calculations.""" fiat_out_csv: Path """The resulting csv file from the fiat calculations."""
[docs] class Params(Parameters): """Parameters. Instances of this class are used in the :py:class:`FIATRun` method to define the required settings. """ run_method: Literal["exe", "python"] = "exe" """How to run the FIAT model. Options are 'exe' for running the executable directly (only on Windows), 'python' for running the model in a Python environment.""" fiat_exe: Optional[Path] = None """The path to the FIAT executable.""" threads: int = 1 """The number of the threads to be used.""" @model_validator(mode="after") def check_fiat_exe(self): """Check the FIAT binary path.""" if self.run_method == "exe" and self.fiat_exe is None: raise ValueError("FIAT binary path is required when run_method is 'exe'.") return self
[docs] class FIATRun(Method): """Method for running a FIAT model. Parameters ---------- fiat_cfg : Path Path to the FIAT config file. run_method : Literal["exe", "python"] How to run the FIAT model. Options are 'exe' for running the executable directly (only on Windows), 'python' for running the model in a Python environment. fiat_exe : Path Path to the FIAT executable **params Additional parameters to pass to the FIATRun instance. See :py:class:`fiat_run Params <hydroflows.methods.fiat.fiat_run.Params>`. See Also -------- :py:class:`fiat_run Input <hydroflows.methods.fiat.fiat_run.Input>` :py:class:`fiat_run Output <hydroflows.methods.fiat.fiat_run.Output>` :py:class:`fiat_run Params <hydroflows.methods.fiat.fiat_run.Params>` """ name: str = "fiat_run" _test_kwargs = { "fiat_cfg": Path("fiat.toml"), "fiat_exe": Path("fiat.exe"), } def __init__( self, fiat_cfg: Path, run_method: Literal["exe", "python"] = "exe", fiat_exe: Optional[Path] = None, **params, ): self.params: Params = Params(fiat_exe=fiat_exe, run_method=run_method, **params) self.input: Input = Input(fiat_cfg=fiat_cfg) self.output: Output = Output( fiat_out_gpkg=self.input.fiat_cfg.parent / "output" / "spatial.gpkg", fiat_out_csv=self.input.fiat_cfg.parent / "output" / "output.csv", ) # TODO check if cfg matches output def _run(self): """Run the FIATRun method.""" # Get basic info cwd = self.input.fiat_cfg.parent fiat_cfg_path = self.input.fiat_cfg.name entrypoint = ( "fiat" if self.params.run_method == "python" else self.params.fiat_exe.as_posix() ) # Setup the cli command command = [ entrypoint, "run", fiat_cfg_path, "-t", str(self.params.threads), ] # Execute the rule subprocess.run(command, check=True, cwd=cwd)