conv_v003

Inverse distance weighted interpolation with external drift.

Version 3 of HydPy-C extends version 2 by taking an additional statistical relationship between the interpolated variable and an arbitrary independent variable into account. A typical use case is elevation-dependent temperature interpolation. You can understand the approach of conv_v003 as a simplification of External Drift Kriging.

The algorithm works as follows (we take elevation-dependent temperature interpolation as an example):

  • Estimate the linear regression coefficients to model the relationship between air temperature and elevation at the available stations for the current simulation time step (or take the given default values).

  • Use the resulting linear model to predict the temperature at the stations and the interpolation target points.

  • Calculate the residuals (differences between predictions and measurements) at all stations.

  • Interpolate the residuals based on the same inverse distance weighting approach as applied by application model conv_v002.

  • Combine the predicted temperature values and the interpolated residuals to gain the final interpolation results at all target points.

For perfect correlations between temperature and elevation, the interpolated values depend only on elevation. If there is no correlation, the interpolated values depend solely on spatial proximity to the stations.

Integration tests

Note

When new to HydPy, consider reading section How to understand integration tests? first.

We start the following explanations with repeating the examples documented for application model conv_v002. Hence, we first define identical test settings (please see the documentation on application model conv_v002 for more information):

>>> from hydpy import pub, Nodes, Element
>>> pub.timegrids = "2000-01-01", "2000-01-04", "1d"
>>> from hydpy.models.conv_v003 import *
>>> parameterstep()
>>> from hydpy import *
>>> in1, in2, in3 = Node("in1"), Node("in2"), Node("in3")
>>> element = Element("conv",
...                   inlets=(in1, in2, in3),
...                   outlets=["out1", "out2", "out3", "out4"])
>>> inputcoordinates(in1=(0.0, 3.0),
...                  in2=(2.0, -1.0),
...                  in3=(4.0, 2.0))
>>> outputcoordinates(out1=(0.0, 3.0),
...                   out2=(3.0, -2.0),
...                   out3=(1.0, 2.0),
...                   out4=(1.0, 1.0))
>>> power(2.0)
>>> maxnmbinputs(3)
>>> element.model = model
>>> from hydpy.core.testtools import IntegrationTest
>>> test = IntegrationTest(element)
>>> test.dateformat = "%Y-%m-%d"
>>> with pub.options.checkseries(False):
...     in1.sequences.sim.series = 1.0, nan, nan
...     in2.sequences.sim.series = 3.0, 2.0, nan
...     in3.sequences.sim.series = 4.0, nan, nan

Next, we prepare the additional parameters of conv_v003. Most importantly, we define the values of the independent variable for all input and output nodes:

>>> inputheights(in1=0.0,
...              in2=2.0,
...              in3=4.0)
>>> outputheights(out1=0.0,
...               out2=1.0,
...               out3=2.0,
...               out4=3.0)

In our example calculations, we use three input nodes. However, we first set the number of data-points that must be available to estimate the linear model to four, which of course is impossible. Hence, conv_v003 will always use the default values. We set both of them to zero and thus effectively disable the “external drift” functionality so that conv_v003 works exactly like conv_v002:

>>> minnmbinputs(4)
>>> defaultconstant(0.0)
>>> defaultfactor(0.0)

Under the given configuration, conv_v003 reproduces the results of the test examples documented for application model conv_v002 precisely:

>>> test()
|       date |           inputs | actualconstant | actualfactor |           inputpredictions |                outputpredictions |           inputresiduals |                 outputresiduals |                 outputs | in1 | in2 | in3 | out1 | out2 | out3 | out4 |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 2000-01-01 | 1.0  3.0     4.0 |            0.0 |          0.0 | 0.0  0.0               0.0 | 0.0  0.0  0.0                0.0 | 1.0  3.0             4.0 | 1.0  3.0  1.75              2.4 | 1.0  3.0  1.75      2.4 | 1.0 | 3.0 | 4.0 |  1.0 |  3.0 | 1.75 |  2.4 |
| 2000-01-02 | nan  2.0     nan |            0.0 |          0.0 | 0.0  0.0               0.0 | 0.0  0.0  0.0                0.0 | nan  2.0             nan | 2.0  2.0   2.0              2.0 | 2.0  2.0   2.0      2.0 | nan | 2.0 | nan |  2.0 |  2.0 |  2.0 |  2.0 |
| 2000-01-03 | nan  nan     nan |            0.0 |          0.0 | 0.0  0.0               0.0 | 0.0  0.0  0.0                0.0 | nan  nan             nan | nan  nan   nan              nan | nan  nan   nan      nan | nan | nan | nan |  nan |  nan |  nan |  nan |
>>> maxnmbinputs(2)
>>> test()
|       date |           inputs | actualconstant | actualfactor |           inputpredictions |                outputpredictions |           inputresiduals |                          outputresiduals |                          outputs | in1 | in2 | in3 | out1 |     out2 |     out3 | out4 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 2000-01-01 | 1.0  3.0     4.0 |            0.0 |          0.0 | 0.0  0.0               0.0 | 0.0  0.0  0.0                0.0 | 1.0  3.0             4.0 | 1.0  3.105263  1.545455              2.0 | 1.0  3.105263  1.545455      2.0 | 1.0 | 3.0 | 4.0 |  1.0 | 3.105263 | 1.545455 |  2.0 |
| 2000-01-02 | nan  2.0     nan |            0.0 |          0.0 | 0.0  0.0               0.0 | 0.0  0.0  0.0                0.0 | nan  2.0             nan | nan       2.0       nan              2.0 | nan       2.0       nan      2.0 | nan | 2.0 | nan |  nan |      2.0 |      nan |  2.0 |
| 2000-01-03 | nan  nan     nan |            0.0 |          0.0 | 0.0  0.0               0.0 | 0.0  0.0  0.0                0.0 | nan  nan             nan | nan       nan       nan              nan | nan       nan       nan      nan | nan | nan | nan |  nan |      nan |      nan |  nan |

