parametertools

This module provides tools for defining and handling different kinds of the parameters of hydrological models.

Module parametertools implements the following members:


hydpy.core.parametertools.get_controlfileheader(model: Union[str, modeltools.Model], parameterstep: Optional[Union[Period, datetime.timedelta, str]] = None, simulationstep: Optional[Union[Period, datetime.timedelta, str]] = None)str[source]

Return the header of a regular or auxiliary parameter control file.

The header contains the default coding information, the import command for the given model and the actual parameter and simulation step sizes.

The first example shows that, if you pass the model argument as a string, you have to take care that this string makes sense:

>>> from hydpy.core.parametertools import get_controlfileheader
>>> from hydpy import Period, prepare_model, pub, Timegrids, Timegrid
>>> print(get_controlfileheader(model="no model class",
...                             parameterstep="-1h",
...                             simulationstep=Period("1h")))
# -*- coding: utf-8 -*-

from hydpy.models.no model class import *

simulationstep("1h")
parameterstep("-1h")

The second example shows the saver option to pass the proper model object. It also shows that function get_controlfileheader() tries to gain the parameter and simulation step sizes from the global Timegrids object contained in the module pub when necessary:

>>> model = prepare_model("lland_v1")
>>> pub.timegrids = "2000.01.01", "2001.01.01", "1h"
>>> print(get_controlfileheader(model=model))
# -*- coding: utf-8 -*-

from hydpy.models.lland_v1 import *

simulationstep("1h")
parameterstep("1d")

class hydpy.core.parametertools.IntConstant(value)[source]

Bases: int

Class for int objects with individual docstrings.

class hydpy.core.parametertools.Constants(*args, **kwargs)[source]

Bases: dict

Base class for defining integer constants for a specific model.

value2name: Dict[int, str]

Mapping from the the values of the constants to their names.

class hydpy.core.parametertools.Parameters(kwargs)[source]

Bases: object

Base class for handling all parameters of a specific model.

Parameters objects handle three parameter subgroups as attributes: the control subparameters, the derived subparameters, and the solver subparameters:

>>> from hydpy.models.hstream_v1 import *
>>> parameterstep("1d")
>>> bool(model.parameters.control)
True
>>> bool(model.parameters.solver)
False

Iterations makes only the non-empty subgroups available, which are actually handling Sequence_ objects:

>>> for subpars in model.parameters:
...     print(subpars.name)
control
derived
>>> len(model.parameters)
2
model: modeltools.Model
control: SubParameters
derived: SubParameters
fixed: SubParameters
solver: SubParameters
update()None[source]

Call method update() of all “secondary” parameters.

Directly after initialisation, neither the primary (control) parameters nor the secondary (derived) parameters of application model hstream_v1 are ready for usage:

>>> from hydpy.models.hstream_v1 import *
>>> parameterstep("1d")
>>> simulationstep("1d")
>>> derived
nmbsegments(?)
c1(?)
c3(?)
c2(?)

Trying to update the values of the secondary parameters while the primary ones are still not defined, raises errors like the following:

>>> model.parameters.update()
Traceback (most recent call last):
...
hydpy.core.exceptiontools.AttributeNotReady: While trying to update parameter `nmbsegments` of element `?`, the following error occurred: For variable `lag`, no value has been defined so far.

With proper values both for parameter Lag and Damp, updating the derived parameters succeeds:

>>> lag(0.0)
>>> damp(0.0)
>>> model.parameters.update()
>>> derived
nmbsegments(0)
c1(0.0)
c3(0.0)
c2(1.0)
save_controls(filepath: Optional[str] = None, parameterstep: Optional[Union[Period, datetime.timedelta, str]] = None, simulationstep: Optional[Union[Period, datetime.timedelta, str]] = None, auxfiler: Optional[auxfiletools.Auxfiler] = None)[source]

Write the control parameters to file.

Usually, a control file consists of a header (see the documentation on the method get_controlfileheader()) and the string representations of the individual Parameter objects handled by the control SubParameters object.

The main functionality of method save_controls() is demonstrated in the documentation on the method save_controls() of class HydPy, which one would apply to write the parameter information of complete HydPy projects. However, to call save_controls() on individual Parameters objects offers the advantage to choose an arbitrary file path, as shown in the following example:

>>> from hydpy.models.hstream_v1 import *
>>> parameterstep("1d")
>>> simulationstep("1h")
>>> lag(1.0)
>>> damp(0.5)
>>> from hydpy import Open
>>> with Open():
...     model.parameters.save_controls("otherdir/otherfile.py")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
otherdir/otherfile.py
-------------------------------------
# -*- coding: utf-8 -*-

from hydpy.models.hstream_v1 import *

simulationstep("1h")
parameterstep("1d")

lag(1.0)
damp(0.5)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Without a given file path and a proper project configuration, method save_controls() raises the following error:

>>> model.parameters.save_controls()
Traceback (most recent call last):
...
RuntimeError: To save the control parameters of a model to a file, its filename must be known.  This can be done, by passing a filename to function `save_controls` directly.  But in complete HydPy applications, it is usally assumed to be consistent with the name of the element handling the model.
verify()None[source]

Call method verify() of all Parameter objects handled by the actual model.

When calling method verify() directly after initialising model hstream_v1 (without using default values), it raises a RuntimeError due to the undefined value of control parameter Lag:

>>> from hydpy.models.hstream_v1 import *
>>> parameterstep("1d")
>>> simulationstep("1d")
>>> model.parameters.verify()
Traceback (most recent call last):
...
RuntimeError: For variable `lag`, 1 required value has not been set yet: lag(?).

Assigning a value to Lag is not sufficient:

>>> model.parameters.control.lag(0.0)
>>> model.parameters.verify()
Traceback (most recent call last):
...
RuntimeError: For variable `damp`, 1 required value has not been set yet: damp(?).

After also defining a suitable value for parameter Damp, the derived parameters are still not ready:

>>> model.parameters.control.damp(0.0)
>>> model.parameters.verify()
Traceback (most recent call last):
...
RuntimeError: For variable `c1`, 1 required value has not been set yet: c1(?).

After updating the derived parameters, method verify() has no reason to complain anymore:

>>> model.parameters.update()
>>> model.parameters.verify()
property secondary_subpars

Iterate through all subgroups of “secondary” parameters.

These secondary parameter subgroups are the derived parameters and the solver parameters, at the moment:

>>> from hydpy.models.hstream_v1 import *
>>> parameterstep("1d")
>>> for subpars in model.parameters.secondary_subpars:
...     print(subpars.name)
derived
solver
class hydpy.core.parametertools.FastAccessParameter[source]

Bases: hydpy.core.variabletools.FastAccess

Used as a surrogate for typed Cython classes handling parameters when working in pure Python mode.

