# pylint: disable=missing-module-docstring
import numpy
from hydpy.core import objecttools
from hydpy.core import parametertools
from hydpy.core.typingtools import *
from hydpy.models.whmod.whmod_constants import *
from hydpy.models.whmod import whmod_constants
from hydpy.models.whmod import whmod_masks
from hydpy.models.whmod import whmod_parameters
from hydpy.models.whmod import whmod_variables
[docs]
class Area(parametertools.Parameter):
"""Total area [m²]."""
NDIM: Final[Literal[0]] = 0
TYPE: Final = float
SPAN = (1e-10, None)
[docs]
class NmbZones(parametertools.NmbParameter):
"""Number of zones (hydrological response units) in a subbasin [-]."""
SPAN = (1, None)
[docs]
class ZoneArea(whmod_parameters.LandTypeCompleteParameter):
"""Zone area [m²]."""
TYPE: Final = float
SPAN = (0.0, None)
[docs]
class LandType(whmod_variables.MixinZones, parametertools.NameParameter):
"""Land cover type [-]."""
constants = whmod_constants.LANDTYPE_CONSTANTS
[docs]
class SoilType(whmod_variables.MixinZones, parametertools.NameParameter):
"""Soil type [-].
>>> from hydpy.models.whmod import *
>>> parameterstep()
>>> nmbzones(9)
>>> landtype(GRASS, DECIDUOUS, CORN, CONIFER, SPRINGWHEAT, WINTERWHEAT, SUGARBEETS,
... SEALED, WATER)
>>> soiltype(SAND, SAND_COHESIVE, LOAM, CLAY, SILT, PEAT, SAND, NONE, NONE)
>>> soiltype
soiltype(SAND, SAND_COHESIVE, LOAM, CLAY, SILT, PEAT, SAND, NONE, NONE)
>>> soiltype(SAND, SAND_COHESIVE, LOAM, CLAY, SILT, PEAT, NONE, NONE, NONE)
Traceback (most recent call last):
...
ValueError: While trying to set the values of parameter `soiltype` of element `?`, \
the following error occurred: The soil type of land type `SUGARBEETS` must not be \
`NONE`.
>>> soiltype
soiltype(?)
>>> soiltype(SAND, SAND_COHESIVE, LOAM, CLAY, SILT, PEAT, SAND, SAND, SAND)
Traceback (most recent call last):
...
ValueError: While trying to set the values of parameter `soiltype` of element \
`?`, the following error occurred: The soil type of land types `SEALED` and `WATER` \
must be `NONE`.
>>> soiltype
soiltype(?)
"""
constants = whmod_constants.SOILTYPE_CONSTANTS
mask = whmod_masks.LandTypeSoil()
def __call__(self, *args, **kwargs) -> None:
def _make_names() -> str:
value2name = whmod_constants.LANDTYPE_CONSTANTS.value2name
names = [value2name[l] for l in landtype[jdxs]]
return objecttools.Inflect.listing("land type", names)
try:
super().__call__(*args, **kwargs)
landtype = self.subpars.landtype.values
should_be_soil = (landtype != SEALED) * (landtype != WATER)
is_soil = self.values != NONE
if numpy.any(jdxs := should_be_soil * ~is_soil):
self._valueready = False
raise ValueError(
f"The soil type of {_make_names()} must not be `NONE`."
)
if numpy.any(jdxs := ~should_be_soil * is_soil):
self._valueready = False
raise ValueError(f"The soil type of {_make_names()} must be `NONE`.")
except BaseException:
objecttools.augment_excmessage(
"While trying to set the values of parameter "
f"{objecttools.elementphrase(self)}"
)
[docs]
class CisternSource(whmod_parameters.LandTypeNonWaterParameter):
"""A flag that indicates whether a zone's excess water (surface runoff or
percolation) is channelled into the cistern [-].."""
TYPE: Final = bool
SPAN = (False, True)
[docs]
class CisternCapacity(parametertools.Parameter):
"""Maximum water amount that can be collected in the cistern [m³]."""
NDIM: Final[Literal[0]] = 0
TYPE: Final = float
SPAN = (0.0, None)
[docs]
class InterceptionCapacity(parametertools.KeywordParameter2D):
"""Maximum interception storage [mm]."""
TYPE: Final = float
SPAN = (0.0, None)
columnnames = parametertools.MonthParameter.entrynames
rownames = whmod_constants.LANDTYPE_CONSTANTS.get_sortednames(
relevant=whmod_masks.LandTypeNonWater.relevant
)
[docs]
class DegreeDayFactor(whmod_parameters.LandTypeNonWaterParameter):
"""Degree day factor for snow melting [mm/T/K]."""
TYPE: Final = float
TIME = True
SPAN = (0.0, None)
[docs]
class AvailableFieldCapacity(whmod_parameters.SoilTypeParameter):
"""Maximum relative soil moisture content [mm/m]."""
SPAN = (0.0, None)
[docs]
class RootingDepth(whmod_parameters.LandTypeSoilParameter):
"""Maximum rooting depth [m]."""
TYPE: Final = float
SPAN = (0.0, None)
[docs]
class GroundwaterDepth(whmod_parameters.SoilTypeParameter):
"""Average groundwater depth [m]."""
SPAN = (0.0, None)
[docs]
class WithCapillaryRise(parametertools.Parameter):
"""Flag to turn on/off capillary rise [-]."""
NDIM: Final[Literal[0]] = 0
TYPE: Final = bool
[docs]
class CapillaryThreshold(whmod_parameters.SoilTypeParameter):
"""Relative soil moisture where the capillary rise starts [-]."""
SPAN = (0.0, None)
[docs]
class CapillaryLimit(whmod_parameters.SoilTypeParameter):
"""Relative soil moisture where the capillary rise reaches its maximum [-]."""
SPAN = (0.0, None)
[docs]
class IrrigationTrigger(parametertools.KeywordParameter2D):
"""Relative soil moisture below which irrigation starts [-]."""
TYPE: Final = float
SPAN = (0.0, 1.0)
columnnames = parametertools.MonthParameter.entrynames
rownames = whmod_constants.LANDTYPE_CONSTANTS.get_sortednames(
relevant=whmod_masks.LandTypeSoil.relevant
)
[docs]
def trim(self, lower: TrimHook = None, upper: TrimHook = None) -> bool:
r"""Trim |IrrigationTrigger| following
:math:`0 \leq IrrigationTrigger \leq IrrigationTarget \leq 1`.
>>> from hydpy.models.whmod import *
>>> parameterstep()
>>> trigger = irrigationtrigger
>>> trigger(
... grass=0.0,
... deciduous=0.0,
... corn=[0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 1.0, 1.3, 0.0, 0.0, 0.0, 0.0],
... conifer=0.0,
... springwheat=0.0,
... winterwheat=0.0,
... sugarbeets=0.0,
... )
>>> trigger.corn_jun, trigger.corn_jul, trigger.corn_aug
(0.7, 1.0, 1.0)
>>> irrigationtarget.corn_jun = 0.7
>>> irrigationtarget.corn_jul = 0.7
>>> trigger(
... grass=0.0,
... deciduous=0.0,
... corn=[0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 1.0, 1.3, 0.0, 0.0, 0.0, 0.0],
... conifer=0.0,
... springwheat=0.0,
... winterwheat=0.0,
... sugarbeets=0.0,
... )
>>> trigger = irrigationtrigger
>>> trigger.corn_jun, trigger.corn_jul, trigger.corn_aug
(0.7, 0.7, 1.0)
"""
if upper is None:
upper = self.subpars.irrigationtarget.values.copy()
upper[numpy.isnan(upper)] = 1.0
return super().trim(lower, upper)
[docs]
class IrrigationTarget(parametertools.KeywordParameter2D):
"""Relative soil moisture content at which irrigation ends [-]."""
TYPE: Final = float
SPAN = (0.0, 1.0)
columnnames = parametertools.MonthParameter.entrynames
rownames = whmod_constants.LANDTYPE_CONSTANTS.get_sortednames(
relevant=whmod_masks.LandTypeSoil.relevant
)
[docs]
def trim(self, lower: TrimHook = None, upper: TrimHook = None) -> bool:
r"""Trim |IrrigationTarget| following
:math:`0 \leq IrrigationTrigger \leq IrrigationTarget \leq 1`.
>>> from hydpy.models.whmod import *
>>> parameterstep()
>>> target = irrigationtarget
>>> target(
... grass=0.0,
... deciduous=0.0,
... corn=[0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.3, -0.1, 0.0, 0.0, 0.0, 0.0],
... conifer=0.0,
... springwheat=0.0,
... winterwheat=0.0,
... sugarbeets=0.0,
... )
>>> target.corn_jun, target.corn_jul, target.corn_aug
(0.7, 0.3, 0.0)
>>> irrigationtrigger.corn_jun = 0.7
>>> irrigationtrigger.corn_jul = 0.7
>>> target(
... grass=0.0,
... deciduous=0.0,
... corn=[0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.3, -0.1, 0.0, 0.0, 0.0, 0.0],
... conifer=0.0,
... springwheat=0.0,
... winterwheat=0.0,
... sugarbeets=0.0,
... )
>>> target = irrigationtarget
>>> target.corn_jun, target.corn_jul, target.corn_aug
(0.7, 0.7, 0.0)
"""
if lower is None:
lower = self.subpars.irrigationtrigger.values.copy()
lower[numpy.isnan(lower)] = 0.0
return super().trim(lower, upper)
[docs]
class WithExternalIrrigation(parametertools.Parameter):
"""Flag to turn on/off external irrigation [-]."""
NDIM: Final[Literal[0]] = 0
TYPE: Final = bool
[docs]
class BaseflowIndex(whmod_parameters.LandTypeGroundwaterParameter):
"""Baseflow index [-]."""
TYPE: Final = float
SPAN = (0.0, 1.0)
[docs]
class RechargeDelay(parametertools.Parameter):
"""Delay between soil percolation and groundwater recharge [T]."""
NDIM: Final[Literal[0]] = 0
TYPE: Final = float
TIME = False
SPAN = (0.0, None)