selectiontools¶
This module implements tools for defining subsets of Node
and Element
objects of
large HydPy projects, called “selections”.
Module selectiontools
implements the following members:
Selections
Collection class forSelection
objects.
Selection
Handles and modifies combinations ofNode
andElement
objects.
- class hydpy.core.selectiontools.Selections(*selections: Selection)[source]¶
Bases:
object
Collection class for
Selection
objects.You can pass an arbitrary number of
Selection
objects to the constructor of classSelections
:>>> sel1 = Selection("sel1", ["node1", "node2"], ["element1"]) >>> sel2 = Selection("sel2", ["node1", "node3"], ["element2"]) >>> selections = Selections(sel1, sel2) >>> selections Selections("sel1", "sel2")
Also, you can query, add, and remove
Selection
objects via attribute access:>>> selections.sel3 Traceback (most recent call last): ... AttributeError: The actual Selections object handles neither a normal attribute nor a Selection object called `sel3`... >>> sel3 = Selection("sel3", ["node1", "node4"], ["element3"]) >>> selections.sel3 = sel3 >>> selections.sel3 Selection("sel3", nodes=("node1", "node4"), elements="element3") >>> "sel3" in dir(selections) True >>> del selections.sel3 >>> "sel3" in dir(selections) False >>> del selections.sel3 Traceback (most recent call last): ... AttributeError: The actual Selections object handles neither a normal attribute nor a Selection object called `sel3` that could be deleted.
Attribute names must be consistent with the name attribute of the respective
Selection
object:>>> selections.sel4 = sel3 Traceback (most recent call last): ... ValueError: To avoid inconsistencies when handling Selection objects as attributes of a Selections object, attribute name and Selection name must be identical. However, for selection `sel3` the given attribute name is `sel4`.
You can use item access alternatively:
>>> selections["sel4"] Traceback (most recent call last): ... KeyError: 'The actual Selections object does not handle a Selection object called `sel4`.' >>> selections["sel4"] = Selection("sel4") >>> selections["sel4"] Selection("sel4", nodes=(), elements=()) >>> del selections["sel4"] >>> del selections["sel4"] Traceback (most recent call last): ... KeyError: 'The actual Selections object does not handle a Selection object called `sel4` that could be deleted.'
You can ask for the existence of specific
Selection
objects within aSelections
object both via its name and via the object itself:>>> sel1 in selections True >>> "sel1" in selections True >>> sel3 in selections False >>> "sel3" in selections False
Class
Selections
supports both theiter()
andlen()
operators:>>> for selection in selections: ... print(selection.name) sel1 sel2 >>> len(selections) 2
For convenience, use the “+”, “-”, “+=”, and “-=” operators to compare and modify
Selections
objects either based on singleSelection
objects or collections ofSelection
objects:>>> larger = selections + sel3 >>> smaller = selections - sel2 >>> sorted(selections.names) ['sel1', 'sel2'] >>> sorted(larger.names) ['sel1', 'sel2', 'sel3'] >>> smaller.names ('sel1',)
>>> smaller += larger >>> sorted(smaller.names) ['sel1', 'sel2', 'sel3'] >>> smaller -= sel1, sel2 >>> smaller.names ('sel3',)
Note that trying to remove non-existing
Selection
objects does not raise errors:>>> smaller -= sel2 >>> smaller.names ('sel3',) >>> smaller - (sel1, sel2, sel3) Selections()
The binary operators do not support types other than the mentioned ones:
>>> smaller -= "sel3" Traceback (most recent call last): ... TypeError: Binary operations on Selections objects are defined for other Selections objects, single Selection objects, or iterables containing `Selection` objects, but the type of the given argument is `str`. >>> smaller -= 1 Traceback (most recent call last): ... TypeError: ... is `int`.
Use the “==” operator to compare two
Selections
objects:>>> larger == smaller False >>> larger == (smaller + selections) True >>> larger == (sel1, sel2, sel3) False
- property names: tuple[str, ...]¶
The names of the actual
Selection
objects.>>> from hydpy import Selection, Selections >>> selections = Selections( ... Selection("sel1", ["node1", "node2"], ["element1"]), ... Selection("sel2", ["node1", "node3"], ["element2"])) >>> sorted(selections.names) ['sel1', 'sel2']
- property nodes: Nodes¶
The
Node
objects of all handledSelection
objects.>>> from hydpy import Selection, Selections >>> selections = Selections( ... Selection("sel1", ["node1", "node2"], ["element1"]), ... Selection("sel2", ["node1", "node3"], ["element2"])) >>> selections.nodes Nodes("node1", "node2", "node3")
- property elements: Elements¶
The
Element
objects of all handledSelection
objects.>>> from hydpy import Selection, Selections >>> selections = Selections( ... Selection("sel1", ["node1"], ["element1"]), ... Selection("sel2", ["node1"], ["element2", "element3"])) >>> selections.elements Elements("element1", "element2", "element3")
- property complete: Selection¶
An automatically created selection that comprises the nodes and elements of all currently available, user-defined selections.
>>> from hydpy import Selection, Selections >>> selections = Selections( ... Selection("sel1", ["node1"], ["element1"]), ... Selection("sel2", ["node1"], ["element2", "element3"])) >>> selections.complete Selection("complete", nodes="node1", elements=("element1", "element2", "element3"))
The selection
complete
is always freshly created and so reflects the current stateSelections
instance:>>> selections.sel1.nodes.add_device("node2") >>> selections.complete Selection("complete", nodes=("node1", "node2"), elements=("element1", "element2", "element3"))
Therefore, changing the
Selection
object returned by propertycomplete
does neither change theSelections
object nor subsequentially returnedcomplete
selections:>>> selections.complete.nodes.add_device("node3") >>> assert "node3" not in selections.nodes >>> selections.complete Selection("complete", nodes=("node1", "node2"), elements=("element1", "element2", "element3"))
Item access is provided:
>>> assert selections["complete"] == selections.complete
Selection
complete
is ignored when iterating through the user-defined selections:>>> assert len(selections) == 2
- add_selections(*selections: Selection) None [source]¶
Add the given
Selection
object(s) to the currentSelections
object.>>> from hydpy import Selection, Selections >>> selections = Selections(Selection("sel1", ["node1"], ["element1"])) >>> selections.add_selections( ... Selection("sel2", ["node1"], ["element2", "element3"]), ... Selection("sel3", ["node2"], [])) >>> selections Selections("sel1", "sel2", "sel3") >>> selections.nodes Nodes("node1", "node2") >>> selections.elements Elements("element1", "element2", "element3")
Selections
rejects anySelection
objects named complete to avoid conflicts with the automatically createdcomplete
selection:>>> selections.add_selections(Selection("complete")) Traceback (most recent call last): ... ValueError: You cannot assign a selection with the name `complete` to a `Selections` object because it would conflict with the selection automatically created by its property `Selections.complete`.
- remove_selections(*selections: Selection) None [source]¶
Remove the given
Selection
object(s) from the currentSelections
object.>>> from hydpy import Selection, Selections >>> selections = Selections( ... Selection("sel1", ["node1"], ["element1"]), ... Selection("sel2", ["node1"], ["element2", "element3"])) >>> selections.remove_selections( ... Selection("sel3", ["node2"], []), selections["sel1"]) >>> selections Selections("sel2") >>> selections.nodes Nodes("node1") >>> selections.elements Elements("element2", "element3")
- find(device: devicetools.NodeOrElement) Selections [source]¶
Return all
Selection
objects containing the givenNode
orElement
object.>>> from hydpy import Elements, Nodes, Selection, Selections >>> nodes = Nodes("n1", "n2", "n3") >>> elements = Elements("e1", "e2") >>> selections = Selections( ... Selection("s1", ["n1", "n2"], ["e1"]), ... Selection("s2", ["n1"])) >>> selections.find(nodes.n1) Selections("s1", "s2") >>> selections.find(nodes.n2) Selections("s1") >>> selections.find(nodes.n3) Selections() >>> selections.find(elements.e1) Selections("s1") >>> selections.find(elements.e2) Selections()
- query_intersections(selection2element: bool = True) dict[Selection, dict[Selection, Elements]] | dict[Element, Selections] [source]¶
A dictionary covering all cases where one
Element
object is a member of multipleSelection
objects.The dictionary’s structure depends on the value of the optional argument selection2element. See method
print_intersections()
for an example.
- print_intersections(selection2element: bool = True) None [source]¶
Print the result of method
query_intersections()
.We use method
print_intersections()
to check if any combination of the following selections handles the same elements.>>> from hydpy import Selection, Selections >>> selections = Selections( ... Selection("s1", nodes="n1",elements=("e1", "e2", "e3")), ... Selection("s2", nodes="n1", elements=("e2", "e3", "e4")), ... Selection("s3", nodes="n1", elements="e3"), ... Selection("s4", nodes="n1", elements=("e5", "e6")), ... )
If we call method
print_intersections()
with argument selection2elementTrue
, we find out which selection intersects with which other and which elements are affected:>>> selections.print_intersections() selection s1 intersects with... ...selection s2 due to the following elements: e2 and e3 ...selection s3 due to the following elements: e3 selection s2 intersects with... ...selection s1 due to the following elements: e2 and e3 ...selection s3 due to the following elements: e3 selection s3 intersects with... ...selection s1 due to the following elements: e3 ...selection s2 due to the following elements: e3
If we call method
print_intersections()
with argument selection2elementFalse
, we find out which element occurs multiple times in which selections:>>> selections.print_intersections(selection2element=False) element e2 is a member of multiple selections: s1 and s2 element e3 is a member of multiple selections: s1, s2, and s3
- class hydpy.core.selectiontools.Selection(name: str, nodes: devicetools.NodesConstrArg = None, elements: devicetools.ElementsConstrArg = None)[source]¶
Bases:
object
Handles and modifies combinations of
Node
andElement
objects.In HydPy,
Node
, andElement
objects are the fundamental means to structure projects. However, keeping the overview of huge projects involving thousands of nodes and elements requires additional strategies.One such strategy is to define different instances of class
Selection
for different aspects of a project. Often, a selection contains all nodes and elements of a certain subcatchment or all elements handling certain model types. Selections can be overlapping, meaning, for example, that an element can be part of a subcatchment selection and of model-type selection at the same time.Selections can be written to and read from individual network files, as explained in the documentation on class
NetworkManager
. Read selections are available via thepub
module. In most application scripts (e.g. for parameter calibration), one performs different operations on the nodes and elements of the different selections (e.g. change parameter “a” and “b” for models of selection “x” and “y”, respectively). However, classSelection
also provides features for creating combinations ofNode
andElement
objects suitable for different tasks, as explained in the documentation of the respective methods. Here we only show its basic usage with the help of the HydPy-H-Lahn example project prepared by functionprepare_full_example_2()
:>>> from hydpy.core.testtools import prepare_full_example_2 >>> _, pub, _ = prepare_full_example_2()
For example, HydPy-H-Lahn defines a headwaters selection:
>>> pub.selections.headwaters Selection("headwaters", nodes=("dill_assl", "lahn_marb"), elements=("land_dill_assl", "land_lahn_marb"))
You can compare this selection with other new or already available selections, with “headwaters < complete” returning
True
meaning that all nodes and elements of the headwater catchments are also part of the entire catchment:>>> from hydpy import Selection >>> test = Selection("test", ... elements=("land_dill_assl", "land_lahn_marb"), ... nodes=("dill_assl", "lahn_marb")) >>> pub.selections.headwaters < test False >>> pub.selections.headwaters <= test True >>> pub.selections.headwaters == test True >>> pub.selections.headwaters != test False >>> pub.selections.headwaters >= test True >>> pub.selections.headwaters > test False >>> pub.selections.headwaters < pub.selections.complete True >>> pub.selections.headwaters <= pub.selections.complete True >>> pub.selections.headwaters == pub.selections.complete False >>> pub.selections.headwaters != pub.selections.complete True >>> pub.selections.headwaters >= pub.selections.complete False >>> pub.selections.headwaters > pub.selections.complete False
The
len()
operator returns the total number of handled node and element objects:>>> len(test) 4
Use the “+=” and “-=” operators to add or remove nodes and elements:
>>> test += pub.selections.complete >>> len(test) 11 >>> test -= pub.selections.complete >>> len(test) 0
Passing a wrong argument to the binary operators results in errors like the following:
>>> test += 1 Traceback (most recent call last): ... AttributeError: While trying to add selection `test` with object `1` of type `int`, the following error occurred: 'int' object has no attribute 'nodes' >>> test -= pub.selections.complete.nodes.dill_assl Traceback (most recent call last): ... AttributeError: While trying to subtract selection `test` with object `dill_assl` of type `Node`, the following error occurred: 'Node' object has no attribute 'nodes' >>> test < "wrong" Traceback (most recent call last): ... AttributeError: While trying to compare selection `test` with object `wrong` of type `str`, the following error occurred: 'str' object has no attribute 'nodes'
But as usual, checking for equality or inequality returns
False
andTrue
for uncomparable objects:>>> test == "wrong" False >>> test != "wrong" True
Applying the
str
function only returns the selection name:>>> str(test) 'test'
- nodes: Nodes¶
The explicitly handled
Node
objects (m).nodes
does not necessarily contain all nodes to which the elements inelements
are linked.
- elements: Elements¶
The explicitly handled
Element
objects.elements
does not necessarily contain all nodes to which the elements innodes
are linked.
- search_upstream(device: devicetools.NodeOrElement, name: str = 'upstream', inclusive: bool = True) Selection [source]¶
Return the network upstream of the given starting point, including the starting point itself.
>>> from hydpy.core.testtools import prepare_full_example_2 >>> hp, pub, _ = prepare_full_example_2()
You can pass both
Node
andElement
objects and, optionally, the name of the newly createdSelection
object:>>> test = pub.selections.complete.copy("test") >>> test.search_upstream(hp.nodes.lahn_leun) Selection("upstream", nodes=("dill_assl", "lahn_leun", "lahn_marb"), elements=("land_dill_assl", "land_lahn_leun", "land_lahn_marb", "stream_dill_assl_lahn_leun", "stream_lahn_marb_lahn_leun")) >>> test.search_upstream(hp.elements.stream_lahn_marb_lahn_leun, "UPSTREAM") Selection("UPSTREAM", nodes=("lahn_leun", "lahn_marb"), elements=("land_lahn_marb", "stream_lahn_marb_lahn_leun"))
Method
search_upstream()
generally selects allNode
objects directly connected to any upstreamElement
object. Set the inclusive argument toFalse
to circumvent this:>>> test.search_upstream(hp.elements.stream_lahn_marb_lahn_leun, "UPSTREAM", ... False) Selection("UPSTREAM", nodes="lahn_marb", elements=("land_lahn_marb", "stream_lahn_marb_lahn_leun"))
Wrong device specifications result in errors like the following:
>>> test.search_upstream(1) Traceback (most recent call last): ... TypeError: While trying to determine an upstream network of selection `test`, the following error occurred: Either a `Node` or an `Element` object is required as the "outlet device", but the given `device` value is of type `int`.
>>> pub.selections.headwaters.search_upstream(hp.nodes.lahn_kalk) Traceback (most recent call last): ... KeyError: "While trying to determine an upstream network of selection `headwaters`, the following error occurred: 'No node named `lahn_kalk` available.'"
Method
select_upstream()
restricts the current selection to the one determined with the methodsearch_upstream()
:>>> test.select_upstream(hp.nodes.lahn_leun) Selection("test", nodes=("dill_assl", "lahn_leun", "lahn_marb"), elements=("land_dill_assl", "land_lahn_leun", "land_lahn_marb", "stream_dill_assl_lahn_leun", "stream_lahn_marb_lahn_leun"))
On the contrary, the method
deselect_upstream()
restricts the current selection to all devices not determined by methodsearch_upstream()
:>>> complete = pub.selections.complete.deselect_upstream(hp.nodes.lahn_leun) >>> complete Selection("complete", nodes="lahn_kalk", elements=("land_lahn_kalk", "stream_lahn_leun_lahn_kalk"))
If necessary, include the “outlet device” manually afterwards:
>>> complete.nodes.add_device(hp.nodes.lahn_leun) >>> complete Selection("complete", nodes=("lahn_kalk", "lahn_leun"), elements=("land_lahn_kalk", "stream_lahn_leun_lahn_kalk"))
Method
search_downstream()
generally selects allNode
objects directly connected to any upstreamElement
object. Set the inclusive argument toFalse
to circumvent this:>>> from hydpy import Element, Nodes, Selection >>> nodes = Nodes( ... "inlet", "outlet1", "outlet2", "input_", "output", "receiver", "sender") >>> upper = Element("upper", ... inlets=nodes.inlet, outlets=(nodes.outlet1, nodes.outlet2), ... inputs=nodes.input_, outputs=nodes.output, ... receivers=nodes.receiver, senders=nodes.sender) >>> test = Selection("test", nodes=nodes, elements=upper) >>> test.search_upstream(nodes.outlet1, inclusive=True) Selection("upstream", nodes=("inlet", "input_", "outlet1", "outlet2", "output", "receiver", "sender"), elements="upper") >>> test.search_upstream(nodes.outlet1, inclusive=False) Selection("upstream", nodes=("inlet", "input_", "outlet1"), elements="upper")
- select_upstream(device: devicetools.NodeOrElement, inclusive: bool = True) Selection [source]¶
Restrict the current selection to the network upstream of the given starting point, including the starting point itself.
See the documentation on method
search_upstream()
for additional information.
- deselect_upstream(device: devicetools.NodeOrElement, inclusive: bool = True) Selection [source]¶
Remove the network upstream of the given starting point from the current selection, including the starting point itself.
See the documentation on method
search_upstream()
for additional information.
- search_downstream(device: devicetools.NodeOrElement, name: str = 'downstream', inclusive: bool = True) Selection [source]¶
Return the network downstream of the given starting point, including the starting point itself.
>>> from hydpy.core.testtools import prepare_full_example_2 >>> hp, pub, _ = prepare_full_example_2()
You can pass both
Node
andElement
objects and, optionally, the name of the newly createdSelection
object:>>> test = pub.selections.complete.copy("test") >>> test.search_downstream(hp.nodes.lahn_marb) Selection("downstream", nodes=("lahn_kalk", "lahn_leun", "lahn_marb"), elements=("stream_lahn_leun_lahn_kalk", "stream_lahn_marb_lahn_leun")) >>> test.search_downstream(hp.elements.land_lahn_marb, "DOWNSTREAM") Selection("DOWNSTREAM", nodes=("lahn_kalk", "lahn_leun", "lahn_marb"), elements=("land_lahn_marb", "stream_lahn_leun_lahn_kalk", "stream_lahn_marb_lahn_leun"))
Wrong device specifications result in errors like the following:
>>> test.search_downstream(1) Traceback (most recent call last): ... TypeError: While trying to determine a downstream network of selection `test`, the following error occurred: Either a `Node` or an `Element` object is required as the "inlet device", but the given `device` value is of type `int`.
>>> pub.selections.headwaters.search_downstream(hp.nodes.lahn_kalk) Traceback (most recent call last): ... KeyError: "While trying to determine a downstream network of selection `headwaters`, the following error occurred: 'No node named `lahn_kalk` available.'"
Method
select_downstream()
restricts the current selection to the one determined with the methodsearch_upstream()
:>>> test.select_downstream(hp.nodes.lahn_marb) Selection("test", nodes=("lahn_kalk", "lahn_leun", "lahn_marb"), elements=("stream_lahn_leun_lahn_kalk", "stream_lahn_marb_lahn_leun"))
On the contrary, the method
deselect_downstream()
restricts the current selection to all devices not determined by methodsearch_downstream()
:>>> complete = pub.selections.complete.deselect_downstream( ... hp.nodes.lahn_marb) >>> complete Selection("complete", nodes="dill_assl", elements=("land_dill_assl", "land_lahn_kalk", "land_lahn_leun", "land_lahn_marb", "stream_dill_assl_lahn_leun"))
If necessary, include the “inlet device” manually afterwards:
>>> complete.nodes.add_device(hp.nodes.lahn_marb) >>> complete Selection("complete", nodes=("dill_assl", "lahn_marb"), elements=("land_dill_assl", "land_lahn_kalk", "land_lahn_leun", "land_lahn_marb", "stream_dill_assl_lahn_leun"))
Method
search_downstream()
generally selects allNode
objects directly connected to any upstreamElement
object. Set the inclusive argument toFalse
to circumvent this:>>> from hydpy import Element, Nodes, Selection >>> nodes = Nodes( ... "inlet1", "inlet2", "outlet", "input_", "output", "receiver", "sender") >>> lower = Element("lower", ... inlets=(nodes.inlet1, nodes.inlet2), outlets=nodes.outlet, ... inputs=nodes.input_, outputs=nodes.output, ... receivers=nodes.receiver, senders=nodes.sender) >>> test = Selection("test", nodes=nodes, elements=lower) >>> test.search_downstream(nodes.inlet1, inclusive=True) Selection("downstream", nodes=("inlet1", "inlet2", "input_", "outlet", "output", "receiver", "sender"), elements="lower") >>> test.search_downstream(nodes.inlet1, inclusive=False) Selection("downstream", nodes=("inlet1", "outlet", "output"), elements="lower")
- select_downstream(device: devicetools.NodeOrElement, inclusive: bool = True) Selection [source]¶
Restrict the current selection to the network downstream of the given starting point, including the starting point itself.
See the documentation on method
search_downstream()
for additional information.
- deselect_downstream(device: devicetools.NodeOrElement, inclusive: bool = True) Selection [source]¶
Remove the network downstream of the given starting point from the current selection, including the starting point itself.
See the documentation on method
search_downstream()
for additional information.
- search_modeltypes(*models: Model | ModuleType | str, name: str = 'modeltypes') Selection [source]¶
Return a
Selection
object containing only the elements currently handling models of the given types.>>> from hydpy.core.testtools import prepare_full_example_2 >>> hp, pub, _ = prepare_full_example_2()
You can pass both
Model
objects and names and, as a keyword argument, the name of the newly createdSelection
object:>>> test = pub.selections.complete.copy("test") >>> from hydpy import prepare_model >>> hland_96 = prepare_model("hland_96")
>>> test.search_modeltypes(hland_96) Selection("modeltypes", nodes=(), elements=("land_dill_assl", "land_lahn_kalk", "land_lahn_leun", "land_lahn_marb")) >>> test.search_modeltypes( ... hland_96, "musk_classic", "lland_dd", name="MODELTYPES") Selection("MODELTYPES", nodes=(), elements=("land_dill_assl", "land_lahn_kalk", "land_lahn_leun", "land_lahn_marb", "stream_dill_assl_lahn_leun", "stream_lahn_leun_lahn_kalk", "stream_lahn_marb_lahn_leun"))
Wrong model specifications result in errors like the following:
>>> test.search_modeltypes("wrong") Traceback (most recent call last): ... ModuleNotFoundError: While trying to determine the elements of selection `test` handling the model defined by the argument(s) `wrong` of type(s) `str`, the following error occurred: No module named 'hydpy.models.wrong'
Method
select_modeltypes()
restricts the current selection to the one determined with the method thesearch_modeltypes()
:>>> test.select_modeltypes(hland_96) Selection("test", nodes=(), elements=("land_dill_assl", "land_lahn_kalk", "land_lahn_leun", "land_lahn_marb"))
On the contrary, the method
deselect_upstream()
restricts the current selection to all devices not determined by method thesearch_upstream()
:>>> pub.selections.complete.deselect_modeltypes(hland_96) Selection("complete", nodes=(), elements=("stream_dill_assl_lahn_leun", "stream_lahn_leun_lahn_kalk", "stream_lahn_marb_lahn_leun"))
- select_modeltypes(*models: Model | ModuleType | str) Selection [source]¶
Restrict the current
Selection
object to all elements containing the given model types (removes all nodes).See the documentation on method
search_modeltypes()
for additional information.
- deselect_modeltypes(*models: Model | ModuleType | str) Selection [source]¶
Restrict the current selection to all elements not containing the given model types (removes all nodes).
See the documentation on method
search_modeltypes()
for additional information.
- search_nodenames(*substrings: str, name: str = 'nodenames') Selection [source]¶
Return a new selection containing all nodes of the current selection with a name containing at least one of the given substrings.
>>> from hydpy.core.testtools import prepare_full_example_2 >>> hp, pub, _ = prepare_full_example_2()
Pass the (sub)strings as positional arguments and, optionally, the name of the newly created
Selection
object as a keyword argument:>>> test = pub.selections.complete.copy("test") >>> from hydpy import prepare_model >>> test.search_nodenames("dill_assl", "lahn_marb") Selection("nodenames", nodes=("dill_assl", "lahn_marb"), elements=())
Wrong string specifications result in errors like the following:
>>> test.search_nodenames(["dill_assl", "lahn_marb"]) Traceback (most recent call last): ... TypeError: While trying to determine the nodes of selection `test` with names containing at least one of the given substrings `['dill_assl', 'lahn_marb']`, the following error occurred: 'in <string>' requires string as left operand, not list
Method
select_nodenames()
restricts the current selection to the one determined with the the methodsearch_nodenames()
:>>> test.select_nodenames("dill_assl", "lahn_marb") Selection("test", nodes=("dill_assl", "lahn_marb"), elements=("land_dill_assl", "land_lahn_kalk", "land_lahn_leun", "land_lahn_marb", "stream_dill_assl_lahn_leun", "stream_lahn_leun_lahn_kalk", "stream_lahn_marb_lahn_leun"))
On the contrary, the method
deselect_nodenames()
restricts the current selection to all devices not determined by the methodsearch_nodenames()
:>>> pub.selections.complete.deselect_nodenames("dill_assl", "lahn_marb") Selection("complete", nodes=("lahn_kalk", "lahn_leun"), elements=("land_dill_assl", "land_lahn_kalk", "land_lahn_leun", "land_lahn_marb", "stream_dill_assl_lahn_leun", "stream_lahn_leun_lahn_kalk", "stream_lahn_marb_lahn_leun"))
- select_nodenames(*substrings: str) Selection [source]¶
Restrict the current selection to all nodes with a name containing at least one of the given substrings (does not affect any elements).
See the documentation on method
search_nodenames()
for additional information.
- deselect_nodenames(*substrings: str) Selection [source]¶
Restrict the current selection to all nodes with a name not containing at least one of the given substrings (does not affect any elements).
See the documentation on method
search_nodenames()
for additional information.
- search_elementnames(*substrings: str, name: str = 'elementnames') Selection [source]¶
Return a new selection containing all elements of the current selection with a name containing at least one of the given substrings.
>>> from hydpy.core.testtools import prepare_full_example_2 >>> hp, pub, _ = prepare_full_example_2()
Pass the (sub)strings as positional arguments and, optionally, the name of the newly created
Selection
object as a keyword argument:>>> test = pub.selections.complete.copy("test") >>> from hydpy import prepare_model >>> test.search_elementnames("dill", "lahn_marb") Selection("elementnames", nodes=(), elements=("land_dill_assl", "land_lahn_marb", "stream_dill_assl_lahn_leun", "stream_lahn_marb_lahn_leun"))
Wrong string specifications result in errors like the following:
>>> test.search_elementnames(["dill", "lahn_marb"]) Traceback (most recent call last): ... TypeError: While trying to determine the elements of selection `test` with names containing at least one of the given substrings `['dill', 'lahn_marb']`, the following error occurred: 'in <string>' requires string as left operand, not list
Method
select_elementnames()
restricts the current selection to the one determined with the methodsearch_elementnames()
:>>> test.select_elementnames("dill", "lahn_marb") Selection("test", nodes=("dill_assl", "lahn_kalk", "lahn_leun", "lahn_marb"), elements=("land_dill_assl", "land_lahn_marb", "stream_dill_assl_lahn_leun", "stream_lahn_marb_lahn_leun"))
On the contrary, the method
deselect_elementnames()
restricts the current selection to all devices not determined by the methodsearch_elementnames()
:>>> pub.selections.complete.deselect_elementnames("dill", "lahn_marb") Selection("complete", nodes=("dill_assl", "lahn_kalk", "lahn_leun", "lahn_marb"), elements=("land_lahn_kalk", "land_lahn_leun", "stream_lahn_leun_lahn_kalk"))
- select_elementnames(*substrings: str) Selection [source]¶
Restrict the current selection to all elements with a name containing at least one of the given substrings (does not affect any nodes).
See the documentation on method
search_elementnames()
for additional information.
- deselect_elementnames(*substrings: str) Selection [source]¶
Restrict the current selection to all elements with a name not containing at least one of the given substrings. (does not affect any nodes).
See the documentation on method
search_elementnames()
for additional information.
- copy(name: str) Selection [source]¶
Return a new
Selection
object with the given name and copies of the handledNodes
andElements
objects based on methodcopy()
.
- add_remotes() None [source]¶
Add all remote nodes linked to at least one of the currently handled elements.
One often encounters the situation (for example, after calling method
select_upstream()
), when a selection does not explicitly include all relevant remote nodes, like in the following example:>>> from hydpy import Element, Selection >>> dam = Element("dam", inlets="inflow", outlets="outflow", ... receivers="discharge_downstream", senders="water_level") >>> sel = Selection("Dam", elements=dam, nodes=("inflow", "outflow")) >>> sel Selection("Dam", nodes=("inflow", "outflow"), elements="dam")
The method
add_remotes()
is a small auxiliary function that takes care of this:>>> sel.add_remotes() >>> sel Selection("Dam", nodes=("discharge_downstream", "inflow", "outflow", "water_level"), elements="dam")
- save_networkfile(filepath: str | None = None, write_defaultnodes: bool = True) None [source]¶
Save the selection as a network file.
>>> from hydpy.core.testtools import prepare_full_example_2 >>> _, pub, TestIO = prepare_full_example_2()
In most cases, one should conveniently write network files via method
save_files()
of classNetworkManager
. However, using the methodsave_networkfile()
allows for additional configuration via the arguments filepath and write_defaultnodes:>>> with TestIO(): ... pub.selections.headwaters.save_networkfile() ... with open("headwaters.py") as networkfile: ... print(networkfile.read()) # -*- coding: utf-8 -*- from hydpy import Element, Node Node("dill_assl", variable="Q", keywords="gauge") Node("lahn_marb", variable="Q", keywords="gauge") Element("land_dill_assl", outlets="dill_assl", keywords="catchment") Element("land_lahn_marb", outlets="lahn_marb", keywords="catchment")
>>> with TestIO(): ... pub.selections.headwaters.save_networkfile( ... "test.py", write_defaultnodes=False) ... with open("test.py") as networkfile: ... print(networkfile.read()) # -*- coding: utf-8 -*- from hydpy import Element, Node Element("land_dill_assl", outlets="dill_assl", keywords="catchment") Element("land_lahn_marb", outlets="lahn_marb", keywords="catchment")
The write_defaultnodes argument does only affect nodes handling the default variable Q:
>>> from hydpy import FusedVariable, Node >>> from hydpy.aliases import ( ... hland_inputs_P, hland_inputs_T, lland_inputs_Nied, dam_receivers_OWL, ... hland_fluxes_Perc, hland_fluxes_Q0, hland_fluxes_Q1, ... dam_factors_WaterLevel) >>> Precip = FusedVariable("Precip", hland_inputs_P, lland_inputs_Nied) >>> Runoff = FusedVariable("Runoff", hland_fluxes_Q0, hland_fluxes_Q1) >>> Level = FusedVariable("Level", dam_receivers_OWL, dam_factors_WaterLevel) >>> nodes = pub.selections.headwaters.nodes >>> nodes.add_device(Node("test1", variable="X")) >>> nodes.add_device(Node("test2", variable=hland_inputs_T)) >>> nodes.add_device(Node("test3", variable=Precip)) >>> nodes.add_device(Node("test4", variable=hland_fluxes_Perc)) >>> nodes.add_device(Node("test5", variable=Runoff)) >>> nodes.add_device(Node("test6", variable=Level)) >>> with TestIO(): ... pub.selections.headwaters.save_networkfile( ... "test.py", write_defaultnodes=False) ... with open("test.py") as networkfile: ... print(networkfile.read()) # -*- coding: utf-8 -*- from hydpy import Element, FusedVariable, Node from hydpy.aliases import ( dam_factors_WaterLevel, dam_receivers_OWL, hland_fluxes_Perc, hland_fluxes_Q0, hland_fluxes_Q1, hland_inputs_P, hland_inputs_T, lland_inputs_Nied, ) Level = FusedVariable("Level", dam_factors_WaterLevel, dam_receivers_OWL) Precip = FusedVariable("Precip", hland_inputs_P, lland_inputs_Nied) Runoff = FusedVariable("Runoff", hland_fluxes_Q0, hland_fluxes_Q1) Node("test1", variable="X") Node("test2", variable=hland_inputs_T) Node("test3", variable=Precip) Node("test4", variable=hland_fluxes_Perc) Node("test5", variable=Runoff) Node("test6", variable=Level) Element("land_dill_assl", outlets="dill_assl", keywords="catchment") Element("land_lahn_marb", outlets="lahn_marb", keywords="catchment")