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:
SelectionsCollection class forSelectionobjects.
SelectionHandles and modifies combinations ofNodeandElementobjects.
- class hydpy.core.selectiontools.Selections(*selections: Selection)[source]¶
Bases:
objectCollection class for
Selectionobjects.You can pass an arbitrary number of
Selectionobjects 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
Selectionobjects 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
Selectionobject:>>> 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
Selectionobjects within aSelectionsobject 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
Selectionssupports 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
Selectionsobjects either based on singleSelectionobjects or collections ofSelectionobjects:>>> 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
Selectionobjects 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
Selectionsobjects:>>> larger == smaller False >>> larger == (smaller + selections) True >>> larger == (sel1, sel2, sel3) False
- property names: tuple[str, ...]¶
The names of the actual
Selectionobjects.>>> 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
Nodeobjects of all handledSelectionobjects.>>> 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
Elementobjects of all handledSelectionobjects.>>> 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
completeis always freshly created and so reflects the current stateSelectionsinstance:>>> selections.sel1.nodes.add_device("node2") >>> selections.complete Selection("complete", nodes=("node1", "node2"), elements=("element1", "element2", "element3"))
Therefore, changing the
Selectionobject returned by propertycompletedoes neither change theSelectionsobject nor subsequentially returnedcompleteselections:>>> 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
completeis ignored when iterating through the user-defined selections:>>> assert len(selections) == 2
- add_selections(*selections: Selection) None[source]¶
Add the given
Selectionobject(s) to the currentSelectionsobject.>>> 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")
Selectionsrejects anySelectionobjects named complete to avoid conflicts with the automatically createdcompleteselection:>>> 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
Selectionobject(s) from the currentSelectionsobject.>>> 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
Selectionobjects containing the givenNodeorElementobject.>>> 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
Elementobject is a member of multipleSelectionobjects.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:
objectHandles and modifies combinations of
NodeandElementobjects.In HydPy,
Node, andElementobjects 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
Selectionfor 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 thepubmodule. 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, classSelectionalso provides features for creating combinations ofNodeandElementobjects 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
Truemeaning 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
FalseandTruefor uncomparable objects:>>> test == "wrong" False >>> test != "wrong" True
Applying the
strfunction only returns the selection name:>>> str(test) 'test'
- nodes: Nodes¶
The explicitly handled
Nodeobjects (m).nodesdoes not necessarily contain all nodes to which the elements inelementsare linked.
- elements: Elements¶
The explicitly handled
Elementobjects.elementsdoes not necessarily contain all nodes to which the elements innodesare 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
NodeandElementobjects and, optionally, the name of the newly createdSelectionobject:>>> 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 allNodeobjects directly connected to any upstreamElementobject. Set the inclusive argument toFalseto 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 allNodeobjects directly connected to any upstreamElementobject. Set the inclusive argument toFalseto 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
NodeandElementobjects and, optionally, the name of the newly createdSelectionobject:>>> 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 allNodeobjects directly connected to any upstreamElementobject. Set the inclusive argument toFalseto 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", "sender"), 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
Selectionobject 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
Modelobjects and names and, as a keyword argument, the name of the newly createdSelectionobject:>>> 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
Selectionobject 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
Selectionobject 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
Selectionobject 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
Selectionobject with the given name and copies of the handledNodesandElementsobjects 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()) 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()) 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()) 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")