masktools

This module implements masking features to define which entries of Parameter or Sequence_ arrays are relevant and which are not.

Module masktools implements the following members:


class hydpy.core.masktools.BaseMask(array=None, doc: str | None = None, **kwargs)[source]

Bases: ndarray[Any, dtype[bool]]

Base class for defining CustomMask and DefaultMask classes.

name: str
classmethod array2mask(array=None, **kwargs) Self[source]

Create a new mask object based on the given ndarray and return it.

class hydpy.core.masktools.CustomMask(array=None, doc: str | None = None, **kwargs)[source]

Bases: BaseMask

Mask that awaits one sets all bool values manually.

Class CustomMask is the most basic applicable mask and provides no special features except for allowing its bool values to be defined manually. Use it when you require a masking behaviour not captured by an available mask.

Like the more advanced masks, CustomMask can work via Python’s descriptor protocol, but it is primarily thought to be applied directly:

>>> from hydpy.core.masktools import CustomMask
>>> mask1 = CustomMask([[True, False, False],
...                     [True, False, False]])

Note that calling any mask object (not only those of type CustomMask) returns a new mask without changing the existing one.

>>> mask2 = mask1([[False, True, False],
...                [False, True, False]])
>>> mask1
CustomMask([[ True, False, False],
            [ True, False, False]])
>>> mask2
CustomMask([[False,  True, False],
            [False,  True, False]])

All masks stem from ndarray. Here are some useful examples of working with them:

>>> mask3 = mask1 + mask2
>>> mask3
CustomMask([[ True,  True, False],
            [ True,  True, False]])
>>> mask3 ^ mask1
CustomMask([[False,  True, False],
            [False,  True, False]])
>>> ~mask3
CustomMask([[False, False,  True],
            [False, False,  True]])
>>> mask1 & mask2
CustomMask([[False, False, False],
            [False, False, False]])

Use the in operator to check if a mask defines a subset of another:

>>> mask1 in mask3
True
>>> mask3 in mask1
False
name: str = 'custommask'
class hydpy.core.masktools.DefaultMask(variable: variabletools.Variable | None = None, doc: str | None = None, **kwargs)[source]

Bases: BaseMask

A mask with all entries being True of the same shape as its master Variable object.

See the documentation on class CustomMask for the basic usage of class DefaultMask.

The following example shows how to apply DefaultMask via Python’s descriptor protocol, which should be the common situation:

>>> from hydpy.core.parametertools import Parameter
>>> from hydpy.core.masktools import DefaultMask
>>> class Par1(Parameter):
...     shape = (2, 3)
...     defaultmask = DefaultMask()
>>> Par1(None).defaultmask
DefaultMask([[ True,  True,  True],
             [ True,  True,  True]])

Alternatively, you can directly connect a DefaultMask with a Variable object:

>>> class Par2(Parameter):
...     shape = (2,)
>>> mask = DefaultMask(Par2(None))
>>> mask
DefaultMask([ True,  True])
variable: variabletools.Variable | None
classmethod new(variable: variabletools.Variable, **kwargs) Self[source]

Return a new DefaultMask object associated with the given Variable object.

name: str = 'defaultmask'
class hydpy.core.masktools.IndexMask(variable: variabletools.Variable | None = None, doc: str | None = None, **kwargs)[source]

Bases: DefaultMask

A mask that depends on a referenced index parameter.

IndexMask must be subclassed. See the masks Complete and Soil of base model hland for two concrete example classes, which are members of the parameter classes ParameterComplete and ParameterSoil. The documentation on these parameter classes provides some application examples. Further, see the documentation on class CustomMask for the basic usage of class DefaultMask.

relevant: tuple[int, ...]

The integer values that are relevant to the referenced index parameter.

variable: variabletools.Variable

The variable for which IndexMask determines the relevant entries.

classmethod new(variable: variabletools.Variable, **kwargs) Self[source]

Return a new IndexMask object of the same shape as the parameter referenced by property refindices.

Entries are only True if the integer values of the respective entries of the referenced index parameter are members of the class attribute tuple relevant.

Before calling new (explicitly or implicitly), one must prepare the variable returned by property refindices:

