sequencetools¶
This module implements tools for defining and handling different kinds of the sequences (time-series) of hydrological models.
Module sequencetools implements the following members:
FastAccessIOSequenceTypeType variable.
IOSequenceTypeType variable.
IOSequencesTypeType variable.
LinkSequenceTypeType variable.
LinkSequencesTypeType variable.
ModelIOSequenceTypeType variable.
ModelIOSequencesTypeType variable.
ModelSequenceTypeType variable.
ModelSequencesTypeType variable.
OutputSequenceTypeType variable.
OutputSequencesTypeType variable.
SequenceTypeType variable.
SequencesTypeType variable.
SubSequencesTypeType variable.
FastAccessIOSequenceProvides fast access to the values of the sequences of a sequence subgroup and supports the handling of internal data series during simulations.
FastAccessInputSequenceFastAccessIOSequencesubclass specialised for input sequences.
FastAccessOutputSequenceFastAccessIOSequencesubclass specialised for output sequences.
FastAccessLinkSequenceFastAccessIOSequencesubclass specialised for link sequences.
FastAccessNodeSequenceFastAccessIOSequencesubclass specialised forNodeobjects.
InfoArraynumpyndarraysubclass that stores and tries to keep an additional info attribute.
SequencesBase class for handling all sequences of a specific model.
SubSequencesBase class for handling subgroups of sequences.
ModelSequencesBase class for handling model-related subgroups of sequences.
IOSequencesSubclass ofSubSequences, specialised for handlingIOSequenceobjects.
ModelIOSequencesBase class for handling model-related subgroups ofIOSequenceobjects.
InputSequencesBase class for handlingInputSequenceobjects.
OutputSequencesBase class for handlingOutputSequenceobjects.
FluxSequencesBase class for handlingFluxSequenceobjects.
StateSequencesBase class for handlingStateSequenceobjects.
LogSequencesBase class for handlingLogSequenceobjects.
AideSequencesBase class for handlingAideSequenceobjects.
LinkSequencesBase class for handlingLinkSequenceobjects.
InletSequencesBase class for handling “inlet”LinkSequenceobjects.
OutletSequencesBase class for handling “outlet”LinkSequenceobjects.
ReceiverSequencesBase class for handling “receiver”LinkSequenceobjects.
SenderSequencesBase class for handling “sender”LinkSequenceobjects.
Sequence_Base class for defining different kinds of sequences.
IOSequenceBase class for sequences with input/output functionalities.
ModelSequenceBase class for sequences to be handled byModelobjects.
ModelIOSequenceBase class for sequences with input/output functionalities to be handled byModelobjects.
InputSequenceBase class for input sequences ofModelobjects.
OutputSequenceBase class forFluxSequenceandStateSequence.
FluxSequenceBase class for flux sequences ofModelobjects.
ConditionSequenceBase class forStateSequenceandLogSequence.
StateSequenceBase class for state sequences ofModelobjects.
LogSequenceBase class for logging sequences ofModelobjects.
AideSequenceBase class for aide sequences ofModelobjects.
LinkSequenceBase class for link sequences ofModelobjects.
InletSequenceBase class for inlet link sequences ofModelobjects.
OutletSequenceBase class for outlet link sequences ofModelobjects.
ReceiverSequenceBase class for receiver link sequences ofModelobjects.
SenderSequenceBase class for sender link sequences ofModelobjects.
NodeSequenceBase class for all sequences to be handled byNodeobjects.
SimClass for handling those values ofNodeobjects that are “simulated”, meaning calculated by hydrological models.
ObsClass for handling those values ofNodeobjects that are observed, meaning read from data files.
NodeSequencesBase class for handlingSimandObssequence objects.
-
class
hydpy.core.sequencetools.FastAccessIOSequence[source]¶ Bases:
hydpy.core.variabletools.FastAccessProvides fast access to the values of the sequences of a sequence subgroup and supports the handling of internal data series during simulations.
The following details are of relevance for HydPy developers only.
FastAccessIOSequenceis applied in Python mode only. In Cython mode it is replaced by model-specific Cython extension classes, which are computationally more efficient. For compatibility with these extension classes,FastAccessIOSequenceobjects work with dynamically set instance members. Suppose there is a sequence named seq1 which is 2-dimensional, then its associated attributes are:seq1 (
ndarray): The actual sequence values._seq1_ndim (
int): Number of dimensions._seq1_length_0 (
int): Length in the first dimension._seq1_length_1 (
int): Length in the second dimension._seq1_ramflag (
bool): Handle internal data in RAM?_seq1_diskflag (
bool): Handle internal data on disk?_seq1_path (
str): Path of the internal data file._seq1_file (
open()): Object handling the internal data file.
Note that the respective
SubSequencesandSequence_objects initialise, change, and apply these dynamical attributes. To handle them directly is error-prone and thus not recommended.-
open_files(idx: int) → None[source]¶ Open all files with an activated disk flag and seek the position indicated by the given index.
-
close_files() → None[source]¶ Close the internal data files of all handled sequences with an activated
diskflag.
-
load_data(idx: int) → None[source]¶ Load the internal data of all sequences with an activated
memoryflag.Read from a file if the corresponding disk flag is activated; read from working memory if the corresponding ram flag is activated.
-
class
hydpy.core.sequencetools.FastAccessInputSequence[source]¶ Bases:
hydpy.core.sequencetools.FastAccessIOSequenceFastAccessIOSequencesubclass specialised for input sequences.-
set_pointerinput(name: str, pdouble: hydpy.cythons.autogen.pointerutils.PDouble) → None[source]¶ Use the given
PDoubleobject as the pointer for the 0-dimensionalInputSequenceobject with the given name.
-
-
class
hydpy.core.sequencetools.FastAccessOutputSequence[source]¶ Bases:
hydpy.core.sequencetools.FastAccessIOSequenceFastAccessIOSequencesubclass specialised for output sequences.-
set_pointeroutput(name: str, pdouble: hydpy.cythons.autogen.pointerutils.PDouble) → None[source]¶ Use the given
PDoubleobject as the pointer for the 0-dimensionalOutputSequenceobject with the given name.
-
-
class
hydpy.core.sequencetools.FastAccessLinkSequence[source]¶ Bases:
hydpy.core.variabletools.FastAccessFastAccessIOSequencesubclass specialised for link sequences.-
alloc(name: str, length: int) → None[source]¶ Allocate enough memory for the given vector length for the
LinkSequencewith the given name.Cython extension classes need to define
alloc()if there is at least one 1-dimensionalLinkSequencesubclasses.
-
dealloc(name: str) → None[source]¶ Free the previously allocated memory of the
LinkSequencewith the given name.Cython extension classes need to define
alloc()if there is at least one 1-dimensionalLinkSequencesubclasses.
-
set_pointer0d(name: str, value: hydpy.cythons.autogen.pointerutils.Double)[source]¶ Use the given
PDoubleobject as the pointer of the 0-dimensionalLinkSequenceobject with the given name.Cython extension classes need to define
set_pointer0d()if there is at least one 0-dimensionalLinkSequencesubclasses.
-
set_pointer1d(name: str, value: hydpy.cythons.autogen.pointerutils.Double, idx: int)[source]¶ Use the given
PDoubleobject as one of the pointers of the 1-dimensionalLinkSequenceobject with the given name.The given index defines the vector position of the pointer.
Cython extension classes need to define
set_pointer0d()if there is at least one 1-dimensionalLinkSequencesubclasses.
-
get_value(name: str) → Union[float, numpy.ndarray][source]¶ Return the actual value(s) the
LinkSequenceobject with the given name is pointing to.
-
-
class
hydpy.core.sequencetools.FastAccessNodeSequence[source]¶ Bases:
hydpy.core.sequencetools.FastAccessIOSequenceFastAccessIOSequencesubclass specialised forNodeobjects.In contrast to other
FastAccessIOSequencesubclasses,FastAccessNodeSequenceonly needs to handle a fixed number of sequences,SimandObs. It thus can define the related attributes explicitly.-
sim: hydpy.cythons.autogen.pointerutils.Double¶
-
obs: hydpy.cythons.autogen.pointerutils.Double¶
-
load_data(idx: int) → None[source]¶ Call both method
load_simdata()and methodload_obsdata().
-
save_data(idx: int) → None[source]¶ Alias for method
save_simdata().
-
-
class
hydpy.core.sequencetools.InfoArray(array, info=None)[source]¶ Bases:
numpy.ndarraynumpyndarraysubclass that stores and tries to keep an additional info attribute.>>> from hydpy.core.sequencetools import InfoArray >>> array = InfoArray([1.0, 2.0], info="this array is short") >>> array InfoArray([ 1., 2.]) >>> array.info 'this array is short' >>> subarray = array[:1] >>> subarray InfoArray([ 1.]) >>> subarray.info 'this array is short'
-
class
hydpy.core.sequencetools.Sequences(model: modeltools.Model, cls_inlets: Optional[Type[InletSequences]] = None, cls_receivers: Optional[Type[ReceiverSequences]] = None, cls_inputs: Optional[Type[InputSequences]] = None, cls_fluxes: Optional[Type[FluxSequences]] = None, cls_states: Optional[Type[StateSequences]] = None, cls_logs: Optional[Type[LogSequences]] = None, cls_aides: Optional[Type[AideSequences]] = None, cls_outlets: Optional[Type[OutletSequences]] = None, cls_senders: Optional[Type[SenderSequences]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None, cythonmodule: Optional[module] = None)[source]¶ Bases:
objectBase class for handling all sequences of a specific model.
Sequencesobjects handle nine sequence subgroups as attributes such as the inlets and the receivers subsequences:>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> sequences = hp.elements.land_dill.model.sequences >>> bool(sequences.inlets) False >>> bool(sequences.fluxes) True
Iteration makes only the non-empty subgroups available which are handling
Sequence_objects:>>> for subseqs in sequences: ... print(subseqs.name) inputs fluxes states logs outlets >>> len(sequences) 5
Class
Sequencesprovides some methods related to reading and writing time-series data, which (directly or indirectly) call the corresponding methods of the handledIOSequenceobjects. In most cases, users should prefer to use the related methods of classHydPybut using the ones of classSequencescan be more convenient when analysing a specific model in-depth.To introduce these methods, we first change two IO-related settings:
>>> from hydpy import round_ >>> pub.options.checkseries = False >>> pub.sequencemanager.generaloverwrite = True
Method
activate_ram()and methoddeactivate_ram()enables/disables handling time-series in rapid access memory and methodsave_series()writes time-series to files:>>> sequences.activate_ram() >>> sequences.inputs.t.ramflag True >>> sequences.inputs.t.series = 1.0, 2.0, 3.0, 4.0 >>> with TestIO(): ... sequences.save_series() >>> sequences.deactivate_ram() >>> sequences.inputs.t.ramflag False >>> sequences.inputs.t.series Traceback (most recent call last): ... AttributeError: Sequence `t` of element `land_dill` is not requested to make any internal data available.
Method
activate_disk()anddeactivate_disk()enables/disables handling time-series on disk and methodload_series()reads time-series from files:>>> with TestIO(): ... sequences.activate_disk() >>> sequences.inputs.t.diskflag True >>> with TestIO(): ... sequences.load_series() ... round_(sequences.inputs.t.series) 1.0, 2.0, 3.0, 4.0 >>> with TestIO(): ... sequences.deactivate_disk() >>> sequences.inputs.t.diskflag False >>> hasattr(sequences.inputs.t, "series") False
Methods
ram2disk()anddisk2ram()allow moving data from RAM to disk and from disk to RAM, respectively:>>> sequences.activate_ram() >>> sequences.inputs.t.ramflag True >>> sequences.inputs.t.series = 1.0, 2.0, 3.0, 4.0 >>> with TestIO(): ... sequences.ram2disk() >>> sequences.inputs.t.diskflag True >>> with TestIO(): ... round_(sequences.inputs.t.series) 1.0, 2.0, 3.0, 4.0 >>> with TestIO(): ... sequences.disk2ram() >>> round_(sequences.inputs.t.series) 1.0, 2.0, 3.0, 4.0
The documentation on class
IOSequenceexplains the underlying functionalities of classIOSequencein more detail.>>> pub.options.checkseries = True >>> pub.sequencemanager.generaloverwrite = False
-
model: modeltools.Model¶
-
inlets: InletSequences¶
-
receivers: ReceiverSequences¶
-
inputs: InputSequences¶
-
fluxes: FluxSequences¶
-
states: StateSequences¶
-
logs: LogSequences¶
-
aides: AideSequences¶
-
outlets: OutletSequences¶
-
senders: SenderSequences¶
-
property
iosubsequences¶ Yield all relevant
IOSequencesobjects handled by the currentSequencesobject.The currently available IO-subgroups are inputs, fluxes, and states.
>>> from hydpy import prepare_model >>> model = prepare_model("hland_v1", "1d") >>> for subseqs in model.sequences.iosubsequences: ... print(subseqs.name) inputs fluxes states
However, not all models implement sequences for all these subgroups. Property
iosubsequencesonly yields those subgroups which are non-empty:>>> model = prepare_model("hstream_v1", "1d") >>> for subseqs in model.sequences.iosubsequences: ... print(subseqs.name) states
-
activate_disk() → None[source]¶ Call method
activate_disk()of all handledIOSequencesobjects.
-
deactivate_disk() → None[source]¶ Call method
deactivate_disk()of all handledIOSequencesobjects.
-
activate_ram() → None[source]¶ Call method
activate_ram()of all handledIOSequencesobjects.
-
deactivate_ram() → None[source]¶ Call method
deactivate_ram()of all handledIOSequencesobjects.
-
ram2disk()[source]¶ Call method
ram2disk()of all handledIOSequencesobjects.
-
disk2ram()[source]¶ Call method
disk2ram()of all handledIOSequencesobjects.
-
load_series()[source]¶ Call method
load_series()of all handledIOSequencesobjects.
-
save_series()[source]¶ Call method
save_ext()of all handledIOSequencesobjects.
-
open_files(idx: int = 0) → None[source]¶ Call method
open_files()of all handledIOSequencesobjects.
-
close_files() → None[source]¶ Call method
close_files()of all handledIOSequencesobjects.
-
load_data(idx: int) → None[source]¶ Call method
load_data()of the handledInputSequencesobject.
-
save_data(idx: int) → None[source]¶ Call method
save_data()of the handledFluxSequencesandStateSequencesobjects.
-
reset() → None[source]¶ Call method
reset()of all handledConditionSequenceobjects.
-
property
conditionsequences¶ Generator object yielding all conditions (
StateSequenceandLogSequenceobjects).
-
property
conditions¶ A nested dictionary which contains the values of all condition sequences.
See the documentation on property
conditionsfor further information.
-
load_conditions(filename: Optional[str] = None) → None[source]¶ Read the initial conditions from a file and assign them to the respective
StateSequenceandLogSequenceobjects handled by the actualSequencesobject.The documentation on method
load_conditions()of classHydPyexplains how to read and write condition values for complete HydPy projects in the most convenient manner. However, using the underlying methodsload_conditions()andsave_conditions()directly offers the advantage to specify alternative filenames. We demonstrate this through using the land_dillElementobject of the LahnH example project and focussing on the values of state sequenceSM:>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> sequences = hp.elements.land_dill.model.sequences >>> sequences.states.sm 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)
From now on, we work in the freshly created condition directory test:
>>> with TestIO(): ... pub.conditionmanager.currentdir = "test"
We set all soil moisture values to zero and write the updated values to the file cold_start.py:
>>> sequences.states.sm(0.0)
>>> with TestIO(): ... sequences.save_conditions("cold_start.py")
Trying to reload from the written file (after changing the soil moisture values again) without passing the file name fails due to assuming the elements name as file name base:
>>> sequences.states.sm(100.0) >>> with TestIO(): ... sequences.load_conditions() Traceback (most recent call last): ... FileNotFoundError: While trying to load the initial conditions of element `land_dill`, the following error occurred: [Errno 2] No such file or directory: '...land_dill.py'
One does not need to state the file extensions (.py) explicitly:
>>> with TestIO(): ... sequences.load_conditions("cold_start") >>> sequences.states.sm sm(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
Note that determining the file name automatically requires a proper reference to the related
Elementobject:>>> del sequences.model.element >>> with TestIO(): ... sequences.save_conditions() Traceback (most recent call last): ... RuntimeError: While trying to save the actual conditions of element `?`, the following error occurred: To load or save the conditions of a model from or to a file, its filename must be known. This can be done, by passing filename to method `load_conditions` or `save_conditions` directly. But in complete HydPy applications, it is usally assumed to be consistent with the name of the element handling the model. Actually, neither a filename is given nor does the model know its master element.
-
save_conditions(filename: Optional[str] = None) → None[source]¶ Query the actual conditions of the
StateSequenceandLogSequenceobjects handled by the actualSequencesobject and write them into an initial condition file.See the documentation on method
load_conditions()for further information.
-
trim_conditions() → None[source]¶ Call method
trim()of each handledConditionSequence.trim_conditions()is just a convenience function for calling methodtrim()of allStateSequenceandLogSequenceobjects returned by propertyconditionsequences. We demonstrate its functionality by preparing an instance of application modellland_v1, using its available default values, and defining out-of-bound values of the soil moisture state sequenceBoWa:>>> from hydpy import prepare_model, pub >>> pub.timegrids = "2000-01-01", "2000-01-10", "1d" >>> with pub.options.usedefaultvalues(True): ... model = prepare_model("lland_v1", "1d") ... model.parameters.control.nhru(2) >>> model.sequences.states.bowa = -100.0 >>> model.sequences.trim_conditions() >>> model.sequences.states.bowa bowa(0.0, 0.0)
-
-
class
hydpy.core.sequencetools.SubSequences(master: GroupType, cls_fastaccess: Optional[Type[FastAccessType]] = None)[source]¶ Bases:
hydpy.core.variabletools.SubVariables[hydpy.core.sequencetools.SequencesType,hydpy.core.sequencetools.SequenceType,hydpy.core.variabletools.FastAccessType]Base class for handling subgroups of sequences.
Each
SubSequencesobject has a fastaccess attribute. When working in pure Python mode, this is an instance either of (a subclass of) classFastAccess:>>> from hydpy import classname, Node, prepare_model, pub >>> with pub.options.usecython(False): ... model = prepare_model("lland_v1") >>> classname(model.sequences.logs.fastaccess) 'FastAccess' >>> classname(model.sequences.inputs.fastaccess) 'FastAccessInputSequence' >>> from hydpy.core.sequencetools import FastAccessNodeSequence >>> with pub.options.usecython(False): ... node = Node("test1") >>> isinstance(node.sequences.fastaccess, FastAccessNodeSequence) True
When working in Cython mode (which is the default mode and much faster), fastaccess is an object of Cython extension class FastAccessNodeSequence of module sequenceutils or of a Cython extension class specialised for the respective model and sequence group:
>>> with pub.options.usecython(True): ... model = prepare_model("lland_v1") >>> classname(model.sequences.inputs.fastaccess) 'InputSequences' >>> from hydpy.cythons.sequenceutils import FastAccessNodeSequence >>> with pub.options.usecython(True): ... node = Node("test2") >>> isinstance(Node("test2").sequences.fastaccess, FastAccessNodeSequence) True
See the documentation of similar class
SubParametersfor further information. However, note the difference that model developers should not subclassSubSequencesdirectly but specialised subclasses likeFluxSequencesorStateSequencesinstead.-
property
name¶ The class name in lower case letters omitting the last eight characters (“equences”).
>>> from hydpy.core.sequencetools import StateSequences >>> class StateSequences(StateSequences): ... CLASSES = () >>> StateSequences(None).name 'states'
-
vars: GroupType¶
-
property
-
class
hydpy.core.sequencetools.ModelSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.SubSequences[hydpy.core.sequencetools.Sequences,hydpy.core.sequencetools.ModelSequenceType,hydpy.core.variabletools.FastAccessType]Base class for handling model-related subgroups of sequences.
-
class
hydpy.core.sequencetools.IOSequences(master: GroupType, cls_fastaccess: Optional[Type[FastAccessType]] = None)[source]¶ Bases:
hydpy.core.sequencetools.SubSequences[hydpy.core.sequencetools.SequencesType,hydpy.core.sequencetools.IOSequenceType,hydpy.core.sequencetools.FastAccessIOSequenceType]Subclass of
SubSequences, specialised for handlingIOSequenceobjects.-
activate_ram()[source]¶ Call method
activate_ram()of all handledIOSequenceobjects.
-
deactivate_ram()[source]¶ Call method
deactivate_ram()of all handledIOSequenceobjects.
-
activate_disk()[source]¶ Call method
activate_disk()of all handledIOSequenceobjects.
-
deactivate_disk()[source]¶ Call method
deactivate_disk()of all handledIOSequenceobjects.
-
ram2disk()[source]¶ Call method
ram2disk()of all handledIOSequenceobjects.
-
disk2ram()[source]¶ Call method
disk2ram()of all handledIOSequenceobjects.
-
load_series()[source]¶ Call method
load_ext()of all handledIOSequenceobjects.
-
save_series()[source]¶ Call method
save_ext()of all handledIOSequenceobjects.
-
open_files(idx: int = 0) → None[source]¶ Call method
open_files()of theFastAccessIOSequenceobject handled as attribute fastaccess.
-
close_files()[source]¶ Call method
close_files()of theFastAccessIOSequenceobject handled as attribute fastaccess.
-
vars: GroupType¶
-
-
class
hydpy.core.sequencetools.ModelIOSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.IOSequences[hydpy.core.sequencetools.Sequences,hydpy.core.sequencetools.ModelIOSequenceType,hydpy.core.sequencetools.FastAccessIOSequenceType],hydpy.core.sequencetools.ModelSequences[hydpy.core.sequencetools.ModelIOSequenceType,hydpy.core.sequencetools.FastAccessIOSequenceType]Base class for handling model-related subgroups of
IOSequenceobjects.-
load_data(idx: int) → None[source]¶ Call method
load_data()of theFastAccessIOSequenceobject handled as attribute fastaccess.
-
save_data(idx: int) → None[source]¶ Call method
save_data()of theFastAccessIOSequenceobject handled as attribute fastaccess.
-
vars: GroupType¶
-
-
class
hydpy.core.sequencetools.InputSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.ModelIOSequences[InputSequence,hydpy.core.sequencetools.FastAccessInputSequence]Base class for handling
InputSequenceobjects.-
vars: GroupType¶
-
-
class
hydpy.core.sequencetools.OutputSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.ModelIOSequences[hydpy.core.sequencetools.OutputSequenceType,hydpy.core.sequencetools.FastAccessOutputSequence]Base class for handling
OutputSequenceobjects.-
update_outputs() → None[source]¶ Call method
update_outputs()of theFastAccessOutputSequenceobject handled as attribute fastaccess.
-
vars: GroupType¶
-
-
class
hydpy.core.sequencetools.FluxSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.OutputSequences[FluxSequence]Base class for handling
FluxSequenceobjects.-
property
name¶ Always return the string “fluxes”.
-
property
numericsequences¶ Iterator for numerical flux sequences.
numerical means that the NUMERIC class attribute of the actual sequence is True:
>>> from hydpy import prepare_model >>> model = prepare_model("dam_v001") >>> len(model.sequences.fluxes) 11 >>> for seq in model.sequences.fluxes.numericsequences: ... print(seq) inflow(nan) actualrelease(nan) flooddischarge(nan) outflow(nan)
-
vars: GroupType¶
-
property
-
class
hydpy.core.sequencetools.StateSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.OutputSequences[StateSequence]Base class for handling
StateSequenceobjects.-
new2old() → None[source]¶ Call method
new2old()of all handledStateSequenceobjects.
-
reset() → None[source]¶ Call method
reset()of all handledStateSequenceobjects.
-
-
class
hydpy.core.sequencetools.LogSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.ModelSequences[LogSequence,hydpy.core.variabletools.FastAccess]Base class for handling
LogSequenceobjects.-
reset() → None[source]¶ Call method
reset()of all handledLogSequenceobjects.
-
-
class
hydpy.core.sequencetools.AideSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.ModelSequences[AideSequence,hydpy.core.variabletools.FastAccess]Base class for handling
AideSequenceobjects.
-
class
hydpy.core.sequencetools.LinkSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.ModelSequences[hydpy.core.sequencetools.LinkSequenceType,hydpy.core.sequencetools.FastAccessLinkSequence]Base class for handling
LinkSequenceobjects.
-
class
hydpy.core.sequencetools.InletSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.LinkSequences[InletSequence]Base class for handling “inlet”
LinkSequenceobjects.
-
class
hydpy.core.sequencetools.OutletSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.LinkSequences[OutletSequence]Base class for handling “outlet”
LinkSequenceobjects.
-
class
hydpy.core.sequencetools.ReceiverSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.LinkSequences[ReceiverSequence]Base class for handling “receiver”
LinkSequenceobjects.
-
class
hydpy.core.sequencetools.SenderSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.LinkSequences[SenderSequence]Base class for handling “sender”
LinkSequenceobjects.
-
class
hydpy.core.sequencetools.Sequence_(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.variabletools.Variable[hydpy.core.sequencetools.SubSequencesType,hydpy.core.variabletools.FastAccessType]Base class for defining different kinds of sequences.
Note that model developers should not derive their model-specific sequence classes from
Sequence_directly but from the “final” subclasses provided in modulesequencetools(e.g.FluxSequence).From the model developer perspective and especially from the user perspective,
Sequence_is only a small extension of its base classVariable. One relevant extension is that (only the) 0-dimensional sequence objects come with a predefined shape:>>> from hydpy import prepare_model >>> model = prepare_model("lland_v1", "1d") >>> model.sequences.fluxes.qa.shape () >>> evpo = model.sequences.fluxes.evpo >>> evpo.shape Traceback (most recent call last): ... hydpy.core.exceptiontools.AttributeNotReady: Shape information for variable `evpo` can only be retrieved after it has been defined.
For high numbers of entries, the string representation puts the names of the constants within a list (to make the string representations executable under Python 3.6; this behaviour changes as soon as Python 3.7 becomes the oldest supported version):
>>> evpo.shape = (255,) >>> evpo evpo(nan, nan, ..., nan, nan) >>> evpo.shape = (256,) >>> evpo evpo([nan, nan, ..., nan, nan])
For consistency with the usage of
Parametersubclasses,Sequence_objects are also “callable” for setting their values (but in a much less and flexible manner):>>> evpo(2.0) >>> evpo evpo([2.0, 2.0, ..., 2.0, 2.0])
Under the hood, class
Sequence_also prepares some attributes of itsFastAccessobject, used for performing the actual simulation calculations. Framework developers should note that the respective fastaccess attributes contain both the name of the sequence and the name of the original attribute in lower case letters. We take NDIM as an example:>>> evpo.fastaccess._evpo_ndim 1
Some of these attributes require updating under some situations. For example, other sequences than
AideSequenceobjects require a “length” attribute, which needs to be updated each time the sequence’s shape changes:>>> evpo.fastaccess._evpo_length 256
-
TYPE¶
-
-
property
subseqs¶ Alias for attribute subvars.
-
property
initinfo¶ A
tuplecontaining the initial value andTrueor a missing value andFalse, depending on the actualSequence_subclass and the actual value of optionusedefaultvalues.In the following, we do not explain property
initinfoitself but show how it affects initialising newSequence_objects. Therefore, let us define a sequence test class and prepare a function for initialising it and connecting the resulting instance to aModelSequencesobject:>>> from hydpy.core.sequencetools import Sequence_, ModelSequences >>> from hydpy.core.variabletools import FastAccess >>> class Test(Sequence_): ... NDIM = 0 ... _CLS_FASTACCESS_PYTHON = FastAccess >>> class SubGroup(ModelSequences): ... CLASSES = (Test,) ... _CLS_FASTACCESS_PYTHON = FastAccess >>> def prepare(): ... subseqs = SubGroup(None) ... test = Test(subseqs) ... test.__hydpy__connect_variable2subgroup__() ... return test
By default, making use of the INIT attribute is disabled:
>>> prepare() test(nan)
Enable it through setting
usedefaultvaluestoTrue:>>> from hydpy import pub >>> with pub.options.usedefaultvalues(True): ... prepare() test(0.0)
Attribute INIT of class
Sequence_comes with the value 0.0 by default, which should be reasonable for mostSequence_subclasses. However, subclasses can define other values. Most importantly, note the possibility to set INIT to None for sequences that do not allow defining a reasonabe initial value for all possible situations:>>> Test.INIT = None >>> prepare() test(nan) >>> with pub.options.usedefaultvalues(True): ... prepare() test(nan)
-
class
hydpy.core.sequencetools.IOSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.Sequence_[hydpy.core.sequencetools.IOSequencesType,hydpy.core.sequencetools.FastAccessIOSequenceType]Base class for sequences with input/output functionalities.
The
IOSequencesubclassesInputSequence,FluxSequence,StateSequence, andNodeSequenceall implement similar special properties, which configure the processes of reading and writing time-series files. In the following, property filetype_ext is taken as an example to explain how to handle them:Usually, each sequence queries its current “external” file type from the
SequenceManagerobject stored in modulepub:>>> from hydpy import pub >>> from hydpy.core.filetools import SequenceManager >>> pub.sequencemanager = SequenceManager()
Depending if the actual sequence stems from
InputSequence,FluxSequence,StateSequence, orNodeSequence, eitherinputfiletype,fluxfiletype,statefiletype, ornodefiletypeare queried:>>> pub.sequencemanager.inputfiletype = "npy" >>> pub.sequencemanager.fluxfiletype = "asc" >>> pub.sequencemanager.nodefiletype = "nc" >>> from hydpy.core import sequencetools as st >>> st.InputSequence(None).filetype_ext 'npy' >>> st.FluxSequence(None).filetype_ext 'asc' >>> st.NodeSequence(None).filetype_ext 'nc'
Alternatively, you can specify filetype_ext for each sequence object individually:
>>> seq = st.InputSequence(None) >>> seq.filetype_ext 'npy' >>> seq.filetype_ext = "nc" >>> seq.filetype_ext 'nc' >>> del seq.filetype_ext >>> seq.filetype_ext 'npy'
If neither a specific definition nor a
SequenceManagerobject is available, property filetype_ext raises the following error:>>> del pub.sequencemanager >>> seq.filetype_ext Traceback (most recent call last): ... RuntimeError: For sequence `inputsequence` attribute filetype_ext cannot be determined. Either set it manually or prepare `pub.sequencemanager` correctly.
How to read and write time-series files is explained in the documentation on modules
filetoolsandnetcdftoolsin some detail. However, reading and writing time-series files is disabled by default, due to reasons of efficiency. You first need to prepare theseriesattribute of the relevantIOSequenceobjects. Typically, you do this by calling methods likeprepare_inputseries()of classHydPy. Here, we use the related features theIOSequenceclass itself, which is a little more complicated but also more flexible when scripting complex workflows.We use the LahnH example project and focus on the input and flux sequences:
>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> inputs = hp.elements.land_lahn_1.model.sequences.inputs >>> fluxes = hp.elements.land_lahn_1.model.sequences.fluxes
IOSequenceobjects come with the propertiesramflaganddiskflag, telling if the respective time-series is available in RAM, on disk, or not available at all. Input sequences are the only ones who need to have one flag activated. Otherwise, the input series would not be available during simulation runs. For example, input sequenceTstores its time-series data in RAM internally, which is the much faster approach and should be preferred, as long as limited storage is not an issue:>>> inputs.t.ramflag True >>> inputs.t.diskflag False >>> from hydpy import repr_, round_ >>> round_(inputs.t.series, 1) -0.7, -1.5, -4.2, -7.4
Convenience function
prepare_full_example_2()also activates theramflagof all flux sequences, which is not necessary to perform a successful simulation but is required to query the complete time-series of simulated values afterwards (otherwise, only the last simulated value would available after a simulation run):>>> fluxes.tc.ramflag True >>> round_(fluxes.tc.series[:, 0]) nan, nan, nan, nan
Use
activate_ram()oractivate_disk()to force a sequence to handle time-series data in RAM or on disk, respectively. We now activate thediskflagof flux sequenceTMean(which automatically disables theramflag). Note that we need to change the current working directory to the iotesting directory temporarily (by using classTestIO) to make sure to create that the related file in the right directory:>>> with TestIO(): ... fluxes.tmean.activate_disk() ... repr_(fluxes.tmean.filepath_int) '...iotesting/LahnH/series/temp/land_lahn_1_flux_tmean.bin'
The user can access the time-series data in the same manner as if being handled in RAM:
>>> fluxes.tmean.ramflag False >>> fluxes.tmean.diskflag True >>> with TestIO(): ... round_(fluxes.tmean.series) nan, nan, nan, nan
For completeness of testing, we also activate the
diskflagof a 1-dimensional sequence:>>> from pprint import pprint >>> with TestIO(): ... fluxes.fracrain.activate_disk() ... pprint(sorted(os.listdir("LahnH/series/temp"))) ['land_lahn_1_flux_fracrain.bin', 'land_lahn_1_flux_tmean.bin']
Apply methods
deactivate_ram()ordeactivate_disk()for sequences that do not provide data relevant for your analysis:>>> fluxes.ep.deactivate_ram() >>> fluxes.ep.ramflag False >>> fluxes.ep.diskflag False >>> fluxes.ep.series Traceback (most recent call last): ... AttributeError: Sequence `ep` of element `land_lahn_1` is not requested to make any internal data available.
After a simulation run, the
seriesof flux sequenceEPis still not available but the time-series data of the other discussed series with either trueramflagordiskflagvalues are:>>> with TestIO(): ... hp.simulate()
>>> fluxes.ep.series = 1.0 Traceback (most recent call last): ... AttributeError: Sequence `ep` of element `land_lahn_1` is not requested to make any internal data available.
>>> round_(fluxes.q1.series, 1) 0.4, 0.4, 0.4, 0.4 >>> round_(fluxes.tc.series[:, 0], 1) 0.2, -0.6, -3.4, -6.6 >>> with TestIO(): ... round_(fluxes.tmean.series, 1) -1.0, -1.8, -4.5, -7.7 >>> with TestIO(): ... round_(fluxes.fracrain.series[:, 0], 1) 0.3, 0.0, 0.0, 0.0
You cannot only access the time-series data of individual
IOSequenceobjects, but you can also modify it. See, for example, the simulated time series for flux sequencePC(adjusted precipitation), which is zero, because the values of input sequenceP(given precipitation) are also zero:>>> round_(fluxes.pc.series[:, 0], 1) 0.0, 0.0, 0.0, 0.0
We can assign different values to attribute
seriesof sequenceP, perform a new simulation run, and see that the newly calculated time-series of sequencePCreflects our data modification:>>> inputs.p.ramflag True >>> inputs.p.series = 10.0 >>> with TestIO(): ... hp.simulate() >>> round_(fluxes.pc.series[:, 0], 1) 10.2, 11.3, 11.3, 11.3
Next, we show that the same feature works for time-series data handled on disk. Therefore, we first call method
ram2disk(), which disablesramflagand enablesdiskflagwithout any loss of information:>>> with TestIO(): ... inputs.p.ram2disk() ... pprint(sorted(os.listdir("LahnH/series/temp"))) ['land_lahn_1_flux_fracrain.bin', 'land_lahn_1_flux_tmean.bin', 'land_lahn_1_input_p.bin'] >>> inputs.p.ramflag False >>> inputs.p.diskflag True >>> with TestIO(): ... round_(inputs.p.series, 1) 10.0, 10.0, 10.0, 10.0
Data modifications still influence simulation runs as to be expected:
>>> with TestIO(): ... inputs.p.series = 20.0 ... hp.simulate() ... round_(fluxes.pc.series[:, 0], 1) 20.5, 22.6, 22.6, 22.6
Method
disk2ram()is the counterpart toram2disk():>>> with TestIO(): ... inputs.p.disk2ram() ... pprint(sorted(os.listdir("LahnH/series/temp"))) ['land_lahn_1_flux_fracrain.bin', 'land_lahn_1_flux_tmean.bin'] >>> inputs.p.ramflag True >>> inputs.p.diskflag False >>> round_(inputs.p.series, 1) 20.0, 20.0, 20.0, 20.0
Method
deactivate_disk()works analogue todeactivate_ram():>>> with TestIO(): ... fluxes.fracrain.deactivate_disk() ... pprint(sorted(os.listdir("LahnH/series/temp"))) ['land_lahn_1_flux_tmean.bin'] >>> fluxes.fracrain.ramflag False >>> fluxes.fracrain.diskflag False
Both methods
deactivate_ram()anddeactivate_disk()do nothing in case the respective flag isFalsealready:>>> fluxes.pc.deactivate_ram() >>> with TestIO(): ... fluxes.fracrain.deactivate_disk()
You can query property
memoryflag, if you are only interested to know if a sequence handles stores its time-series data, but not how:>>> fluxes.pc.memoryflag False >>> fluxes.tmean.memoryflag True >>> inputs.p.memoryflag True
Another convenience property is
seriesshape, which combines the length of the simulation period with the shape of the individualIOSequenceobject:>>> inputs.p.seriesshape (4,) >>> fluxes.pc.seriesshape (4, 13)
Note that resetting the
shapeof amIOSequenceobject does not change how it handles its internal time-series data, but results in a loss of current information:>>> fluxes.tc.seriesshape (4, 13) >>> fluxes.fastaccess._tc_length 13 >>> round_(fluxes.tc.series[:, 0], 1) 0.2, -0.6, -3.4, -6.6
>>> fluxes.tc.shape = (2,) >>> fluxes.tc.seriesshape (4, 2) >>> fluxes.fastaccess._tc_length 2 >>> round_(fluxes.tc.series[:, 0], 1) nan, nan, nan, nan
Resetting the
shapeofIOSequenceobjects which are not storing their internal time-series data works too:>>> fluxes.pc.seriesshape (4, 13) >>> fluxes.fastaccess._pc_length 13 >>> round_(fluxes.pc.series[:, 0], 1) Traceback (most recent call last): ... AttributeError: Sequence `pc` of element `land_lahn_1` is not requested to make any internal data available.
>>> fluxes.pc.shape = (2,) >>> fluxes.pc.seriesshape (4, 2) >>> fluxes.fastaccess._pc_length 2 >>> round_(fluxes.pc.series[:, 0], 1) Traceback (most recent call last): ... AttributeError: Sequence `pc` of element `land_lahn_1` is not requested to make any internal data available.
-
filetype_ext: ClassVar[hydpy.core.sequencetools._FileType]¶
-
dirpath_ext: ClassVar[hydpy.core.sequencetools._DirPathProperty]¶
-
aggregation_ext: ClassVar[hydpy.core.sequencetools._AggregationProperty]¶
-
overwrite_ext: ClassVar[hydpy.core.sequencetools._OverwriteProperty]¶
-
rawfilename¶ DefaultPropertyhandling the filename without ending for external and internal data files.>>> from hydpy.core.sequencetools import StateSequence >>> class Test(StateSequence): ... descr_device = "node1" ... descr_sequence = "subgroup_test" >>> Test(None).rawfilename 'node1_subgroup_test'
-
filename_ext¶ The full filename of the external data file.
The “external” filename consists of
rawfilenameand offiletype_ext. For simplicity, we add the attribute rawfilename to the initialised sequence object in the following example:>>> from hydpy.core.sequencetools import StateSequence >>> seq = StateSequence(None) >>> seq.rawfilename = "test" >>> seq.filetype_ext = "nc" >>> seq.filename_ext 'test.nc'
-
property
filename_int¶ The full filename of the internal data file.
The “internal” filename consists of
rawfilenameand the file ending .bin. For simplicity, we add the attribute rawfilename to the initialised sequence object in the following example:>>> from hydpy.core.sequencetools import StateSequence >>> seq = StateSequence(None) >>> seq.rawfilename = "test" >>> seq.filename_int 'test.bin'
-
dirpath_int¶ The absolute path of the directory of the internal data file.
Usually, each sequence queries its current “internal” directory path from the
SequenceManagerobject stored in modulepub:>>> from hydpy import pub, repr_, TestIO >>> from hydpy.core.filetools import SequenceManager >>> pub.sequencemanager = SequenceManager()
We overwrite
basepathand prepare a folder in the iotesting directory to simplify the following examples:>>> basepath = SequenceManager.basepath >>> SequenceManager.basepath = "test" >>> TestIO.clear() >>> import os >>> with TestIO(): ... os.makedirs("test/temp")
Generally, property
dirpath_intqueries propertytempdirpath:>>> from hydpy.core import sequencetools as st >>> seq = st.InputSequence(None) >>> with TestIO(): ... repr_(seq.dirpath_int) 'test/temp'
Alternatively, you can specify
dirpath_intfor each sequence object individually:>>> seq.dirpath_int = "path" >>> os.path.split(seq.dirpath_int) ('', 'path') >>> del seq.dirpath_int >>> with TestIO(): ... os.path.split(seq.dirpath_int) ('test', 'temp')
If neither a specific definition nor a
SequenceManagerobject is, property dirpath_int raises the following error:>>> del pub.sequencemanager >>> seq.dirpath_int Traceback (most recent call last): ... RuntimeError: For sequence `inputsequence` the directory of the internal data file cannot be determined. Either set it manually or prepare `pub.sequencemanager` correctly.
Remove the basepath mock:
>>> SequenceManager.basepath = basepath
-
filepath_ext¶ The absolute path to the external data file.
The path pointing to the “external” file consists of
dirpath_extandfilename_ext. For simplicity, we define both manually in the following example:>>> from hydpy.core.sequencetools import StateSequence >>> seq = StateSequence(None) >>> seq.dirpath_ext = "path" >>> seq.filename_ext = "file.npy" >>> from hydpy import repr_ >>> repr_(seq.filepath_ext) 'path/file.npy'
-
filepath_int¶ The absolute path to the internal data file.
The path pointing to the “internal” file consists of
dirpath_intandfilename_int, which itself is defined by rawfilename. For simplicity, we define both manually in the following example:>>> from hydpy.core.sequencetools import StateSequence >>> seq = StateSequence(None) >>> seq.dirpath_int = "path" >>> seq.rawfilename = "file" >>> from hydpy import repr_ >>> repr_(seq.filepath_int) 'path/file.bin'
-
update_fastaccess() → None[source]¶ Update the
FastAccessIOSequenceobject handled by the actualIOSequenceobject.Users do not need to apply the method
update_fastaccess()directly. The following information should be relevant for framework developers only.The main documentation on class
Sequence_mentions that theFastAccessIOSequenceattribute handles some information about its sequences, but this information needs to be kept up-to-date by the sequences themselves. This updating is the task of methodupdate_fastaccess(), which some other methods of classIOSequencecall. We show this via the hidden attribute length, which is 0 after initialisation, and automatically set to another value when assigning it to propertyshapeofIOSequencesubclasses asNKor:>>> from hydpy import prepare_model >>> model = prepare_model("lland_v1") >>> nkor = model.sequences.fluxes.nkor >>> nkor.fastaccess._nkor_length 0 >>> nkor.shape = (3,) >>> nkor.fastaccess._nkor_length 3
-
activate_ram() → None[source]¶ Demand reading/writing internal data from/to RAM.
See the main documentation on class
IOSequencefor further information.
-
activate_disk() → None[source]¶ Demand reading/writing internal data from/to hard disk.
See the main documentation on class
IOSequencefor further information.
-
deactivate_ram() → None[source]¶ Prevent from reading/writing internal data from/to hard disk.
See the main documentation on class
IOSequencefor further information.
-
deactivate_disk() → None[source]¶ Prevent from reading/writing internal data from/to hard disk.
See the main documentation on class
IOSequencefor further information.
-
ram2disk() → None[source]¶ Move internal data from RAM to disk.
See the main documentation on class
IOSequencefor further information.
-
disk2ram() → None[source]¶ Move internal data from disk to RAM.
See the main documentation on class
IOSequencefor further information.
-
property
ramflag¶ A flag telling if the actual
IOSequenceobject makes its internal time-series data available using RAM space.See the main documentation on class
IOSequencefor further information.
-
property
diskflag¶ A flag telling if the actual
IOSequenceobject makes its internal time-series data available using disk space.See the main documentation on class
IOSequencefor further information.
-
property
memoryflag¶ A flag telling if the actual
IOSequenceobject makes its internal time-series data available somehow.See the main documentation on class
IOSequencefor further information.
-
property
shape¶ A tuple containing the actual lengths of all dimensions.
When setting a new
shapeof anIOSequenceobject, one automatically calls methodupdate_fastaccess()and, if necessary, prepares the new internalseriesarray.See the main documentation on class
IOSequencefor further information.
-
property
seriesshape¶ The shape of the whole time-series (time being the first dimension).
-
property
numericshape¶ The shape of the array of temporary values required for the relevant numerical solver.
The class
ELSModel, being the base of the “dam” model, uses the “Explicit Lobatto Sequence” for solving differential equations and therefore requires up to eleven array fields for storing temporary values. Hence, thenumericshapeof the 0-dimensional sequenceInflowis eleven:>>> from hydpy import prepare_model >>> model = prepare_model("dam") >>> model.sequences.fluxes.inflow.numericshape (11,)
Changing the
shapethrough a little trick (just for demonstration purposes) shows that there are eleven entries for each “normal”Inflowvalue:>>> from hydpy.models.dam.dam_fluxes import Inflow >>> shape = Inflow.shape >>> Inflow.shape = (2,) >>> model.sequences.fluxes.inflow.numericshape (11, 2) >>> Inflow.shape = shape
Erroneous configurations result in the following error:
>>> del model.numconsts >>> model.sequences.fluxes.inflow.numericshape Traceback (most recent call last): ... AttributeError: The `numericshape` of a sequence like `inflow` depends on the configuration of the actual integration algorithm. While trying to query the required configuration data `nmb_stages` of the model associated with element `?`, the following error occurred: 'Model' object has no attribute 'numconsts'
-
property
series¶ Internal time-series data within an
InfoArraycovering the whole initialisation period (defined by thesimTimegridof the globalTimegridsobject available in modulepub).
-
property
simseries¶ Read and write access to the data of property
seriesfor the actual simulation period (defined by thesimTimegridof the globalTimegridsobject available in modulepub).>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> t = hp.elements.land_lahn_1.model.sequences.inputs.t >>> pub.timegrids.sim.dates = "1996-01-02", "1996-01-04" >>> from hydpy import print_values >>> print_values(t.series) -0.705395, -1.505553, -4.221268, -7.446349 >>> print_values(t.simseries) -1.505553, -4.221268 >>> t.simseries = 1.0, 2.0 >>> print_values(t.series) -0.705395, 1.0, 2.0, -7.446349
-
property
evalseries¶ Read and write access to the data of property
seriesfor the actual evaluation period (defined by theeval_Timegridof the globalTimegridsobject available in modulepub).>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> t = hp.elements.land_lahn_1.model.sequences.inputs.t >>> pub.timegrids.eval_.dates = "1996-01-02", "1996-01-04" >>> from hydpy import print_values >>> print_values(t.series) -0.705395, -1.505553, -4.221268, -7.446349 >>> print_values(t.evalseries) -1.505553, -4.221268 >>> t.evalseries = 1.0, 2.0 >>> print_values(t.series) -0.705395, 1.0, 2.0, -7.446349
-
load_ext() → None[source]¶ Read the internal data from an external data file.
Method
load_ext()only calls methodload_file()of classSequenceManagerpassing itself as the only argument. Hence, see the documentation on the classSequenceManagerfor further information. The following example only shows the error messages whenload_file()is missing due to incomplete project configurations:>>> from hydpy.core.sequencetools import StateSequence >>> StateSequence(None).load_ext() Traceback (most recent call last): ... hydpy.core.exceptiontools.AttributeNotReady: While trying to load the external time-series data of `statesequence`, the following error occurred: Attribute sequencemanager of module `pub` is not defined at the moment.
-
adjust_series(timegrid_data: timetools.Timegrid, values: numpy.ndarray) → numpy.ndarray[source]¶ Adjust a time-series to the current initialisation period.
Note that, in most HydPy applications, method
adjust_series()is called by other methods related to reading data from files and does not need to be called by the user directly. If you want to call it directly for some reasons, you need to make sure that the shape of the givennumpyndarrayfits the givenTimegridobject.Often, time-series data available in (external) data files cover a longer period than required for an actual simulation run. Method
adjust_series()selects the relevant data by comparing the initialisationTimegridavailable in modulepuband the given “data”Timegridobject. We explain this behaviour by using the LahnH example project and focussing on theObssequence ofNodedill:>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> obs = hp.nodes.dill.sequences.obs
With identical initialisation and data time grids, method
adjust_series()returns the given data completely:>>> from hydpy import Timegrid >>> import numpy >>> with TestIO(), pub.options.checkseries(False): ... obs.adjust_series(Timegrid("1996-01-01", "1996-01-05", "1d"), ... numpy.arange(4, dtype=float)) array([ 0., 1., 2., 3.])
For “too long” available data, it only returns the relevant one:
>>> with TestIO(), pub.options.checkseries(False): ... obs.adjust_series(Timegrid("1995-12-31", "1996-01-07", "1d"), ... numpy.arange(7, dtype=float)) array([ 1., 2., 3., 4.])
For “too short” available data, the behaviour differs depending on option
checkseries. Withcheckseriesbeing enabled, methodadjust_series()raises aRuntimeError. Withcheckseriesbeing disabled, it extends the given array withnanvalues (using methodadjust_short_series()):>>> with TestIO(), pub.options.checkseries(True): ... obs.adjust_series(Timegrid("1996-01-02", "1996-01-04", "1d"), ... numpy.zeros((3,))) Traceback (most recent call last): ... RuntimeError: For sequence `obs` of node `dill` the initialisation time grid (Timegrid("1996-01-01 00:00:00", "1996-01-05 00:00:00", "1d")) does not define a subset of the time grid of the external data file `...dill_obs_q.asc` (Timegrid("1996-01-02 00:00:00", "1996-01-04 00:00:00", "1d")).
>>> with TestIO(), pub.options.checkseries(False): ... obs.adjust_series(Timegrid("1996-01-02", "1996-01-04", "1d"), ... numpy.zeros((2,))) array([ nan, 0., 0., nan])
Additional checks raise errors in case of non-matching shapes or time information:
>>> with TestIO(): ... obs.adjust_series(Timegrid("1996-01-01", "1996-01-05", "1d"), ... numpy.zeros((5, 2))) Traceback (most recent call last): ... RuntimeError: The shape of sequence `obs` of node `dill` is `()` but according to the external data file `...dill_obs_q.asc` it should be `(2,)`.
>>> with TestIO(): ... obs.adjust_series(Timegrid("1996-01-01", "1996-01-05", "1h"), ... numpy.zeros((24*5,))) Traceback (most recent call last): ... RuntimeError: According to external data file `...dill_obs_q.asc`, the date time step of sequence `obs` of node `dill` is `1h` but the actual simulation time step is `1d`.
-
adjust_short_series(timegrid: timetools.Timegrid, values: numpy.ndarray) → numpy.ndarray[source]¶ Adjust a short time-series to a longer time grid.
Mostly, time-series data to be read from external data files should span (at least) the whole initialisation period of a HydPy project. However, for some variables which are only used for comparison (e.g. observed runoff used for calibration), incomplete time-series might also be helpful. Method
adjust_short_series()adjusts such incomplete series to the public initialisation time grid stored in modulepub. It is automatically called in methodadjust_series()when necessary provided that the optioncheckseriesis disabled.Assume the initialisation period of a HydPy project spans five days:
>>> from hydpy import pub >>> pub.timegrids = "2000.01.10", "2000.01.15", "1d"
Prepare a node series object for observational data:
>>> from hydpy.core.sequencetools import Obs >>> obs = Obs(None)
Prepare a test function that expects the time grid of the data and the data itself, which returns the adjusted array through calling method
adjust_short_series():>>> import numpy >>> def test(timegrid): ... values = numpy.ones(len(timegrid)) ... return obs.adjust_short_series(timegrid, values)
The following calls to the test function show the arrays returned for different kinds of misalignments:
>>> from hydpy import Timegrid >>> test(Timegrid("2000.01.05", "2000.01.20", "1d")) array([ 1., 1., 1., 1., 1.]) >>> test(Timegrid("2000.01.12", "2000.01.15", "1d")) array([ nan, nan, 1., 1., 1.]) >>> test(Timegrid("2000.01.12", "2000.01.17", "1d")) array([ nan, nan, 1., 1., 1.]) >>> test(Timegrid("2000.01.10", "2000.01.13", "1d")) array([ 1., 1., 1., nan, nan]) >>> test(Timegrid("2000.01.08", "2000.01.13", "1d")) array([ 1., 1., 1., nan, nan]) >>> test(Timegrid("2000.01.12", "2000.01.13", "1d")) array([ nan, nan, 1., nan, nan]) >>> test(Timegrid("2000.01.05", "2000.01.10", "1d")) array([ nan, nan, nan, nan, nan]) >>> test(Timegrid("2000.01.05", "2000.01.08", "1d")) array([ nan, nan, nan, nan, nan]) >>> test(Timegrid("2000.01.15", "2000.01.18", "1d")) array([ nan, nan, nan, nan, nan]) >>> test(Timegrid("2000.01.16", "2000.01.18", "1d")) array([ nan, nan, nan, nan, nan])
After enabling option
usedefaultvalues, the missing values are initialised with zero instead of nan:>>> with pub.options.usedefaultvalues(True): ... test(Timegrid("2000.01.12", "2000.01.17", "1d")) array([ 0., 0., 1., 1., 1.])
-
check_completeness() → None[source]¶ Raise a
RuntimeErrorif theseriescontains at least onenanvalue and if the optioncheckseriesis enabled.>>> from hydpy import pub >>> pub.timegrids = "2000-01-01", "2000-01-11", "1d" >>> from hydpy.core.sequencetools import StateSequence, StateSequences >>> class Seq(StateSequence): ... NDIM = 0 ... NUMERIC = False >>> class StateSequences(StateSequences): ... CLASSES = (Seq,) >>> seq = Seq(StateSequences(None)) >>> seq.__hydpy__connect_variable2subgroup__() >>> seq.activate_ram() >>> seq.check_completeness() Traceback (most recent call last): ... RuntimeError: The series array of sequence `seq` contains 10 nan values.
>>> seq.series = 1.0 >>> seq.check_completeness()
>>> seq.series[3] = numpy.nan >>> seq.check_completeness() Traceback (most recent call last): ... RuntimeError: The series array of sequence `seq` contains 1 nan value.
>>> with pub.options.checkseries(False): ... seq.check_completeness()
-
save_ext() → None[source]¶ Write the internal data into an external data file.
Method
save_ext()only calls methodsave_file()of classSequenceManagerpassing itself as the only argument. Hence, see the documentation on class theSequenceManagerfor further information. The following example only shows the error messages whensave_file()is missing due to incomplete project configurations:>>> from hydpy.core.sequencetools import StateSequence >>> StateSequence(None).save_ext() Traceback (most recent call last): ... hydpy.core.exceptiontools.AttributeNotReady: While trying to save the external time-series data of `statesequence`, the following error occurred: Attribute sequencemanager of module `pub` is not defined at the moment.
-
save_mean(*args, **kwargs) → None[source]¶ Average the time-series date with method
average_series()of classIOSequenceand write the result to file using methodsave_file()of classSequenceManager.The main documentation on class
SequenceManagerprovides some examples.
-
average_series(*args, **kwargs) → hydpy.core.sequencetools.InfoArray[source]¶ Average the actual time-series of the
Variableobject for all time points.Method
average_series()works similarly as methodaverage_values()of classVariable, from which we borrow some examples. However, firstly, we have to prepare aTimegridsobject to define theserieslength:>>> from hydpy import pub >>> pub.timegrids = "2000-01-01", "2000-01-04", "1d"
As shown for method
average_values(), for 0-dimensionalIOSequenceobjects the result of methodaverage_series()equalsseriesitself:>>> from hydpy.core.sequencetools import StateSequence, StateSequences >>> class SoilMoisture(StateSequence): ... NDIM = 0 ... NUMERIC = False >>> class StateSequences(StateSequences): ... CLASSES = (SoilMoisture,) >>> sm = SoilMoisture(StateSequences(None)) >>> sm.__hydpy__connect_variable2subgroup__() >>> sm.activate_ram() >>> import numpy >>> sm.series = numpy.array([190.0, 200.0, 210.0]) >>> sm.average_series() InfoArray([ 190., 200., 210.])
For
IOSequenceobjects with an increased dimensionality, we require a weighting parameter:>>> SoilMoisture.NDIM = 1 >>> sm.shape = 3 >>> sm.activate_ram() >>> sm.series = ( ... [190.0, 390.0, 490.0], ... [200.0, 400.0, 500.0], ... [210.0, 410.0, 510.0]) >>> from hydpy.core.parametertools import Parameter >>> class Area(Parameter): ... NDIM = 1 ... shape = (3,) ... value = numpy.array([1.0, 1.0, 2.0]) >>> area = Area(None) >>> SoilMoisture.refweights = property(lambda self: area) >>> sm.average_series() InfoArray([ 390., 400., 410.])
The documentation on method
average_values()provides many examples of how to use different masks in different ways. Here, we only show the results of methodaverage_series()for a mask selecting the first two entries, for a mask selecting no entry at all, and for an ill-defined mask:>>> from hydpy.core.masktools import DefaultMask >>> class Soil(DefaultMask): ... @classmethod ... def new(cls, variable, **kwargs): ... return cls.array2mask(maskvalues) >>> SoilMoisture.mask = Soil()
>>> maskvalues = [True, True, False] >>> sm.average_series() InfoArray([ 290., 300., 310.])
>>> maskvalues = [False, False, False] >>> sm.average_series() nan
>>> maskvalues = [True, True] >>> sm.average_series() Traceback (most recent call last): ... IndexError: While trying to calculate the mean value of the internal time-series of sequence `soilmoisture`, the following error occurred: While trying to access the value(s) of variable `area` with key `[ True True]`, the following error occurred: boolean index did not match indexed array along dimension 0; dimension is 3 but corresponding boolean dimension is 2
-
aggregate_series(*args, **kwargs) → hydpy.core.sequencetools.InfoArray[source]¶ Aggregate time-series data based on the actual
aggregation_extattribute ofIOSequencesubclasses.We prepare some nodes and elements with the help of method
prepare_io_example_1()and select a 1-dimensional flux sequence of typeNKoras an example:>>> from hydpy.examples import prepare_io_example_1 >>> nodes, elements = prepare_io_example_1() >>> seq = elements.element3.model.sequences.fluxes.nkor
If
aggregation_extis none, the original time-series values are returned:>>> seq.aggregation_ext 'none' >>> seq.aggregate_series() InfoArray([[ 24., 25., 26.], [ 27., 28., 29.], [ 30., 31., 32.], [ 33., 34., 35.]])
If
aggregation_extis mean, methodaggregate_series()is called:>>> seq.aggregation_ext = "mean" >>> seq.aggregate_series() InfoArray([ 25., 28., 31., 34.])
In case the state of the sequence is invalid:
>>> seq.aggregation_ext = "nonexistent" >>> seq.aggregate_series() Traceback (most recent call last): ... RuntimeError: Unknown aggregation mode `nonexistent` for sequence `nkor` of element `element3`.
The following technical test confirms the propr passing of all potential positional and keyword arguments
>>> seq.aggregation_ext = "mean" >>> from unittest import mock >>> seq.average_series = mock.MagicMock() >>> _ = seq.aggregate_series(1, x=2) >>> seq.average_series.assert_called_with(1, x=2)
-
-
class
hydpy.core.sequencetools.ModelSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.Sequence_[hydpy.core.sequencetools.ModelSequencesType,hydpy.core.variabletools.FastAccessType]Base class for sequences to be handled by
Modelobjects.-
property
descr_sequence¶ Description of the
ModelSequenceobject itself and theSubSequencesgroup it belongs to.>>> from hydpy import prepare_model >>> from hydpy.models import test_v1 >>> model = prepare_model(test_v1) >>> model.sequences.fluxes.q.descr_sequence 'flux_q'
-
property
descr_model¶ Description of the
ModeltheModelSequenceobject belongs to.>>> from hydpy import prepare_model >>> from hydpy.models import test, test_v1 >>> model = prepare_model(test) >>> model.sequences.fluxes.q.descr_model 'test' >>> model = prepare_model(test_v1) >>> model.sequences.fluxes.q.descr_model 'test_v1'
-
property
descr_device¶ Description of the
Elementobject theModelSequenceobject belongs to.>>> from hydpy import prepare_model, Element >>> element = Element("test_element_1") >>> from hydpy.models import test_v1 >>> model = prepare_model(test_v1) >>> model.sequences.fluxes.q.descr_device '?' >>> element.model = model >>> model.sequences.fluxes.q.descr_device 'test_element_1'
-
subvars: SubVariablesType¶
-
property
-
class
hydpy.core.sequencetools.ModelIOSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.ModelSequence[hydpy.core.sequencetools.ModelIOSequencesType,hydpy.core.sequencetools.FastAccessIOSequenceType],hydpy.core.sequencetools.IOSequence[hydpy.core.sequencetools.ModelIOSequencesType,hydpy.core.sequencetools.FastAccessIOSequenceType]Base class for sequences with input/output functionalities to be handled by
Modelobjects.-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.InputSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.ModelIOSequence[hydpy.core.sequencetools.InputSequences,hydpy.core.sequencetools.FastAccessInputSequence]Base class for input sequences of
Modelobjects.InputSequenceobjects provide their master model with input data, which is possible in two ways: either by providing their individually managed data (usually read from file) or data shared with an input node (usually calculated by another model). This flexibility allows, for example, to let application modelhland_v1read already preprocessed precipitation time-series or to couple it with application modelconv_v001, which interpolates precipitation during the simulation run.The second mechanism (coupling
InputSequenceobjects with input nodes) is rather new, and we might adjust the relevant interfaces in the future. As soon as we finally settled things, we improve the following example and place it more prominently. In short, it shows that working with both types of input data sources at the same time works well and that the differentdeploymodeoptions are supported:>>> from hydpy import Element, FusedVariable, HydPy, Node, print_values, pub, TestIO >>> from hydpy.inputs import hland_T, hland_P >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> node_t = Node("node_t", variable=hland_T) >>> node_p = Node("node_p", variable=FusedVariable("Precip", hland_P)) >>> node_q = Node("node_q") >>> land_dill = Element("land_dill", ... inputs=[node_t, node_p], ... outlets=node_q)
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1() >>> import os >>> with TestIO(): ... os.chdir("LahnH/control/default") ... with open("land_dill.py") as controlfile: ... exec(controlfile.read(), {}, locals()) ... parameters.update() ... land_dill.model = model
>>> model.sequences.inputs.t.inputflag True >>> model.sequences.inputs.p.inputflag True >>> model.sequences.inputs.epn.inputflag False
>>> hp.update_devices(nodes=[node_t, node_p, node_q], elements=land_dill) >>> hp.prepare_inputseries() >>> hp.prepare_fluxseries() >>> with TestIO(): ... hp.load_inputseries()
>>> hp.nodes.prepare_allseries() >>> node_t.deploymode = "oldsim" >>> node_t.sequences.sim.series = 1.0, 2.0, 3.0, 4.0, 5.0 >>> node_p.deploymode = "obs" >>> node_p.sequences.obs.series = 0.0, 4.0, 0.0, 8.0, 0.0
>>> hp.simulate()
>>> print_values(model.sequences.inputs.t.series) 1.0, 2.0, 3.0, 4.0, 5.0 >>> print_values(model.sequences.fluxes.tc.series[:, 0]) 2.05, 3.05, 4.05, 5.05, 6.05 >>> print_values(model.sequences.inputs.p.series) 0.0, 4.0, 0.0, 8.0, 0.0 >>> print_values(model.sequences.fluxes.pc.series[:, 0]) 0.0, 3.441339, 0.0, 6.882678, 0.0 >>> print_values(model.sequences.inputs.epn.series) 0.285483, 0.448182, 0.302786, 0.401946, 0.315023 >>> print_values(model.sequences.fluxes.epc.series[:, 0]) 0.314763, 0.524569, 0.46086, 0.689852, 0.630047
-
filetype_ext: ClassVar[_FileType]¶ Ending of the external data file.
Attribute filetype_ext is connected with attribute inputfiletype of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.inputfiletype >>> SequenceManager.inputfiletype = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import InputSequence >>> sequence = InputSequence(None) >>> sequence.filetype_ext 'global' >>> sequence.filetype_ext = "local" >>> sequence.filetype_ext 'local' >>> del sequence.filetype_ext >>> sequence.filetype_ext 'global' >>> SequenceManager.inputfiletype = temp
-
dirpath_ext: ClassVar[_DirPathProperty]¶ Absolute path of the directory of the external data file.
Attribute dirpath_ext is connected with attribute inputdirpath of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.inputdirpath >>> SequenceManager.inputdirpath = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import InputSequence >>> sequence = InputSequence(None) >>> sequence.dirpath_ext 'global' >>> sequence.dirpath_ext = "local" >>> sequence.dirpath_ext 'local' >>> del sequence.dirpath_ext >>> sequence.dirpath_ext 'global' >>> SequenceManager.inputdirpath = temp
-
aggregation_ext: ClassVar[_AggregationProperty]¶ Type of aggregation performed when writing the time-series data to an external data file.
Attribute aggregation_ext is connected with attribute inputaggregation of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.inputaggregation >>> SequenceManager.inputaggregation = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import InputSequence >>> sequence = InputSequence(None) >>> sequence.aggregation_ext 'global' >>> sequence.aggregation_ext = "local" >>> sequence.aggregation_ext 'local' >>> del sequence.aggregation_ext >>> sequence.aggregation_ext 'global' >>> SequenceManager.inputaggregation = temp
-
overwrite_ext: ClassVar[_OverwriteProperty]¶ True/False flag indicating if overwriting an existing data file is allowed or not.
Attribute overwrite_ext is connected with attribute inputoverwrite of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.inputoverwrite >>> SequenceManager.inputoverwrite = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import InputSequence >>> sequence = InputSequence(None) >>> sequence.overwrite_ext 'global' >>> sequence.overwrite_ext = "local" >>> sequence.overwrite_ext 'local' >>> del sequence.overwrite_ext >>> sequence.overwrite_ext 'global' >>> SequenceManager.inputoverwrite = temp
-
set_pointer(double: hydpy.cythons.autogen.pointerutils.Double) → None[source]¶ Prepare a pointer referencing the given
Doubleobject.Method
set_pointer()should be of relevance for framework developers and eventually for some model developers only.
-
property
inputflag¶ A flag telling if the actual
InputSequenceobject queries its data from an input node (True) or uses individually managed data, usually read from a data file (False).See the main documentation on class
InputSequencefor further information.
-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.OutputSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.ModelIOSequence[hydpy.core.sequencetools.OutputSequencesType,hydpy.core.sequencetools.FastAccessOutputSequence]Base class for
FluxSequenceandStateSequence.OutputSequencesubclasses implement an optional output mechanism. Generally, as all instances ofModelSequencesubclasses, output sequences handle values calculated within a simulation time step. With an activatedoutputflag, they also pass their internal values to an output node (see the documentation on classElement), which makes them accessible to other models.This output mechanism (coupling
OutputSequenceobjects with output nodes) is rather new, and we might adjust the relevant interfaces in the future. Additionally, it works for 0-dimensional output sequences only so far. As soon as we finally settled things, we improve the following example and place it more prominently. In short, it shows that everything works well for the differentdeploymodeoptions:>>> from hydpy import Element, HydPy, Node, print_values, pub, Selection, TestIO >>> from hydpy.outputs import hland_Perc, hland_Q0, hland_Q1, hland_UZ >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> node_q0 = Node("node_q0", variable=hland_Q0) >>> node_q1 = Node("node_q1", variable=hland_Q1) >>> node_perc = Node("node_perc", variable=hland_Perc) >>> node_uz = Node("node_uz", variable=hland_UZ) >>> node_q = Node("node_q") >>> land_dill = Element("land_dill", ... outlets=node_q, ... outputs=[node_q0, node_q1, node_perc, node_uz])
>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1() >>> import os >>> with TestIO(): ... os.chdir("LahnH/control/default") ... with open("land_dill.py") as controlfile: ... exec(controlfile.read(), {}, locals()) ... parameters.update() ... land_dill.model = model
>>> model.sequences.fluxes.q0.outputflag True >>> model.sequences.fluxes.q1.outputflag True >>> model.sequences.fluxes.perc.outputflag True >>> model.sequences.fluxes.qt.outputflag False >>> model.sequences.states.uz.outputflag True >>> model.sequences.states.lz.outputflag False
>>> hp.update_devices(nodes=[node_q0, node_q1, node_perc, node_uz], ... elements=land_dill) >>> with TestIO(): ... hp.load_conditions()
>>> hp.prepare_inputseries() >>> with TestIO(): ... hp.load_inputseries() >>> hp.prepare_fluxseries() >>> hp.prepare_stateseries() >>> hp.nodes.prepare_allseries()
>>> node_q0.deploymode = "oldsim" >>> node_q0.sequences.sim.series = 1.0 >>> node_q0.sequences.obs.series = 2.0 >>> node_q1.deploymode = "obs" >>> node_q1.sequences.obs.series = 3.0 >>> node_perc.deploymode = "newsim" >>> node_perc.sequences.obs.series = 4.0 >>> node_uz.sequences.obs.series = 5.0
>>> hp.simulate()
>>> print_values(node_q0.sequences.sim.series) 1.0, 1.0, 1.0, 1.0, 1.0 >>> print_values(node_q0.sequences.obs.series) 2.0, 2.0, 2.0, 2.0, 2.0
>>> print_values(model.sequences.fluxes.q1.series) 0.530696, 0.539661, 0.548003, 0.555721, 0.562883 >>> print_values(node_q1.sequences.sim.series) 0.530696, 0.539661, 0.548003, 0.555721, 0.562883 >>> print_values(node_q1.sequences.obs.series) 3.0, 3.0, 3.0, 3.0, 3.0
>>> print_values(model.sequences.fluxes.perc.series) 0.692545, 0.689484, 0.687425, 0.684699, 0.682571 >>> print_values(node_perc.sequences.sim.series) 0.692545, 0.689484, 0.687425, 0.684699, 0.682571 >>> print_values(node_perc.sequences.obs.series) 4.0, 4.0, 4.0, 4.0, 4.0
>>> print_values(model.sequences.states.uz.series) 5.620222, 4.359519, 3.33013, 2.450124, 1.66734 >>> print_values(node_uz.sequences.sim.series) 5.620222, 4.359519, 3.33013, 2.450124, 1.66734 >>> print_values(node_uz.sequences.obs.series) 5.0, 5.0, 5.0, 5.0, 5.0
-
set_pointer(double: hydpy.cythons.autogen.pointerutils.Double) → None[source]¶ Prepare a pointer referencing the given
Doubleobject.Method
set_pointer()should be of relevance for framework developers and eventually for some model developers only.
-
property
outputflag¶ A flag telling if the actual
OutputSequenceobject passes its data to an output node (True) or not (False).See the main documentation on class
OutputSequencefor further information.
-
subvars: SubVariablesType¶
-
filetype_ext: ClassVar[_FileType]¶
-
dirpath_ext: ClassVar[_DirPathProperty]¶
-
aggregation_ext: ClassVar[_AggregationProperty]¶
-
overwrite_ext: ClassVar[_OverwriteProperty]¶
-
-
class
hydpy.core.sequencetools.FluxSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.OutputSequence[hydpy.core.sequencetools.FluxSequences]Base class for flux sequences of
Modelobjects.-
filetype_ext: ClassVar[_FileType]¶ Ending of the external data file.
Attribute filetype_ext is connected with attribute fluxfiletype of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.fluxfiletype >>> SequenceManager.fluxfiletype = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import FluxSequence >>> sequence = FluxSequence(None) >>> sequence.filetype_ext 'global' >>> sequence.filetype_ext = "local" >>> sequence.filetype_ext 'local' >>> del sequence.filetype_ext >>> sequence.filetype_ext 'global' >>> SequenceManager.fluxfiletype = temp
-
dirpath_ext: ClassVar[_DirPathProperty]¶ Absolute path of the directory of the external data file.
Attribute dirpath_ext is connected with attribute fluxdirpath of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.fluxdirpath >>> SequenceManager.fluxdirpath = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import FluxSequence >>> sequence = FluxSequence(None) >>> sequence.dirpath_ext 'global' >>> sequence.dirpath_ext = "local" >>> sequence.dirpath_ext 'local' >>> del sequence.dirpath_ext >>> sequence.dirpath_ext 'global' >>> SequenceManager.fluxdirpath = temp
-
aggregation_ext: ClassVar[_AggregationProperty]¶ Type of aggregation performed when writing the time-series data to an external data file.
Attribute aggregation_ext is connected with attribute fluxaggregation of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.fluxaggregation >>> SequenceManager.fluxaggregation = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import FluxSequence >>> sequence = FluxSequence(None) >>> sequence.aggregation_ext 'global' >>> sequence.aggregation_ext = "local" >>> sequence.aggregation_ext 'local' >>> del sequence.aggregation_ext >>> sequence.aggregation_ext 'global' >>> SequenceManager.fluxaggregation = temp
-
overwrite_ext: ClassVar[_OverwriteProperty]¶ True/False flag indicating if overwriting an existing data file is allowed or not.
Attribute overwrite_ext is connected with attribute fluxoverwrite of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.fluxoverwrite >>> SequenceManager.fluxoverwrite = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import FluxSequence >>> sequence = FluxSequence(None) >>> sequence.overwrite_ext 'global' >>> sequence.overwrite_ext = "local" >>> sequence.overwrite_ext 'local' >>> del sequence.overwrite_ext >>> sequence.overwrite_ext 'global' >>> SequenceManager.fluxoverwrite = temp
-
property
shape¶ A tuple containing the actual lengths of all dimensions.
FluxSequenceobjects come with some additional fastaccess attributes, which should be of interest for framework developers only. However, model developers should note that we did implement only 0-dimensionalFluxSequencesubclasses with aTrueNUMERIC flag so far. Hence, we still need to prove the complete functionality of our design of 1-dimensionalFluxSequencesubclasses with aTrueNUMERIC flag.One example of a 0-dimensional sequence is the results array, handling the (intermediate or final) calculation results for flux sequence
Inflowof thedammodel:>>> from hydpy import prepare_model, print_values, pub >>> model = prepare_model("dam_v001") >>> inflow = model.sequences.fluxes.inflow >>> print_values(inflow.fastaccess._inflow_results) 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
We now show the still not thoroughly tested functionality of 1-dimensional numerical flux sequences by changing the dimensionality of class
Inflowand working in pure Python mode. Now, the results attribute isNoneinitially, as propertynumericshapeis unknown. However, setting theshapeattribute ofFluxSequenceobjects prepares all “fastaccess attributes” automatically:>>> from hydpy.models.dam.dam_fluxes import Inflow >>> Inflow.NDIM = 1 >>> with pub.options.usecython(False): ... model = prepare_model("dam_v001") >>> inflow = model.sequences.fluxes.inflow >>> inflow.fastaccess._inflow_results
>>> inflow.shape = (2,) >>> inflow.shape (2,) >>> inflow.fastaccess._inflow_results.shape (11, 2)
>>> Inflow.NDIM = 0
-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.ConditionSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.ModelSequence[hydpy.core.sequencetools.ModelSequencesType,hydpy.core.variabletools.FastAccessType]Base class for
StateSequenceandLogSequence.Class
ConditionSequenceshould not be subclassed by model developers directly. Inherit fromStateSequenceorLogSequenceinstead.-
trim(lower=None, upper=None)[source]¶ Apply
trim()of modulevariabletools.
-
reset()[source]¶ Reset the value of the actual
StateSequenceorLogSequenceobject to the last value defined by “calling” the object.We use the
lland_v2application model, which handles sequences derived fromStateSequence(takingInzpas an example) and fromLogSequence(takingWET0as an example):>>> from hydpy import prepare_model, pub >>> model = prepare_model("lland_v2")
After defining their shapes, both sequences contain
nanvalues:>>> inzp = model.sequences.states.inzp >>> inzp.shape = (2,) >>> inzp inzp(nan, nan) >>> wet0 = model.sequences.logs.wet0 >>> wet0.shape = 2 >>> wet0 wet0([[nan, nan]])
Before “calling” the sequences, method
reset()does nothing:>>> inzp.values = 0.0 >>> inzp.reset() >>> inzp inzp(0.0, 0.0) >>> wet0.values = 0.0 >>> wet0.reset() >>> wet0 wet0([[0.0, 0.0]])
After “calling” the sequences, method
reset()reuses the respective arguments:>>> with pub.options.warntrim(False): ... inzp(0.0, 1.0) >>> inzp.values = 0.0 >>> inzp inzp(0.0, 0.0) >>> with pub.options.warntrim(False): ... inzp.reset() >>> inzp inzp(0.0, 1.0) >>> wet0(1.0, 2.0) >>> wet0.values = 3.0 >>> wet0 wet0([[3.0, 3.0]]) >>> wet0.reset() >>> wet0 wet0([[1.0, 2.0]])
-
-
class
hydpy.core.sequencetools.StateSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.OutputSequence[hydpy.core.sequencetools.StateSequences],hydpy.core.sequencetools.ConditionSequence[hydpy.core.sequencetools.StateSequences,hydpy.core.sequencetools.FastAccessOutputSequence]Base class for state sequences of
Modelobjects.Each
StateSequenceobject is capable in handling states at two different “time points”: at the beginning of a simulation step via propertyoldand the end of a simulation step via propertynew. These properties are reflected by two different fastaccess attributes. fastaccess_new is an alias for the standard fastaccess attribute storing the customary information. fastaccess_old is an additional feature for storing the supplemental information.We demonstrate the above explanations using state sequence
SMof base modelhland_v1with a shape of two:>>> from hydpy import prepare_model >>> model = prepare_model("hland", "1d") >>> model.parameters.control.fc.shape = (2,) >>> model.parameters.control.fc = 100.0 >>> sm = model.sequences.states.sm >>> sm.shape = (2,)
Initially, no values are available at all:
>>> sm sm(nan, nan) >>> sm.values array([ nan, nan]) >>> sm.new array([ nan, nan]) >>> sm.old array([ nan, nan])
The typical way to define state values, especially within condition files, is to “call” state sequence objects, which sets both the “old” and the “new” states to the given value(s):
>>> sm(1.0) >>> sm.values array([ 1., 1.]) >>> sm.new array([ 1., 1.]) >>> sm.old array([ 1., 1.])
Alternatively, one can assign values to property
newor propertyold(note that usingnewis identical with using thevalueproperty):>>> sm.new = 2.0, 3.0 >>> sm sm(2.0, 3.0) >>> sm.values array([ 2., 3.]) >>> sm.new array([ 2., 3.]) >>> sm.old array([ 1., 1.])
>>> sm.old = 200.0 >>> sm sm(2.0, 3.0) >>> sm.values array([ 2., 3.]) >>> sm.new array([ 2., 3.]) >>> sm.old array([ 200., 200.])
Assigning problematic values to property
oldresults in very similar error messages as assigning problematic values to propertyvalue:>>> sm.old = 1.0, 2.0, 3.0 Traceback (most recent call last): ... ValueError: While trying to set the old value(s) of state sequence `sm`, the following error occurred: While trying to convert the value(s) `(1.0, 2.0, 3.0)` to a numpy ndarray with shape `(2,)` and type `float`, the following error occurred: could not broadcast input array from shape (3,) into shape (2,)
Just for completeness: Method
new2old()effectively takes the new values as old ones, but more efficiently than using the propertiesnewandold, as it used during simulation runs (in fact, the Python methodnew2old()is usually replaced by model-specific, cythonized version when working in Cython mode):>>> sm.new2old() >>> sm.values array([ 2., 3.]) >>> sm.new array([ 2., 3.]) >>> sm.old array([ 2., 3.])
-
filetype_ext: ClassVar[_FileType]¶ Ending of the external data file.
Attribute filetype_ext is connected with attribute statefiletype of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.statefiletype >>> SequenceManager.statefiletype = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import StateSequence >>> sequence = StateSequence(None) >>> sequence.filetype_ext 'global' >>> sequence.filetype_ext = "local" >>> sequence.filetype_ext 'local' >>> del sequence.filetype_ext >>> sequence.filetype_ext 'global' >>> SequenceManager.statefiletype = temp
-
dirpath_ext: ClassVar[_DirPathProperty]¶ Absolute path of the directory of the external data file.
Attribute dirpath_ext is connected with attribute statedirpath of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.statedirpath >>> SequenceManager.statedirpath = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import StateSequence >>> sequence = StateSequence(None) >>> sequence.dirpath_ext 'global' >>> sequence.dirpath_ext = "local" >>> sequence.dirpath_ext 'local' >>> del sequence.dirpath_ext >>> sequence.dirpath_ext 'global' >>> SequenceManager.statedirpath = temp
-
aggregation_ext: ClassVar[_AggregationProperty]¶ Type of aggregation performed when writing the time-series data to an external data file.
Attribute aggregation_ext is connected with attribute stateaggregation of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.stateaggregation >>> SequenceManager.stateaggregation = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import StateSequence >>> sequence = StateSequence(None) >>> sequence.aggregation_ext 'global' >>> sequence.aggregation_ext = "local" >>> sequence.aggregation_ext 'local' >>> del sequence.aggregation_ext >>> sequence.aggregation_ext 'global' >>> SequenceManager.stateaggregation = temp
-
overwrite_ext: ClassVar[_OverwriteProperty]¶ True/False flag indicating if overwriting an existing data file is allowed or not.
Attribute overwrite_ext is connected with attribute stateoverwrite of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.stateoverwrite >>> SequenceManager.stateoverwrite = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import StateSequence >>> sequence = StateSequence(None) >>> sequence.overwrite_ext 'global' >>> sequence.overwrite_ext = "local" >>> sequence.overwrite_ext 'local' >>> del sequence.overwrite_ext >>> sequence.overwrite_ext 'global' >>> SequenceManager.stateoverwrite = temp
-
property
shape¶ A tuple containing the actual lengths of all dimensions.
StateSequenceobjects come with some additional fastaccess attributes, which should be of interest for framework developers only. However, model developers should note that we did implement only 1-dimensionalStateSequencesubclasses with aTrueNUMERIC flag so far. We still need to prove the complete functionality of our design of 1-dimensionalStateSequencesubclasses with aTrueNUMERIC flag.One example of a 0-dimensional sequence is the results array, handling the (intermediate or final) calculation results for state sequence
WaterVolumeof thedammodel:>>> from hydpy import prepare_model, print_values, pub >>> model = prepare_model("dam_v001") >>> watervolume = model.sequences.states.watervolume >>> print_values(watervolume.fastaccess._watervolume_results) 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
We now show the still not thoroughly tested functionality of 1-dimensional numerical state sequences by changing the dimensionality of class
WaterVolumeand working in pure Python mode. Now, the results attribute isNoneinitially, as propertynumericshapeis unknown. However, setting theshapeattribute ofStateSequenceobjects prepares all “fastaccess attributes” automatically:>>> from hydpy.models.dam.dam_states import WaterVolume >>> WaterVolume.NDIM = 1 >>> with pub.options.usecython(False): ... model = prepare_model("dam_v001") >>> watervolume = model.sequences.states.watervolume >>> watervolume.fastaccess._watervolume_results
>>> watervolume.shape = (2,) >>> watervolume.shape (2,) >>> watervolume.fastaccess._watervolume_results.shape (11, 2)
>>> WaterVolume.NDIM = 0
-
property
new¶ State(s) after calling a
Modelcalculation method. (Alias for propertyvalue).Property
newhandles, in contrast to propertyold, the newly calculated state values during each simulation step. It supports testing and debugging of individualModelmethods but istypically irrelevant when scripting HydPy workflows.
-
property
old¶ State(s) before calling a
Modelcalculation method.Note the similarity to property
new. However, propertyoldreferences the initial states of the respective simulation step, which should not be changed byModelcalculation methods.
-
-
class
hydpy.core.sequencetools.LogSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.ConditionSequence[hydpy.core.sequencetools.LogSequences,hydpy.core.variabletools.FastAccess]Base class for logging sequences of
Modelobjects.Class
LogSequenceserves similar purposes as classStateSequence, but is less strict in its assumptions. WhileStateSequenceobjects always handle two states (theoldand thenewone),LogSequenceobjects are supposed to remember an arbitrary or sequence-specific number of values, which can be state values but for example also flux values. A typical use case is to store “old” values of effective precipitation to calculate “new” values of direct discharge using the unit hydrograph concept in later simulation steps.It is up to the model developer to make sure that a
LogSequencesubclass has the right dimensionality and shape to store the required information. By convention, the “memory” of eachLogSequenceshould be placed on the first axis for non-scalar properties.As
StateSequenceobjects,LogSequenceobjects store relevant information to start a new simulation run where another one has ended, and are thus written into and read from condition files.-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.AideSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.ModelSequence[hydpy.core.sequencetools.AideSequences,hydpy.core.variabletools.FastAccess]Base class for aide sequences of
Modelobjects.Aide sequences store data that is of importance only temporarily but must be shared by different calculation methods of a
Modelobject.-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.LinkSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.ModelSequence[hydpy.core.sequencetools.LinkSequencesType,hydpy.core.sequencetools.FastAccessLinkSequence]Base class for link sequences of
Modelobjects.LinkSequenceobjects do not handle values themselves. Instead, they point to the values handledNodeSequenceobjects, using the functionalities provided by the Cython modulepointerutils. MultipleLinkSequenceobjects of different application models can query and modify the sameNodeSequencevalues, allowing differentModelobjects to share information and interact with each other.A note for developers:
LinkSequencesubclasses must be either 0-dimensional or 1-dimensional.Users might encounter the following exception, which is a safety measure to — as the error message suggests — prevent from segmentation faults:
>>> from hydpy.core.sequencetools import LinkSequence >>> seq = LinkSequence(None) >>> seq linksequence(?) >>> seq.value Traceback (most recent call last): ... AttributeError: While trying to query the value(s) of link sequence `linksequence` of element `?`, the following error occurred: Proper connections are missing (which could result in segmentation faults when using it, so please be careful).
-
set_pointer(double: hydpy.cythons.autogen.pointerutils.Double, idx: int = 0) → None[source]¶ Prepare a pointer referencing the given
Doubleobject.For 1-dimensional sequence objects, one also needs to specify the relevant index position of the pointer via argument idx.
Method
set_pointer()should be of relevance for framework developers and eventually for some model developers only.
-
property
value¶ The actual value(s) the
LinkSequenceobject is pointing at.Changing a
valueof aLinkSequenceobject seems very much like changing avalueof any otherVariableobject. However, be aware that you are changing a value that is handled by aNodeSequenceobject. We demonstrate this by using the LahnH example project through invoking functionprepare_full_example_2():>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2()
We focus on the
hstream_v1application model stream_lahn_1_lahn_2 routing inflow from node lahn_1 to node lahn_2:>>> model = hp.elements.stream_lahn_1_lahn_2.model
The first example shows that the 0-dimensional outlet sequence
Qpoints to theSimsequence of node lahn_2:>>> model.sequences.outlets.q q(0.0) >>> hp.nodes.lahn_2.sequences.sim = 1.0 >>> model.sequences.outlets.q q(1.0) >>> model.sequences.outlets.q(2.0) >>> hp.nodes.lahn_2.sequences.sim sim(2.0)
The second example shows that the 1-dimensional inlet sequence
Qpoints to theSimsequence of node lahn_1:>>> model.sequences.inlets.q q(0.0) >>> hp.nodes.lahn_1.sequences.sim = 1.0 >>> model.sequences.inlets.q q(1.0) >>> model.sequences.inlets.q(2.0) >>> hp.nodes.lahn_1.sequences.sim sim(2.0)
Direct querying the values of both link sequences shows that the value of the 0-dimensional outlet sequence is scalar, of course, and that the value of the 1-dimensional inlet sequence is one entry of a vector:
>>> model.sequences.outlets.q.value 2.0 >>> model.sequences.inlets.q.values array([ 2.])
Assigning bad data results in the standard error messages:
>>> model.sequences.outlets.q.value = 1.0, 2.0 Traceback (most recent call last): ... ValueError: While trying to assign the value(s) (1.0, 2.0) to link sequence `q` of element `stream_lahn_1_lahn_2`, the following error occurred: 2 values are assigned to the scalar variable `q` of element `stream_lahn_1_lahn_2`. >>> model.sequences.inlets.q.values = 1.0, 2.0 Traceback (most recent call last): ... ValueError: While trying to assign the value(s) (1.0, 2.0) to link sequence `q` of element `stream_lahn_1_lahn_2`, the following error occurred: While trying to convert the value(s) `(1.0, 2.0)` to a numpy ndarray with shape `(1,)` and type `float`, the following error occurred: could not broadcast input array from shape (2,) into shape (1,)
In the example above, the 1-dimensional inlet sequence
Qpoints to the value of a singleNodeSequencevalue only. We now prepare ahbranch_v1application model instance to show what happens when connecting a 1-dimensionalLinkSequenceobject (Branched) with threeNodeSequenceobjects (see the documentation of application modelhbranch_v1for more details):>>> from hydpy import Element, Nodes, prepare_model >>> model = prepare_model("hbranch_v1") >>> nodes = Nodes("input1", "input2", "output1", "output2", "output3") >>> branch = Element("branch", ... inlets=["input1", "input2"], ... outlets=["output1", "output2", "output3"]) >>> model.parameters.control.xpoints( ... 0.0, 2.0, 4.0, 6.0) >>> model.parameters.control.ypoints( ... output1=[0.0, 1.0, 2.0, 3.0], ... output2=[0.0, 1.0, 0.0, 0.0], ... output3=[0.0, 0.0, 2.0, 6.0]) >>> branch.model = model
Our third example demonstrates that each field of the values of a 1-dimensional
LinkSequenceobjects points to anotherNodeSequenceobject:>>> nodes.output1.sequences.sim = 1.0 >>> nodes.output2.sequences.sim = 2.0 >>> nodes.output3.sequences.sim = 3.0 >>> model.sequences.outlets.branched branched(1.0, 2.0, 3.0) >>> model.sequences.outlets.branched = 4.0, 5.0, 6.0 >>> nodes.output1.sequences.sim sim(4.0) >>> nodes.output2.sequences.sim sim(5.0) >>> nodes.output3.sequences.sim sim(6.0)
-
property
shape¶ A tuple containing the actual lengths of all dimensions.
Property
shapeof classLinkSequenceworks similarly as the generalshapeproperty of classVariablebut you need to be extra careful due to the pointer mechanism underlying classLinkSequence. Change the shape of a link sequence for good reasons only. Please read the documentation on propertyvaluefirst and then see the following examples which are, again, based on the LahnH example project and application modelhstream_v1:>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> model = hp.elements.stream_lahn_1_lahn_2.model
The default mechanisms of HydPy prepare both 0-dimensional and 1-dimensional link sequences with a proper shape (which, for inlet sequence
Q, depends on the number of connectedNodeobjects):>>> model.sequences.outlets.q.shape () >>> model.sequences.inlets.q.shape (1,)
Trying to set the only possible shape of 0-dimensional link sequences or to set any different shape results in the standard behaviour:
>>> model.sequences.outlets.q.shape = () >>> model.sequences.outlets.q.shape = (1,) Traceback (most recent call last): ... ValueError: While trying to set the shape of link sequence`q` of element `stream_lahn_1_lahn_2`, the following error occurred: The shape information of 0-dimensional variables as `q` of element `stream_lahn_1_lahn_2` can only be `()`, but `(1,)` is given.
Changing the shape of 1-dimensional link sequences is supported but results in losing the connection to the
NodeSequencevalues of the respective nodes. The following exception is raised to prevent segmentation faults until proper connections are available:>>> model.sequences.inlets.q.shape = (2,) >>> model.sequences.inlets.q.shape (2,) >>> model.sequences.inlets.q.shape = 1 >>> model.sequences.inlets.q.shape (1,) >>> model.sequences.inlets.q Traceback (most recent call last): ... RuntimeError: While trying to query the value(s) of link sequence `q` of element `stream_lahn_1_lahn_2`, the following error occurred: The pointer of the actual `PPDouble` instance at index `0` requested, but not prepared yet via `set_pointer`.
>>> model.sequences.inlets.q(1.0) Traceback (most recent call last): ... RuntimeError: While trying to assign the value(s) 1.0 to link sequence `q` of element `stream_lahn_1_lahn_2`, the following error occurred: The pointer of the actual `PPDouble` instance at index `0` requested, but not prepared yet via `set_pointer`.
Querying the shape of a link sequence should rarely result in errors. However, if we enforce it by deleting the fastaccess attribute, we get an error message like the following:
>>> del model.sequences.inlets.q.fastaccess >>> model.sequences.inlets.q.shape Traceback (most recent call last): ... AttributeError: While trying to query the shape of link sequence`q` of element `stream_lahn_1_lahn_2`, the following error occurred: 'Q' object has no attribute 'fastaccess'
-
-
class
hydpy.core.sequencetools.InletSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.LinkSequence[hydpy.core.sequencetools.InletSequences]Base class for inlet link sequences of
Modelobjects.-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.OutletSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.LinkSequence[hydpy.core.sequencetools.OutletSequences]Base class for outlet link sequences of
Modelobjects.-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.ReceiverSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.LinkSequence[hydpy.core.sequencetools.ReceiverSequences]Base class for receiver link sequences of
Modelobjects.-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.SenderSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.LinkSequence[hydpy.core.sequencetools.SenderSequences]Base class for sender link sequences of
Modelobjects.-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.NodeSequence(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.IOSequence[NodeSequences,hydpy.core.sequencetools.FastAccessNodeSequence]Base class for all sequences to be handled by
Nodeobjects.-
filetype_ext: ClassVar[_FileType]¶ Ending of the external data file.
Attribute filetype_ext is connected with attribute nodefiletype of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.nodefiletype >>> SequenceManager.nodefiletype = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import NodeSequence >>> sequence = NodeSequence(None) >>> sequence.filetype_ext 'global' >>> sequence.filetype_ext = "local" >>> sequence.filetype_ext 'local' >>> del sequence.filetype_ext >>> sequence.filetype_ext 'global' >>> SequenceManager.nodefiletype = temp
-
dirpath_ext: ClassVar[_DirPathProperty]¶ Absolute path of the directory of the external data file.
Attribute dirpath_ext is connected with attribute nodedirpath of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.nodedirpath >>> SequenceManager.nodedirpath = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import NodeSequence >>> sequence = NodeSequence(None) >>> sequence.dirpath_ext 'global' >>> sequence.dirpath_ext = "local" >>> sequence.dirpath_ext 'local' >>> del sequence.dirpath_ext >>> sequence.dirpath_ext 'global' >>> SequenceManager.nodedirpath = temp
-
aggregation_ext: ClassVar[_AggregationProperty]¶ Type of aggregation performed when writing the time-series data to an external data file.
Attribute aggregation_ext is connected with attribute nodeaggregation of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.nodeaggregation >>> SequenceManager.nodeaggregation = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import NodeSequence >>> sequence = NodeSequence(None) >>> sequence.aggregation_ext 'global' >>> sequence.aggregation_ext = "local" >>> sequence.aggregation_ext 'local' >>> del sequence.aggregation_ext >>> sequence.aggregation_ext 'global' >>> SequenceManager.nodeaggregation = temp
-
overwrite_ext: ClassVar[_OverwriteProperty]¶ True/False flag indicating if overwriting an existing data file is allowed or not.
Attribute overwrite_ext is connected with attribute nodeoverwrite of class
SequenceManager, as shown by the following technical example (see the documentation on classIOSequencefor some explanations on the usage of this and similar properties ofIOSequencesubclasses):>>> from hydpy.core.filetools import SequenceManager >>> temp = SequenceManager.nodeoverwrite >>> SequenceManager.nodeoverwrite = "global" >>> from hydpy import pub >>> pub.sequencemanager = SequenceManager() >>> from hydpy.core.sequencetools import NodeSequence >>> sequence = NodeSequence(None) >>> sequence.overwrite_ext 'global' >>> sequence.overwrite_ext = "local" >>> sequence.overwrite_ext 'local' >>> del sequence.overwrite_ext >>> sequence.overwrite_ext 'global' >>> SequenceManager.nodeoverwrite = temp
-
property
descr_sequence¶ Description of the
NodeSequenceobject including thevariableto be represented.>>> from hydpy import Node >>> Node("test_node_1", "T").sequences.sim.descr_sequence 'sim_t'
>>> from hydpy import FusedVariable >>> from hydpy.inputs import hland_T, lland_TemL >>> Temp = FusedVariable("Temp", hland_T, lland_TemL) >>> Node("test_node_2", Temp).sequences.sim.descr_sequence 'sim_temp'
-
property
descr_device¶ Description of the
Nodeobject theNodeSequenceobject belongs to.>>> from hydpy import Node >>> Node("test_node_2").sequences.sim.descr_device 'test_node_2'
-
property
value¶ The actual sequence value.
For framework users, property
valueof classNodeSequenceworks as usual and explained in the documentation on propertyshapeof classVariable. However, framework developers should note thatNodeSequenceobjects useDoubleobjects for storing their values and making them accessible toPDoubleandPPDoubleobjects as explained in detail in the documentation on classLinkSequence. For safety reasons, this mechanism is hidden for framework users via conversions to typefloat:>>> from hydpy import Node >>> sim = Node("node").sequences.sim >>> sim(1.0) >>> sim sim(1.0) >>> sim.value 1.0 >>> sim.fastaccess.sim Double(1.0)
>>> sim.value = 2.0 >>> sim sim(2.0)
Node sequences return errors like the following in case they receive misspecified values or ill-configured:
>>> sim.value = 1.0, 2.0 Traceback (most recent call last): ... TypeError: While trying to assign the value `(1.0, 2.0)` to sequence `sim` of node `node`, the following error occurred: float() argument must be a string or a number, not 'tuple'
>>> del sim.fastaccess >>> sim.value Traceback (most recent call last): ... AttributeError: While trying to query the value of sequence `sim` of node `node`, the following error occurred: 'Sim' object has no attribute 'fastaccess'
-
property
seriescomplete¶ True/False flag indicating whether simulated or observed data is fully available or not.
We use the observation series of node dill of the LahnH project as an example:
>>> from hydpy.examples import prepare_full_example_2 >>> hp, pub, TestIO = prepare_full_example_2() >>> obs = hp.nodes.dill.sequences.obs
When the sequence does not handle any time-series data,
seriescompleteisFalse:>>> obs.deactivate_ram() >>> obs.series Traceback (most recent call last): ... AttributeError: Sequence `obs` of node `dill` is not requested to make any internal data available. >>> obs.seriescomplete False
As long as any time-series data is missing,
seriescompleteis stillFalse:>>> obs.activate_ram() >>> obs.series[:-1] = 1.0 >>> obs.series InfoArray([ 1., 1., 1., nan]) >>> obs.seriescomplete False
Only with all data being not
nan,seriescompleteisTrue:>>> obs.series[-1] = 1.0 >>> obs.seriescomplete True
-
-
class
hydpy.core.sequencetools.Sim(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.IOSequence[NodeSequences,hydpy.core.sequencetools.FastAccessNodeSequence]Class for handling those values of
Nodeobjects that are “simulated”, meaning calculated by hydrological models.-
load_ext() → None[source]¶ Read time-series data like method
load_ext()of classIOSequencebut with special handling of missing data.The method’s “special handling” is to convert errors to warnings. We explain the reasons in the documentation on method
load_ext()of classObs, from which we borrow the following examples. The only differences are that methodload_ext()of classSimdoes not disable propertymemoryflagand uses the optionwarnmissingsimfileinstead ofwarnmissingobsfile:>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1() >>> from hydpy import HydPy, pub, TestIO >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... hp.prepare_models() ... hp.prepare_simseries() >>> sim = hp.nodes.dill.sequences.sim >>> with TestIO(): ... sim.load_ext() Traceback (most recent call last): ... UserWarning: While trying to load the external data of sequence `sim` of node `dill`, the following error occurred: [Errno 2] No such file or directory: '...dill_sim_q.asc' >>> sim.series InfoArray([ nan, nan, nan, nan, nan])
>>> sim.series = 1.0 >>> with TestIO(): ... sim.save_ext() >>> sim.series = 0.0 >>> with TestIO(): ... sim.load_ext() >>> sim.series InfoArray([ 1., 1., 1., 1., 1.])
>>> import numpy >>> sim.series[2] = numpy.nan >>> with TestIO(): ... pub.sequencemanager.nodeoverwrite = True ... sim.save_ext() >>> with TestIO(): ... sim.load_ext() Traceback (most recent call last): ... UserWarning: While trying to load the external data of sequence `sim` of node `dill`, the following error occurred: The series array of sequence `sim` of node `dill` contains 1 nan value. >>> sim.series InfoArray([ 1., 1., nan, 1., 1.])
>>> sim.series = 0.0 >>> with TestIO(): ... with pub.options.warnmissingsimfile(False): ... sim.load_ext() >>> sim.series InfoArray([ 1., 1., nan, 1., 1.])
-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.Obs(subvars: SubVariablesType)[source]¶ Bases:
hydpy.core.sequencetools.IOSequence[NodeSequences,hydpy.core.sequencetools.FastAccessNodeSequence]Class for handling those values of
Nodeobjects that are observed, meaning read from data files.-
load_ext() → None[source]¶ Read time-series data like method
load_ext()of classIOSequencebut with special handling of missing data.When reading incomplete time-series data, HydPy usually raises a
RuntimeErrorto prevent from performing erroneous calculations. For instance, this makes sense for meteorological input data, being a strict requirement for hydrological simulations. However, the same often does not hold for the time-series ofObssequences, e.g. representing measured discharge. Measured discharge is often handled as an optional input value, or even used for comparison purposes only.According to this reasoning, HydPy raises (at most) a
UserWarningin case of missing or incomplete external time-series data ofObssequences. The following examples show this based on the LahnH project, mainly focussing on theObssequence of node dill, which is ready for handling time-series data at the end of the following steps:>>> from hydpy.examples import prepare_full_example_1 >>> prepare_full_example_1() >>> from hydpy import HydPy, pub, TestIO >>> hp = HydPy("LahnH") >>> pub.timegrids = "1996-01-01", "1996-01-06", "1d" >>> with TestIO(): ... hp.prepare_network() ... hp.prepare_models() ... hp.prepare_obsseries() >>> obs = hp.nodes.dill.sequences.obs >>> obs.ramflag True
Trying to read non-existing data raises the following warning and disables the sequence’s ability to handle time-series data:
>>> with TestIO(): ... hp.load_obsseries() Traceback (most recent call last): ... UserWarning: The `memory flag` of sequence `obs` of node `dill` had to be set to `False` due to the following problem: While trying to load the external data of sequence `obs` of node `dill`, the following error occurred: [Errno 2] No such file or directory: '...dill_obs_q.asc' >>> obs.ramflag False
After writing a complete external data file, everything works fine:
>>> obs.activate_ram() >>> obs.series = 1.0 >>> with TestIO(): ... obs.save_ext() >>> obs.series = 0.0 >>> with TestIO(): ... obs.load_ext() >>> obs.series InfoArray([ 1., 1., 1., 1., 1.])
Reading incomplete data also results in a warning message, but does not disable the
memoryflag:>>> import numpy >>> obs.series[2] = numpy.nan >>> with TestIO(): ... pub.sequencemanager.nodeoverwrite = True ... obs.save_ext() >>> with TestIO(): ... obs.load_ext() Traceback (most recent call last): ... UserWarning: While trying to load the external data of sequence `obs` of node `dill`, the following error occurred: The series array of sequence `obs` of node `dill` contains 1 nan value. >>> obs.memoryflag True
Option
warnmissingobsfileallows disabling the warning messages without altering the functionalities described above:>>> hp.prepare_obsseries() >>> with TestIO(): ... with pub.options.warnmissingobsfile(False): ... hp.load_obsseries() >>> obs.series InfoArray([ 1., 1., nan, 1., 1.]) >>> hp.nodes.lahn_1.sequences.obs.memoryflag False
-
subvars: SubVariablesType¶
-
-
class
hydpy.core.sequencetools.NodeSequences(master: devicetools.Node, cls_fastaccess: Optional[Type[hydpy.core.sequencetools.FastAccessNodeSequence]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)[source]¶ Bases:
hydpy.core.sequencetools.IOSequences[devicetools.Node,hydpy.core.sequencetools.NodeSequence,hydpy.core.sequencetools.FastAccessNodeSequence]Base class for handling
SimandObssequence objects.Basically,
NodeSequencesworks like the differentModelSequencessubclasses used for handlingModelSequenceobjects. The main difference is that they do not reference aSequencesobject (which is only handled byElementobjects but not byNodeobjects). Instead, they reference their masterNodeobject via the attribute node directly:>>> from hydpy import Node >>> node = Node("node") >>> node.sequences.node Node("node", variable="Q")
The implemented methods just call the same method of the underlying fastaccess attribute, which is an instance of (a Cython extension class of) the Python class
FastAccessNodeSequence.-
node: devicetools.Node¶
-
load_data(idx: int) → None[source]¶ Call method
load_data()of the current fastaccess attribute.>>> from hydpy import Node, pub >>> with pub.options.usecython(False): ... node = Node("node") >>> from unittest import mock >>> method = "hydpy.core.sequencetools.FastAccessNodeSequence.load_data" >>> with mock.patch(method) as mocked: ... node.sequences.load_data(5) >>> mocked.call_args_list [call(5)]
-
load_simdata(idx: int) → None[source]¶ Call method
load_simdata()of the current fastaccess attribute.>>> from hydpy import Node, pub >>> with pub.options.usecython(False): ... node = Node("node") >>> from unittest import mock >>> method = "hydpy.core.sequencetools.FastAccessNodeSequence.load_simdata" >>> with mock.patch(method) as mocked: ... node.sequences.load_simdata(5) >>> mocked.call_args_list [call(5)]
-
load_obsdata(idx: int) → None[source]¶ Call method
load_obsdata()of the current fastaccess attribute.>>> from hydpy import Node, pub >>> with pub.options.usecython(False): ... node = Node("node") >>> from unittest import mock >>> method = "hydpy.core.sequencetools.FastAccessNodeSequence.load_obsdata" >>> with mock.patch(method) as mocked: ... node.sequences.load_obsdata(5) >>> mocked.call_args_list [call(5)]
-
save_data(idx: int) → None[source]¶ Call method
save_data()of the current fastaccess attribute.>>> from hydpy import Node, pub >>> with pub.options.usecython(False): ... node = Node("node") >>> from unittest import mock >>> method = "hydpy.core.sequencetools.FastAccessNodeSequence.save_data" >>> with mock.patch(method) as mocked: ... node.sequences.save_data(5) >>> mocked.call_args_list [call(5)]
-
save_simdata(idx: int) → None[source]¶ Call method
save_simdata()of the current fastaccess attribute.>>> from hydpy import Node, pub >>> with pub.options.usecython(False): ... node = Node('node') >>> from unittest import mock >>> method = "hydpy.core.sequencetools.FastAccessNodeSequence.save_simdata" >>> with mock.patch(method) as mocked: ... node.sequences.save_simdata(5) >>> mocked.call_args_list [call(5)]
-