class hydpy.core.parametertools.SubParameters(master: hydpy.core.parametertools.Parameters, cls_fastaccess: Optional[Type[hydpy.core.parametertools.FastAccessParameter]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]

Bases: hydpy.core.variabletools.SubVariables[hydpy.core.parametertools.Parameters, Parameter, hydpy.core.parametertools.FastAccessParameter]

Base class for handling subgroups of model parameters.

When trying to implement a new model, one has to define its specific Parameter subclasses. Currently, the HydPy framework distinguishes between control parameters, derived parameters, fixed parameters, and solver parameters. Each Parameter subclass is a member of a collection class derived from SubParameters, called “ControlParameters”, “DerivedParameters”, “FixedParameters”, or “SolverParameters”, respectively. Indicate membership by putting the parameter subclasses into the tuple “CLASSES”:

>>> from hydpy.core.parametertools import Parameter, SubParameters
>>> class Par2(Parameter):
...     """Parameter 2 [-]."""
...     NDIM = 1
...     TYPE = float
...     TIME = None
>>> class Par1(Parameter):
...     """Parameter 1 [-]."""
...     NDIM = 1
...     TYPE = float
...     TIME = None
>>> class ControlParameters(SubParameters):
...     """Control Parameters."""
...     CLASSES = (Par2,
...                Par1)

The order within the tuple determines the order of iteration:

>>> control = ControlParameters(None)
>>> control
par2(?)
par1(?)

Each SubParameters object has a fastaccess attribute. When working in pure Python mode, this is an instance of class FastAccessParameter:

>>> from hydpy import classname, prepare_model, pub
>>> with pub.options.usecython(False):
...     model = prepare_model("lland_v1")
>>> classname(model.parameters.control.fastaccess)
'FastAccessParameter'

When working in Cython mode (which is the default mode and much faster), fastaccess is an object of a Cython extension class specialised for the respective model and sequence group:

>>> with pub.options.usecython(True):
...     model = prepare_model("lland_v1")
>>> classname(model.parameters.control.fastaccess)
'ControlParameters'
property name

The class name in lower case letters omitting the last ten characters (“parameters”).

>>> from hydpy.core.parametertools import SubParameters
>>> class ControlParameters(SubParameters):
...     CLASSES = ()
>>> ControlParameters(None).name
'control'
exception hydpy.core.parametertools.KeywordArgumentsError[source]

Bases: RuntimeError

A specialised RuntimeError raised by class KeywordArguments.

class hydpy.core.parametertools.KeywordArguments(_KeywordArguments__valid: bool = True, **keywordarguments: T)[source]

Bases: Generic[hydpy.core.typingtools.T]

A handler for the keyword arguments of the instances of specific Parameter subclasses.

Class KeywordArguments is a rather elaborate feature of HydPy primarily thought for framework developers. One possible use-case for (advanced) HydPy users is writing polished auxiliary control files. When dealing with such a problem, have a look on method extend().

The purpose of class KeywordArguments is to simplify handling instances of Parameter subclasses which allow setting values by calling them with keyword arguments. When useful, instances of Parameter subclasses should return a valid KeywordArguments object via property keywordarguments. This object should contain the keyword arguments that, when passed to the same parameter instance or another parameter instance of the same type, sets it into an equal state. This is best explained by the following example based on parameter TRefT of application model lland_v1 (see the documentation on property keywordarguments of class ZipParameter for additional information):

>>> from hydpy.models.lland_v1 import *
>>> parameterstep()
>>> nhru(4)
>>> lnk(ACKER, LAUBW, WASSER, ACKER)
>>> treft(acker=2.0, laubw=1.0)
>>> treft.keywordarguments
KeywordArguments(acker=2.0, laubw=1.0)

You can initialise a KeywordArguments object on your own:

>>> from hydpy import KeywordArguments
>>> kwargs1 = KeywordArguments(acker=3.0, laubw=2.0, nadelw=1.0)
>>> kwargs1
KeywordArguments(acker=3.0, laubw=2.0, nadelw=1.0)

After preparing a KeywordArguments object, it is “valid” by default:

>>> kwargs1.valid
True

Pass False as a positional argument to the constructor if you want your KeywordArguments object to be invalid at first:

>>> kwargs2 = KeywordArguments(False)
>>> kwargs2
KeywordArguments()
>>> kwargs2.valid
False

Flag valid for example helps to distinguish between empty objects that are okay to be empty and those that are not. When we, for example, set all hydrological response units to land-use type WASSER (water), parameter TRefT returns the following valid KeywordArguments object, as its values do not need to be defined for water areas:

>>> lnk(WASSER)
>>> treft
treft(nan)
>>> treft.keywordarguments
KeywordArguments()
>>> treft.keywordarguments.valid
True

Class KeywordArguments supports features like iteration but raises the exception KeywordArgumentsError when trying to iterate an invalid object:

>>> for keyword, argument in kwargs1:
...     print(keyword, argument)
acker 3.0
laubw 2.0
nadelw 1.0
>>> for keyword, argument in kwargs2:
...     print(keyword, argument)
Traceback (most recent call last):
...
hydpy.core.parametertools.KeywordArgumentsError: Cannot iterate an invalid `KeywordArguments` object.

The same holds when trying to check if a specific keyword-value item is available:

>>> ("acker", 3.0) in kwargs1
True
>>> ("laubw", 3.0) in kwargs1
False
>>> ("?", "???") in kwargs1
False
>>> ("laubw", 3.0) in kwargs2
Traceback (most recent call last):
...
hydpy.core.parametertools.KeywordArgumentsError: Cannot check if an item is defined by an invalid `KeywordArguments` object.

However, keyword access is always possible:

>>> kwargs2["laubw"] = 3.0
>>> kwargs2["laubw"]
3.0
>>> del kwargs2["laubw"]
>>> kwargs2["laubw"]
Traceback (most recent call last):
...
KeyError: 'The current `KeywordArguments` object does not handle an argument under the keyword `laubw`.'
>>> del kwargs2["laubw"]
Traceback (most recent call last):
...
KeyError: 'The current `KeywordArguments` object does not handle an argument under the keyword `laubw`.'

Two KeywordArguments objects are considered equal if they have the same validity state, the same length, and if all items are equal:

>>> KeywordArguments(True) == KeywordArguments(False)
False
>>> KeywordArguments(x=1) == KeywordArguments(x=1, y=2)
False
>>> KeywordArguments(x=1, y=2) == KeywordArguments(x=1, y=3)
False
>>> KeywordArguments(x=1, y=2) == KeywordArguments(x=1, y=2)
True

You can also compare with other objects (always False) and use the “!=” operator:

>>> KeywordArguments() == "test"
False
>>> KeywordArguments(x=1, y=2) != KeywordArguments(x=1, y=2)
False
valid: bool

Flag indicating whether the actual KeywordArguments object is valid or not.

add(name: str, value: T)None[source]

Add a keyword argument.

Method add() works both for valid and invalid KeywordArguments objects without changing their validity status:

>>> from hydpy import KeywordArguments
>>> kwargs = KeywordArguments()
>>> kwargs.add("one", 1)
>>> kwargs.valid = False
>>> kwargs.add("two", 2)
>>> kwargs
KeywordArguments(one=1, two=2)

It raises the following error when (possibly accidentally) trying to overwrite an existing keyword argument:

>>> kwargs.add("one", 3)
Traceback (most recent call last):
...
hydpy.core.parametertools.KeywordArgumentsError: Cannot add argument value `3` of type `int` to the current `KeywordArguments` object as it already handles the unequal argument `1` under the keyword `one`.

On the other hand, redefining the save value causes no harm and thus does not trigger an exception:

>>> kwargs.add("one", 1)
>>> kwargs
KeywordArguments(one=1, two=2)
subset_of(other: hydpy.core.parametertools.KeywordArguments[T])bool[source]

Check if the actual KeywordArguments object is a subset of the given one.

First, we define the following (valid) KeywordArguments objects:

>>> from hydpy import KeywordArguments
>>> kwargs1 = KeywordArguments(a=1, b=2)
>>> kwargs2 = KeywordArguments(a= 1, b=2, c=3)
>>> kwargs3 = KeywordArguments(a= 1, b=3)

Method subset_of() requires that the keywords handled by the left KeywordArguments object form a subset of the keywords of the right KeywordArguments object:

>>> kwargs1.subset_of(kwargs2)
True
>>> kwargs2.subset_of(kwargs1)
False

Additionally, all values corresponding to the union of the relevant keywords must be equal:

>>> kwargs1.subset_of(kwargs3)
False

If at least one of both KeywordArguments is invalid, method subset_of() generally returns False:

>>> kwargs2.valid = False
>>> kwargs1.subset_of(kwargs2)
False
>>> kwargs2.subset_of(kwargs1)
False
>>> kwargs2.subset_of(kwargs2)
False
extend(parametertype: Type[Parameter], elements: Iterable[devicetools.Element], raise_exception: bool = True)None[source]

Extend the currently available keyword arguments based on the parameters of the given type handled by the given elements.

Sometimes (for example, when writing auxiliary control files) one is interested in a superset of all keyword arguments related to a specific Parameter type relevant for certain Element objects. To show how method extend() can help in such cases, we make use of the LahnH example project:

>>> from hydpy.examples import prepare_full_example_2
>>> hp, pub, TestIO = prepare_full_example_2()

First, we prepare an empty KeywordArguments object:

>>> from hydpy import KeywordArguments
>>> kwargs = KeywordArguments()
>>> kwargs
KeywordArguments()

When passing a Parameter subclass (in our example IcMax) and some Element objects (at first the headwater elements, which handle instances of application model hland_v1), method extend() collects their relevant keyword arguments:

>>> from hydpy.models.hland.hland_control import IcMax
>>> kwargs.extend(IcMax, pub.selections.headwaters.elements)
>>> kwargs
KeywordArguments(field=1.0, forest=1.5)

Applying method extend() also on the non-headwaters does not change anything, as the values of parameter IcMax are consistent for the whole Lahn river basin:

>>> kwargs.extend(IcMax, pub.selections.nonheadwaters.elements)
>>> kwargs
KeywordArguments(field=1.0, forest=1.5)

Next, we change the interception capacity of forests in one subcatchment:

>>> icmax = hp.elements.land_lahn_2.model.parameters.control.icmax
>>> icmax(field=1.0, forest=2.0)

Re-applying method extend() now raises the following error:

>>> kwargs.extend(IcMax, pub.selections.nonheadwaters.elements)
Traceback (most recent call last):
...
hydpy.core.parametertools.KeywordArgumentsError: While trying to extend the keyword arguments based on the available `IcMax` parameter objects, the following error occurred: While trying to add the keyword arguments for element `land_lahn_2`, the following error occurred: Cannot add argument value `2.0` of type `float64` to the current `KeywordArguments` object as it already handles the unequal argument `1.5` under the keyword `forest`.

The old keywords arguments and the validity status remain unchanged:

>>> kwargs
KeywordArguments(field=1.0, forest=1.5)
>>> kwargs.valid
True

When we modify the same IcMax parameter object in a way that it cannot return a valid KeywordArguments object anymore, we get the following error message:

>>> icmax(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)
>>> kwargs.extend(IcMax, pub.selections.nonheadwaters.elements)
Traceback (most recent call last):
...
hydpy.core.parametertools.KeywordArgumentsError: While trying to extend the keyword arguments based on the available `IcMax` parameter objects, the following error occurred: While trying to add the keyword arguments for element `land_lahn_2`, the following error occurred: Cannot iterate an invalid `KeywordArguments` object.

When setting the raise_exception argument to False, method extend() handles such errors internally and, instead of raising an error invalidates the actual KeywordArguments object:

>>> kwargs.extend(
...     IcMax, pub.selections.nonheadwaters.elements, raise_exception=False)
>>> kwargs
KeywordArguments()
>>> kwargs.valid
False

Trying to extend an invalid KeywordArguments object by default also raises an exception of type KeywordArgumentsError:

>>> kwargs.extend(IcMax, pub.selections.headwaters.elements)
Traceback (most recent call last):
...
hydpy.core.parametertools.KeywordArgumentsError: While trying to extend the keyword arguments based on the available `IcMax` parameter objects, the following error occurred: The `KeywordArguments` object is invalid.

When setting raise_exception to False instead, nothing happens:

>>> kwargs.extend(IcMax, pub.selections.headwaters.elements, raise_exception=False)
>>> kwargs
KeywordArguments()
>>> kwargs.valid
False
class hydpy.core.parametertools.Parameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for model parameters.

In HydPy, each kind of model parameter is represented by a unique class. In almost all cases, you should derive such a class, directly or indirectly, from class Parameter, which provides all necessary features that assure the new parameter class works well when applied in different contexts.

In most cases, the functionalities of class Parameter are sufficient for deriving new classes without doing any real coding (writing new or extending existing methods). However, one sometimes prefers to do some extensions to simplify the usage of the parameter class. Before doing so on your own, have a look at the specialised subclasses already available in module parametertools. One example is class SeasonalParameter, which allows defining parameter values that vary seasonally (e.g. the leaf area index).

Class Parameter itself extends class Variable. Hence, all model-specific Parameter subclasses must define both a value dimensionality and a type via class constants NDIM and TYPE, respectively. Additionally, one has to define the class constant TIME, telling how parameter values depend on the simulation step size (see methods get_timefactor() and apply_timefactor()). Also, model developers might find it useful to define initial default values via INIT or minimum and maximum values via SPAN:

Let us first prepare a new parameter class without time-dependency (indicated by assigning None) and initialise it:

>>> from hydpy.core.parametertools import Parameter
>>> class Par(Parameter):
...     NDIM = 0
...     TYPE = float
...     TIME = None
...     SPAN = 0.0, 5.0
>>> par = Par(None)

As described in the documentation on base class Variable, one can directly assign values via property value:

>>> par.value = 6.0
>>> par
par(6.0)

For Parameter objects, there is an alternative way to define new values, which should be preferred in most cases (especially when writing control files), by “calling” the parameter with suitable arguments. For example, this offers the advantage of automatical trimming. In the example above, the assigned value (6.0) violates the upper bound (5.0) of our test parameter. When using the “call” syntax, the wrong value is corrected immediately:

>>> from hydpy import pub
>>> with pub.options.warntrim(True):
...     par(7.0)
Traceback (most recent call last):
...
UserWarning: For variable `par` at least one value needed to be trimmed.  The old and the new value(s) are `7.0` and `5.0`, respectively.
>>> par
par(5.0)

The “call” syntax provides some additional features and related error messages. Use the auxfile keyword argument to tell that another control file defines the actual parameter value. Note that you cannot use this feature in the interactive mode:

>>> par(auxfile="test")
Traceback (most recent call last):
...
RuntimeError: While trying to extract information for parameter `par` from file `test`, the following error occurred: Cannot determine the corresponding model.  Use the `auxfile` keyword in usual parameter control files only.

Also note, that you cannot combine the auxfile keyword with any other keyword:

>>> par(auxfile="test", x1=1, x2=2, x3=3)
Traceback (most recent call last):
...
ValueError: It is not allowed to combine keyword `auxfile` with other keywords, but for parameter `par` of element `?` also the following keywords are used: x1, x2, and x3.

Some Parameter subclasses support other keyword arguments. The standard error message for unsupported arguments is the following:

>>> par(wrong=1.0)
Traceback (most recent call last):
...
NotImplementedError: The value(s) of parameter `par` of element `?` could not be set based on the given keyword arguments.

Passing a wrong number of positional arguments results in the following error:

>>> par(1.0, 2.0)
Traceback (most recent call last):
...
TypeError: While trying to set the value(s) of variable `par`, the following error occurred: The given value `[ 1.  2.]` cannot be converted to type `float`.

Passing no argument or both positional and keyword arguments are also disallowed:

>>> par()
Traceback (most recent call last):
...
ValueError: For parameter `par` of element `?` neither a positional nor a keyword argument is given.
>>> par(1.0, auxfile="test")
Traceback (most recent call last):
...
ValueError: For parameter `par` of element `?` both positional and keyword arguments are given, which is ambiguous.

Our next Parameter test class is a little more complicated, as it handles a (1-dimensional) vector of time-dependent values (indicated by setting the class attribute TIME to True):

>>> class Par(Parameter):
...     NDIM = 1
...     TYPE = float
...     TIME = True
...     SPAN = 0.0, None

We prepare a shape of length 2 and set different simulation and parameter step sizes, to see that the required time-related adjustments work correctly:

>>> par = Par(None)
>>> par.shape = (2,)
>>> pub.options.parameterstep = "1d"
>>> pub.options.simulationstep = "2d"

Now you can pass one single value, an iterable containing two values, or two separate values as positional arguments, to set both required values. Note that the given values are assumed to agree with the actual parameter step size, and are converted internally to agree with the actual simulation step size. The string representation shows values that agree with the parameter step size; the values property shows the values that agree with the simulation step size, relevant during simulation runs. Also, the string representation shows only one value, in case all (relevant) values are identical:

>>> par(3.0)
>>> par
par(3.0)
>>> par.values
array([ 6.,  6.])
>>> par([0.0, 4.0])
>>> par
par(0.0, 4.0)
>>> par.values
array([ 0.,  8.])
>>> par(1.0, 2.0)
>>> par
par(1.0, 2.0)
>>> par.values
array([ 2.,  4.])

Using the call syntax to set parameter values triggers method trim() automatically:

>>> with pub.options.warntrim(True):
...     par(-1.0, 3.0)
Traceback (most recent call last):
...
UserWarning: For variable `par` at least one value needed to be trimmed.  The old and the new value(s) are `-2.0, 6.0` and `0.0, 6.0`, respectively.
>>> par
par(0.0, 3.0)
>>> par.values
array([ 0.,  6.])

You are free to change the parameter step size (temporarily) to change the string representation of Parameter handling time-dependent values without a risk to change the actual values relevant for simulation:

>>> with pub.options.parameterstep("2d"):
...     print(par)
...     print(repr(par.values))
par(0.0, 6.0)
array([ 0.,  6.])
>>> par
par(0.0, 3.0)
>>> par.values
array([ 0.,  6.])

The highest number of dimensions of Parameter subclasses supported is currently two. The following examples repeat some examples from above for a 2-dimensional parameter that handles that values inversely related to the simulation step size (indicated by setting the class attribute TIME to False):

>>> class Par(Parameter):
...     NDIM = 2
...     TYPE = float
...     TIME = False
...     SPAN = 0.0, 5.0
>>> par = Par(None)
>>> par.shape = (2, 3)
>>> par(9.0)
>>> par
par(9.0)
>>> par.values
array([[ 4.5,  4.5,  4.5],
       [ 4.5,  4.5,  4.5]])
>>> par([[1.0, 2.0, 3.0],
...      [4.0, 5.0, 6.0]])
>>> par
par([[1.0, 2.0, 3.0],
     [4.0, 5.0, 6.0]])
>>> par.values
array([[ 0.5,  1. ,  1.5],
       [ 2. ,  2.5,  3. ]])
>>> par(1.0, 2.0)
Traceback (most recent call last):
...
ValueError: While trying to set the value(s) of variable `par`, the following error occurred: While trying to convert the value(s) `[ 0.5  1. ]` to a numpy ndarray with shape `(2, 3)` and type `float`, the following error occurred: could not broadcast input array from shape (2,) into shape (2,3)
TIME: Optional[bool]
property subpars

Alias for attribute subvars.

property initinfo

A tuple containing the initial value and True or a missing value and False, depending on the actual Parameter subclass and the actual value of option usedefaultvalues.

In the following we show how method the effects of property initinfo when initiasing new Parameter objects. Let’s define a parameter test class and prepare a function for initialising it and connecting the resulting instance to a SubParameters object:

>>> from hydpy.core.parametertools import Parameter, SubParameters
>>> class Test(Parameter):
...     NDIM = 0
...     TYPE = float
...     TIME = None
...     INIT = 2.0
>>> class SubGroup(SubParameters):
...     CLASSES = (Test,)
>>> def prepare():
...     subpars = SubGroup(None)
...     test = Test(subpars)
...     test.__hydpy__connect_variable2subgroup__()
...     return test

By default, making use of the INIT attribute is disabled:

>>> test = prepare()
>>> test
test(?)

Enable it through setting usedefaultvalues to True:

>>> from hydpy import pub
>>> pub.options.usedefaultvalues = True
>>> test = prepare()
>>> test
test(2.0)

When no INIT attribute is defined (indicated by None), enabling usedefaultvalues has no effect, of course:

>>> Test.INIT = None
>>> test = prepare()
>>> test
test(?)

For time-dependent parameter values, the INIT attribute is assumed to be related to a parameterstep() of one day:

>>> pub.options.parameterstep = "2d"
>>> pub.options.simulationstep = "12h"
>>> Test.INIT = 2.0
>>> Test.TIME = True
>>> test = prepare()
>>> test
test(4.0)
>>> test.value
1.0
classmethod get_timefactor()float[source]

Factor to adjust a new value of a time-dependent parameter.

For a time-dependent parameter, its effective value depends on the simulation step size. Method get_timefactor() returns the fraction between the current simulation step size and the current parameter step size.

Method get_timefactor() raises the following error when time information is not available:

>>> from hydpy.core.parametertools import Parameter
>>> Parameter.get_timefactor()
Traceback (most recent call last):
...
RuntimeError: To calculate the conversion factor for adapting the values of the time-dependent parameters, you need to define both a parameter and a simulation time step size first.

One can define both time step sizes directly:

>>> from hydpy import pub
>>> pub.options.parameterstep = "1d"
>>> pub.options.simulationstep = "6h"
>>> Parameter.get_timefactor()
0.25

As usual, the “global” simulation step size of the Timegrids object of module pub is prefered:

>>> from hydpy import pub
>>> pub.timegrids = "2000-01-01", "2001-01-01", "12h"
>>> Parameter.get_timefactor()
0.5
trim(lower=None, upper=None)None[source]

Apply function trim() of module variabletools.

classmethod apply_timefactor(values: ArrayFloat)ArrayFloat[source]

Change and return the given value(s) in accordance with get_timefactor() and the type of time-dependence of the actual parameter subclass.

For the same conversion factor returned by method get_timefactor(), method apply_timefactor() behaves differently depending on the TIME attribute of the respective Parameter subclass. We first prepare a parameter test class and define both the parameter and simulation step size:

>>> from hydpy.core.parametertools import Parameter
>>> class Par(Parameter):
...     TIME = None
>>> from hydpy import pub
>>> pub.options.parameterstep = "1d"
>>> pub.options.simulationstep = "6h"

None means the value(s) of the parameter are not time-dependent (e.g. maximum storage capacity). Hence, apply_timefactor() returns the original value(s):

>>> Par.apply_timefactor(4.0)
4.0

True means the effective parameter value is proportional to the simulation step size (e.g. travel time). Hence, apply_timefactor() returns a reduced value in the next example (where the simulation step size is smaller than the parameter step size):

>>> Par.TIME = True
>>> Par.apply_timefactor(4.0)
1.0

False means the effective parameter value is inversely proportional to the simulation step size (e.g. storage coefficient). Hence, apply_timefactor() returns an increased value in the next example:

>>> Par.TIME = False
>>> Par.apply_timefactor(4.0)
16.0
classmethod revert_timefactor(values: ArrayFloat)ArrayFloat[source]

The inverse version of method apply_timefactor().

See the explanations on method Parameter.apply_timefactor| to understand the following examples:

>>> from hydpy.core.parametertools import Parameter
>>> class Par(Parameter):
...     TIME = None
>>> Par.parameterstep = "1d"
>>> Par.simulationstep = "6h"
>>> Par.revert_timefactor(4.0)
4.0
>>> Par.TIME = True
>>> Par.revert_timefactor(4.0)
16.0
>>> Par.TIME = False
>>> Par.revert_timefactor(4.0)
1.0
update()None[source]

To be overridden by all “secondary” parameters.

Parameter subclasses to be used as “primary” parameters (control parameters) do not need to implement method update(). For such classes, invoking the method results in the following error message:

>>> from hydpy.core.parametertools import Parameter
>>> class Par(Parameter):
...     pass
>>> Par(None).update()
Traceback (most recent call last):
...
RuntimeError: Parameter `par` of element `?` does not implement method `update`.
property keywordarguments

An invalid KeywordArguments object.

By default, instances of Parameter subclasses return empty, invalid KeywordArguments objects:

>>> from hydpy.core.parametertools import Parameter
>>> kwa = Parameter(None).keywordarguments
>>> kwa
KeywordArguments()
>>> kwa.valid
False

See the documentation on class ZipParameter for the implementation of a Parameter subclass overriding this behaviour.

compress_repr()Optional[str][source]

Try to find a compressed parameter value representation and return it.

compress_repr() raises a NotImplementedError when failing to find a compressed representation.

For the following examples, we define a 1-dimensional sequence handling time-dependent floating-point values:

>>> from hydpy.core.parametertools import Parameter
>>> class Test(Parameter):
...     NDIM = 1
...     TYPE = float
...     TIME = True
>>> test = Test(None)

Before and directly after defining the parameter shape, nan is returned:

>>> test.compress_repr()
'?'
>>> test
test(?)
>>> test.shape = 4
>>> test
test(?)

Due to the time-dependence of the values of our test class, we need to specify a parameter and a simulation time step:

>>> from hydpy import pub
>>> pub.options.parameterstep = "1d"
>>> pub.options.simulationstep = "8h"

Compression succeeds when all required values are identical:

>>> test(3.0, 3.0, 3.0, 3.0)
>>> test.values
array([ 1.,  1.,  1.,  1.])
>>> test.compress_repr()
'3.0'
>>> test
test(3.0)

Method compress_repr() returns None in case the required values are not identical:

>>> test(1.0, 2.0, 3.0, 3.0)
>>> test.compress_repr()
>>> test
test(1.0, 2.0, 3.0, 3.0)

If some values are not required, indicate this by the mask descriptor:

>>> import numpy
>>> test(3.0, 3.0, 3.0, numpy.nan)
>>> test
test(3.0, 3.0, 3.0, nan)
>>> Test.mask = numpy.array([True, True, True, False])
>>> test
test(3.0)

If trying to access the mask results in an error, compress_repr() behaves as if no mask were available:

>>> def getattribute(obj, name):
...     if name == 'mask':
...         raise BaseException
...     return object.__getattribute__(obj, name)
>>> Test.__getattribute__ = getattribute
>>> test
test(3.0, 3.0, 3.0, nan)

For a shape of zero, the string representing includes an empty list:

>>> test.shape = 0
>>> test.compress_repr()
'[]'
>>> test
test([])

Method compress_repr() works similarly for different Parameter subclasses. The following examples focus on a 2-dimensional parameter handling integer values:

>>> from hydpy.core.parametertools import Parameter
>>> class Test(Parameter):
...     NDIM = 2
...     TYPE = int
...     TIME = None
>>> test = Test(None)
>>> test.compress_repr()
'?'
>>> test
test(?)
>>> test.shape = (2, 3)
>>> test
test(?)
>>> test([[3, 3, 3],
...       [3, 3, 3]])
>>> test
test(3)
>>> test([[3, 3, -999999],
...       [3, 3, 3]])
>>> test
test([[3, 3, -999999],
      [3, 3, 3]])
>>> Test.mask = numpy.array([
...     [True, True, False],
...     [True, True, True]])
>>> test
test(3)
>>> test.shape = (0, 0)
>>> test
test([[]])
name: str = 'parameter'
unit: str = '?'
class hydpy.core.parametertools.NameParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Parameter displaying the names of constants instead of their values.

For demonstration, we define the test class LandType, covering three different types of land covering. For this purpose, we need to prepare a dictionary of type Constants (class attribute CONSTANTS), mapping the land type names to identity values. The entries of the SPAN tuple should agree with the lowest and highest identity values. The class attributes NDIM, TYPE, and TIME are already set to 1, float, and None by base class NameParameter:

>>> from hydpy.core.parametertools import Constants, NameParameter
>>> class LandType(NameParameter):
...     SPAN = (1, 3)
...     CONSTANTS = Constants(SOIL=1, WATER=2, GLACIER=3)

Additionally, we make the constants available within the local namespace (which is usually done by importing the constants from the selected application model automatically):

>>> SOIL, WATER, GLACIER = 1, 2, 3

For parameters of zero length, unprepared values, and identical required values, the string representations of NameParameter subclasses equal the string representations of other Parameter subclasses:

>>> landtype = LandType(None)
>>> landtype.shape = 0
>>> landtype
landtype([])
>>> landtype.shape = 5
>>> landtype
landtype(?)
>>> landtype(SOIL)
>>> landtype
landtype(SOIL)

For non-identical required values, class NameParameter replaces the identity values with their names:

>>> landtype(SOIL, WATER, GLACIER, WATER, SOIL)
>>> landtype
landtype(SOIL, WATER, GLACIER, WATER, SOIL)

For high numbers of entries, string representations are wrapped:

>>> landtype.shape = 22
>>> landtype(SOIL)
>>> landtype.values[0] = WATER
>>> landtype.values[-1] = GLACIER
>>> landtype
landtype(WATER, SOIL, SOIL, SOIL, SOIL, SOIL, SOIL, SOIL, SOIL, SOIL,
         SOIL, SOIL, SOIL, SOIL, SOIL, SOIL, SOIL, SOIL, SOIL, SOIL,
         SOIL, GLACIER)

For very high numbers of entries, the string representation puts the names of the constants within a list (to make the string representations executable under Python 3.6; this behaviour will change as soon as Python 3.7 becomes the oldest supported version):

>>> landtype.shape = 256
>>> landtype(SOIL)
>>> landtype.values[0] = WATER
>>> landtype.values[-1] = GLACIER
>>> landtype   
landtype([WATER, SOIL, ..., SOIL, GLACIER])
NDIM: int = 1
TYPE
TIME: Optional[bool] = None
CONSTANTS: hydpy.core.parametertools.Constants
name: str = 'nameparameter'
unit: str = '?'
class hydpy.core.parametertools.ZipParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for 1-dimensional model parameters that offers an additional keyword-based zipping functionality.

Many models implemented in the HydPy framework realise the concept of hydrological response units via 1-dimensional Parameter objects, each entry corresponding with an individual unit. To allow for a maximum of flexibility, one can define their values independently, which allows, for example, for applying arbitrary relationships between the altitude of individual response units and a precipitation correction factor to be parameterised.

However, very often, hydrological modellers set identical values for different hydrological response units of the same type. One could, for example, set the same leaf area index for all units of the same land-use type. Class ZipParameter allows defining parameters, which conveniently support this parameterisation strategy.

To see how base class ZipParameter works, we need to create some additional subclasses. First, we need a parameter defining the type of the individual hydrological response units, which can be done by subclassing from NameParameter. We do so by taking the example from the documentation of the NameParameter class:

>>> from hydpy.core.parametertools import NameParameter
>>> SOIL, WATER, GLACIER = 1, 2, 3
>>> class LandType(NameParameter):
...     SPAN = (1, 3)
...     CONSTANTS = {"SOIL":  SOIL, "WATER": WATER, "GLACIER": GLACIER}
>>> landtype = LandType(None)

Second, we need an IndexMask subclass. Our subclass Land references the respective LandType parameter object (we do this in a simplified manner, see class ParameterComplete for a “real world” example) but is supposed to focus on the response units of type soil or glacier only:

>>> from hydpy.core.masktools import IndexMask
>>> class Land(IndexMask):
...     RELEVANT_VALUES = (SOIL, GLACIER)
...     @staticmethod
...     def get_refindices(variable):
...         return variable.landtype

Third, we prepare the actual ZipParameter subclass, holding the same constants dictionary as the LandType parameter and the Land mask as attributes. We assume that the values of our test class Par are time-dependent and set different parameter and simulation step sizes, to show that the related value adjustments work. Also, we make the LandType object available via attribute access, which is a hack to make the above simplification work:

>>> from hydpy.core.parametertools import ZipParameter
>>> class Par(ZipParameter):
...     TYPE = float
...     TIME = True
...     SPAN = (0.0, None)
...     MODEL_CONSTANTS = LandType.CONSTANTS
...     mask = Land()
...     landtype = landtype
>>> par = Par(None)
>>> from hydpy import pub
>>> pub.options.parameterstep = "1d"
>>> pub.options.simulationstep = "12h"

For parameters with zero-length or with unprepared or identical parameter values, the string representation looks as usual:

>>> landtype.shape = 0
>>> par.shape = 0
>>> par
par([])
>>> landtype.shape = 5
>>> landtype(SOIL, WATER, GLACIER, WATER, SOIL)
>>> par.shape = 5
>>> par
par(?)
>>> par(2.0)
>>> par
par(2.0)
>>> par.values
array([ 1.,  1.,  1.,  1.,  1.])

The extended feature of class ZipParameter is to allow passing values via keywords, each keyword corresponding to one of the relevant constants (in our example: SOIL and GLACIER) in lower case letters:

>>> par(soil=4.0, glacier=6.0)
>>> par
par(glacier=6.0, soil=4.0)
>>> par.values
array([  2.,  nan,   3.,  nan,   2.])

Use the default argument if you want to assign the same value to entries with different constants:

>>> par(soil=2.0, default=8.0)
>>> par
par(glacier=8.0, soil=2.0)
>>> par.values
array([  1.,  nan,   4.,  nan,   1.])

Using a keyword argument corresponding to an existing, but not relevant constant (in our example: WATER) is silently ignored:

>>> par(soil=4.0, glacier=6.0, water=8.0)
>>> par
par(glacier=6.0, soil=4.0)
>>> par.values
array([  2.,  nan,   3.,  nan,   2.])

However, using a keyword not corresponding to any constant raises an exception:

>>> par(soil=4.0, glacier=6.0, wrong=8.0)
Traceback (most recent call last):
...
TypeError: While trying to set the values of parameter `par` of element `?` based on keyword arguments `soil, glacier, and wrong`, the following error occurred: Keyword `wrong` is not among the available model constants.

The same is true when passing incomplete information:

>>> par(soil=4.0)
Traceback (most recent call last):
...
TypeError: While trying to set the values of parameter `par` of element `?` based on keyword arguments `soil`, the following error occurred: The given keywords are incomplete and no default value is available.

Values exceeding the bounds defined by class attribute SPAN are trimmed as usual:

>>> from hydpy import pub
>>> with pub.options.warntrim(False):
...     par(soil=-10.0, glacier=10.0)
>>> par
par(glacier=10.0, soil=0.0)

For convenience, you can get or set all values related to a specific constant via attribute access:

>>> par.soil
array([ 0.,  0.])
>>> par.soil = 2.5
>>> par
par(glacier=10.0, soil=5.0)

Improper use of these “special attributes” results in errors like the following:

>>> par.Soil
Traceback (most recent call last):
...
AttributeError: `Soil` is neither a normal attribute of parameter `par` of element `?` nor among the following special attributes: soil, water, and glacier.
>>> par.soil = "test"
Traceback (most recent call last):
...
ValueError: While trying the set the value(s) of parameter `par` of element `?` related to the special attribute `soil`, the following error occurred: could not convert string to float: 'test'
NDIM: int = 1
MODEL_CONSTANTS: Dict[str, int]
property keywordarguments

A KeywordArguments object providing the currently valid keyword arguments.

We take parameter TRefT of application model lland_v1 as an example and set its shape (the number of hydrological response units defined by parameter NHRU) to four and prepare the land-use types ACKER (acre), LAUBW (deciduous forest), and WASSER (water) via parameter Lnk:

>>> from hydpy.models.lland_v1 import *
>>> parameterstep()
>>> nhru(4)
>>> lnk(ACKER, LAUBW, WASSER, ACKER)

After defining all required values via keyword arguments (note that parameter TRefT does not need any values for response units of type WASSER), property keywordarguments makes exactly these keywords arguments available:

>>> treft(acker=2.0, laubw=1.0)
>>> treft.keywordarguments
KeywordArguments(acker=2.0, laubw=1.0)
>>> treft.keywordarguments.valid
True

In the following example, both the first and the fourth response unit are of type ACKER but have different TRefT values, which cannot be the result of defining values via keyword arguments. Hence, the returned KeywordArguments object is invalid:

>>> treft(1.0, 2.0, 3.0, 4.0)
>>> treft.keywordarguments
KeywordArguments()
>>> treft.keywordarguments.valid
False

This is different from the situation where all response units are of type WASSER, where one does not need to define any values for parameter TRefT. Thus, the returned KeywordArguments object is also empty but valid:

>>> lnk(WASSER)
>>> treft.keywordarguments
KeywordArguments()
>>> treft.keywordarguments.valid
True
name: str = 'zipparameter'
unit: str = '?'
class hydpy.core.parametertools.SeasonalParameter(subvars)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for parameters handling values showing a seasonal variation.

Quite a lot of model parameter values change on an annual basis. One example is the leaf area index. For deciduous forests within temperate climatic regions, it shows a clear peak during the summer season.

If you want to vary the parameter values on a fixed (for example, a monthly) basis, KeywordParameter2D might be the best starting point. See the LanduseMonthParameter class of the lland base model as an example, which is used to define parameter LAI, handling monthly leaf area index values for different land-use classes.

However, class SeasonalParameter offers more flexibility in defining seasonal patterns, which is often helpful for modelling technical control systems. One example is the parameter pair W and Q of base model llake, defining the desired water stage to discharge relationship throughout the year.

For the following examples, we assume a simulation step size of one day:

>>> from hydpy import pub
>>> pub.timegrids = "2000-01-01", "2001-01-01", "1d"

Let us prepare an empty 1-dimensional SeasonalParameter instance:

>>> from hydpy.core.parametertools import SeasonalParameter
>>> class Par(SeasonalParameter):
...     NDIM = 1
...     TIME = None
>>> par = Par(None)
>>> par.NDIM = 1
>>> par
par()

The shape is determined automatically, as described in the documentation on property shape in more detail:

>>> par.shape = (None,)
>>> par.shape
(366,)

Pairs of TOY objects and float values define the seasonal pattern. One can assign them all at once via keyword arguments:

>>> par(_1=2., _7_1=4., _3_1_0_0_0=5.)

Note that all keywords in the call above are proper TOY initialisation arguments. Misspelt keywords result in error messages like the following:

>>> Par(None)(_a=1.)
Traceback (most recent call last):
...
ValueError: While trying to define the seasonal parameter value `par` of element `?` for time of year `_a`, the following error occurred: While trying to initialise a TOY object based on argument value `_a` of type `str`, the following error occurred: While trying to retrieve the month, the following error occurred: For TOY (time of year) objects, all properties must be of type `int`, but the value `a` of type `str` given for property `month` cannot be converted to `int`.

As the following string representation shows are the pairs of each SeasonalParameter instance automatically sorted:

>>> par
par(toy_1_1_0_0_0=2.0,
    toy_3_1_0_0_0=5.0,
    toy_7_1_0_0_0=4.0)

By default, toy is used as a prefix string. Using this prefix string, one can change the toy-value pairs via attribute access:

>>> par.toy_1_1_0_0_0
2.0
>>> del par.toy_1_1_0_0_0
>>> par.toy_2_1_0_0_0 = 2.
>>> par
par(toy_2_1_0_0_0=2.0,
    toy_3_1_0_0_0=5.0,
    toy_7_1_0_0_0=4.0)

For attribute access, zero hours, minutes, or seconds can be left out:

>>> par.toy_2_1
2.0

When using functions getattr() and delattr(), one can also omit the “toy” prefix:

>>> getattr(par, "2_1")
2.0
>>> delattr(par, "2_1")
>>> getattr(par, "2_1")
Traceback (most recent call last):
...
AttributeError: Seasonal parameter `par` of element `?` has neither a normal attribute nor does it handle a "time of year" named `2_1`.
>>> delattr(par, "2_1")
Traceback (most recent call last):
...
AttributeError: Seasonal parameter `par` of element `?` has neither a normal attribute nor does it handle a "time of year" named `2_1`.

Applying the len() operator on SeasonalParameter objects returns the number of toy-value pairs.

>>> len(par)
2

New values are checked to be compatible with the predefined shape:

>>> par.toy_1_1_0_0_0 = [1., 2.]   
Traceback (most recent call last):
...
TypeError: While trying to add a new or change an existing toy-value pair for the seasonal parameter `par` of element `?`, the following error occurred: float() argument must be a string or a number...
>>> par = Par(None)
>>> par.NDIM = 2
>>> par.shape = (None, 3)
>>> par.toy_1_1_0_0_0 = [1., 2.]
Traceback (most recent call last):
...
ValueError: While trying to add a new or change an existing toy-value pair for the seasonal parameter `par` of element `?`, the following error occurred: could not broadcast input array from shape (2,) into shape (3,)

If you do not require seasonally varying parameter values in a specific situation, you can pass a single positional argument:

>>> par(5.0)
>>> par
par([5.0, 5.0, 5.0])

Note that class SeasonalParameter associates the given value(s) to the “first” time of the year, internally:

>>> par.toys
(TOY("1_1_0_0_0"),)

Incompatible positional arguments result in errors like the following:

>>> par(1.0, 2.0)
Traceback (most recent call last):
...
ValueError: While trying to set the value(s) of variable `par`, the following error occurred: While trying to convert the value(s) `[ 1.  2.]` to a numpy ndarray with shape `(366, 3)` and type `float`, the following error occurred: could not broadcast input array from shape (2,) into shape (366,3)
TYPE
strict_valuehandling: ClassVar[bool] = False
refresh()None[source]

Update the actual simulation values based on the toy-value pairs.

Usually, one does not need to call refresh explicitly. The “magic” methods __call__, __setattr__, and __delattr__ invoke it automatically, when required.

Method refresh() calculates only those time variable parameter values required for the defined initialisation period. We start with an initialisation period covering a full year, making a complete calculation necessary:

>>> from hydpy import pub
>>> pub.timegrids = "2000-01-01", "2001-01-01", "1d"

Instantiate a 1-dimensional SeasonalParameter object:

>>> from hydpy.core.parametertools import SeasonalParameter
>>> class Par(SeasonalParameter):
...     NDIM = 1
...     TYPE = float
...     TIME = None
>>> par = Par(None)
>>> par.shape = (None,)

When a SeasonalParameter object does not contain any toy-value pairs yet, the method refresh() sets all actual simulation values to zero:

>>> par.values = 1.
>>> par.refresh()
>>> par.values[0]
0.0

When there is only one toy-value pair, its values are relevant for all actual simulation values:

>>> par.toy_1 = 2. # calls refresh automatically
>>> par.values[0]
2.0

Method refresh() performs a linear interpolation for the central time points of each simulation time step. Hence, in the following example, the original values of the toy-value pairs do not show up:

>>> par.toy_12_31 = 4.
>>> from hydpy import round_
>>> round_(par.values[0])
2.00274
>>> round_(par.values[-2])
3.99726
>>> par.values[-1]
3.0

If one wants to preserve the original values in this example, one would have to set the corresponding toy instances in the middle of some simulation step intervals:

>>> del par.toy_1
>>> del par.toy_12_31
>>> par.toy_1_1_12 = 2
>>> par.toy_12_31_12 = 4.
>>> par.values[0]
2.0
>>> round_(par.values[1])
2.005479
>>> round_(par.values[-2])
3.994521
>>> par.values[-1]
4.0

For short initialisation periods, method refresh() performs only the required interpolations for efficiency reasons:

>>> pub.timegrids = "2000-01-02", "2000-01-05", "1d"
>>> Par.NDIM = 2
>>> par = Par(None)
>>> par.shape = (None, 3)
>>> par.toy_1_2_12 = 2.0
>>> par.toy_1_6_12 = 0.0, 2.0, 4.0
>>> par.values[:6]
array([[ nan,  nan,  nan],
       [ 2. ,  2. ,  2. ],
       [ 1.5,  2. ,  2.5],
       [ 1. ,  2. ,  3. ],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])
interp(date: hydpy.core.timetools.Date)float[source]

Perform a linear value interpolation for the given date and return the result.

Instantiate a 1-dimensional SeasonalParameter object:

>>> from hydpy import pub
>>> pub.timegrids = "2000-01-01", "2001-01-01", "1d"
>>> from hydpy.core.parametertools import SeasonalParameter
>>> class Par(SeasonalParameter):
...     NDIM = 1
...     TYPE = float
...     TIME = None
>>> par = Par(None)
>>> par.shape = (None,)

Define three toy-value pairs:

>>> par(_1=2.0, _2=5.0, _12_31=4.0)

Passing a Date object matching a TOY object exactly returns the corresponding float value:

>>> from hydpy import Date
>>> par.interp(Date("2000.01.01"))
2.0
>>> par.interp(Date("2000.02.01"))
5.0
>>> par.interp(Date("2000.12.31"))
4.0

For all intermediate points, interp() performs a linear interpolation:

>>> from hydpy import round_
>>> round_(par.interp(Date("2000.01.02")))
2.096774
>>> round_(par.interp(Date("2000.01.31")))
4.903226
>>> round_(par.interp(Date("2000.02.02")))
4.997006
>>> round_(par.interp(Date("2000.12.30")))
4.002994

Linear interpolation is also allowed between the first and the last pair when they do not capture the endpoints of the year:

>>> par(_1_2=2.0, _12_30=4.0)
>>> round_(par.interp(Date("2000.12.29")))
3.99449
>>> par.interp(Date("2000.12.30"))
4.0
>>> round_(par.interp(Date("2000.12.31")))
3.333333
>>> round_(par.interp(Date("2000.01.01")))
2.666667
>>> par.interp(Date("2000.01.02"))
2.0
>>> round_(par.interp(Date("2000.01.03")))
2.00551

The following example briefly shows interpolation performed for a 2-dimensional parameter:

>>> Par.NDIM = 2
>>> par = Par(None)
>>> par.shape = (None, 2)
>>> par(_1_1=[1., 2.], _1_3=[-3, 0.])
>>> result = par.interp(Date("2000.01.02"))
>>> round_(result[0])
-1.0
>>> round_(result[1])
1.0
property toys

A sorted tuple of all contained TOY objects.

property shape

A tuple containing the actual lengths of all dimensions.

Setting the shape of SeasonalParameter objects differs from setting the shape of other Variable subclasses, due to handling time on the first axis. The simulation step size determines the length of this axis. Hence, trying to set the shape before the simulation step size is known does not work:

>>> from hydpy.core.parametertools import SeasonalParameter
>>> class Par(SeasonalParameter):
...     NDIM = 1
...     TYPE = float
...     TIME = None
>>> par = Par(None)
>>> par.shape = (None,)
Traceback (most recent call last):
...
RuntimeError: It is not possible the set the shape of the seasonal parameter `par` of element `?` at the moment.  You need to define the simulation step size first.  However, in complete HydPy projects this stepsize is indirectly defined via `pub.timegrids.stepsize` automatically.

After preparing the simulation step size, you can pass a tuple with a single entry of any value to define the shape of the defined 1-dimensional test class. Property shape replaces this arbitrary value by the number of simulation steps fitting into a leap year:

>>> from hydpy import pub
>>> pub.options.simulationstep = "1d"
>>> par.shape = (123,)
>>> par.shape
(366,)

Assigning a single, arbitrary value also works well:

>>> par.shape = None
>>> par.shape
(366,)

For higher-dimensional parameters, property shape replaces the first entry of the assigned iterable, accordingly:

>>> Par.NDIM = 2
>>> par.shape = (None, 3)
>>> par.shape
(366, 3)

For simulation steps not cleanly fitting into a leap year, the ceil-operation determines the number of entries:

>>> pub.options.simulationstep = "100d"
>>> par.shape = (None, 3)
>>> par.shape
(4, 3)
name: str = 'seasonalparameter'
unit: str = '?'
class hydpy.core.parametertools.KeywordParameter1D(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for 1-dimensional model parameters with values depending on one factor.

When subclassing from KeywordParameter1D one needs to define the class attribute ENTRYNAMES. A typical use case is that ENTRYNAMES defines seasons like the months or, as in our example, half-years:

>>> from hydpy.core.parametertools import KeywordParameter1D
>>> class IsHot(KeywordParameter1D):
...     TYPE = bool
...     TIME = None
...     ENTRYNAMES = ("winter", "summer")

Usually, KeywordParameter1D objects prepare their shape automatically. However, to simplify this test case, we define it manually:

>>> ishot = IsHot(None)
>>> ishot.shape = 2

You can pass all parameter values both via positional or keyword arguments:

>>> ishot(True)
>>> ishot
ishot(True)
>>> ishot(False, True)
>>> ishot
ishot(winter=False, summer=True)
>>> ishot(winter=True, summer=False)
>>> ishot
ishot(winter=True, summer=False)
>>> ishot.values
array([ True, False], dtype=bool)

We check the given keyword arguments for correctness and completeness:

>>> ishot(winter=True)
Traceback (most recent call last):
...
ValueError: When setting parameter `ishot` of element `?` via keyword arguments, each string defined in `ENTRYNAMES` must be used as a keyword, but the following keywords are not: `summer`.
>>> ishot(winter=True, summer=False, spring=True, autumn=False)
Traceback (most recent call last):
...
ValueError: When setting parameter `ishot` of element `?` via keyword arguments, each keyword must be defined in `ENTRYNAMES`, but the following keywords are not: `spring and autumn`.

Class KeywordParameter1D implements attribute access, including specialised error messages:

>>> ishot.winter, ishot.summer = ishot.summer, ishot.winter
>>> ishot
ishot(winter=False, summer=True)
>>> ishot.spring
Traceback (most recent call last):
...
AttributeError: Parameter `ishot` of element `?` does not handle an attribute named `spring`.
>>> ishot.shape = 1
>>> ishot.summer
Traceback (most recent call last):
...
IndexError: While trying to retrieve a value from parameter `ishot` of element `?` via the attribute `summer`, the following error occurred: index 1 is out of bounds for axis 0 with size 1
>>> ishot.summer = True
Traceback (most recent call last):
...
IndexError: While trying to assign a new value to parameter `ishot` of element `?` via attribute `summer`, the following error occurred: index 1 is out of bounds for axis 0 with size 1
NDIM: int = 1
ENTRYNAMES: ClassVar[Tuple[str, ]]
strict_valuehandling: ClassVar[bool] = False
name: str = 'keywordparameter1d'
unit: str = '?'
class hydpy.core.parametertools.MonthParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for parameters which values depend on the actual month.

Please see the documentation on class KeywordParameter1D on how to use MonthParameter objects and class WG2Z of base model lland as an example implementation:

>>> from hydpy.models.lland import *
>>> simulationstep("12h")
>>> parameterstep("1d")
>>> wg2z(3.0, 2.0, 1.0, 0.0, -1.0, -2.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0)
>>> wg2z
wg2z(jan=3.0, feb=2.0, mar=1.0, apr=0.0, may=-1.0, jun=-2.0, jul=-3.0,
     aug=-2.0, sep=-1.0, oct=0.0, nov=1.0, dec=2.0)

Note that attribute access provides access to the “real” values related to the current simulation time step:

>>> wg2z.feb
2.0
>>> wg2z.feb = 4.0
>>> wg2z
wg2z(jan=3.0, feb=4.0, mar=1.0, apr=0.0, may=-1.0, jun=-2.0, jul=-3.0,
     aug=-2.0, sep=-1.0, oct=0.0, nov=1.0, dec=2.0)
ENTRYNAMES: ClassVar[Tuple[str, ]] = ('jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec')
name: str = 'monthparameter'
unit: str = '?'
TIME: Optional[bool]
TYPE: Type
subvars: SubVariablesType
class hydpy.core.parametertools.KeywordParameter2D(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for 2-dimensional model parameters with values depending on two factors.

When subclassing from KeywordParameter2D one needs to define the class attributes ROWNAMES and COLNAMES (both of type tuple). A typical use case is that ROWNAMES defines some land-use classes and COLNAMES defines seasons, months, or the like. Here, we consider a simple corresponding example, where the values of the boolean parameter IsWarm both depend on the on the hemisphere and the half-year period:

>>> from hydpy.core.parametertools import KeywordParameter2D
>>> class IsWarm(KeywordParameter2D):
...     TYPE = bool
...     TIME = None
...     ROWNAMES = ("north", "south")
...     COLNAMES = ("apr2sep", "oct2mar")

Instantiate the defined parameter class and define its shape:

>>> iswarm = IsWarm(None)
>>> iswarm.shape = (2, 2)

KeywordParameter2D allows us to set the values of all rows via keyword arguments:

>>> iswarm(north=[True, False],
...        south=[False, True])
>>> iswarm
iswarm(north=[True, False],
       south=[False, True])
>>> iswarm.values
array([[ True, False],
       [False,  True]], dtype=bool)

If a keyword is missing, it raises a ValueError:

>>> iswarm(north=[True, False])
Traceback (most recent call last):
...
ValueError: While setting parameter `iswarm` of element `?` via row related keyword arguments, each string defined in `ROWNAMES` must be used as a keyword, but the following keywords are not: `south`.

One can modify single rows via attribute access:

>>> iswarm.north = False, False
>>> iswarm.north
array([False, False], dtype=bool)

The same holds for the columns:

>>> iswarm.apr2sep = True, False
>>> iswarm.apr2sep
array([ True, False], dtype=bool)

Also, combined row-column access is possible:

>>> iswarm.north_apr2sep
True
>>> iswarm.north_apr2sep = False
>>> iswarm.north_apr2sep
False

All three forms of attribute access define augmented exception messages in case anything goes wrong:

>>> iswarm.north = True, True, True
Traceback (most recent call last):
...
ValueError: While trying to assign new values to parameter `iswarm` of element `?` via the row related attribute `north`, the following error occurred: could not broadcast input array from shape (3,) into shape (2,)
>>> iswarm.apr2sep = True, True, True
Traceback (most recent call last):
...
ValueError: While trying to assign new values to parameter `iswarm` of element `?` via the column related attribute `apr2sep`, the following error occurred: could not broadcast input array from shape (3,) into shape (2,)
>>> iswarm.shape = (1, 1)
>>> iswarm.south_apr2sep = False
Traceback (most recent call last):
...
IndexError: While trying to assign new values to parameter `iswarm` of element `?` via the row and column related attribute `south_apr2sep`, the following error occurred: index 1 is out of bounds for axis 0 with size 1
>>> iswarm.south
Traceback (most recent call last):
...
IndexError: While trying to retrieve values from parameter `iswarm` of element `?` via the row related attribute `south`, the following error occurred: index 1 is out of bounds for axis 0 with size 1
>>> iswarm.oct2mar
Traceback (most recent call last):
...
IndexError: While trying to retrieve values from parameter `iswarm` of element `?` via the column related attribute `oct2mar`, the following error occurred: index 1 is out of bounds for axis 1 with size 1
>>> iswarm.south_oct2mar
Traceback (most recent call last):
...
IndexError: While trying to retrieve values from parameter `iswarm` of element `?` via the row and column related attribute `south_oct2mar`, the following error occurred: index 1 is out of bounds for axis 0 with size 1
>>> iswarm.shape = (2, 2)

Unknown attribute names result in the following error:

>>> iswarm.wrong
Traceback (most recent call last):
...
AttributeError: Parameter `iswarm` of element `?` does neither handle a normal attribute nor a row or column related attribute named `wrong`.

One still can define the parameter values via positional arguments:

>>> iswarm(True)
>>> iswarm
iswarm(north=[True, True],
       south=[True, True])

For parameters with many columns, string representations are adequately wrapped:

>>> iswarm.shape = (2, 10)
>>> iswarm
iswarm(north=[False, False, False, False, False, False, False, False,
              False, False],
       south=[False, False, False, False, False, False, False, False,
              False, False])
NDIM: int = 2
ROWNAMES: ClassVar[Tuple[str, ]]
COLNAMES: ClassVar[Tuple[str, ]]
strict_valuehandling: ClassVar[bool] = False
name: str = 'keywordparameter2d'
unit: str = '?'
class hydpy.core.parametertools.RelSubweightsMixin[source]

Bases: object

Mixin class for derived parameters reflecting some absolute values of the referenced weighting parameter in relative terms.

RelSubweightsMixin is supposed to be combined with parameters implementing property refweights.

The documentation on base model hland provides some example implementations like class RelSoilZoneArea.

mask: masktools.BaseMask
refweights: hydpy.core.parametertools.Parameter
update()None[source]

Update subclass of RelSubweightsMixin based on refweights.

class hydpy.core.parametertools.LeftRightParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for handling two values, a left one and a right one.

The original purpose of class LeftRightParameter is to make the handling of river channel related parameters with different values for both river banks a little more convenient.

As an example, we define a parameter class describing the width both of the left and the right flood plain of a river segment:

>>> from hydpy.core.parametertools import LeftRightParameter
>>> class FloodPlainWidth(LeftRightParameter):
...     TYPE = float
...     TIME = None
>>> floodplainwidth = FloodPlainWidth(None)

Here, we need to set the shape of the parameter to 2, which is an automated procedure in full model setups:

>>> floodplainwidth.shape = 2

Parameter values can be defined as usual:

>>> floodplainwidth(3.0)
>>> floodplainwidth
floodplainwidth(3.0)

Alternatively, use the keywords left or l and right or r to define both values individually:

>>> floodplainwidth(left=1.0, right=2.0)
>>> floodplainwidth
floodplainwidth(left=1.0, right=2.0)
>>> floodplainwidth(l=2.0, r=1.0)
>>> floodplainwidth
floodplainwidth(left=2.0, right=1.0)

Incomplete information results in the following errors:

>>> floodplainwidth(left=2.0)
Traceback (most recent call last):
...
ValueError: When setting the values of parameter `floodplainwidth` of element `?` via keyword arguments, either `right` or `r` for the "right" parameter value must be given, but is not.
>>> floodplainwidth(right=1.0)
Traceback (most recent call last):
...
ValueError: When setting the values of parameter `floodplainwidth` of element `?` via keyword arguments, either `left` or `l` for the "left" parameter value must be given, but is not.

Additionally, one can query and modify the individual values via the attribute names left and right:

>>> floodplainwidth.left
2.0
>>> floodplainwidth.left = 3.0
>>> floodplainwidth.right
1.0
>>> floodplainwidth.right = 4.0
>>> floodplainwidth
floodplainwidth(left=3.0, right=4.0)
NDIM: int = 1
strict_valuehandling: ClassVar[bool] = False
property left

The “left” value of the actual parameter object.

property right

The “right” value of the actual parameter object.

name: str = 'leftrightparameter'
unit: str = '?'
class hydpy.core.parametertools.FixedParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for defining parameters with fixed values.

Model model-users usually do not modify the values of FixedParameter objects. Hence, such objects prepare their “initial” values automatically whenever possible, even when option usedefaultvalues is disabled.

property initinfo

A tuple always containing the fixed value and True, except for time-dependent parameters and incomplete time-information.

>>> from hydpy.core.parametertools import FixedParameter
>>> class Par(FixedParameter):
...   NDIM, TYPE, TIME, SPAN = 0, float, True, (0., None)
...   INIT = 100.0
>>> par = Par(None)
>>> par.initinfo
(nan, False)
>>> from hydpy import pub
>>> pub.options.parameterstep = "1d"
>>> pub.options.simulationstep = "12h"
>>> par.initinfo
(50.0, True)
restore()None[source]

Restore the original parameter value.

Method restore() is relevant for testing mainly. Note that it might be necessary to call it after changing the simulation step size, as shown in the following example using the parameter LambdaG of base model lland:

>>> from hydpy.models.lland import *
>>> simulationstep("1d")
>>> parameterstep("1d")
>>> from hydpy import round_
>>> fixed.lambdag
lambdag(0.05184)
>>> round_(fixed.lambdag.value)
0.05184
>>> simulationstep("12h")
>>> fixed.lambdag
lambdag(0.10368)
>>> round_(fixed.lambdag.value)
0.05184
>>> fixed.lambdag.restore()
>>> fixed.lambdag
lambdag(0.05184)
>>> round_(fixed.lambdag.value)
0.02592
name: str = 'fixedparameter'
unit: str = '?'
TIME: Optional[bool]
NDIM: int
TYPE: Type
subvars: SubVariablesType
class hydpy.core.parametertools.SolverParameter(subvars)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

Base class for defining parameters controlling numerical algorithms for solving model equations.

So far, the equation systems of most models implemented into HydPy are primarily coded as approximative solutions. However, there are also some models stating the original equations only. One example is the dam model. Its code consists of the original differential equations, which must be solved by a separate algorithm. Such algorithms, like the Runge Kutta schema implemented in class ELSModel, often come with some degrees of freedom, for example, to control the striven numerical accuracy.

On the one hand, the model developer should know best how to configure a numerical algorithm he selects for solving the model equations. On the other hand, there might be situations when the model user has diverging preferences. For example, he might favour higher numerical accuracies in one project and faster computation times in another one. Therefore, the update() method of class SolverParameter relies on an INIT value defined by the model developer as long as the user does not define an alternative value in his control files.

As an example, we derive the numerical tolerance parameter Tol:

>>> from hydpy.core.parametertools import SolverParameter
>>> class Tol(SolverParameter):
...     NDIM = 0
...     TYPE = float
...     TIME = None
...     SPAN = (0.0, None)
...     INIT = 0.1

Initially, the method update() applies the value of the class constant INIT:

>>> tol = Tol(None)
>>> tol.update()
>>> tol
tol(0.1)

One can define an alternative value via “calling” the parameter as usual:

>>> tol(0.01)
>>> tol
tol(0.01)

Afterwards, update() reuses the alternative value instead of the value of class constant INIT:

>>> tol.update()
>>> tol
tol(0.01)

This alternative value is accessible and changeable via property alternative_initvalue:

>>> tol.alternative_initvalue
0.01
>>> tol.alternative_initvalue = 0.001
>>> tol.update()
>>> tol
tol(0.001)

One must delete the alternative value to make INIT relevant again:

>>> del tol.alternative_initvalue
>>> tol.alternative_initvalue
Traceback (most recent call last):
...
AttributeError: No alternative initial value for solver parameter `tol` of element `?` has been defined so far.
>>> tol.update()
>>> tol
tol(0.1)

Very often, solver parameters depend on other model settings as the simulation step size or the catchment size, but INIT is always constant. To allow for more flexibility, model developers can override the method modify_init(), which allows adapting the effective parameter value to the actual project settings.

As a most simple example, we extend our class Tol with a modify_init() method that doubles the original INIT value:

>>> class ModTol(Tol):
...     def modify_init(self):
...         return 2.0 * self.INIT
>>> modtol = ModTol(None)
>>> modtol.update()
>>> modtol
modtol(0.2)

Note that modify_init() changes the value of INIT only, not the value of alternative_initvalue:

>>> modtol.alternative_initvalue = 0.01
>>> modtol.update()
>>> modtol
modtol(0.01)
update()None[source]

Update the actual parameter value based on INIT or, if available, on alternative_initvalue.

See the main documentation on class SolverParameter for more information.

modify_init()Union[bool, int, float][source]

Return the value of class constant INIT.

Override this method to support project-specific solver parameters. See the main documentation on class SolverParameter for more information.

property alternative_initvalue

A user-defined value to be used instead of the value of class constant INIT.

See the main documentation on class SolverParameter for more information.

name: str = 'solverparameter'
unit: str = '?'
class hydpy.core.parametertools.SecondsParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

The length of the actual simulation step size in seconds [s].

NDIM: int = 0
TYPE
TIME: Optional[bool] = None
SPAN: Tuple[Union[int, float, bool, None], Union[int, float, bool, None]] = (0.0, None)
update()None[source]

Take the number of seconds from the current simulation time step.

>>> from hydpy import pub
>>> from hydpy.core.parametertools import SecondsParameter
>>> secondsparameter = SecondsParameter(None)
>>> with pub.options.parameterstep("1d"):
...     with pub.options.simulationstep("12h"):
...         secondsparameter.update()
...         secondsparameter
secondsparameter(43200.0)
name: str = 'secondsparameter'
unit: str = 's'
subvars: SubVariablesType
class hydpy.core.parametertools.HoursParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

The length of the actual simulation step size in hours [h].

NDIM: int = 0
TYPE
TIME: Optional[bool] = None
SPAN: Tuple[Union[int, float, bool, None], Union[int, float, bool, None]] = (0.0, None)
update()None[source]

Take the number of hours from the current simulation time step.

>>> from hydpy import pub
>>> from hydpy.core.parametertools import HoursParameter
>>> hoursparameter = HoursParameter(None)
>>> with pub.options.parameterstep("1d"):
...     with pub.options.simulationstep("12h"):
...         hoursparameter.update()
>>> hoursparameter
hoursparameter(12.0)
name: str = 'hoursparameter'
unit: str = 'h'
subvars: SubVariablesType
class hydpy.core.parametertools.DaysParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

The length of the actual simulation step size in days [d].

NDIM: int = 0
TYPE
TIME: Optional[bool] = None
SPAN: Tuple[Union[int, float, bool, None], Union[int, float, bool, None]] = (0.0, None)
update()None[source]

Take the number of days from the current simulation time step.

>>> from hydpy import pub
>>> from hydpy.core.parametertools import DaysParameter
>>> daysparameter = DaysParameter(None)
>>> with pub.options.parameterstep("1d"):
...     with pub.options.simulationstep("12h"):
...         daysparameter.update()
>>> daysparameter
daysparameter(0.5)
name: str = 'daysparameter'
unit: str = 'd'
subvars: SubVariablesType
class hydpy.core.parametertools.TOYParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

References the timeofyear index array provided by the instance of class Indexer available in module pub. [-].

NDIM: int = 1
TYPE
TIME: Optional[bool] = None
SPAN: Tuple[Union[int, float, bool, None], Union[int, float, bool, None]] = (0, None)
update()None[source]

Reference the actual timeofyear array of the Indexer object available in module pub.

>>> from hydpy import pub
>>> pub.timegrids = "27.02.2004", "3.03.2004", "1d"
>>> from hydpy.core.parametertools import TOYParameter
>>> toyparameter = TOYParameter(None)
>>> toyparameter.update()
>>> toyparameter
toyparameter(57, 58, 59, 60, 61)
name: str = 'toyparameter'
unit: str = '-'
subvars: SubVariablesType
class hydpy.core.parametertools.MOYParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

References the monthofyear index array provided by the instance of class Indexer available in module pub [-].

NDIM: int = 1
TYPE
TIME: Optional[bool] = None
SPAN: Tuple[Union[int, float, bool, None], Union[int, float, bool, None]] = (0, 11)
update()None[source]

Reference the actual monthofyear array of the Indexer object available in module pub.

>>> from hydpy import pub
>>> pub.timegrids = "27.02.2004", "3.03.2004", "1d"
>>> from hydpy.core.parametertools import MOYParameter
>>> moyparameter = MOYParameter(None)
>>> moyparameter.update()
>>> moyparameter
moyparameter(1, 1, 1, 2, 2)
name: str = 'moyparameter'
unit: str = '-'
subvars: SubVariablesType
class hydpy.core.parametertools.DOYParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

References the dayofyear index array provided by the instance of class Indexer available in module pub [-].

NDIM: int = 1
name: str = 'doyparameter'
unit: str = '-'
subvars: SubVariablesType
TYPE
TIME: Optional[bool] = None
SPAN: Tuple[Union[int, float, bool, None], Union[int, float, bool, None]] = (0, 365)
update()None[source]

Reference the actual dayofyear array of the Indexer object available in module pub.

>>> from hydpy import pub
>>> pub.timegrids = "27.02.2004", "3.03.2004", "1d"
>>> from hydpy.core.parametertools import DOYParameter
>>> doyparameter = DOYParameter(None)
>>> doyparameter.update()
>>> doyparameter
doyparameter(57, 58, 59, 60, 61)
class hydpy.core.parametertools.SCTParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

References the standardclocktime array provided by the instance of class Indexer available in module pub [h].

name: str = 'sctparameter'
unit: str = 'h'
subvars: SubVariablesType
NDIM: int = 1
TYPE
TIME: Optional[bool] = None
SPAN: Tuple[Union[int, float, bool, None], Union[int, float, bool, None]] = (0.0, 86400.0)
update()None[source]

Reference the actual standardclocktime array of the Indexer object available in module pub.

>>> from hydpy import pub
>>> pub.timegrids = "27.02.2004 21:00", "28.02.2004 03:00", "1h"
>>> from hydpy.core.parametertools import SCTParameter
>>> sctparameter = SCTParameter(None)
>>> sctparameter.update()
>>> sctparameter
sctparameter(21.5, 22.5, 23.5, 0.5, 1.5, 2.5)
class hydpy.core.parametertools.UTCLongitudeParameter(subvars: SubVariablesType)[source]

Bases: hydpy.core.variabletools.Variable[hydpy.core.parametertools.SubParameters, hydpy.core.parametertools.FastAccessParameter]

References the current “UTC longitude” defined by option utclongitude.

name: str = 'utclongitudeparameter'
unit: str = '?'
subvars: SubVariablesType
NDIM: int = 0
TYPE
TIME: Optional[bool] = None
SPAN: Tuple[Union[int, float, bool, None], Union[int, float, bool, None]] = (-180, 180)
update()[source]

Apply the current value of option utclongitude.

>>> from hydpy import pub
>>> pub.options.utclongitude
15
>>> from hydpy.core.parametertools import UTCLongitudeParameter
>>> utclongitudeparameter = UTCLongitudeParameter(None)
>>> utclongitudeparameter.update()
>>> utclongitudeparameter
utclongitudeparameter(15)

Note that changing the value of option utclongitude might makes re-calling method update() necessary:

>>> pub.options.utclongitude = 0
>>> utclongitudeparameter
utclongitudeparameter(15)
>>> utclongitudeparameter.update()
>>> utclongitudeparameter
utclongitudeparameter(0)