>>> from hydpy.models.hland import *
>>> parameterstep()
>>> states.sm.mask
Traceback (most recent call last):
...
RuntimeError: The mask of parameter `sm` of element `?` cannot be determined as long as parameter `zonetype` is not prepared properly.
>>> nmbzones(4)
>>> zonetype(FIELD, FOREST, ILAKE, GLACIER)
>>> states.sm.mask
Soil([ True,  True, False, False])

If the shape of the refindices parameter is zero (which is not allowed for hland), the returned mask is empty:

>>> zonetype.shape = 0
>>> states.shape = 0
>>> states.sm.mask
Soil([])
classmethod get_refindices(variable: variabletools.Variable) parametertools.NameParameter[source]

Return the Parameter object to determine which entries of IndexMask must be True and which False.

The given variable must be the concrete Variable object the IndexMask is responsible for.

Needs to be overwritten by subclasses:

>>> from hydpy.core.parametertools import Parameter
>>> from hydpy.core.masktools import IndexMask
>>> class Par(Parameter):
...     mask = IndexMask()
>>> Par(None).mask
Traceback (most recent call last):
...
NotImplementedError: Method `get_refindices` of class `IndexMask` must be overridden, which is not the case for class `IndexMask`.
property refindices: NameParameter

Parameter object for determining which entries of IndexMask are True and which False.

static get_refinement(variable: variabletools.Variable) variabletools.Variable | None[source]

If available, return a boolean variable for selecting only the relevant entries of the considered variable.

property refinement: variabletools.Variable | None

If available, a boolean variable for selecting only the relevant entries of the considered variable.

narrow_relevant(relevant: tuple[int, ...] | None = None) set[int][source]

Return a set of all currently relevant constants.

name: str = 'indexmask'
class hydpy.core.masktools.SubmodelIndexMask(variable: variabletools.Variable | None = None, doc: str | None = None, **kwargs)[source]

Bases: IndexMask

A mask that depends on a referenced index parameter of another model.

classmethod get_refindices(variable: variabletools.Variable) parametertools.NameParameter[source]

Return the Parameter object to determine which entries of SubmodelIndexMask must be True and which False.

SubmodelIndexMask works only for given ZipParameter instances and tries to return the currently handled refindices parameter instance.

name: str = 'submodelindexmask'
class hydpy.core.masktools.Masks[source]

Bases: object

Base class for handling groups of masks.

Masks subclasses are basically just containers, which are defined similar as SubParameters and SubSequences subclasses:

>>> from hydpy.core.masktools import Masks
>>> from hydpy.core.masktools import IndexMask, DefaultMask, CustomMask
>>> class Masks(Masks):
...     CLASSES = (IndexMask, DefaultMask)
>>> masks = Masks()

The contained mask classes are available via attribute access in lower case letters:

>>> masks
indexmask of module hydpy.core.masktools
defaultmask of module hydpy.core.masktools
>>> masks.indexmask is IndexMask
True
>>> "indexmask" in dir(masks)
True

The in operator is supported:

>>> IndexMask in masks
True
>>> CustomMask in masks
False
>>> "mask" in masks
Traceback (most recent call last):
...
TypeError: The given value `mask` of type `str` is neither a Mask class nor a Mask instance.

Using item access, strings (in whatever case), mask classes, and mask objects are accepted:

>>> masks["IndexMask"] is IndexMask
True
>>> masks["indexmask"] is IndexMask
True
>>> masks[IndexMask] is IndexMask
True
>>> masks[CustomMask()]
Traceback (most recent call last):
...
RuntimeError: While trying to retrieve a mask based on key `CustomMask([])`, the following error occurred: The key does not define an available mask.
>>> masks["test"]
Traceback (most recent call last):
...
RuntimeError: While trying to retrieve a mask based on key `'test'`, the following error occurred: The key does not define an available mask.
>>> masks[1]
Traceback (most recent call last):
...
TypeError: While trying to retrieve a mask based on key `1`, the following error occurred: The given key is neither a `string` a `mask` type.
property name: Literal['masks']

masks

>>> from hydpy.core.masktools import Masks
>>> Masks().name
'masks'
class hydpy.core.masktools.NodeMasks[source]

Bases: Masks

Masks subclass for class Node.

At the moment, the purpose of class NodeMasks is to make the implementation of ModelSequence and NodeSequence more similar. It will become relevant for applications as soon as we support 1-dimensional node sequences.