itemtools¶
This module implements so-called exchange items, simplifying the
modification of the values of Parameter and Sequence_ objects.
Module itemtools implements the following members:
ExchangeSpecificationSpecification of a specificParameterorSequence_type.
ExchangeItemBase class for exchanging values with multipleParameterorSequence_objects of a certain type.
ChangeItemBase class for changing the values of multipleParameterorSequence_objects of a specific type.
SetItemItem for assigningvalueto multipleParameterorSequence_objects of a specific type.
MathItemBase class for performing some mathematical operations on the given values before assigning them to the handled target variables.
GetItemBase class for querying the values of multipleParameterorSequence_objects of a specific type.
-
class
hydpy.core.itemtools.ExchangeSpecification(master: str, variable: str)[source]¶ Bases:
objectSpecification of a specific
ParameterorSequence_type.ExchangeSpecificationis a helper class forExchangeItemand its subclasses. Its constructor interprets two strings (without any checks on plausibility) and makes their information available as attributes. The following tests list the expected cases:>>> from hydpy.core.itemtools import ExchangeSpecification >>> ExchangeSpecification("hland_v1", "fluxes.qt") ExchangeSpecification("hland_v1", "fluxes.qt") >>> ExchangeSpecification("hland_v1", "fluxes.qt.series") ExchangeSpecification("hland_v1", "fluxes.qt.series") >>> ExchangeSpecification("node", "sim") ExchangeSpecification("node", "sim") >>> ExchangeSpecification("node", "sim.series") ExchangeSpecification("node", "sim.series")
The following attributes are accessible:
>>> spec = ExchangeSpecification("hland_v1", "fluxes.qt") >>> spec ExchangeSpecification("hland_v1", "fluxes.qt") >>> spec.master 'hland_v1' >>> spec.subgroup 'fluxes' >>> spec.variable 'qt' >>> spec.series False
-
property
specstring¶ The string corresponding to the current values of subgroup, state, and variable.
>>> from hydpy.core.itemtools import ExchangeSpecification >>> spec = ExchangeSpecification("hland_v1", "fluxes.qt") >>> spec.specstring 'fluxes.qt' >>> spec.series = True >>> spec.specstring 'fluxes.qt.series' >>> spec.subgroup = None >>> spec.specstring 'qt.series'
-
property
-
class
hydpy.core.itemtools.ExchangeItem[source]¶ Bases:
objectBase class for exchanging values with multiple
ParameterorSequence_objects of a certain type.-
targetspecs: hydpy.core.itemtools.ExchangeSpecification¶
-
device2target: Dict[Union[hydpy.core.devicetools.Node, hydpy.core.devicetools.Element], hydpy.core.variabletools.Variable[Any, Any]]¶
-
collect_variables(selections: hydpy.core.selectiontools.Selections) → None[source]¶ Apply method
insert_variables()to collect the relevant target variables handled by the devices of the givenSelectionsobject.We prepare the LahnH example project to be able to use its
Selectionsobject:>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2()
We change the type of a specific application model to the type of its base model for reasons explained later:
>>> from hydpy.models.hland import Model >>> hp.elements.land_lahn_3.model.__class__ = Model
We prepare a
SetItemas an example, handling allIcsequences corresponding to any application models derived fromhland:>>> from hydpy import SetItem >>> item = SetItem("ic", "hland", "states.ic", 0) >>> item.targetspecs ExchangeSpecification("hland", "states.ic")
Applying method
collect_variables()connects theSetItemobject with all four relevantIcobjects:>>> item.collect_variables(pub.selections) >>> land_dill = hp.elements.land_dill >>> sequence = land_dill.model.sequences.states.ic >>> item.device2target[land_dill] is sequence True >>> for element in sorted(item.device2target, key=lambda x: x.name): ... print(element) land_dill land_lahn_1 land_lahn_2 land_lahn_3
Asking for
Icobjects corresponding to application modelhland_v1only, results in skipping theElementland_lahn_3 (handling thehlandbase model due to the hack above):>>> item = SetItem("ic", "hland_v1", "states.ic", 0) >>> item.collect_variables(pub.selections) >>> for element in sorted(item.device2target, key=lambda x: x.name): ... print(element) land_dill land_lahn_1 land_lahn_2
Selecting a series of a variable instead of the variable itself only affects the targetspec attribute:
>>> item = SetItem("t", "hland_v1", "inputs.t.series", 0) >>> item.collect_variables(pub.selections) >>> item.targetspecs ExchangeSpecification("hland_v1", "inputs.t.series") >>> sequence = land_dill.model.sequences.inputs.t >>> item.device2target[land_dill] is sequence True
To pass an ill-defined subgroup name results in the following error:
>>> from hydpy import SetItem >>> item = SetItem("ic", "hland", "wrong_group.wrong_variable", 0) >>> item.collect_variables(pub.selections) Traceback (most recent call last): ... RuntimeError: Model `hland_v1` of element `land_dill` does neither handle a parameter of sequence subgroup named `wrong_group.
It is both possible to address sequences of
Nodeobjects, as well as their time series, by arguments “node” and “nodes”:>>> item = SetItem("sim", "node", "sim", 0) >>> item.collect_variables(pub.selections) >>> dill = hp.nodes.dill >>> item.targetspecs ExchangeSpecification("node", "sim") >>> item.device2target[dill] is dill.sequences.sim True >>> for node in sorted(item.device2target, key=lambda x: x.name): ... print(node) dill lahn_1 lahn_2 lahn_3 >>> item = SetItem("sim", "nodes", "sim.series", 0) >>> item.collect_variables(pub.selections) >>> item.targetspecs ExchangeSpecification("nodes", "sim.series") >>> for node in sorted(item.device2target, key=lambda x: x.name): ... print(node) dill lahn_1 lahn_2 lahn_3
-
insert_variables(device2variable: Dict[Union[hydpy.core.devicetools.Node, hydpy.core.devicetools.Element], hydpy.core.variabletools.Variable[Any, Any]], exchangespec: hydpy.core.itemtools.ExchangeSpecification, selections: hydpy.core.selectiontools.Selections) → None[source]¶ Determine the relevant target or base variables (as defined by the given
ExchangeSpecificationobject) handled by the givenSelectionsobject and insert them into the given device2variable dictionary.
-
-
class
hydpy.core.itemtools.ChangeItem[source]¶ Bases:
hydpy.core.itemtools.ExchangeItemBase class for changing the values of multiple
ParameterorSequence_objects of a specific type.-
device2target: Dict[Union[hydpy.core.devicetools.Node, hydpy.core.devicetools.Element], hydpy.core.variabletools.Variable[Any, Any]]¶
-
property
shape¶ The shape of the target variables.
Trying to access property
shapebefore calling methodcollect_variables()results in the following error:>>> from hydpy import SetItem >>> SetItem("name", "master", "target", 0).shape Traceback (most recent call last): ... RuntimeError: The shape of SetItem `name` has not been determined so far.
See method
collect_variables()for further information.
-
property
value¶ The value(s) that can be used to change the values of target variables through applying method
update_variables()of classChangeItem.>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> from hydpy import SetItem >>> item = SetItem("ic", "hland", "states.ic", 0) >>> item.collect_variables(pub.selections) >>> item.value = 1 >>> item.value array(1.0) >>> item.value = 1, 2 Traceback (most recent call last): ... ValueError: When trying to convert the value(s) `(1, 2)` assigned to SetItem `ic` to a numpy array of shape `()` and type `float`, the following error occurred: could not broadcast input array from shape (2,) into shape ()
-
update_variables() → None[source]¶ Subclasses must define a mathematical operation for updating the values of target variables.
>>> from hydpy.core.itemtools import ChangeItem >>> ChangeItem().update_variables() Traceback (most recent call last): ... NotImplementedError
-
collect_variables(selections: hydpy.core.selectiontools.Selections) → None[source]¶ Apply method
collect_variables()of the base classExchangeItemand determine theshapeof the currentChangeItemobject afterwards, depending on its dimensionality and eventually on the shape of its target variables.For the following examples, we prepare the LahnH example project:
>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2()
0-dimensional change-items do not have a variable shape, which is indicated by an empty tuple:
>>> from hydpy import SetItem >>> item = SetItem("ic", "hland", "states.ic", 0) >>> item.collect_variables(pub.selections) >>> item.shape ()
1-dimensional change-items take the shape of their target variables, which must be equal for all instances:
>>> item = SetItem("ic", "hland", "states.ic", 1) >>> item.collect_variables(pub.selections) Traceback (most recent call last): ... RuntimeError: SetItem `ic` cannot handle target variables of different shapes.
>>> for element in hp.elements.catchment: ... element.model.parameters.control.nmbzones(3) >>> item = SetItem("ic", "hland", "states.ic", 1) >>> item.collect_variables(pub.selections) >>> item.shape (3,)
Passing a
Selectionsobject not containing any relevant target variables results in the following error:>>> item = SetItem("ic", "hland", "states.ic", 1) >>> from hydpy import Selections >>> item.collect_variables(Selections()) Traceback (most recent call last): ... RuntimeError: Cannot determine the shape of the actual `SetItem` object, as the given `Selections` object does not handle any relevant target variables.
-
update_variable(variable: hydpy.core.variabletools.Variable[Any, Any], value: numpy.ndarray) → None[source]¶ Assign the given value(s) to the given target or base variable.
If the assignment fails,
update_variable()raises an error like the following:>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> item = SetItem("alpha", "hland_v1", "control.alpha", 0) >>> item.collect_variables(pub.selections) >>> item.update_variables() Traceback (most recent call last): ... TypeError: When trying to update a target variable of SetItem `alpha` with the value(s) `None`, the following error occurred: While trying to set the value(s) of variable `alpha` of element `...`, the following error occurred: The given value `None` cannot be converted to type `float`.
-
-
class
hydpy.core.itemtools.SetItem(name: str, master: str, target: str, ndim: int)[source]¶ Bases:
hydpy.core.itemtools.ChangeItemItem for assigning
valueto multipleParameterorSequence_objects of a specific type.-
targetspecs: hydpy.core.itemtools.ExchangeSpecification¶
-
device2target: Dict[Union[hydpy.core.devicetools.Node, hydpy.core.devicetools.Element], hydpy.core.variabletools.Variable[Any, Any]]¶
-
update_variables() → None[source]¶ Assign the current objects
valueto the values of the target variables.We use the LahnH project in the following:
>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2()
In the first example, a 0-dimensional
SetItemchanges the value of the 0-dimensional parameterAlpha:>>> from hydpy.core.itemtools import SetItem >>> item = SetItem("alpha", "hland_v1", "control.alpha", 0) >>> item SetItem("alpha", "hland_v1", "control.alpha", 0) >>> item.collect_variables(pub.selections) >>> item.value is None True >>> land_dill = hp.elements.land_dill >>> land_dill.model.parameters.control.alpha alpha(1.0) >>> item.value = 2.0 >>> item.value array(2.0) >>> land_dill.model.parameters.control.alpha alpha(1.0) >>> item.update_variables() >>> land_dill.model.parameters.control.alpha alpha(2.0)
In the second example, a 0-dimensional
SetItemchanges the values of the 1-dimensional parameterFC:>>> item = SetItem("fc", "hland_v1", "control.fc", 0) >>> item.collect_variables(pub.selections) >>> item.value = 200.0 >>> land_dill.model.parameters.control.fc fc(278.0) >>> item.update_variables() >>> land_dill.model.parameters.control.fc fc(200.0)
In the third example, a 1-dimensional
SetItemchanges the values of the 1-dimensional sequenceIc:>>> for element in hp.elements.catchment: ... element.model.parameters.control.nmbzones(5) ... element.model.parameters.control.icmax(4.0) >>> item = SetItem("ic", "hland_v1", "states.ic", 1) >>> item.collect_variables(pub.selections) >>> land_dill.model.sequences.states.ic ic(nan, nan, nan, nan, nan) >>> item.value = 2.0 >>> item.update_variables() >>> land_dill.model.sequences.states.ic ic(2.0, 2.0, 2.0, 2.0, 2.0) >>> item.value = 1.0, 2.0, 3.0, 4.0, 5.0 >>> item.update_variables() >>> land_dill.model.sequences.states.ic ic(1.0, 2.0, 3.0, 4.0, 4.0)
-
-
class
hydpy.core.itemtools.MathItem(name: str, master: str, target: str, base: str, ndim: int)[source]¶ Bases:
hydpy.core.itemtools.ChangeItemBase class for performing some mathematical operations on the given values before assigning them to the handled target variables.
Subclasses of
MathItemlikeAddItemhandle not only target variables but also base variables:>>> from hydpy import AddItem >>> item = AddItem( ... "sfcf", "hland_v1", "control.sfcf", "control.rfcf", 0) >>> item AddItem("sfcf", "hland_v1", "control.sfcf", "control.rfcf", 0) >>> item.targetspecs ExchangeSpecification("hland_v1", "control.sfcf") >>> item.basespecs ExchangeSpecification("hland_v1", "control.rfcf")
Generally, a
MathItemcalculates the target variable of a specificDeviceobject by using its currentvalueand the value(s) of the base variable of the sameDevice.-
basespecs: hydpy.core.itemtools.ExchangeSpecification¶
-
device2base: Dict[Union[hydpy.core.devicetools.Node, hydpy.core.devicetools.Element], hydpy.core.variabletools.Variable[Any, Any]]¶
-
collect_variables(selections: hydpy.core.selectiontools.Selections) → None[source]¶ Apply method
collect_variables()of the base classChangeItemand also apply methodinsert_variables()of classExchangeItemto collect the relevant base variables handled by the devices of the givenSelectionsobject.>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> from hydpy import AddItem >>> item = AddItem("alpha", "hland_v1", "control.sfcf", "control.rfcf", 0) >>> item.collect_variables(pub.selections) >>> land_dill = hp.elements.land_dill >>> control = land_dill.model.parameters.control >>> item.device2target[land_dill] is control.sfcf True >>> item.device2base[land_dill] is control.rfcf True >>> for device in sorted(item.device2base, key=lambda x: x.name): ... print(device) land_dill land_lahn_1 land_lahn_2 land_lahn_3
-
-
class
hydpy.core.itemtools.AddItem(name: str, master: str, target: str, base: str, ndim: int)[source]¶ Bases:
hydpy.core.itemtools.MathItemMathItemsubclass performing additions.-
update_variables() → None[source]¶ Add the general
valuewith theDevicespecific base variable and assign the result to the respective target variable.>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> from hydpy.models.hland_v1 import FIELD >>> for element in hp.elements.catchment: ... control = element.model.parameters.control ... control.nmbzones(3) ... control.zonetype(FIELD) ... control.rfcf(1.1) >>> from hydpy.core.itemtools import AddItem >>> item = AddItem( ... "sfcf", "hland_v1", "control.sfcf", "control.rfcf", 1) >>> item.collect_variables(pub.selections) >>> land_dill = hp.elements.land_dill >>> land_dill.model.parameters.control.sfcf sfcf(?) >>> item.value = -0.1, 0.0, 0.1 >>> item.update_variables() >>> land_dill.model.parameters.control.sfcf sfcf(1.0, 1.1, 1.2)
>>> land_dill.model.parameters.control.rfcf.shape = 2 >>> land_dill.model.parameters.control.rfcf = 1.1 >>> item.update_variables() Traceback (most recent call last): ... ValueError: When trying to add the value(s) `[-0.1 0. 0.1]` of AddItem `sfcf` and the value(s) `[ 1.1 1.1]` of variable `rfcf` of element `land_dill`, the following error occurred: operands could not be broadcast together with shapes (2,) (3,)...
-
basespecs: hydpy.core.itemtools.ExchangeSpecification¶
-
device2base: Dict[Union[hydpy.core.devicetools.Node, hydpy.core.devicetools.Element], hydpy.core.variabletools.Variable[Any, Any]]¶
-
device2target: Dict[Union[hydpy.core.devicetools.Node, hydpy.core.devicetools.Element], hydpy.core.variabletools.Variable[Any, Any]]¶
-
targetspecs: hydpy.core.itemtools.ExchangeSpecification¶
-
-
class
hydpy.core.itemtools.GetItem(master: str, target: str)[source]¶ Bases:
hydpy.core.itemtools.ExchangeItemBase class for querying the values of multiple
ParameterorSequence_objects of a specific type.-
collect_variables(selections: hydpy.core.selectiontools.Selections) → None[source]¶ Apply method
collect_variables()of the base classExchangeItemand determine the ndim attribute of the currentChangeItemobject afterwards.The value of ndim depends on whether the values of the target variable or its time series are of interest:
>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> from hydpy.core.itemtools import SetItem >>> for target in ("states.lz", "states.lz.series", ... "states.sm", "states.sm.series"): ... item = GetItem("hland_v1", target) ... item.collect_variables(pub.selections) ... print(item, item.ndim) GetItem("hland_v1", "states.lz") 0 GetItem("hland_v1", "states.lz.series") 1 GetItem("hland_v1", "states.sm") 1 GetItem("hland_v1", "states.sm.series") 2
-
yield_name2value(idx1: Optional[int] = None, idx2: Optional[int] = None) → Iterator[Tuple[str, str]][source]¶ Sequentially return name-value-pairs describing the current state of the target variables.
The names are automatically generated and contain both the name of the
Deviceof the respectiveVariableobject and the target description:>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> from hydpy.core.itemtools import SetItem >>> item = GetItem("hland_v1", "states.lz") >>> item.collect_variables(pub.selections) >>> hp.elements.land_dill.model.sequences.states.lz = 100.0 >>> for name, value in item.yield_name2value(): ... print(name, value) land_dill_states_lz 100.0 land_lahn_1_states_lz 8.18711 land_lahn_2_states_lz 10.14007 land_lahn_3_states_lz 7.52648 >>> item = GetItem("hland_v1", "states.sm") >>> item.collect_variables(pub.selections) >>> hp.elements.land_dill.model.sequences.states.sm = 2.0 >>> for name, value in item.yield_name2value(): ... print(name, value) land_dill_states_sm [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0] land_lahn_1_states_sm [99.27505, ..., 142.84148] ...
When querying time series, one can restrict the span of interest by passing index values:
>>> item = GetItem("nodes", "sim.series") >>> item.collect_variables(pub.selections) >>> hp.nodes.dill.sequences.sim.series = 1.0, 2.0, 3.0, 4.0 >>> for name, value in item.yield_name2value(): ... print(name, value) dill_sim_series [1.0, 2.0, 3.0, 4.0] lahn_1_sim_series [nan, ... ... >>> for name, value in item.yield_name2value(2, 3): ... print(name, value) dill_sim_series [3.0] lahn_1_sim_series [nan] ...
-