diff --git a/python/ngen_cal/src/ngen/cal/calibration_cathment.py b/python/ngen_cal/src/ngen/cal/calibration_cathment.py index 601f2814..7b46c9a3 100644 --- a/python/ngen_cal/src/ngen/cal/calibration_cathment.py +++ b/python/ngen_cal/src/ngen/cal/calibration_cathment.py @@ -1,11 +1,10 @@ from __future__ import annotations -from pandas import DataFrame, read_csv # type: ignore +import pandas as pd import shutil from typing import TYPE_CHECKING if TYPE_CHECKING: - from pandas import DataFrame from pathlib import Path from geopandas import GeoSeries from datetime import datetime @@ -33,7 +32,7 @@ def __init__(self, workdir: Path, id: str, nexus, params: dict = {}): """ FormulatableCatchment.__init__(self=self, catchment_id=id, params=params, outflow=nexus) - Adjustable.__init__(self=self, df=DataFrame(params).rename(columns={'init': '0'})) + Adjustable.__init__(self=self, df=pd.DataFrame(params).rename(columns={'init': '0'})) #FIXME paramterize self._output_file = workdir/f'{self.id}.csv' self._workdir = workdir @@ -86,7 +85,7 @@ def evaluation_range(self) -> tuple[datetime, datetime] | None: return self._eval_range @property - def output(self) -> DataFrame: + def output(self) -> pd.DataFrame: """ The model output hydrograph for this catchment This re-reads the output file each call, as the output for given calibration catchment changes @@ -94,7 +93,7 @@ def output(self) -> DataFrame: """ try: #FIXME get the output variable from config - self._output = read_csv(self._output_file, usecols=["Time", self._output_var], parse_dates=['Time'], index_col='Time', dtype={self._output_var: 'float64'}) + self._output = pd.read_csv(self._output_file, usecols=["Time", self._output_var], parse_dates=['Time'], index_col='Time', dtype={self._output_var: 'float64'}) self._output.rename(columns={self._output_var:'sim_flow'}, inplace=True) #FIXME make sure units are correct here... #Assumes model catchment outputs are in m/hr, convert to m^3/s @@ -113,7 +112,7 @@ def output(self, df): self._output = df @property - def observed(self) -> DataFrame: + def observed(self) -> pd.DataFrame: """ The observed hydrograph for this catchment FIXME move output/observed to calibratable? """ diff --git a/python/ngen_cal/tests/conftest.py b/python/ngen_cal/tests/conftest.py index 678b1cf8..32c06a48 100644 --- a/python/ngen_cal/tests/conftest.py +++ b/python/ngen_cal/tests/conftest.py @@ -175,7 +175,7 @@ def catchment(nexus, fabric, workdir, mocker) -> Generator[CalibrationCatchment, return catchment @pytest.fixture -def catchment2(nexus, fabric, workdir) -> Generator[CalibrationCatchment, None, None]: +def catchment2(nexus, fabric, workdir) -> CalibrationCatchment: """ A hy_features catchment implementing the calibratable interface Doesn't mock output, can be used to test semantics of erronous output diff --git a/python/ngen_cal/tests/test_calibration_catchment.py b/python/ngen_cal/tests/test_calibration_catchment.py index d13ee276..6e41b6fd 100644 --- a/python/ngen_cal/tests/test_calibration_catchment.py +++ b/python/ngen_cal/tests/test_calibration_catchment.py @@ -1,41 +1,52 @@ -import pytest +""" +Test suite for calibratable_catchment +""" + +from __future__ import annotations + from typing import TYPE_CHECKING +import pytest + if TYPE_CHECKING: from ngen.cal.calibration_cathment import CalibrationCatchment -""" - Test suite for calibratable_catchment -""" -@pytest.mark.usefixtures("catchment") -def test_df(catchment: 'CalibrationCatchment') -> None: +def test_df(catchment: CalibrationCatchment) -> None: """ - Test the catchments proper construction of the parameter dataframe + Test the catchments proper construction of the parameter dataframe """ - assert catchment.df.iloc[0]['param'] == 'some_param' - assert catchment.df.iloc[0]['0'] == 0.5 - assert catchment.df.iloc[0]['min'] == 0.0 - assert catchment.df.iloc[0]['max'] == 1.0 + assert catchment.df.iloc[0]["param"] == "some_param" + assert catchment.df.iloc[0]["0"] == 0.5 + assert catchment.df.iloc[0]["min"] == 0.0 + assert catchment.df.iloc[0]["max"] == 1.0 -@pytest.mark.usefixtures("catchment2") -def test_output(catchment2: 'CalibrationCatchment', monkeypatch) -> None: + +def test_output( + catchment2: CalibrationCatchment, + monkeypatch: pytest.MonkeyPatch, +) -> None: """ - Test proper handling of non-existent output + Test proper handling of non-existent output """ import pandas as pd - monkeypatch.setattr(pd, "read_csv", lambda *args, **kwargs: FileNotFoundError()) + + def file_not_found(*args, **kwargs): + raise FileNotFoundError + + monkeypatch.setattr(pd, "read_csv", file_not_found) output = catchment2.output - assert output == None + assert output is None + -@pytest.mark.usefixtures("catchment") -def test_observed(catchment: 'CalibrationCatchment') -> None: +def test_observed(catchment: CalibrationCatchment) -> None: """ - Test proper handling of non-existent output + Test proper handling of non-existent output """ catchment.observed = None with pytest.raises(RuntimeError): - obs = catchment.observed + catchment.observed + -#TODO test catchment_set -#TODO test evaluation_range? +# TODO test catchment_set +# TODO test evaluation_range?