Now we enable the “external drift” functionality by providing non-zero default values. Hence, conv_v003 employs the same linear model in all simulation time steps:

>>> maxnmbinputs(3)
>>> defaultfactor(1.0)
>>> defaultconstant(2.0)
>>> test()
|       date |           inputs | actualconstant | actualfactor |           inputpredictions |                outputpredictions |             inputresiduals |                       outputresiduals |                    outputs | in1 | in2 | in3 | out1 | out2 |    out3 | out4 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 2000-01-01 | 1.0  3.0     4.0 |            2.0 |          1.0 | 2.0  4.0               6.0 | 2.0  3.0  4.0                5.0 | -1.0  -1.0            -2.0 | -1.0  -1.1  -1.15625             -1.2 | 1.0  1.9  2.84375      3.8 | 1.0 | 3.0 | 4.0 |  1.0 |  1.9 | 2.84375 |  3.8 |
| 2000-01-02 | nan  2.0     nan |            2.0 |          1.0 | 2.0  4.0               6.0 | 2.0  3.0  4.0                5.0 |  nan  -2.0             nan | -2.0  -2.0      -2.0             -2.0 | 0.0  1.0      2.0      3.0 | nan | 2.0 | nan |  0.0 |  1.0 |     2.0 |  3.0 |
| 2000-01-03 | nan  nan     nan |            2.0 |          1.0 | 2.0  4.0               6.0 | 2.0  3.0  4.0                5.0 |  nan   nan             nan |  nan   nan       nan              nan | nan  nan      nan      nan | nan | nan | nan |  nan |  nan |     nan |  nan |

If we set the required number of data-points to three (two would also be fine), conv_v003 estimates the parameters of the linear model (ActualFactor and ActualConstant) in the first time step on its own, and falls back to the default values in the remaining time steps:

>>> minnmbinputs(2)
>>> test()
|       date |           inputs | actualconstant | actualfactor |                     inputpredictions |                               outputpredictions |                      inputresiduals |                                 outputresiduals |                       outputs | in1 | in2 | in3 | out1 |  out2 |     out3 | out4 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 2000-01-01 | 1.0  3.0     4.0 |       1.166667 |         0.75 | 1.166667  2.666667          4.166667 | 1.166667  1.916667  2.666667           3.416667 | -0.166667  0.333333       -0.166667 | -0.166667  0.258333  -0.096354         0.033333 | 1.0  2.175  2.570312     3.45 | 1.0 | 3.0 | 4.0 |  1.0 | 2.175 | 2.570312 | 3.45 |
| 2000-01-02 | nan  2.0     nan |            2.0 |          1.0 |      2.0       4.0               6.0 |      2.0       3.0       4.0                5.0 |       nan      -2.0             nan |      -2.0      -2.0       -2.0             -2.0 | 0.0    1.0       2.0      3.0 | nan | 2.0 | nan |  0.0 |   1.0 |      2.0 |  3.0 |
| 2000-01-03 | nan  nan     nan |            2.0 |          1.0 |      2.0       4.0               6.0 |      2.0       3.0       4.0                5.0 |       nan       nan             nan |       nan       nan        nan              nan | nan    nan       nan      nan | nan | nan | nan |  nan |   nan |      nan |  nan |

The final example shows that everything works as expected for the edge cases of perfect and missing correlation. In the first time step, there is a perfect (negative) correlation at the input nodes. Hence, all residuals (calculated for the input nodes and interpolated for the output nodes) are zero. In the second time step, there is no correlation. Hence, all values predicted by the linear model are the same. The third time step shows that conv_v003 handles the special (but not uncommon) case of missing variability in the input values well:

