xmltools¶
This module provides features for executing HydPy workflows based on XML configuration files.
At the heart of module xmltools
lies function run_simulation()
, thought to be applied
via a command line (see the documentation on script hyd
for further information).
run_simulation()
expects that the HydPy project you want to work with is available in
your current working directory and contains an XML configuration file (as
single_run.xml in the example project folder LahnH). This configuration file must
agree with the XML schema HydPyConfigSingleRun.xsd, which is available in the
Configuration Tools subpackage and separately downloadable for each HydPy release.
If you did implement new or changed existing models, you have to update this schema
file. HydPy does this automatically through its setup mechanism (see the
documentation on class XSDWriter
).
To show how to apply run_simulation()
via a command line, we first copy the LahnH
project into the iotesting folder by calling the function prepare_full_example_1()
:
>>> from hydpy.examples import prepare_full_example_1
>>> prepare_full_example_1()
Running the simulation requires defining the main script (hyd.py), the function
specifying the actual workflow (run_simulation), the name of the project of interest
(LahnH), and the name of the relevant XML configuration file (single_run.xml). We
pass the required text to function run_subprocess()
of module subprocess to simulate
using the command line:
>>> from hydpy import run_subprocess, TestIO
>>> import subprocess
>>> with TestIO():
... result = run_subprocess("hyd.py run_simulation LahnH single_run.xml")
Start HydPy project `LahnH` (...).
Read configuration file `single_run.xml` (...).
Interpret the defined options (...).
Interpret the defined period (...).
Read all network files (...).
Activate the selected network (...).
Read the required control files (...).
Read the required condition files (...).
Read the required time series files (...).
Perform the simulation run (...).
Write the desired condition files (...).
Write the desired time series files (...).
As defined by the XML configuration file, the simulation started on the first and
ended on the sixth of January 1996. The following example shows the read initial
conditions and the written final conditions of sequence SM
for the
12 hydrological response units of the subcatchment land_dill:
>>> with TestIO():
... filepath = "LahnH/conditions/init_1996_01_01_00_00_00/land_dill.py"
... with open(filepath) as file_:
... print("".join(file_.readlines()[10:12]))
... filepath = "LahnH/conditions/init_1996_01_06/land_dill.py"
... with open(filepath) as file_:
... print("".join(file_.readlines()[9:12]))
sm(185.13164, 181.18755, 199.80432, 196.55888, 212.04018, 209.48859,
222.12115, 220.12671, 230.30756, 228.70779, 236.91943, 235.64427)
sm(183.873078, 179.955801, 198.446011, 195.222634, 210.598689,
208.064445, 220.611126, 218.630245, 228.741883, 227.152989,
235.308805, 234.042313)
The intermediate soil moisture values have been stored in a NetCDF file called hland_v1_state_sm.nc:
>>> import numpy
>>> from hydpy import print_values
>>> from hydpy.core.netcdftools import netcdf4, chars2str, query_variable
>>> with TestIO():
... ncfile = netcdf4.Dataset("LahnH/series/soildata/hland_v1_state_sm.nc")
... chars2str(query_variable(ncfile, "station_id")[:].data)[:3]
... print_values(query_variable(ncfile, "state_sm")[:, 0])
['land_dill_0', 'land_dill_1', 'land_dill_2']
184.926173, 184.603966, 184.386666, 184.098541, 183.873078
>>> ncfile.close()
Spatially averaged time series values have been stored in files ending with the suffix _mean:
>>> import time
>>> time.sleep(10)
>>> with TestIO(clear_all=True):
... print_values((numpy.load("LahnH/series/averages/lahn_1_sim_q_mean.npy")[13:]))
9.647824, 8.517795, 7.781311, 7.344944, 7.153142
Module xmltools
implements the following members:
find()
Return the first XML element with the given name found in the given XML root.
strip()
Remove the XML namespace from the given string and return it.
PrepareSeriesArguments
Helper class that determines and provides the arguments for functionprepare_series()
.
run_simulation()
Perform a HydPy workflow according to the given XML configuration file available in the given project’s directory.
XMLBase
Base class for the concrete classesXMLInterface
,XMLConditions
,XMLSeries
, andXMLSubseries
.
XMLInterface
An interface to XML configuration files that are valid concerning schema file HydPyConfigSingleRun.xsd or HydPyConfigMultipleRuns.xsd.
XMLNetworkBase
Base class forXMLNetworkDefault
andXMLNetworkUserDefined
.
XMLNetworkDefault
Helper class forXMLInterface
responsible for loading devices from network files when the XML file does not specify a network directory.
XMLNetworkUserDefined
Helper class forXMLInterface
responsible for loading devices from network files when the XML file specifies a network directory.
XMLControlBase
Base class forXMLControlDefault
andXMLControlUserDefined
.
XMLControlDefault
Helper class forXMLInterface
responsible for loading models from control files when the XML file does not specify a control directory.
XMLControlUserDefined
Helper class forXMLInterface
responsible for loading models from control files when the XML file specifies a control directory.
XMLConditions
Helper class forXMLInterface
responsible for loading and saving initial conditions.
XMLSeries
Helper class forXMLInterface
responsible for loading and saving time series data, which is further delegated to suitable instances of classXMLSubseries
.
XMLSelector
Base class forXMLSubseries
andXMLVar
responsible for querying the relevantNode
andElement
objects.
XMLSubseries
Helper class forXMLSeries
responsible for loading and saving time series data.
XMLExchange
Helper class forXMLInterface
responsible for interpreting exchange items, accessible via differentXMLItemgroup
instances.
XMLItemgroup
Helper class forXMLExchange
responsible for handling the exchange items related to model parameters and sequences separately from the exchange items of node sequences.
XMLModel
Helper class forXMLItemgroup
responsible for handling the exchange items related to different parameter or sequence groups ofModel
objects.
XMLSubvars
Helper class forXMLModel
responsible for handling the exchange items related to individual parameters or sequences ofModel
objects.
XMLNode
Helper class forXMLItemgroup
responsible for handling the exchange items related to individual parameters or sequences ofNode
objects.
XMLVar
Helper class forXMLSubvars
andXMLNode
responsible for creating a defined exchange item.
XSDWriter
A pureclassmethod
class for writing the actual XML schema file HydPyConfigBase.xsd, which makes sure that an XML configuration file is readable by classXMLInterface
.
- hydpy.auxs.xmltools.find(root: Element, name: str, optional: Literal[True, False] = True) Element | None [source]¶
Return the first XML element with the given name found in the given XML root.
>>> from hydpy.auxs.xmltools import find, XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> find(interface.root, "timegrid").tag.endswith("timegrid") True
By default, function
find()
returnsNone
in case the required element is missing:>>> find(interface.root, "wrong")
Set the argument optional to
False
to let functionfind()
raise errors instead:>>> find(interface.root, "wrong", optional=False) Traceback (most recent call last): ... AttributeError: The actual XML element `config` does not define a XML subelement named `wrong`. Please make sure your XML file follows the relevant XML schema.
- hydpy.auxs.xmltools.strip(name: str) str [source]¶
Remove the XML namespace from the given string and return it.
>>> from hydpy.auxs.xmltools import strip >>> strip("{https://github.com/something.xsd}something") 'something'
- class hydpy.auxs.xmltools.PrepareSeriesArguments(allocate_ram: bool, read_jit: bool, write_jit: bool)[source]¶
Bases:
NamedTuple
Helper class that determines and provides the arguments for function
prepare_series()
.- classmethod from_xmldata(is_reader: bool, is_input: bool, prefer_ram: bool) PrepareSeriesArguments [source]¶
Create a
PrepareSeriesArguments
object based on the (already prepared) information of an XML file.- Meaning of the arguments:
is_reader: is the current XML-Element responsible for reading (or writing)?
is_input: serve the addressed sequences as inputs (or outputs)?
prefer_ram: prefer to handle time-series data in RAM (or read and write it just in time)?
>>> from hydpy.auxs.xmltools import PrepareSeriesArguments >>> from_xmldata = PrepareSeriesArguments.from_xmldata
Test cases for reading input data:
>>> from_xmldata(is_reader=True, is_input=True, prefer_ram=True) PrepareSeriesArguments(allocate_ram=True, read_jit=False, write_jit=False)
>>> from_xmldata(is_reader=True, is_input=True, prefer_ram=False) PrepareSeriesArguments(allocate_ram=False, read_jit=True, write_jit=False)
Attempting to read output data results in an
AssertionError
(disallowed by all available XML schema files):>>> from_xmldata(is_reader=True, is_input=False, prefer_ram=True) Traceback (most recent call last): ... AssertionError: reading output values is disallowed
>>> from_xmldata(is_reader=True, is_input=False, prefer_ram=False) Traceback (most recent call last): ... AssertionError: reading output values is disallowed
Test cases for writing input data (this is for the rare case where an external tool like OpenDA provides or modifies the input data in RAM, and we want to write it to a file for documentation purposes):
>>> from_xmldata(is_reader=False, is_input=True, prefer_ram=True) PrepareSeriesArguments(allocate_ram=True, read_jit=False, write_jit=False)
>>> from_xmldata(is_reader=False, is_input=True, prefer_ram=False) PrepareSeriesArguments(allocate_ram=True, read_jit=False, write_jit=True)
Test cases for writing output data:
>>> from_xmldata(is_reader=False, is_input=False, prefer_ram=True) PrepareSeriesArguments(allocate_ram=True, read_jit=False, write_jit=False)
>>> from_xmldata(is_reader=False, is_input=False, prefer_ram=False) PrepareSeriesArguments(allocate_ram=False, read_jit=False, write_jit=True)
- hydpy.auxs.xmltools.run_simulation(projectname: str, xmlfile: str) None [source]¶
Perform a HydPy workflow according to the given XML configuration file available in the given project’s directory.
Function
run_simulation()
is a “script function”. We explain its normal usage in the main documentation on modulexmltools
.
- class hydpy.auxs.xmltools.XMLBase[source]¶
Bases:
object
Base class for the concrete classes
XMLInterface
,XMLConditions
,XMLSeries
, andXMLSubseries
.Subclasses of
XMLBase
support iterating XML subelements while skipping those named selections:>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("multiple_runs.xml", make_filepath("LahnH")) >>> itemgroup = interface.exchange.itemgroups[1] >>> for element in itemgroup: ... print(strip(element.tag)) hland_v1 >>> for element in itemgroup.models[0].subvars[0].vars[0]: ... print(strip(element.tag)) name level
- property name: str¶
Apply function
strip()
to the root of the object of theXMLBase
subclass.>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> interface.name 'config' >>> interface.series_io.readers[0].name 'reader'
- find(name: str, optional: Literal[True, False] = True) Element | None [source]¶
Apply function
find()
to the root of the object of theXMLBase
subclass.>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> interface.find("timegrid").tag.endswith("timegrid") True
>>> interface.find("wrong")
>>> interface.find("wrong", optional=False) Traceback (most recent call last): ... AttributeError: The actual XML element `config` does not define a XML subelement named `wrong`. Please make sure your XML file follows the relevant XML schema.
- class hydpy.auxs.xmltools.XMLInterface(filename: str, directory: str | None = None)[source]¶
Bases:
XMLBase
An interface to XML configuration files that are valid concerning schema file HydPyConfigSingleRun.xsd or HydPyConfigMultipleRuns.xsd.
>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> interface.root.tag '{https://github.com/hydpy-dev/hydpy/releases/download/your-hydpy-version/HydPyConfigSingleRun.xsd}config' >>> interface = XMLInterface('multiple_runs.xml', make_filepath('LahnH')) >>> interface.root.tag '{https://github.com/hydpy-dev/hydpy/releases/download/your-hydpy-version/HydPyConfigMultipleRuns.xsd}config' >>> XMLInterface('wrongfilepath.xml', 'wrongdir') Traceback (most recent call last): ... FileNotFoundError: While trying to parse the XML configuration file ...wrongfilepath.xml, the following error occurred: [Errno 2] No such file or directory: '...wrongfilepath.xml'
- validate_xml() None [source]¶
Raise an error if the actual XML does not agree with one of the available schema files.
# ToDo: should it be accompanied by a script function?
The first example relies on a distorted version of the configuration file single_run.xml:
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1() >>> from hydpy import TestIO, xml_replace >>> from hydpy.auxs.xmltools import XMLInterface >>> import os >>> with TestIO(): ... xml_replace("LahnH/single_run", ... firstdate="1996-01-32T00:00:00") template file: LahnH/single_run.xmlt target file: LahnH/single_run.xml replacements: config_start --> <...HydPyConfigBase.xsd" ...HydPyConfigSingleRun.xsd"> (default argument) firstdate --> 1996-01-32T00:00:00 (given argument) zip_ --> false (default argument) config_end --> </hpcsr:config> (default argument) >>> with TestIO(): ... interface = XMLInterface("single_run.xml", "LahnH") >>> interface.validate_xml() Traceback (most recent call last): ... xmlschema.validators.exceptions.XMLSchemaDecodeError: While trying to validate XML file `...single_run.xml`, the following error occurred: failed validating '1996-01-32T00:00:00' with XsdAtomicBuiltin(name='xs:dateTime')... ... Reason: day is out of range for month ... Schema: ... Instance: ... <firstdate xmlns="https://github.com/hydpy-dev/hydpy/releases/download/your-hydpy-version/HydPyConfigBase.xsd">1996-01-32T00:00:00</firstdate> ... Path: /hpcsr:config/timegrid/firstdate ...
In the second example, we examine a correct configuration file:
>>> with TestIO(): ... xml_replace("LahnH/single_run") ... interface = XMLInterface("single_run.xml", "LahnH") template file: LahnH/single_run.xmlt target file: LahnH/single_run.xml replacements: config_start --> <...HydPyConfigBase.xsd" ...HydPyConfigSingleRun.xsd"> (default argument) firstdate --> 1996-01-01T00:00:00 (default argument) zip_ --> false (default argument) config_end --> </hpcsr:config> (default argument) >>> interface.validate_xml()
The XML configuration file must correctly refer to the corresponding schema file:
>>> with TestIO(): ... xml_replace("LahnH/single_run", ... config_start="<config>", ... config_end="</config>") ... interface = XMLInterface("single_run.xml", "LahnH") template file: LahnH/single_run.xmlt target file: LahnH/single_run.xml replacements: config_start --> <config> (given argument) firstdate --> 1996-01-01T00:00:00 (default argument) zip_ --> false (default argument) config_end --> </config> (given argument) >>> interface.validate_xml() Traceback (most recent call last): ... RuntimeError: While trying to validate XML file `...single_run.xml`, the following error occurred: Configuration file `single_run.xml` does not correctly refer to one of the available XML schema files (HydPyConfigSingleRun.xsd and HydPyConfigMultipleRuns.xsd).
XML files based on HydPyConfigMultipleRuns.xsd can be validated as well:
>>> with TestIO(): ... interface = XMLInterface("multiple_runs.xml", "LahnH") >>> interface.validate_xml()
- update_options() None [source]¶
Update the
Options
object available in thepub
module with the values defined in the options XML element.>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy import pub >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> pub.options.ellipsis = 0 >>> pub.options.parameterstep = "1h" >>> pub.options.printprogress = True >>> pub.options.reprdigits = -1 >>> pub.options.utcoffset = -60 >>> pub.options.timestampleft = False >>> pub.options.warnsimulationstep = 0 >>> interface.update_options() >>> pub.options Options( checkseries -> 1 ellipsis -> 0 parameterstep -> Period("1d") printprogress -> 0 reprcomments -> 0 reprdigits -> 6 simulationstep -> Period() trimvariables -> 1 usecython -> 1 usedefaultvalues -> 0 utclongitude -> 15 utcoffset -> 60 timestampleft -> 1 warnmissingcontrolfile -> 0 warnmissingobsfile -> 1 warnmissingsimfile -> 1 warnsimulationstep -> 0 warntrim -> 1 ) >>> pub.options.printprogress = False >>> pub.options.reprdigits = 6
- update_timegrids() None [source]¶
Update the
Timegrids
object available in thepub
module with the values defined in the timegrid XML element.>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1() >>> from hydpy import HydPy, pub, TestIO >>> from hydpy.auxs.xmltools import XMLInterface >>> hp = HydPy("LahnH") >>> with TestIO(): ... XMLInterface("single_run.xml").update_timegrids() >>> pub.timegrids Timegrids("1996-01-01T00:00:00", "1996-01-06T00:00:00", "1d")
- update_selections() None [source]¶
Create
Selection
objects based on the add_selections XML element and add them to theSelections
object available in modulepub
.The Lahn example project comes with four selections:
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1() >>> from hydpy import HydPy, pub, TestIO >>> from hydpy.auxs.xmltools import find, XMLInterface >>> hp = HydPy("LahnH") >>> with TestIO(): ... hp.prepare_network() ... interface = XMLInterface("single_run.xml") >>> pub.selections Selections("complete", "headwaters", "nonheadwaters", "streams")
Following the definitions of the add_selections element of the configuration file single_run.xml, method
update_selections()
creates three additional selections based on given device names, keywords, or selection names (you could also combine these subelements):>>> interface.update_selections() >>> pub.selections Selections("complete", "from_devices", "from_keywords", "from_selections", "headwaters", "nonheadwaters", "streams") >>> pub.selections.from_devices Selection("from_devices", nodes=(), elements=("land_lahn_1", "land_lahn_2")) >>> pub.selections.from_keywords Selection("from_keywords", nodes=(), elements=("land_dill", "land_lahn_1", "land_lahn_2", "land_lahn_3")) >>> pub.selections.from_selections Selection("from_selections", nodes=("dill", "lahn_1", "lahn_2", "lahn_3"), elements=("land_dill", "land_lahn_1", "land_lahn_2", "land_lahn_3", "stream_dill_lahn_2", "stream_lahn_1_lahn_2", "stream_lahn_2_lahn_3"))
Defining wrong device names, keywords, or selection names results in error messages:
>>> add_selections = find(interface.root, "add_selections") >>> add_selections[2][1].text = "streams no_selection" >>> interface.update_selections() Traceback (most recent call last): ... RuntimeError: The XML configuration file tried to add the devices of a selection named `no_selection` to the custom selection `from_selections` but none of the available selections has this name.
>>> add_selections[1][1].text = "catchment no_keyword" >>> interface.update_selections() Traceback (most recent call last): ... RuntimeError: The XML configuration file tried to add at least one device based on the keyword `no_keyword` to the custom selection `from_keywords` but none of the available devices has this keyword.
>>> add_selections[0][1].text = "dill no_device" >>> interface.update_selections() Traceback (most recent call last): ... RuntimeError: The XML configuration file tried to add a device named `no_device` to the custom selection `from_devices` but none of the available devices has this name.
- property selections: Selections¶
The
Selections
object defined on the main level of the actual XML file.>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> with TestIO(): ... hp.prepare_network() ... interface = XMLInterface("single_run.xml") >>> interface.update_selections() >>> interface.find("selections").text = "headwaters streams" >>> selections = interface.selections >>> for selection in selections: ... print(selection.name) headwaters streams >>> selections.headwaters Selection("headwaters", nodes=("dill", "lahn_1"), elements=("land_dill", "land_lahn_1")) >>> interface.find("selections").text = "head_waters" >>> interface.selections Traceback (most recent call last): ... NameError: The XML configuration file tries to define a selection using the text `head_waters`, but the actual project does not handle such a `Selection` object.
- property elements: Iterator[Element]¶
Yield all
Element
objects returned byselections
without duplicates.>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> with TestIO(): ... hp.prepare_network() ... interface = XMLInterface("single_run.xml") >>> interface.update_timegrids() >>> interface.update_selections() >>> interface.find("selections").text = "headwaters streams" >>> for element in interface.elements: ... print(element.name) land_dill land_lahn_1 stream_dill_lahn_2 stream_lahn_1_lahn_2 stream_lahn_2_lahn_3
- property fullselection: Selection¶
A
Selection
object that contains allElement
andNode
objects defined byselections
.>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> with TestIO(): ... hp.prepare_network() ... interface = XMLInterface("single_run.xml") >>> interface.update_selections() >>> interface.find("selections").text = "nonheadwaters" >>> interface.fullselection Selection("fullselection", nodes=("lahn_2", "lahn_3"), elements=("land_lahn_2", "land_lahn_3")) >>> interface.find("selections").text = "from_keywords" >>> interface.fullselection Selection("fullselection", nodes=(), elements=("land_dill", "land_lahn_1", "land_lahn_2", "land_lahn_3"))
- property network_io: XMLNetworkDefault | XMLNetworkUserDefined¶
The network_io element defined in the actual XML file.
>>> from hydpy.auxs.xmltools import XMLInterface, strip >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> interface.network_io.text 'default' >>> interface = XMLInterface("multiple_runs.xml", make_filepath("LahnH")) >>> interface.network_io.text 'default'
- property control_io: XMLControlDefault | XMLControlUserDefined¶
The control_io element defined in the actual XML file.
>>> from hydpy.auxs.xmltools import XMLInterface, strip >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> interface.control_io.text 'default' >>> interface = XMLInterface("multiple_runs.xml", make_filepath("LahnH")) >>> interface.control_io.text 'default'
- property conditions_io: XMLConditions¶
The condition_io element defined in the actual XML file.
>>> from hydpy.auxs.xmltools import XMLInterface, strip >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> strip(interface.series_io.root.tag) 'series_io'
- property series_io: XMLSeries¶
The series_io element defined in the actual XML file.
>>> from hydpy.auxs.xmltools import XMLInterface, strip >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> strip(interface.series_io.root.tag) 'series_io'
- property exchange: XMLExchange¶
The exchange element defined in the actual XML file.
>>> from hydpy.auxs.xmltools import XMLInterface, strip >>> from hydpy.data import make_filepath >>> interface = XMLInterface( ... "multiple_runs.xml", make_filepath("LahnH")) >>> strip(interface.exchange.root.tag) 'exchange'
- class hydpy.auxs.xmltools.XMLNetworkBase[source]¶
Bases:
object
Base class for
XMLNetworkDefault
andXMLNetworkUserDefined
.- master: XMLInterface¶
- prepare_network() None [source]¶
Prepare the
Selections
object available in the globalpub
module:>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import attrready, HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... interface = XMLInterface("single_run.xml") ... interface.find("network_io").text = "wrong" ... interface.network_io.prepare_network() Traceback (most recent call last): ... RuntimeError: The directory `...wrong` does not contain any network files.
>>> with TestIO(): ... interface = XMLInterface("single_run.xml") ... interface.find("network_io").text = "default" ... interface.network_io.prepare_network() >>> pub.selections Selections("complete", "headwaters", "nonheadwaters", "streams")
- class hydpy.auxs.xmltools.XMLNetworkDefault(master: XMLInterface, text: str | None)[source]¶
Bases:
XMLNetworkBase
Helper class for
XMLInterface
responsible for loading devices from network files when the XML file does not specify a network directory.
- class hydpy.auxs.xmltools.XMLNetworkUserDefined(master: XMLInterface, root: Element, text: str | None)[source]¶
Bases:
XMLBase
,XMLNetworkBase
Helper class for
XMLInterface
responsible for loading devices from network files when the XML file specifies a network directory.
- class hydpy.auxs.xmltools.XMLControlBase[source]¶
Bases:
object
Base class for
XMLControlDefault
andXMLControlUserDefined
.- master: XMLInterface¶
- prepare_models() None [source]¶
Prepare the
Model
objects of allElement
objects returned byelements
:>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import attrready, HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... interface = XMLInterface("single_run.xml") ... interface.update_selections() ... interface.find("selections").text = "headwaters" ... interface.control_io.prepare_models() >>> interface.update_timegrids() >>> hp.elements.land_lahn_1.model.parameters.control.alpha alpha(1.0) >>> attrready(hp.elements.land_lahn_2, "model") False
- class hydpy.auxs.xmltools.XMLControlDefault(master: XMLInterface, text: str | None)[source]¶
Bases:
XMLControlBase
Helper class for
XMLInterface
responsible for loading models from control files when the XML file does not specify a control directory.
- class hydpy.auxs.xmltools.XMLControlUserDefined(master: XMLInterface, root: Element, text: str | None)[source]¶
Bases:
XMLBase
,XMLControlBase
Helper class for
XMLInterface
responsible for loading models from control files when the XML file specifies a control directory.
- class hydpy.auxs.xmltools.XMLConditions(master: XMLInterface, root: Element)[source]¶
Bases:
XMLBase
Helper class for
XMLInterface
responsible for loading and saving initial conditions.- load_conditions(currentdir: str | None = None) None [source]¶
Load the condition files of the
Model
objects of allElement
objects returned byelements
:>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... hp.prepare_models() ... interface = XMLInterface("single_run.xml") ... interface.update_selections() ... interface.find("selections").text = "headwaters" ... interface.conditions_io.load_conditions() >>> interface.update_timegrids() >>> hp.elements.land_lahn_1.model.sequences.states.lz lz(8.18711) >>> hp.elements.land_lahn_2.model.sequences.states.lz lz(nan)
- save_conditions(currentdir: str | None = None) None [source]¶
Save the condition files of the
Model
objects of allElement
objects returned byelements
:>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> import os >>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... hp.prepare_models() ... hp.elements.land_dill.model.sequences.states.lz = 999.0 ... interface = XMLInterface("single_run.xml") ... interface.update_timegrids() ... interface.update_selections() ... interface.find("selections").text = "headwaters" ... interface.conditions_io.save_conditions() ... dirpath = "LahnH/conditions/init_1996_01_06" ... with open(os.path.join(dirpath, "land_dill.py")) as file_: ... print(file_.readlines()[11].strip()) ... os.path.exists(os.path.join(dirpath, "land_lahn_2.py")) lz(999.0) False >>> from hydpy import xml_replace >>> with TestIO(): ... xml_replace("LahnH/single_run", printflag=False, zip_="true") ... interface = XMLInterface("single_run.xml") ... interface.find("selections").text = "headwaters" ... os.path.exists("LahnH/conditions/init_1996_01_06.zip") ... interface.conditions_io.save_conditions() ... os.path.exists("LahnH/conditions/init_1996_01_06.zip") False True
- class hydpy.auxs.xmltools.XMLSeries(master: XMLInterface, root: Element)[source]¶
Bases:
XMLBase
Helper class for
XMLInterface
responsible for loading and saving time series data, which is further delegated to suitable instances of classXMLSubseries
.- property readers: List[XMLSubseries]¶
The reader XML elements defined in the actual XML file.
>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> for reader in interface.series_io.readers: ... print(reader.info) all input data
- property writers: List[XMLSubseries]¶
The writer XML elements defined in the actual XML file.
>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> for writer in interface.series_io.writers: ... print(writer.info) precipitation soilmoisture averaged
- prepare_series() None [source]¶
Call
prepare_series()
of allXMLSubseries
objects.
- load_series(currentdir: str | None = None) None [source]¶
Call
load_series()
of allXMLSubseries
objects handled as “readers”.
- save_series(currentdir: str | None = None) None [source]¶
Call
load_series()
of allXMLSubseries
objects handled as “writers”.
- class hydpy.auxs.xmltools.XMLSelector[source]¶
Bases:
XMLBase
Base class for
XMLSubseries
andXMLVar
responsible for querying the relevantNode
andElement
objects.- property selections: Selections¶
The
Selections
object defined for the respective respective IO series or exchange item elements of the actual XML file.Property
selections
of classXMLSelector
falls back to the general propertyselections
ofXMLInterface
if the relevant IO series or exchange item element does not define a unique selection:>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... hp.prepare_models() ... interface = XMLInterface("single_run.xml") >>> interface.update_selections() >>> series_io = interface.series_io >>> for seq in (series_io.readers + series_io.writers): ... print(seq.info, seq.selections.names) all input data ('from_keywords',) precipitation ('headwaters', 'from_devices') soilmoisture ('complete',) averaged ('from_selections',)
If property
selections
does not find any definitions, it raises the following error:>>> interface.root.remove(interface.find("selections")) >>> series_io = interface.series_io >>> for seq in (series_io.readers + series_io.writers): ... print(seq.info, seq.selections.names) Traceback (most recent call last): ... AttributeError: Unable to find a XML element named "selections". Please make sure your XML file follows the relevant XML schema.
- property elements: Iterator[Element]¶
Return the
Element
objects selected by the actual IO series or exchange item element.>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> with TestIO(): ... hp.prepare_network() ... interface = XMLInterface("single_run.xml") >>> interface.update_selections() >>> for element in interface.series_io.writers[0].elements: ... print(element.name) land_dill land_lahn_1 land_lahn_2
- property nodes: Iterator[Node]¶
Return the
Node
objects selected by the actual IO series or exchange item element.>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> with TestIO(): ... hp.prepare_network() ... interface = XMLInterface("single_run.xml") >>> interface.update_selections() >>> for node in interface.series_io.writers[0].nodes: ... print(node.name) dill lahn_1
- class hydpy.auxs.xmltools.XMLSubseries(master: XMLSeries, root: Element)[source]¶
Bases:
XMLSelector
Helper class for
XMLSeries
responsible for loading and saving time series data.- prepare_sequencemanager(currentdir: str | None = None) None [source]¶
Configure the
SequenceManager
object available in modulepub
following the definitions of the actual XML reader or writer element when available; if not, use those of the XML series_io element or fall back to the default.Compare the following results with single_run.xml to see that the first writer element re-defines the default file type (asc), that the second writer element defines an alternative file type (npy), and that the third writer relies on the general file type. The base mechanism is the same for other options, e.g. the aggregation mode.
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, TestIO, XMLInterface, pub >>> hp = HydPy("LahnH") >>> with TestIO(): ... hp.prepare_network() ... interface = XMLInterface("single_run.xml") >>> series_io = interface.series_io >>> with TestIO(): ... series_io.writers[0].prepare_sequencemanager() ... pub.sequencemanager.currentdir 'default' >>> pub.sequencemanager.filetype 'asc' >>> pub.sequencemanager.overwrite 1 >>> pub.sequencemanager.aggregation 'none' >>> with TestIO(): ... series_io.writers[1].prepare_sequencemanager() ... pub.sequencemanager.currentdir 'soildata' >>> pub.sequencemanager.filetype 'nc' >>> pub.sequencemanager.overwrite 0 >>> pub.sequencemanager.aggregation 'none' >>> with TestIO(): ... series_io.writers[2].prepare_sequencemanager() ... pub.sequencemanager.currentdir 'averages' >>> pub.sequencemanager.filetype 'npy' >>> pub.sequencemanager.aggregation 'mean' >>> pub.sequencemanager.overwrite 1 >>> pub.sequencemanager.aggregation 'mean'
- property model2subs2seqs: DefaultDict[str, DefaultDict[str, List[str]]]¶
A nested
defaultdict
containing the model-specific information provided by the XML sequences element.>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> series_io = interface.series_io >>> model2subs2seqs = series_io.writers[2].model2subs2seqs >>> for model, subs2seqs in sorted(model2subs2seqs.items()): ... for subs, seq in sorted(subs2seqs.items()): ... print(model, subs, seq) hland_v1 factors ['tc'] hland_v1 fluxes ['tf'] hland_v1 states ['sm'] musk_classic states ['discharge']
- property subs2seqs: Dict[str, List[str]]¶
A
defaultdict
containing the node-specific information provided by XML sequences element.>>> from hydpy.auxs.xmltools import XMLInterface >>> from hydpy.data import make_filepath >>> interface = XMLInterface("single_run.xml", make_filepath("LahnH")) >>> series_io = interface.series_io >>> subs2seqs = series_io.writers[2].subs2seqs >>> for subs, seq in sorted(subs2seqs.items()): ... print(subs, seq) node ['sim', 'obs']
- prepare_series() None [source]¶
Call method
prepare_series()
of classIOSequence
for all sequences selected by the given element of the actual XML file.Method
prepare_series()
solves a complex task, as it needs to determine the correct arguments for methodprepare_series()
of classIOSequence
. Those arguments depend on whether the respectiveXMLSubseries
element is for reading or writing data, addresses input or output sequences, and if one prefers to handle time-series data in RAM or read or write it “just in time” during model simulations. Methodprepare_series()
delegates some of the related logic to thefrom_xmldata()
method of classPrepareSeriesArguments
. The following examples demonstrate that methodprepare_series()
implements the remaining logic correctly.>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1() >>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... hp.prepare_models() ... interface = XMLInterface("single_run.xml") >>> interface.update_timegrids() >>> interface.update_selections()
First, we check and discuss the proper setting of the properties
ramflag
,diskflag_reading
, anddiskflag_writing
for the sequences defined in single_run.xml. First, we callprepare_series()
for availableXMLSubseries
objects:>>> series_io = interface.series_io >>> for reader in series_io.readers: ... reader.prepare_series() >>> for writer in series_io.writers: ... writer.prepare_series()
The following test function prints the options of the specified sequence of element “Dill”:
>>> def print_io_options(groupname, sequencename): ... sequences = hp.elements.land_dill.model.sequences ... sequence = sequences[groupname][sequencename] ... print(f"ramflag={sequence.ramflag}") ... print(f"diskflag_reading={sequence.diskflag_reading}") ... print(f"diskflag_writing={sequence.diskflag_writing}")
The XML file uses the jit mode for all non-aggregated time series. Reader elements handle input sequences and writer elements handle output sequences. Hence,
ramflag
is generallyFalse
whilediskflag_reading
isTrue
for the input sequences anddiskflag_writing
isTrue
for the output sequences:>>> print_io_options("inputs", "p") ramflag=False diskflag_reading=True diskflag_writing=False
>>> print_io_options("fluxes", "pc") ramflag=False diskflag_reading=False diskflag_writing=True
Currently, aggregation only works in combination with mode ram:
>>> print_io_options("factors", "tc") ramflag=True diskflag_reading=False diskflag_writing=False
For sequence
SM
, two writers apply. The writer “soil moisture” triggers writing the complete time-series “just in time” during the simulation run. In contrast, the writer “averaged” initiates writing averaged time-series after the simulation run. The configuration of sequenceSM
reflects this, with both “ram flag” and “disk flag writing” being “True”:>>> print_io_options("states", "sm") ramflag=True diskflag_reading=False diskflag_writing=True
We temporarily convert the single reader element to a writer element and apply method
prepare_series()
again. At first, this does not work, as the affected input sequences have previously been configured for “just in time” reading, which does not work in combination with “just in time” writing:>>> reader = series_io.readers[0] >>> reader.root.tag = reader.root.tag.replace("reader", "writer") >>> reader.prepare_series() Traceback (most recent call last): ... ValueError: Reading from and writing into the same NetCDF file "just in time" during a simulation run is not supported but tried for sequence `p` of element `land_dill`.
After resetting all
InputSequence
objects and re-applyingprepare_series()
, bothramflag
anddiskflag_writing
areTrue
. This case is the only one where a single reader or writer enables two flags (see the documentation on methodfrom_xmldata()
for further information):>>> hp.prepare_allseries(allocate_ram=False, jit=False) >>> reader.prepare_series() >>> reader.root.tag = reader.root.tag.replace("writer", "reader") >>> print_io_options("inputs", "p") ramflag=True diskflag_reading=False diskflag_writing=True
If we prefer the ram mode, things are more straightforward. Then, option
ramflag
isTrue
, and optionsdiskflag_reading
anddiskflag_writing
areFalse
regardless of all other options:>>> hp.prepare_allseries(allocate_ram=False, jit=False) >>> series_io.find("mode").text = "ram" >>> for reader in series_io.readers: ... reader.find("mode").text = "ram" ... reader.prepare_series() >>> for writer in series_io.writers: ... mode = writer.find("mode") ... if mode is not None: ... mode.text = "ram" ... writer.prepare_series()
>>> print_io_options("inputs", "p") ramflag=True diskflag_reading=False diskflag_writing=False
>>> print_io_options("fluxes", "pc") ramflag=True diskflag_reading=False diskflag_writing=False
>>> print_io_options("states", "sm") ramflag=True diskflag_reading=False diskflag_writing=False
>>> reader = series_io.readers[0] >>> reader.root.tag = reader.root.tag.replace("reader", "writer") >>> reader.prepare_series() >>> reader.root.tag = reader.root.tag.replace("writer", "reader") >>> print_io_options("inputs", "p") ramflag=True diskflag_reading=False diskflag_writing=False
- load_series(currentdir: str | None) None [source]¶
Load time series data as defined by the actual XML reader element.
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, xml_replace, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... hp.prepare_models() ... xml_replace("LahnH/single_run", printflag=False) ... interface = XMLInterface("single_run.xml") ... interface.update_options() ... interface.update_timegrids() ... interface.update_selections() ... series_io = interface.series_io ... series_io.prepare_series() ... series_io.load_series() >>> from hydpy import print_values >>> print_values(hp.elements.land_dill.model.sequences.inputs.t.series[:3]) -0.298846, -0.811539, -2.493848
- save_series(currentdir: str | None) None [source]¶
Save time series data as defined by the actual XML writer element.
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, xml_replace, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... hp.prepare_models() ... xml_replace("LahnH/single_run", printflag=False) ... interface = XMLInterface("single_run.xml") >>> interface.update_options() >>> interface.update_timegrids() >>> interface.update_selections() >>> series_io = interface.series_io >>> series_io.prepare_series() >>> hp.elements.land_dill.model.sequences.fluxes.pc.series[2, 3] = 9.0 >>> hp.nodes.lahn_2.sequences.sim.series[4] = 7.0 >>> with TestIO(): ... series_io.save_series() >>> import numpy >>> with TestIO(): ... os.path.exists("LahnH/series/default/land_lahn_2_flux_pc.npy") ... os.path.exists("LahnH/series/default/land_lahn_3_flux_pc.npy") ... numpy.load("LahnH/series/default/land_dill_flux_pc.npy")[13+2, 3] ... numpy.load("LahnH/series/default/lahn_2_sim_q_mean.npy")[13+4] True False 9.0 7.0
- change_dirpath(currentdir: str | None) None [source]¶
Set the
dirpath
of all relevantIOSequence
objects to thecurrentpath
of theSequenceManager
object available in thepub
module.This “information freezing” is required for those sequences selected for reading data from or writing data to different directories “just in time” during a simulation run.
- reset_dirpath() None [source]¶
Revert
change_dirpath()
.
- class hydpy.auxs.xmltools.XMLExchange(master: XMLInterface, root: Element)[source]¶
Bases:
XMLBase
Helper class for
XMLInterface
responsible for interpreting exchange items, accessible via differentXMLItemgroup
instances.- property parameteritems: List[ChangeItem]¶
Create and return all items for changing control parameter values.
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_everything() ... interface = XMLInterface("multiple_runs.xml") >>> interface.update_selections() >>> for item in interface.exchange.parameteritems: ... print(item.name) alpha beta lag damp sfcf_1 sfcf_2 sfcf_3 k4
- property inputitems: List[SetItem]¶
Return all items for changing input sequence values.
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_everything() ... interface = XMLInterface("multiple_runs.xml") >>> interface.update_selections() >>> for item in interface.exchange.inputitems: ... print(item.name) t_headwaters
- property conditionitems: List[SetItem]¶
Return all items for changing condition sequence values.
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_everything() ... interface = XMLInterface("multiple_runs.xml") >>> interface.update_selections() >>> for item in interface.exchange.conditionitems: ... print(item.name) ic_lahn_2 ic_lahn_1 sm_lahn_2 sm_lahn_1 quh
- property outputitems: List[SetItem]¶
Return all items for querying the current values or the complete time series of sequences in the “setitem” style.
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_everything() ... interface = XMLInterface("multiple_runs.xml") >>> interface.update_selections() >>> for item in interface.exchange.outputitems: ... print(item.name) swe_headwaters
- property getitems: List[GetItem]¶
Return all items for querying the current values or the complete time series of sequences in the “getitem style”.
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_everything() ... interface = XMLInterface("multiple_runs.xml") >>> interface.update_selections() >>> for item in interface.exchange.getitems: ... print(item.target) factors_tmean fluxes_qt fluxes_qt_series states_sm states_sm_series nodes_sim_series
- prepare_series() None [source]¶
Prepare all required
series
arrays via theprepare_series()
method.
- property itemgroups: List[XMLItemgroup]¶
The relevant
XMLItemgroup
objects.
- class hydpy.auxs.xmltools.XMLItemgroup(master: XMLExchange, root: Element)[source]¶
Bases:
XMLBase
Helper class for
XMLExchange
responsible for handling the exchange items related to model parameters and sequences separately from the exchange items of node sequences.
- class hydpy.auxs.xmltools.XMLModel(master: XMLItemgroup, root: Element)[source]¶
Bases:
XMLBase
Helper class for
XMLItemgroup
responsible for handling the exchange items related to different parameter or sequence groups ofModel
objects.
- class hydpy.auxs.xmltools.XMLSubvars(master: XMLModel, root: Element)[source]¶
Bases:
XMLBase
Helper class for
XMLModel
responsible for handling the exchange items related to individual parameters or sequences ofModel
objects.
- class hydpy.auxs.xmltools.XMLNode(master: XMLItemgroup, root: Element)[source]¶
Bases:
XMLBase
Helper class for
XMLItemgroup
responsible for handling the exchange items related to individual parameters or sequences ofNode
objects.
- class hydpy.auxs.xmltools.XMLVar(master: XMLSubvars | XMLNode, root: Element)[source]¶
Bases:
XMLSelector
Helper class for
XMLSubvars
andXMLNode
responsible for creating a defined exchange item.- property item: ExchangeItem¶
The defined
ExchangeItem
object.We first prepare the LahnH example project and then create the related
XMLInterface
object defined by the XML configuration file multiple_runs:>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1()
>>> from hydpy import HydPy, round_, pub, TestIO, XMLInterface >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_everything() ... interface = XMLInterface("multiple_runs.xml") >>> interface.update_selections()
One of the defined
SetItem
objects modifies the values of allAlpha
objects of application modelhland_v1
. We demonstrate this for the control parameter object handled by the land_dill element:>>> var = interface.exchange.itemgroups[0].models[0].subvars[0].vars[0] >>> item = var.item >>> item.value array(2.) >>> hp.elements.land_dill.model.parameters.control.alpha alpha(1.0) >>> item.update_variables() >>> hp.elements.land_dill.model.parameters.control.alpha alpha(2.0)
The second example is comparable but focuses on a
SetItem
modifying control parameterNmbSegments
of application modelmusk_classic
via its keyword argument lag:>>> var = interface.exchange.itemgroups[0].models[2].subvars[0].vars[0] >>> item = var.item >>> item.value array(5.) >>> hp.elements.stream_dill_lahn_2.model.parameters.control.nmbsegments nmbsegments(lag=0.0) >>> item.update_variables() >>> hp.elements.stream_dill_lahn_2.model.parameters.control.nmbsegments nmbsegments(lag=5.0)
The third discussed
SetItem
assigns the same value to all entries of state sequenceSM
, resulting in the same soil moisture for all individual hydrological response units of element land_lahn_2:>>> var = interface.exchange.itemgroups[1].models[0].subvars[0].vars[2] >>> item = var.item >>> item.name 'sm_lahn_2' >>> item.value array([123.]) >>> hp.elements.land_lahn_2.model.sequences.states.sm sm(138.31396, 135.71124, 147.54968, 145.47142, 154.96405, 153.32805, 160.91917, 159.62434, 165.65575, 164.63255) >>> item.update_variables() >>> hp.elements.land_lahn_2.model.sequences.states.sm sm(123.0, 123.0, 123.0, 123.0, 123.0, 123.0, 123.0, 123.0, 123.0, 123.0)
In contrast to the last example, the fourth
SetItem
is 1-dimensional and thus allows to assign different values to the individual hydrological response units of element land_lahn_1:>>> var = interface.exchange.itemgroups[1].models[0].subvars[0].vars[3] >>> item = var.item >>> item.name 'sm_lahn_1' >>> item.value array([110., 120., 130., 140., 150., 160., 170., 180., 190., 200., 210., 220., 230.]) >>> hp.elements.land_lahn_1.model.sequences.states.sm sm(99.27505, 96.17726, 109.16576, 106.39745, 117.97304, 115.56252, 125.81523, 123.73198, 132.80035, 130.91684, 138.95523, 137.25983, 142.84148) >>> with pub.options.warntrim(False): ... item.update_variables() >>> hp.elements.land_lahn_1.model.sequences.states.sm sm(110.0, 120.0, 130.0, 140.0, 150.0, 160.0, 170.0, 180.0, 190.0, 200.0, 206.0, 206.0, 206.0)
Without defining initial values in the XML file, the
value
property of eachSetItem
starts with the averaged (see item ic_lahn_2) or original (see item ic_lahn_1) values of the corresponding sequences:>>> var = interface.exchange.itemgroups[1].models[0].subvars[0].vars[0] >>> item = var.item >>> item.name 'ic_lahn_2' >>> round_(item.value) 1.184948 >>> round_(hp.elements.land_lahn_2.model.sequences.states.ic.average_values()) 1.184948 >>> var = interface.exchange.itemgroups[1].models[0].subvars[0].vars[1] >>> item = var.item >>> item.name 'ic_lahn_1' >>> item.value array([0.96404, 1.36332, 0.96458, 1.46458, 0.96512, 1.46512, 0.96565, 1.46569, 0.96617, 1.46617, 0.96668, 1.46668, 1.46719]) >>> hp.elements.land_lahn_1.model.sequences.states.ic ic(0.96404, 1.36332, 0.96458, 1.46458, 0.96512, 1.46512, 0.96565, 1.46569, 0.96617, 1.46617, 0.96668, 1.46668, 1.46719)
Finally, one
SetItem
addresses the time series if the input sequenceT
of both headwater catchments. Similar to the example above, its initial values stem from its target sequences’ initial (time series) values:>>> var = interface.exchange.itemgroups[2].models[0].subvars[0].vars[0] >>> item = var.item >>> item.value array([[-0.29884643, -0.81153886, -2.49384849, -5.96884868, -6.9996175 ], [-0.70539496, -1.50555283, -4.22126769, -7.44634946, -8.11936591]]) >>> hp.elements.land_dill.model.sequences.inputs.t.series InfoArray([-0.29884643, -0.81153886, -2.49384849, -5.96884868, -6.9996175 ]) >>> hp.elements.land_lahn_1.model.sequences.inputs.t.series InfoArray([-0.70539496, -1.50555283, -4.22126769, -7.44634946, -8.11936591]) >>> item.value = [0.0, 1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0, 9.0] >>> item.update_variables() >>> hp.elements.land_dill.model.sequences.inputs.t.series InfoArray([0., 1., 2., 3., 4.]) >>> hp.elements.land_lahn_1.model.sequences.inputs.t.series InfoArray([5., 6., 7., 8., 9.])
AddItem
sfcf_1, sfcf_2, and sfcf_3 serve to demonstrate how a scalar value (sfcf_1 and sfcf_2) or a vector of values can be used to change the value of a “target” parameter (SfCF
) in relation to a “base” parameter (RfCF
):>>> for element in pub.selections.headwaters.elements: ... element.model.parameters.control.rfcf(1.1) >>> for element in pub.selections.nonheadwaters.elements: ... element.model.parameters.control.rfcf(1.0)
>>> for subvars in interface.exchange.itemgroups[3].models[0].subvars: ... for var in subvars.vars: ... var.item.update_variables() >>> for element in hp.elements.catchment: ... print(element, repr(element.model.parameters.control.sfcf)) land_dill sfcf(1.4) land_lahn_1 sfcf(1.4) land_lahn_2 sfcf(1.2) land_lahn_3 sfcf(field=1.1, forest=1.2)
MultiplyItem
k4 works similar to the described add items but multiplies the current values of the base parameter objects of typeK
with 10 to gain new values for the target parameter objects of typeK4
:>>> for subvars in interface.exchange.itemgroups[4].models[0].subvars: ... for var in subvars.vars: ... var.item.update_variables() >>> for element in hp.elements.catchment: ... control = element.model.parameters.control ... print(element, repr(control.k), repr(control.k4)) land_dill k(0.005618) k4(0.056177) land_lahn_1 k(0.005325) k4(0.053247) land_lahn_2 k(0.005948) k4(0.059481) land_lahn_3 k(0.002571) k4(0.025712)
The final three examples focus on
GetItem
objects. OneGetItem
object queries the actual values of theSM
states of all relevant elements:>>> var = interface.exchange.itemgroups[5].models[0].subvars[2].vars[0] >>> hp.elements.land_dill.model.sequences.states.sm = 1.0 >>> for name, target in var.item.yield_name2value(): ... print(name, target) land_dill_states_sm [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] land_lahn_1_states_sm [110.0, 120.0, 130.0, 140.0, 150.0, 160.0, 170.0, 180.0, 190.0, 200.0, 206.0, 206.0, 206.0] land_lahn_2_states_sm [123.0, 123.0, 123.0, 123.0, 123.0, 123.0, 123.0, 123.0, 123.0, 123.0] land_lahn_3_states_sm [101.3124...]
Another
GetItem
object queries the actual value of theTMean
factor sequence of element land_dill:>>> hp.elements.land_dill.model.sequences.factors.tmean(1.0) >>> for var in interface.exchange.itemgroups[5].models[0].subvars[0].vars: ... for name, target in var.item.yield_name2value(): ... print(name, target) land_dill_factors_tmean 1.0
Another
GetItem
object queries both the actual and the time series values of theQT
flux sequence of element land_dill:>>> qt = hp.elements.land_dill.model.sequences.fluxes.qt >>> qt(1.0) >>> qt.series = 2.0 >>> for var in interface.exchange.itemgroups[5].models[0].subvars[1].vars: ... for name, target in var.item.yield_name2value(): ... print(name, target) land_dill_fluxes_qt 1.0 land_dill_fluxes_qt_series [2.0, 2.0, 2.0, 2.0, 2.0]
Last but not least, one
GetItem
queries the simulated time series values available through node dill:>>> var = interface.exchange.itemgroups[5].nodes[0].vars[0] >>> hp.nodes.dill.sequences.sim.series = range(5) >>> for name, target in var.item.yield_name2value(): ... print(name, target) dill_nodes_sim_series [0.0, 1.0, 2.0, 3.0, 4.0] >>> for name, target in var.item.yield_name2value(2, 4): ... print(name, target) dill_nodes_sim_series [2.0, 3.0]
- class hydpy.auxs.xmltools.XSDWriter[source]¶
Bases:
object
A pure
classmethod
class for writing the actual XML schema file HydPyConfigBase.xsd, which makes sure that an XML configuration file is readable by classXMLInterface
.Unless you are interested in enhancing HydPy’s XML functionalities, you should, if any, be interested in method
write_xsd()
only.- confpath: str = '/home/travis/build/hydpy-dev/hydpy/.nox/sphinx/lib/python3.11/site-packages/hydpy/conf'¶
- filepath_source: str = '/home/travis/build/hydpy-dev/hydpy/.nox/sphinx/lib/python3.11/site-packages/hydpy/conf/HydPyConfigBase.xsdt'¶
- filepath_target: str = '/home/travis/build/hydpy-dev/hydpy/.nox/sphinx/lib/python3.11/site-packages/hydpy/conf/HydPyConfigBase.xsd'¶
- classmethod write_xsd() None [source]¶
Write the complete base schema file HydPyConfigBase.xsd based on the template file HydPyConfigBase.xsdt.
Method
write_xsd()
adds model-specific information to the general information of template file HydPyConfigBase.xsdt regarding reading and writing of time series data and exchanging parameter and sequence values, for example, during calibration.The following example shows that after writing a new schema file, method
validate_xml()
does not raise an error when either applied to the XML configuration files single_run.xml or multiple_runs.xml of the LahnH example project:>>> import os >>> from hydpy.auxs.xmltools import XSDWriter, XMLInterface >>> if os.path.exists(XSDWriter.filepath_target): ... os.remove(XSDWriter.filepath_target) >>> os.path.exists(XSDWriter.filepath_target) False >>> XSDWriter.write_xsd() >>> os.path.exists(XSDWriter.filepath_target) True
>>> from hydpy.data import make_filepath >>> for configfile in ("single_run.xml", "multiple_runs.xml"): ... XMLInterface(configfile, make_filepath("LahnH")).validate_xml()
- static get_basemodelnames() List[str] [source]¶
Return a sorted
list
containing all base model names.>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_basemodelnames()) ['arma', 'conv', ..., 'wland']
- static get_applicationmodelnames() List[str] [source]¶
Return a sorted
list
containing all application model names.>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_applicationmodelnames()) [...'dam_v001', 'dam_v002', 'dam_v003', 'dam_v004', 'dam_v005',...]
- classmethod get_insertion() str [source]¶
Return the complete string to be inserted into the string of the template file.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_insertion()) <complexType name="dam_v001_readerType"> <sequence> <element name="inputs" minOccurs="0"> <complexType> <sequence> <element name="precipitation" minOccurs="0"/> <element name="evaporation" minOccurs="0"/> </sequence> </complexType> </element> </sequence> </complexType> ... <complexType name="readerType"> <sequence> <element name="node" type="hpcb:node_readerType" minOccurs="0"/> <element name="dam_v001" type="hpcb:dam_v001_readerType" minOccurs="0"/> ... <element name="wland_v002" type="hpcb:wland_v002_readerType" minOccurs="0"/> </sequence> </complexType> ... <complexType name="arma_v1_writerType"> <sequence> <element name="fluxes" minOccurs="0"> <complexType> <sequence> <element name="qin" ... <element name="qout" minOccurs="0"/> </sequence> </complexType> </element> </sequence> </complexType> ... <complexType name="writerType"> <sequence> <element name="node" type="hpcb:node_writerType" minOccurs="0"/> <element name="arma_v1" type="hpcb:arma_v1_writerType" minOccurs="0"/> ... <element name="wland_v002" type="hpcb:wland_v002_writerType" minOccurs="0"/> </sequence> </complexType>
- classmethod get_modelinsertion(model: modeltools.Model, type_: str, indent: int) str | None [source]¶
Return the insertion string required for the given application model.
>>> from hydpy.auxs.xmltools import XSDWriter >>> from hydpy import prepare_model >>> model = prepare_model("hland_v1") >>> print(XSDWriter.get_modelinsertion( ... model=model, type_="reader", indent=1)) <element name="inputs" minOccurs="0"> <complexType> <sequence> <element name="p" minOccurs="0"/> ... <element name="epn" minOccurs="0"/> </sequence> </complexType> </element> >>> print(XSDWriter.get_modelinsertion( ... model=model, type_="writer", indent=1)) <element name="inputs" minOccurs="0"> <complexType> <sequence> <element name="p" minOccurs="0"/> ... </element> <element name="fluxes" minOccurs="0"> ... </element> <element name="states" minOccurs="0"> ... </element>
>>> model = prepare_model("arma_v1") >>> XSDWriter.get_modelinsertion( ... model=model, type_="reader", indent=1) >>> print(XSDWriter.get_modelinsertion( ... model=model, type_="writer", indent=1)) <element name="fluxes" minOccurs="0"> <complexType> <sequence> <element name="qin" minOccurs="0"/> ... <element name="qout" minOccurs="0"/> </sequence> </complexType> </element>
- classmethod get_subsequencesinsertion(subsequences: SubSequences[Any, Any, Any], indent: int) str [source]¶
Return the insertion string required for the given group of sequences.
>>> from hydpy.auxs.xmltools import XSDWriter >>> from hydpy import prepare_model >>> model = prepare_model("hland_v1") >>> print(XSDWriter.get_subsequencesinsertion( ... model.sequences.factors, 1)) <element name="factors" minOccurs="0"> <complexType> <sequence> <element name="tmean" minOccurs="0"/> <element name="tc" minOccurs="0"/> ... <element name="contriarea" minOccurs="0"/> </sequence> </complexType> </element>
- static get_sequenceinsertion(sequence: sequencetools.Sequence_[Any, Any], indent: int) str [source]¶
Return the insertion string required for the given sequence.
>>> from hydpy.auxs.xmltools import XSDWriter >>> from hydpy import prepare_model >>> model = prepare_model("hland_v1") >>> print(XSDWriter.get_sequenceinsertion(model.sequences.fluxes.pc, 1)) <element name="pc" minOccurs="0"/>
- classmethod get_readerwriterinsertion(type_: Literal['reader', 'writer'], indent: int) str [source]¶
Return the insertion all sequences relevant for reading or writing time-series data.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_readerwriterinsertion("reader", 1)) <complexType name="readerType"> <sequence> <element name="node" type="hpcb:node_readerType" minOccurs="0"/> <element name="dam_v001" type="hpcb:dam_v001_readerType" minOccurs="0"/> ... <element name="wland_v002" type="hpcb:wland_v002_readerType" minOccurs="0"/> </sequence> </complexType> >>> print(XSDWriter.get_readerwriterinsertion("writer", 1)) <complexType name="writerType"> <sequence> <element name="node" type="hpcb:node_writerType" minOccurs="0"/> <element name="arma_v1" type="hpcb:arma_v1_writerType" minOccurs="0"/> ... <element name="wland_v002" type="hpcb:wland_v002_writerType" minOccurs="0"/> </sequence> </complexType>
- classmethod get_exchangeinsertion() str [source]¶
Return the complete string related to the definition of exchange items to be inserted into the string of the template file.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_exchangeinsertion()) <complexType name="arma_v1_mathitemType"> ... <element name="setitems"> ... <complexType name="arma_v1_setitemsType"> ... <element name="additems"> ... <element name="multiplyitems"> ... <element name="getitems"> ...
- classmethod get_mathitemsinsertion(indent: int) str [source]¶
Return a string defining a model-specific XML type extending ItemType.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_mathitemsinsertion(1)) <complexType name="arma_v1_mathitemType"> <complexContent> <extension base="hpcb:mathitemType"> <choice> <element name="control.responses"/> ... <element name="fluxes.qout"/> </choice> </extension> </complexContent> </complexType> <complexType name="conv_v001_mathitemType"> ...
- classmethod get_keyworditemsinsertion(indent: int) str [source]¶
Return a string defining additional types that support modifying parameter values by specific keyword arguments.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_keyworditemsinsertion(1)) <simpleType name="musk_control_nmbsegments_keywordType"> <restriction base="string"> <enumeration value="lag"/> </restriction> </simpleType> <complexType name="musk_control_nmbsegments_setitemType"> <complexContent> <extension base="hpcb:setitemType"> <sequence> <element name="keyword" type="hpcb:musk_control_nmbsegments_keywordType" minOccurs = "0"/> </sequence> </extension> </complexContent> </complexType> ...
- classmethod get_itemsinsertion(itemgroup: str, indent: int) str [source]¶
Return a string defining the XML element for the given exchange item group.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_itemsinsertion("setitems", 1)) <element name="setitems"> <complexType> <sequence> <element ref="hpcb:selections" minOccurs="0"/> ... <element name="hland_v1" type="hpcb:hland_v1_setitemsType" minOccurs="0" maxOccurs="unbounded"/> ... <element name="nodes" type="hpcb:nodes_setitemsType" minOccurs="0" maxOccurs="unbounded"/> </sequence> <attribute name="info" type="string"/> </complexType> </element>
- classmethod get_itemtypesinsertion(itemgroup: str, indent: int) str [source]¶
Return a string defining the required types for the given exchange item group.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_itemtypesinsertion( ... "setitems", 1)) <complexType name="arma_v1_setitemsType"> ... </complexType> <complexType name="dam_v001_setitemsType"> ... <complexType name="nodes_setitemsType"> ...
- classmethod get_itemtypeinsertion(itemgroup: str, modelname: str, indent: int) str [source]¶
Return a string defining the required types for the given combination of an exchange item group and an application model.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_itemtypeinsertion( ... "setitems", "hland_v1", 1)) <complexType name="hland_v1_setitemsType"> <sequence> <element ref="hpcb:selections" minOccurs="0"/> <element name="control" minOccurs="0" maxOccurs="unbounded"> ... </sequence> </complexType>
- classmethod get_nodesitemtypeinsertion(itemgroup: str, indent: int) str [source]¶
Return a string defining the required types for the given combination of an exchange item group and
Node
objects.>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_nodesitemtypeinsertion( ... "setitems", 1)) <complexType name="nodes_setitemsType"> <sequence> <element ref="hpcb:selections" minOccurs="0"/> <element name="sim" type="hpcb:setitemType" minOccurs="0" maxOccurs="unbounded"/> <element name="obs" type="hpcb:setitemType" minOccurs="0" maxOccurs="unbounded"/> <element name="sim.series" type="hpcb:setitemType" minOccurs="0" maxOccurs="unbounded"/> <element name="obs.series" type="hpcb:setitemType" minOccurs="0" maxOccurs="unbounded"/> </sequence> </complexType>
- classmethod get_subgroupsiteminsertion(itemgroup: str, modelname: str, indent: int) str [source]¶
Return a string defining the required types for the given combination of an exchange item group and an application model.
>>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_subgroupsiteminsertion( ... "setitems", "hland_v1", 1)) <element name="control" minOccurs="0" maxOccurs="unbounded"> ... </element> <element name="inputs" ... <element name="factors" ... <element name="fluxes" ... <element name="states" ... <element name="logs" ...
- classmethod get_subgroupiteminsertion(itemgroup: str, model: modeltools.Model, subgroup: variabletools.SubVariables[Any, Any, Any], indent: int) str [source]¶
Return a string defining the required types for the given combination of an exchange item group and a specific variable subgroup of an application model or class
Node
.Note that for setitems and getitems setitemType and getitemType are referenced, respectively, and for all others, the model-specific mathitemType:
>>> from hydpy import prepare_model >>> model = prepare_model("hland_v1") >>> from hydpy.auxs.xmltools import XSDWriter >>> print(XSDWriter.get_subgroupiteminsertion( ... "setitems", model, model.parameters.control, 1)) <element name="control" minOccurs="0" maxOccurs="unbounded"> <complexType> <sequence> <element ref="hpcb:selections" minOccurs="0"/> <element name="area" type="hpcb:setitemType" minOccurs="0" maxOccurs="unbounded"/> <element name="nmbzones" ... </sequence> </complexType> </element>
>>> print(XSDWriter.get_subgroupiteminsertion( ... "getitems", model, model.parameters.control, 1)) <element name="control" ... <element name="area" type="hpcb:getitemType" minOccurs="0" maxOccurs="unbounded"/> ...
>>> print(XSDWriter.get_subgroupiteminsertion( ... "additems", model, model.parameters.control, 1)) <element name="control" ... <element name="area" type="hpcb:hland_v1_mathitemType" minOccurs="0" maxOccurs="unbounded"/> ...
>>> print(XSDWriter.get_subgroupiteminsertion( ... "multiplyitems", model, model.parameters.control, 1)) <element name="control" ... <element name="area" type="hpcb:hland_v1_mathitemType" minOccurs="0" maxOccurs="unbounded"/> ...
For sequence classes, additional “series” elements are added:
>>> print(XSDWriter.get_subgroupiteminsertion( ... "setitems", model, model.sequences.factors, 1)) <element name="factors" ... <element name="tmean" type="hpcb:setitemType" minOccurs="0" maxOccurs="unbounded"/> <element name="tmean.series" type="hpcb:setitemType" minOccurs="0" maxOccurs="unbounded"/> <element name="tc" ... </sequence> </complexType> </element>