>>> in1.sequences.sim.series = 4.0, 0.0, 0.0
>>> in2.sequences.sim.series = 3.0, 1.0, 0.0
>>> in3.sequences.sim.series = 2.0, 0.0, 0.0
>>> test()
|       date |           inputs | actualconstant | actualfactor |                     inputpredictions |                               outputpredictions |                      inputresiduals |                                 outputresiduals |                      outputs | in1 | in2 | in3 | out1 | out2 |     out3 | out4 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 2000-01-01 | 4.0  3.0     2.0 |            4.0 |         -0.5 |      4.0       3.0               2.0 |      4.0       3.5       3.0                2.5 |       0.0       0.0             0.0 |       0.0       0.0        0.0              0.0 | 4.0   3.5       3.0      2.5 | 4.0 | 3.0 | 2.0 |  4.0 |  3.5 |      3.0 |  2.5 |
| 2000-01-02 | 0.0  1.0     0.0 |       0.333333 |          0.0 | 0.333333  0.333333          0.333333 | 0.333333  0.333333  0.333333           0.333333 | -0.333333  0.666667       -0.333333 | -0.333333  0.516667  -0.192708         0.066667 | 0.0  0.85  0.140625      0.4 | 0.0 | 1.0 | 0.0 |  0.0 | 0.85 | 0.140625 |  0.4 |
| 2000-01-03 | 0.0  0.0     0.0 |            0.0 |          0.0 |      0.0       0.0               0.0 |      0.0       0.0       0.0                0.0 |       0.0       0.0             0.0 |       0.0       0.0        0.0              0.0 | 0.0   0.0       0.0      0.0 | 0.0 | 0.0 | 0.0 |  0.0 |  0.0 |      0.0 |  0.0 |
class hydpy.models.conv_v003.Model[source]

Bases: hydpy.models.conv.conv_model.Model

Version 3 of the Conv model.

The following “inlet update methods” are called in the given sequence at the beginning of each simulation step:
The following “run methods” are called in the given sequence during each simulation step:
The following “outlet update methods” are called in the given sequence at the end of each simulation step:
The following “additional methods” might be called by one or more of the other methods or are meant to be directly called by the user:
class hydpy.models.conv_v003.ControlParameters(master: hydpy.core.parametertools.Parameters, cls_fastaccess: Optional[Type[hydpy.core.parametertools.FastAccessParameter]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.variabletools.SubVariables[hydpy.core.parametertools.Parameters, Parameter, hydpy.core.parametertools.FastAccessParameter]

Control parameters of model conv_v003.

The following classes are selected:
  • InputCoordinates() Coordinates of the inlet nodes [?].

  • OutputCoordinates() Coordinates of the outlet nodes [?].

  • InputHeights() The height (above sea level or anything else) of the input nodes [?].

  • OutputHeights() The height (above sea level or anything else) of the output nodes [?].

  • MaxNmbInputs() The maximum number of input locations to be taken into account for interpolating the values of a specific output location [-].

  • MinNmbInputs() The minimum number of inputs for performing a statistical analysis [-].

  • DefaultConstant() Default or fallback value for the constant of the linear regression model [?].

  • DefaultFactor() Default or fallback value for the factor of the linear regression model [?].

  • Power() Power parameter for calculating inverse distance weights [-].

class hydpy.models.conv_v003.DerivedParameters(master: hydpy.core.parametertools.Parameters, cls_fastaccess: Optional[Type[hydpy.core.parametertools.FastAccessParameter]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.variabletools.SubVariables[hydpy.core.parametertools.Parameters, Parameter, hydpy.core.parametertools.FastAccessParameter]

Derived parameters of model conv_v003.

The following classes are selected:
  • NmbInputs() The number of inlet nodes [-]

  • NmbOutputs() The number of outlet nodes [-]

  • Distances() Distances of the inlet nodes to each outlet node [?].

  • ProximityOrder() Indices of the inlet nodes in the order of their proximity to each outlet node [-].

  • Weights() Weighting coefficients of the inlet nodes corresponding to their proximity to each outlet node and parameter Power [-].

class hydpy.models.conv_v003.FluxSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.sequencetools.OutputSequences[FluxSequence]

Flux sequences of model conv_v003.

The following classes are selected:
  • Inputs() The (unmodified) values supplied by the input nodes [?].

  • ActualConstant() The actual value for the constant of the linear regression model [?].

  • ActualFactor() The actual value for the factor of the linear regression model [?].

  • InputPredictions() The values of the input nodes predicted by a regression model [?].

  • OutputPredictions() The values of the output nodes predicted by a regression model [?].

  • InputResiduals() The exact residuals of a regression model calculated for the input nodes [?].

  • OutputResiduals() The guessed residuals of a regression model interpolated for the input nodes [?].

  • Outputs() The final interpolation results estimated for the output nodes [?].

class hydpy.models.conv_v003.InletSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.sequencetools.LinkSequences[InletSequence]

Inlet sequences of model conv_v003.

The following classes are selected:
class hydpy.models.conv_v003.OutletSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.sequencetools.LinkSequences[OutletSequence]

Outlet sequences of model conv_v003.

The following classes are selected: