In [ ]:

Session 2: Quick tour of Veneer

  • Main features of Veneer (and veneer-py)
    • Starting a new notebook
    • Querying models
    • Running models and Retrieving results
    • Manipulating model setup and the ‘Allow Scripts’ option
    • PEST and Parallel processing
    • GUI and Command Line
    • Local and Remote connections
    • Getting help

Start Source and Veneer

If you haven't already started Source, do so now, following the instructions in 0Setup_and_Hello_World.ipynb to load and start Veneer using the Tools|Web Server Monitoring option.

Which Model?

Note: This session uses ExampleProject/RiverModel1.rsproj. You are welcome to work with your own model instead, however you will need to change the notebook text at certain points to reflect the names of nodes, links and functions in your model file.

Starting a new Notebook

You can edit your local copy of this notebook. Alternatively, start a new notebook and enter the relevant code there. From an existing notebook, use the File|New Notebook|Python 3 menu to start a new notebook using Python 3 syntax.

You can also create a new notebook from the main Jupyter dashboard, using the New button.

It's probably worth using a Markdown cell at the top of the notebook to describe the purpose of the notebook (if only to remind yourself later...)

Then, in the first code block, you should import relevant Python packages and generally initialise your Python environment with anything needed for the notebook:


In [1]:
import veneer
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

import

The Python import statement makes other packages available to your current session.

There are a few forms of import, two of which are illustrated here:

  • import veneer makes the main veneer-py package available. You can access parts of the package using veneer.<member>
  • import pandas as pd imports the pandas package, but aliases it as pd for convenience. For common packages (such as numpy adn pandas) there is often a well-used abbreviation, such as np and pd.
  • from os import mkdir, makedirs imports one or more specific members of the os package and makes them available without any prefix
  • from os import * imports all the members of the os package and makes them available without any prefix (eg makedirs('test')).

%matplotlib

%matplotlib enables plotting by configuring a rendering engine for the matplotlib package. Anything starting with % is a special ('magic') command to Jupyter/IPython - it isn't standard Python.

The %matplotlib magic command accepts an optional parameter indicating which rendering backend to use for the current session. I've used inline, which renders charts directly within the notebook as HTML <img> tags. I find this best for creating self-sufficient notebooks that can be circulated and read without running. The downside is that the charts aren't interactive.

Other options worth noting:

  • %matplotlib - (ie without specifying a rendering backend). This gives you the default for your current system. On my Windows machine, this uses the Qt4 windowing toolkit and charts appear in their own window, with basic zoom, pan, export and layout controls.
  • %matplotlib notebook - Renders within the notebook with some basic interactive chart controls.

In [2]:
%matplotlib inline
plt.plot(range(10))


Out[2]:
[<matplotlib.lines.Line2D at 0x8fb7898>]

In [3]:
%matplotlib notebook

In [4]:
plt.plot(range(10))


Out[4]:
[<matplotlib.lines.Line2D at 0x9822c88>]

In [5]:
%matplotlib inline

Aside: the range function is a generator. In this case, its generating a consecutive integers, starting from 0 and going up to, but not including, 10.

Try:

print(range(10))

and

print(list(range(10))


In [ ]:

Initialising a Veneer client

veneer-py provides functions for accessing a running copy of Source/Veneer. Most of these functions are provided through an instance of the Veneer client class, within the veneer package. You can have as many clients as you need - for example, to point to different copies of Source that are running concurrently.

By default, the client will attempt to connect to a copy of Source/Veneer running on the local machine and hosted on port 9876


In [6]:
v = veneer.Veneer()
# Equiavelent to
# v = veneer.Veneer(host='localhost',port=9876)

In [ ]:

The rest of this tutorial uses v to refer to current Veneer client

Querying models

veneer-py provides two groups of functions:

  1. Functions for accessing the various URLs defined by Veneer (eg v.network() accesses the /network URL), and
  2. Functions for accessing the catch-all, IronPython endpoint (eg v.model.catchments.runoff.get_param_values('SMSC') uses IronPython to query the SMSC parameter in the rainfall runoff models)

The functions in group 1 should work on all Source models, whereas the functions in group 2 tend to be more model specific.

This section deals with group 1 - functions related to specific URLs.

Network queries

You can retrieve the current node link network (including catchment polygons if present) using v.network(). The result includes a list of features, which you can search and filter for particular nodes/links/catchments.


In [7]:
the_network = v.network()

In [8]:
all_nodes = the_network['features'].find_by_feature_type('node')
len(all_nodes)


Out[8]:
6

In [9]:
all_nodes._all_values('name')


Out[9]:
['Ungauged Inflow', 'Storage', 'SP', 'MFR', 'Water User', 'End Of System']

You can also perform some basic topological queries on the network, such as finding all network outlets, or finding upstream/downstream links for a given node


In [10]:
outlets = the_network.outlet_nodes()
outlets


Out[10]:
[{'geometry': {'coordinates': [323, 718], 'type': 'Point'}, 'properties': {'icon': '/resources/GaugeNodeModel', 'name': 'End Of System', 'feature_type': 'node', 'schematic_location': [323, 718]}, 'type': 'Feature', 'id': '/network/nodes/12'}]

In [11]:
the_network.upstream_links(outlets[0])


Out[11]:
[{'geometry': {'coordinates': [[317, 560], [323, 718]], 'type': 'LineString'}, 'properties': {'to_node': '/network/nodes/12', 'name': 'SR3', 'feature_type': 'link', 'from_node': '/network/nodes/6'}, 'type': 'Feature', 'id': '/network/link/3'}]

If you have GeoPandas installed, you can convert network to a GeoDataFrame, which is useful for visualisation, reporting and advanced filtering.


In [12]:
network_df = the_network.as_dataframe()
network_df


Out[12]:
feature_type from_node geometry icon name schematic_location to_node id
0 node NaN POINT (317 286) /resources/InjectedFlow Ungauged Inflow [317, 286] NaN /network/nodes/1
1 node NaN POINT (317 393) /resources/StorageNodeModel Storage [317, 393] NaN /network/nodes/3
2 node NaN POINT (317 560) /resources/ExtractionNodeModel SP [317, 560] NaN /network/nodes/6
3 node NaN POINT (317 478) /resources/MinimumFlowConstraintModel MFR [317, 478] NaN /network/nodes/10
4 node NaN POINT (200 619) /resources/WaterUserNodeModel Water User [200, 619] NaN /network/nodes/11
5 node NaN POINT (323 718) /resources/GaugeNodeModel End Of System [323, 718] NaN /network/nodes/12
6 link /network/nodes/3 LINESTRING (317 393, 317 478) NaN Default Link #4 NaN /network/nodes/10 /network/link/0
7 link /network/nodes/10 LINESTRING (317 478, 317 560) NaN SR2 NaN /network/nodes/6 /network/link/1
8 link /network/nodes/6 LINESTRING (317 560, 200 619) NaN Default Link #6 NaN /network/nodes/11 /network/link/2
9 link /network/nodes/6 LINESTRING (317 560, 323 718) NaN SR3 NaN /network/nodes/12 /network/link/3
10 link /network/nodes/1 LINESTRING (317 286, 317 393) NaN Default Link #5 NaN /network/nodes/3 /network/link/4

With a GeoDataFrame, you can filter against any column


In [13]:
network_df[network_df.feature_type=='node']


Out[13]:
feature_type from_node geometry icon name schematic_location to_node id
0 node NaN POINT (317 286) /resources/InjectedFlow Ungauged Inflow [317, 286] NaN /network/nodes/1
1 node NaN POINT (317 393) /resources/StorageNodeModel Storage [317, 393] NaN /network/nodes/3
2 node NaN POINT (317 560) /resources/ExtractionNodeModel SP [317, 560] NaN /network/nodes/6
3 node NaN POINT (317 478) /resources/MinimumFlowConstraintModel MFR [317, 478] NaN /network/nodes/10
4 node NaN POINT (200 619) /resources/WaterUserNodeModel Water User [200, 619] NaN /network/nodes/11
5 node NaN POINT (323 718) /resources/GaugeNodeModel End Of System [323, 718] NaN /network/nodes/12

In [14]:
network_df[network_df.icon=='/resources/StorageNodeModel']


Out[14]:
feature_type from_node geometry icon name schematic_location to_node id
1 node NaN POINT (317 393) /resources/StorageNodeModel Storage [317, 393] NaN /network/nodes/3

Querying Functions and Variables

You can query all functions using v.functions(), and all variables with v.variables().


In [15]:
model_functions = v.functions()
model_functions


Out[15]:
[{'Name': '$InflowCalc', 'Expression': '/* Scaling factor 3.5 */\r\n3.5*$Runoff\r\n'}, {'Name': '$FlowRequirement', 'Expression': 'lookup($MFR_Piecewise,$InflowCalc)\r\n'}]

In [16]:
model_variables = v.variables()
model_variables


Out[16]:
[{'FullName': '$Now.Day', 'TimeSeries': None, 'ID': 1, 'Name': '$Day', 'VeneerDebugInfo': None, 'VariableType': 'NowVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Start.Day', 'TimeSeries': None, 'ID': 2, 'Name': '$Day', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$End.Day', 'TimeSeries': None, 'ID': 3, 'Name': '$Day', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Now.Month', 'TimeSeries': None, 'ID': 4, 'Name': '$Month', 'VeneerDebugInfo': None, 'VariableType': 'NowVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Start.Month', 'TimeSeries': None, 'ID': 5, 'Name': '$Month', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$End.Month', 'TimeSeries': None, 'ID': 6, 'Name': '$Month', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Now.Year', 'TimeSeries': None, 'ID': 7, 'Name': '$Year', 'VeneerDebugInfo': None, 'VariableType': 'NowVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Start.Year', 'TimeSeries': None, 'ID': 8, 'Name': '$Year', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$End.Year', 'TimeSeries': None, 'ID': 9, 'Name': '$Year', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Now.Hour', 'TimeSeries': None, 'ID': 10, 'Name': '$Hour', 'VeneerDebugInfo': None, 'VariableType': 'NowVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Start.Hour', 'TimeSeries': None, 'ID': 11, 'Name': '$Hour', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$End.Hour', 'TimeSeries': None, 'ID': 12, 'Name': '$Hour', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Now.DayOfYear', 'TimeSeries': None, 'ID': 13, 'Name': '$DayOfYear', 'VeneerDebugInfo': None, 'VariableType': 'NowVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Start.DayOfYear', 'TimeSeries': None, 'ID': 14, 'Name': '$DayOfYear', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$End.DayOfYear', 'TimeSeries': None, 'ID': 15, 'Name': '$DayOfYear', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Now.DaysInMonth', 'TimeSeries': None, 'ID': 16, 'Name': '$DaysInMonth', 'VeneerDebugInfo': None, 'VariableType': 'NowVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$Start.DaysInMonth', 'TimeSeries': None, 'ID': 17, 'Name': '$DaysInMonth', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$End.DaysInMonth', 'TimeSeries': None, 'ID': 18, 'Name': '$DaysInMonth', 'VeneerDebugInfo': None, 'VariableType': 'FixedDateVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$ActiveInputSet', 'TimeSeries': None, 'ID': 19, 'Name': '$ActiveInputSet', 'VeneerDebugInfo': None, 'VariableType': 'ActiveInputSetVariable', 'VeneerSupported': False, 'PiecewiseFunction': None}, {'FullName': '$MFR_Piecewise', 'TimeSeries': None, 'ID': 21, 'Name': '$MFR_Piecewise', 'VeneerDebugInfo': None, 'VariableType': 'LinearVariable', 'VeneerSupported': True, 'PiecewiseFunction': '/variables/MFR_Piecewise/Piecewise'}, {'FullName': '$Runoff', 'TimeSeries': '/variables/Runoff/TimeSeries', 'ID': 20, 'Name': '$Runoff', 'VeneerDebugInfo': 'DisplayName=$Runoff;ResultUnit=no unit selected (None);', 'VariableType': 'TimeSeriesVariable', 'VeneerSupported': True, 'PiecewiseFunction': None}]

Both v.functions() and v.variables() return a searchable list:


In [17]:
model_variables.find_by_Name('$Runoff')


Out[17]:
[{'FullName': '$Runoff', 'TimeSeries': '/variables/Runoff/TimeSeries', 'ID': 20, 'Name': '$Runoff', 'VeneerDebugInfo': 'DisplayName=$Runoff;ResultUnit=no unit selected (None);', 'VariableType': 'TimeSeriesVariable', 'VeneerSupported': True, 'PiecewiseFunction': None}]

Note: When you get a searchable list, you can also convert it to a Pandas Data Frame if that is more convenient


In [18]:
model_variables.as_dataframe()


Out[18]:
FullName ID Name PiecewiseFunction TimeSeries VariableType VeneerDebugInfo VeneerSupported
0 $Now.Day 1 $Day None None NowVariable None False
1 $Start.Day 2 $Day None None FixedDateVariable None False
2 $End.Day 3 $Day None None FixedDateVariable None False
3 $Now.Month 4 $Month None None NowVariable None False
4 $Start.Month 5 $Month None None FixedDateVariable None False
5 $End.Month 6 $Month None None FixedDateVariable None False
6 $Now.Year 7 $Year None None NowVariable None False
7 $Start.Year 8 $Year None None FixedDateVariable None False
8 $End.Year 9 $Year None None FixedDateVariable None False
9 $Now.Hour 10 $Hour None None NowVariable None False
10 $Start.Hour 11 $Hour None None FixedDateVariable None False
11 $End.Hour 12 $Hour None None FixedDateVariable None False
12 $Now.DayOfYear 13 $DayOfYear None None NowVariable None False
13 $Start.DayOfYear 14 $DayOfYear None None FixedDateVariable None False
14 $End.DayOfYear 15 $DayOfYear None None FixedDateVariable None False
15 $Now.DaysInMonth 16 $DaysInMonth None None NowVariable None False
16 $Start.DaysInMonth 17 $DaysInMonth None None FixedDateVariable None False
17 $End.DaysInMonth 18 $DaysInMonth None None FixedDateVariable None False
18 $ActiveInputSet 19 $ActiveInputSet None None ActiveInputSetVariable None False
19 $MFR_Piecewise 21 $MFR_Piecewise /variables/MFR_Piecewise/Piecewise None LinearVariable None True
20 $Runoff 20 $Runoff None /variables/Runoff/TimeSeries TimeSeriesVariable DisplayName=$Runoff;ResultUnit=no unit selecte... True

v.variables() only returns summary information about the variable. If you want to get at the actual time series (or the piecewise linear function or similar), use v.variable_time_series(name) (or v.variable_piecewise(name)):


In [19]:
runoff_ts = v.variable_time_series('$Runoff')
runoff_ts.plot()


Out[19]:
<matplotlib.axes._subplots.AxesSubplot at 0x9a765c0>

In [20]:
mfr_piecewise = v.variable_piecewise('MFR_Piecewise')
mfr_piecewise


Out[20]:
Lookup Result
0 0 0.0
1 100 1.0
2 101 1.1
3 1000 100.0
4 10000 2000.0

Note: At this stage, only Time Series and Piecewise Linear variables are supported through this mechanism

Data Sources

You can get a list of all Data Sources in the model with v.data_sources()


In [21]:
data_sources = v.data_sources()
data_sources


Out[21]:
[{'FullName': '/ForcingData_csv', 'Path': '/', 'Name': 'ForcingData_csv', 'Items': [{'Details': [{'TimeSeries': {'Name': 'Inflow', 'StartDate': '01/01/1901 00:00:00', 'Max': 13.09, 'Min': 0, 'EndDate': '12/31/2013 00:00:00', 'TimeStep': 'Daily', 'Mean': 1.518634390521643, 'Units': 'mm/d', 'Sum': 62678.59719999978, 'NoDataValue': -9999}, 'Name': 'Inflow'}, {'TimeSeries': {'Name': 'Rainfall', 'StartDate': '01/01/1901 00:00:00', 'Max': 210.9999, 'Min': 0, 'EndDate': '12/31/2013 00:00:00', 'TimeStep': 'Daily', 'Mean': 3.9211440845104604, 'Units': 'mm/d', 'Sum': 161837.37980000023, 'NoDataValue': -9999}, 'Name': 'Rainfall'}, {'TimeSeries': {'Name': 'PET', 'StartDate': '01/01/1901 00:00:00', 'Max': 8.502, 'Min': 2.0902, 'EndDate': '12/31/2013 00:00:00', 'TimeStep': 'Daily', 'Mean': 4.522002851743327, 'Units': 'mm/d', 'Sum': 186636.62370000235, 'NoDataValue': -9999}, 'Name': 'PET'}], 'Name': 'Default Input Set', 'InputSets': ['Default Input Set'], 'DetailsAsCSV': None, 'UnitsForNewTS': None}], 'id': '/dataSources/ForcingData_csv'}]

Using .as_dataframe() can help to interpret the information:


In [22]:
data_sources.as_dataframe()


Out[22]:
FullName Items Name Path id
0 /ForcingData_csv [{'Details': [{'TimeSeries': {'Name': 'Inflow'... ForcingData_csv / /dataSources/ForcingData_csv

This highlights that the Items column has nested information:


In [23]:
data_sources[0]['Items']


Out[23]:
[{'Details': [{'Name': 'Inflow',
    'TimeSeries': {'EndDate': '12/31/2013 00:00:00',
     'Max': 13.09,
     'Mean': 1.518634390521643,
     'Min': 0,
     'Name': 'Inflow',
     'NoDataValue': -9999,
     'StartDate': '01/01/1901 00:00:00',
     'Sum': 62678.59719999978,
     'TimeStep': 'Daily',
     'Units': 'mm/d'}},
   {'Name': 'Rainfall',
    'TimeSeries': {'EndDate': '12/31/2013 00:00:00',
     'Max': 210.9999,
     'Mean': 3.9211440845104604,
     'Min': 0,
     'Name': 'Rainfall',
     'NoDataValue': -9999,
     'StartDate': '01/01/1901 00:00:00',
     'Sum': 161837.37980000023,
     'TimeStep': 'Daily',
     'Units': 'mm/d'}},
   {'Name': 'PET',
    'TimeSeries': {'EndDate': '12/31/2013 00:00:00',
     'Max': 8.502,
     'Mean': 4.522002851743327,
     'Min': 2.0902,
     'Name': 'PET',
     'NoDataValue': -9999,
     'StartDate': '01/01/1901 00:00:00',
     'Sum': 186636.62370000235,
     'TimeStep': 'Daily',
     'Units': 'mm/d'}}],
  'DetailsAsCSV': None,
  'InputSets': ['Default Input Set'],
  'Name': 'Default Input Set',
  'UnitsForNewTS': None}]

So, v.data_sources() returns information about all data sources. Specifically, it returns the list of data sources, and, for each one, information about the different time series. However, v.data_sources does not return the entire time series. (This is mainly for speed - on big models, this can be HUGE)

To get to the time series, either use v.data_source(name) to retrieve a single data source (and all the time series within it) OR v.data_source_item(source,name) to retrieve a particular time series.

Note: With v.data_source_item you can retrieve the time series for an item that is associated with a particular input set.


In [24]:
forcing = v.data_source('ForcingData_csv')
forcing


Out[24]:
{'FullName': '/ForcingData_csv',
 'Items': [{'Details':             Inflow     PET  Rainfall
 Date                                
 1901-01-01  0.1469  3.2992    0.0000
 1901-01-02  0.1381  3.2992    3.3983
 1901-01-03  0.5186  3.2992    6.8529
 1901-01-04  0.8163  3.2992    1.0206
 1901-01-05  0.7895  3.2992    4.2553
 1901-01-06  3.2796  3.2992   34.5720
 1901-01-07  2.3858  3.2992    0.0000
 1901-01-08  1.5464  3.2992    0.0000
 1901-01-09  1.0746  3.2992    0.0000
 1901-01-10  0.8072  3.2992    0.0000
 1901-01-11  0.6536  3.2992    0.0000
 1901-01-12  0.5633  3.2992    0.0000
 1901-01-13  0.5083  3.2992    0.0000
 1901-01-14  0.4730  3.2992    0.0000
 1901-01-15  0.4489  3.2992    0.0000
 1901-01-16  0.4310  3.2992    0.1968
 1901-01-17  0.4167  3.2992    0.0038
 1901-01-18  2.2677  3.2992   23.7419
 1901-01-19  1.6556  3.2992    0.6581
 1901-01-20  1.1583  3.2992    0.0000
 1901-01-21  0.8762  3.2992    0.0000
 1901-01-22  0.7139  3.2992    0.0000
 1901-01-23  0.6182  3.2992    0.0000
 1901-01-24  0.5598  3.2992    0.0000
 1901-01-25  0.5221  3.2992    0.0000
 1901-01-26  0.4961  3.2992    0.0000
 1901-01-27  0.4767  3.2992    0.0000
 1901-01-28  0.4611  3.2992    0.0000
 1901-01-29  0.4477  3.2992    0.0000
 1901-01-30  0.4357  3.2992    0.0000
 ...            ...     ...       ...
 2013-12-02  0.4249  3.1944    0.0000
 2013-12-03  0.4147  3.1944    0.0000
 2013-12-04  0.4048  3.1944    0.0000
 2013-12-05  0.3950  3.1944    0.0000
 2013-12-06  0.3855  3.1944    0.0000
 2013-12-07  0.3763  3.1944    0.0000
 2013-12-08  0.3672  3.1944    0.0000
 2013-12-09  0.3584  3.1944    0.0000
 2013-12-10  0.3498  3.1944    0.0000
 2013-12-11  0.3414  3.1944    0.0000
 2013-12-12  0.3332  3.1944    0.0000
 2013-12-13  0.3251  3.1944    0.0000
 2013-12-14  0.3173  3.1944    0.0000
 2013-12-15  0.3097  3.1944    0.0000
 2013-12-16  0.3022  3.1944    0.0000
 2013-12-17  0.2949  3.1944    0.0000
 2013-12-18  0.2878  3.1944    0.0000
 2013-12-19  0.2809  3.1944    0.0000
 2013-12-20  0.2741  3.1944    0.0000
 2013-12-21  0.2675  3.1944    0.0000
 2013-12-22  0.2610  3.1944    0.0000
 2013-12-23  0.2547  3.1944    0.0000
 2013-12-24  0.2486  3.1944    0.0000
 2013-12-25  0.2426  3.1944    0.0000
 2013-12-26  0.2367  3.1944    0.0000
 2013-12-27  0.2310  3.1944    0.0000
 2013-12-28  0.2254  3.1944    0.0000
 2013-12-29  0.2199  3.1944    0.0000
 2013-12-30  0.2146  3.1944    0.0000
 2013-12-31  0.2094  3.1944    0.0000
 
 [41273 rows x 3 columns], 'Name': 'Default Input Set', 'InputSets': ['Default Input Set'], 'DetailsAsCSV': None, 'UnitsForNewTS': None}],
 'Name': 'ForcingData_csv',
 'Path': '/',
 'id': '/dataSources/ForcingData_csv'}

You can see that the time series are included, but they are still nested within the returned data. Essentially, Veneer has returned the data for each input set, with each being a separate Pandas DataFrame.

You can get to an individual DataFrame back with find_one_by_Name


In [25]:
forcing_as_df = forcing['Items'].find_one_by_Name('Default Input Set')['Details']
forcing_as_df[0:30] # Look at the first 30 time steps


Out[25]:
Inflow PET Rainfall
Date
1901-01-01 0.1469 3.2992 0.0000
1901-01-02 0.1381 3.2992 3.3983
1901-01-03 0.5186 3.2992 6.8529
1901-01-04 0.8163 3.2992 1.0206
1901-01-05 0.7895 3.2992 4.2553
1901-01-06 3.2796 3.2992 34.5720
1901-01-07 2.3858 3.2992 0.0000
1901-01-08 1.5464 3.2992 0.0000
1901-01-09 1.0746 3.2992 0.0000
1901-01-10 0.8072 3.2992 0.0000
1901-01-11 0.6536 3.2992 0.0000
1901-01-12 0.5633 3.2992 0.0000
1901-01-13 0.5083 3.2992 0.0000
1901-01-14 0.4730 3.2992 0.0000
1901-01-15 0.4489 3.2992 0.0000
1901-01-16 0.4310 3.2992 0.1968
1901-01-17 0.4167 3.2992 0.0038
1901-01-18 2.2677 3.2992 23.7419
1901-01-19 1.6556 3.2992 0.6581
1901-01-20 1.1583 3.2992 0.0000
1901-01-21 0.8762 3.2992 0.0000
1901-01-22 0.7139 3.2992 0.0000
1901-01-23 0.6182 3.2992 0.0000
1901-01-24 0.5598 3.2992 0.0000
1901-01-25 0.5221 3.2992 0.0000
1901-01-26 0.4961 3.2992 0.0000
1901-01-27 0.4767 3.2992 0.0000
1901-01-28 0.4611 3.2992 0.0000
1901-01-29 0.4477 3.2992 0.0000
1901-01-30 0.4357 3.2992 0.0000

You can jump to a particular data source item (typically a column from an original file) with v.data_source_item(source,name)


In [26]:
rainfall = v.data_source_item('ForcingData_csv','Rainfall')
rainfall[0:30]


Out[26]:
Rainfall
Date
1901-01-01 0.0000
1901-01-02 3.3983
1901-01-03 6.8529
1901-01-04 1.0206
1901-01-05 4.2553
1901-01-06 34.5720
1901-01-07 0.0000
1901-01-08 0.0000
1901-01-09 0.0000
1901-01-10 0.0000
1901-01-11 0.0000
1901-01-12 0.0000
1901-01-13 0.0000
1901-01-14 0.0000
1901-01-15 0.0000
1901-01-16 0.1968
1901-01-17 0.0038
1901-01-18 23.7419
1901-01-19 0.6581
1901-01-20 0.0000
1901-01-21 0.0000
1901-01-22 0.0000
1901-01-23 0.0000
1901-01-24 0.0000
1901-01-25 0.0000
1901-01-26 0.0000
1901-01-27 0.0000
1901-01-28 0.0000
1901-01-29 0.0000
1901-01-30 0.0000

In [ ]:

Input Sets

Veneer provides access to the scenario input sets - primarily the commands for changing individual model parameters - through `v.input_sets()


In [27]:
input_sets = v.input_sets()
input_sets


Out[27]:
[{'Filename': None, 'ReloadOnRun': False, 'Configuration': ['Nodes.Ungauged Inflow.Elevation = 50 m', 'Nodes.Storage.Elevation = 15 m', 'Nodes.MFR.Elevation = 5 m'], 'Name': 'Default Input Set', 'URL': '/inputSets/Default Input Set'}]

Within a given input set, the individual commands are available in the Configuration property


In [28]:
input_sets.find_one_by_Name('Default Input Set')['Configuration']


Out[28]:
['Nodes.Ungauged Inflow.Elevation = 50 m',
 'Nodes.Storage.Elevation = 15 m',
 'Nodes.MFR.Elevation = 5 m']

Input sets are a lot more interesting when you are changing them and applying them from Python...

Running Models

You can run the current scenario, with its current settings (start/end date, input set, run configuration, etc) using v.run_model()


In [29]:
response,run_url = v.run_model()
response,run_url


Out[29]:
(302, 'runs/1')

After a successful run, veneer-py returns the URL of the new run - this can be used to retrieve an index of all the available results and, from there, the actual time series results


In [30]:
run_url


Out[30]:
'runs/1'

In [31]:
index = v.retrieve_run(run_url)
index


Out[31]:
{'DateRun': '08/01/2017 17:00:31',
 'Name': 'Scenario 1 (1)',
 'Number': 1,
 'Results': [{'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/Default Link 4/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Default Link #4', 'TimeSeriesName': 'Straight-Through Routing: Default Link #4: Upstream Flow'}, {'RecordingElement': 'Catchment Inflow', 'TimeSeriesUrl': '/runs/1/location/Default Link 4/element/Catchment Inflow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Default Link #4', 'TimeSeriesName': 'Straight-Through Routing: Default Link #4: Catchment Inflow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/Default Link 4/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Default Link #4', 'TimeSeriesName': 'Straight-Through Routing: Default Link #4: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/Default Link 4/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'Default Link #4', 'TimeSeriesName': 'Straight-Through Routing: Default Link #4: Storage Volume'}, {'RecordingElement': 'Lateral Flow', 'TimeSeriesUrl': '/runs/1/location/Default Link 4/element/Lateral Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Default Link #4', 'TimeSeriesName': 'Straight-Through Routing: Default Link #4: Lateral Flow'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Default Link 4/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'Default Link #4', 'TimeSeriesName': 'Straight-Through Routing: Default Link #4: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Default Link 4/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'Default Link #4', 'TimeSeriesName': 'Straight-Through Routing: Default Link #4: Downstream Flow Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/Default Link 4/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'Default Link #4', 'TimeSeriesName': 'Default Link #4: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Upstream Flow'}, {'RecordingElement': 'Catchment Inflow', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Catchment Inflow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Catchment Inflow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Storage Volume'}, {'RecordingElement': 'Live Storage Volume', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Live Storage Volume/variable/Live Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Live Storage Volume', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Live Storage Volume'}, {'RecordingElement': 'Time Series Flux', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Time Series Flux/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Time Series Flux'}, {'RecordingElement': 'Loss / Gain Flux', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Loss %2F Gain Flux/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Loss / Gain Flux'}, {'RecordingElement': 'Lateral Flow', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Lateral Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Lateral Flow'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'SR2', 'TimeSeriesName': 'Storage Routing: SR2: Downstream Flow Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/SR2/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'SR2', 'TimeSeriesName': 'SR2: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Upstream Flow'}, {'RecordingElement': 'Catchment Inflow', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Catchment Inflow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Catchment Inflow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Storage Volume'}, {'RecordingElement': 'Live Storage Volume', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Live Storage Volume/variable/Live Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Live Storage Volume', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Live Storage Volume'}, {'RecordingElement': 'Time Series Flux', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Time Series Flux/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Time Series Flux'}, {'RecordingElement': 'Loss / Gain Flux', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Loss %2F Gain Flux/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Loss / Gain Flux'}, {'RecordingElement': 'Lateral Flow', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Lateral Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Lateral Flow'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'SR3', 'TimeSeriesName': 'Storage Routing: SR3: Downstream Flow Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/SR3/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'SR3', 'TimeSeriesName': 'SR3: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/Default Link 5/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Default Link #5', 'TimeSeriesName': 'Straight-Through Routing: Default Link #5: Upstream Flow'}, {'RecordingElement': 'Catchment Inflow', 'TimeSeriesUrl': '/runs/1/location/Default Link 5/element/Catchment Inflow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Default Link #5', 'TimeSeriesName': 'Straight-Through Routing: Default Link #5: Catchment Inflow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/Default Link 5/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Default Link #5', 'TimeSeriesName': 'Straight-Through Routing: Default Link #5: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/Default Link 5/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'Default Link #5', 'TimeSeriesName': 'Straight-Through Routing: Default Link #5: Storage Volume'}, {'RecordingElement': 'Lateral Flow', 'TimeSeriesUrl': '/runs/1/location/Default Link 5/element/Lateral Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Default Link #5', 'TimeSeriesName': 'Straight-Through Routing: Default Link #5: Lateral Flow'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Default Link 5/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'Default Link #5', 'TimeSeriesName': 'Straight-Through Routing: Default Link #5: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Default Link 5/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'Default Link #5', 'TimeSeriesName': 'Straight-Through Routing: Default Link #5: Downstream Flow Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/Default Link 5/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'Default Link #5', 'TimeSeriesName': 'Default Link #5: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/Ungauged Inflow/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Ungauged Inflow', 'TimeSeriesName': 'Inflow: Ungauged Inflow: Upstream Flow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/Ungauged Inflow/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Ungauged Inflow', 'TimeSeriesName': 'Inflow: Ungauged Inflow: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/Ungauged Inflow/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'Ungauged Inflow', 'TimeSeriesName': 'Inflow: Ungauged Inflow: Storage Volume'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Ungauged Inflow/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'Ungauged Inflow', 'TimeSeriesName': 'Inflow: Ungauged Inflow: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Ungauged Inflow/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'Ungauged Inflow', 'TimeSeriesName': 'Inflow: Ungauged Inflow: Downstream Flow Volume'}, {'RecordingElement': 'Forecast Volume', 'TimeSeriesUrl': '/runs/1/location/Ungauged Inflow/element/Forecast Volume/variable/0', 'RunNumber': 1, 'RecordingVariable': '0', 'NetworkElement': 'Ungauged Inflow', 'TimeSeriesName': 'Inflow: Ungauged Inflow: Forecast Volume: Current time step + 1'}, {'RecordingElement': 'Inflow Volume', 'TimeSeriesUrl': '/runs/1/location/Ungauged Inflow/element/Inflow Volume/variable/Inflow Volume', 'RunNumber': 1, 'RecordingVariable': 'Inflow Volume', 'NetworkElement': 'Ungauged Inflow', 'TimeSeriesName': 'Inflow: Ungauged Inflow: Inflow Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/Ungauged Inflow/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'Ungauged Inflow', 'TimeSeriesName': 'Ungauged Inflow: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Upstream Flow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Storage Volume'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Downstream Flow Volume'}, {'RecordingElement': 'Hydropower', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Hydropower/variable/Hydropower', 'RunNumber': 1, 'RecordingVariable': 'Hydropower', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Total'}, {'RecordingElement': 'Storage Surface Area', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Storage Surface Area/variable/Storage Surface Area', 'RunNumber': 1, 'RecordingVariable': 'Storage Surface Area', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Storage Surface Area'}, {'RecordingElement': 'Rainfall Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Rainfall Volume/variable/Rainfall Volume', 'RunNumber': 1, 'RecordingVariable': 'Rainfall Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Rainfall Volume'}, {'RecordingElement': 'Evaporation Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Evaporation Volume/variable/Evaporation Volume', 'RunNumber': 1, 'RecordingVariable': 'Evaporation Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Evaporation Volume'}, {'RecordingElement': 'Infiltration Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Infiltration Volume/variable/Infiltration Volume', 'RunNumber': 1, 'RecordingVariable': 'Infiltration Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Infiltration Volume'}, {'RecordingElement': 'Ceded Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Ceded Volume/variable/Ceded Volume', 'RunNumber': 1, 'RecordingVariable': 'Ceded Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Ceded Volume'}, {'RecordingElement': 'Internal Spill Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Internal Spill Volume/variable/Internal Spill Volume', 'RunNumber': 1, 'RecordingVariable': 'Internal Spill Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Internal Spill Volume'}, {'RecordingElement': 'External Spill Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/External Spill Volume/variable/External Spill Volume', 'RunNumber': 1, 'RecordingVariable': 'External Spill Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: External Spill Volume'}, {'RecordingElement': 'Regulated Release Volume', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Regulated Release Volume/variable/Regulated Release Volume', 'RunNumber': 1, 'RecordingVariable': 'Regulated Release Volume', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Storage: Regulated Release Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/Storage/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'Storage', 'TimeSeriesName': 'Storage: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/SP/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SP', 'TimeSeriesName': 'Supply Point: SP: Upstream Flow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/SP/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'SP', 'TimeSeriesName': 'Supply Point: SP: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/SP/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'SP', 'TimeSeriesName': 'Supply Point: SP: Storage Volume'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/SP/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'SP', 'TimeSeriesName': 'Supply Point: SP: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/SP/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'SP', 'TimeSeriesName': 'Supply Point: SP: Downstream Flow Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/SP/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'SP', 'TimeSeriesName': 'SP: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/MFR/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'MFR', 'TimeSeriesName': 'Minimum Flow Requirement: MFR: Upstream Flow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/MFR/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'MFR', 'TimeSeriesName': 'Minimum Flow Requirement: MFR: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/MFR/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'MFR', 'TimeSeriesName': 'Minimum Flow Requirement: MFR: Storage Volume'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/MFR/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'MFR', 'TimeSeriesName': 'Minimum Flow Requirement: MFR: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/MFR/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'MFR', 'TimeSeriesName': 'Minimum Flow Requirement: MFR: Downstream Flow Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/MFR/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'MFR', 'TimeSeriesName': 'MFR: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User: Water User: Upstream Flow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User: Water User: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User: Water User: Storage Volume'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User: Water User: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User: Water User: Downstream Flow Volume'}, {'RecordingElement': 'Demand & Storage Interface', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand & Storage Interface/variable/Demand & Storage Interface@Demand Model@Regulated Requirements', 'RunNumber': 1, 'RecordingVariable': 'Demand & Storage Interface@Demand Model@Regulated Requirements', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Demand Model > Regulated Requirements: 0'}, {'RecordingElement': 'Demand & Storage Interface', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand & Storage Interface/variable/Demand & Storage Interface@Demand Model@Regulated Water Supplied', 'RunNumber': 1, 'RecordingVariable': 'Demand & Storage Interface@Demand Model@Regulated Water Supplied', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Demand Model > Regulated Water Supplied'}, {'RecordingElement': 'Demand Model', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand Model/variable/Demand Model@Crops@Crop Type 0@Area', 'RunNumber': 1, 'RecordingVariable': 'Demand Model@Crops@Crop Type #0@Area', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Crops > Crop Type #0 > Area'}, {'RecordingElement': 'Demand Model', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand Model/variable/Demand Model@Crops@Crop Type 0@Crop Production', 'RunNumber': 1, 'RecordingVariable': 'Demand Model@Crops@Crop Type #0@Crop Production', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Crops > Crop Type #0 > Crop Production'}, {'RecordingElement': 'Demand Model', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand Model/variable/Demand Model@Crops@Crop Type 0@Crop Yield', 'RunNumber': 1, 'RecordingVariable': 'Demand Model@Crops@Crop Type #0@Crop Yield', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Crops > Crop Type #0 > Crop Yield'}, {'RecordingElement': 'Demand Model', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand Model/variable/Demand Model@Crops@Crop Type 0@Evapo-Transpiration', 'RunNumber': 1, 'RecordingVariable': 'Demand Model@Crops@Crop Type #0@Evapo-Transpiration', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Crops > Crop Type #0 > Evapo-Transpiration'}, {'RecordingElement': 'Demand Model', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand Model/variable/Demand Model@Crops@Crop Type 0@Requirement', 'RunNumber': 1, 'RecordingVariable': 'Demand Model@Crops@Crop Type #0@Requirement', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Crops > Crop Type #0 > Requirement'}, {'RecordingElement': 'Demand Model', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand Model/variable/Demand Model@Crops@Crop Type 0@Soil Depletion', 'RunNumber': 1, 'RecordingVariable': 'Demand Model@Crops@Crop Type #0@Soil Depletion', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Crops > Crop Type #0 > Soil Depletion'}, {'RecordingElement': 'Demand Model', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Demand Model/variable/Demand Model@Crops@Crop Type 0@Water Supplied', 'RunNumber': 1, 'RecordingVariable': 'Demand Model@Crops@Crop Type #0@Water Supplied', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User > Water User > Crops > Crop Type #0 > Water Supplied'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/Water User/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'Water User', 'TimeSeriesName': 'Water User: Mass Balance'}, {'RecordingElement': 'Upstream Flow', 'TimeSeriesUrl': '/runs/1/location/End Of System/element/Upstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'End Of System', 'TimeSeriesName': 'Gauge: End Of System: Upstream Flow'}, {'RecordingElement': 'Downstream Flow', 'TimeSeriesUrl': '/runs/1/location/End Of System/element/Downstream Flow/variable/Flow', 'RunNumber': 1, 'RecordingVariable': 'Flow', 'NetworkElement': 'End Of System', 'TimeSeriesName': 'Gauge: End Of System: Downstream Flow'}, {'RecordingElement': 'Storage Volume', 'TimeSeriesUrl': '/runs/1/location/End Of System/element/Storage Volume/variable/Storage Volume', 'RunNumber': 1, 'RecordingVariable': 'Storage Volume', 'NetworkElement': 'End Of System', 'TimeSeriesName': 'Gauge: End Of System: Storage Volume'}, {'RecordingElement': 'Upstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/End Of System/element/Upstream Flow Volume/variable/Upstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Upstream Flow Volume', 'NetworkElement': 'End Of System', 'TimeSeriesName': 'Gauge: End Of System: Upstream Flow Volume'}, {'RecordingElement': 'Downstream Flow Volume', 'TimeSeriesUrl': '/runs/1/location/End Of System/element/Downstream Flow Volume/variable/Downstream Flow Volume', 'RunNumber': 1, 'RecordingVariable': 'Downstream Flow Volume', 'NetworkElement': 'End Of System', 'TimeSeriesName': 'Gauge: End Of System: Downstream Flow Volume'}, {'RecordingElement': 'Mass Balance', 'TimeSeriesUrl': '/runs/1/location/End Of System/element/Mass Balance/variable/Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Mass Balance', 'NetworkElement': 'End Of System', 'TimeSeriesName': 'End Of System: Mass Balance'}, {'RecordingElement': 'Scenario Mass Balance', 'TimeSeriesUrl': '/runs/1/location/Scenario Mass Balance/element/Scenario Mass Balance/variable/Scenario Mass Balance', 'RunNumber': 1, 'RecordingVariable': 'Scenario Mass Balance', 'NetworkElement': 'Scenario Mass Balance', 'TimeSeriesName': 'Scenario Mass Balance Total'}],
 'Scenario': 'Scenario 1',
 'Status': 'LogWarning'}

This index lists all of the time series (under ['Results']) and can be used to retrieve individual time series, or collections of time series


In [32]:
index['Results'].as_dataframe()


Out[32]:
NetworkElement RecordingElement RecordingVariable RunNumber TimeSeriesName TimeSeriesUrl
0 Default Link #4 Upstream Flow Flow 1 Straight-Through Routing: Default Link #4: Ups... /runs/1/location/Default Link 4/element/Upstre...
1 Default Link #4 Catchment Inflow Flow 1 Straight-Through Routing: Default Link #4: Cat... /runs/1/location/Default Link 4/element/Catchm...
2 Default Link #4 Downstream Flow Flow 1 Straight-Through Routing: Default Link #4: Dow... /runs/1/location/Default Link 4/element/Downst...
3 Default Link #4 Storage Volume Storage Volume 1 Straight-Through Routing: Default Link #4: Sto... /runs/1/location/Default Link 4/element/Storag...
4 Default Link #4 Lateral Flow Flow 1 Straight-Through Routing: Default Link #4: Lat... /runs/1/location/Default Link 4/element/Latera...
5 Default Link #4 Upstream Flow Volume Upstream Flow Volume 1 Straight-Through Routing: Default Link #4: Ups... /runs/1/location/Default Link 4/element/Upstre...
6 Default Link #4 Downstream Flow Volume Downstream Flow Volume 1 Straight-Through Routing: Default Link #4: Dow... /runs/1/location/Default Link 4/element/Downst...
7 Default Link #4 Mass Balance Mass Balance 1 Default Link #4: Mass Balance /runs/1/location/Default Link 4/element/Mass B...
8 SR2 Upstream Flow Flow 1 Storage Routing: SR2: Upstream Flow /runs/1/location/SR2/element/Upstream Flow/var...
9 SR2 Catchment Inflow Flow 1 Storage Routing: SR2: Catchment Inflow /runs/1/location/SR2/element/Catchment Inflow/...
10 SR2 Downstream Flow Flow 1 Storage Routing: SR2: Downstream Flow /runs/1/location/SR2/element/Downstream Flow/v...
11 SR2 Storage Volume Storage Volume 1 Storage Routing: SR2: Storage Volume /runs/1/location/SR2/element/Storage Volume/va...
12 SR2 Live Storage Volume Live Storage Volume 1 Storage Routing: SR2: Live Storage Volume /runs/1/location/SR2/element/Live Storage Volu...
13 SR2 Time Series Flux Flow 1 Storage Routing: SR2: Time Series Flux /runs/1/location/SR2/element/Time Series Flux/...
14 SR2 Loss / Gain Flux Flow 1 Storage Routing: SR2: Loss / Gain Flux /runs/1/location/SR2/element/Loss %2F Gain Flu...
15 SR2 Lateral Flow Flow 1 Storage Routing: SR2: Lateral Flow /runs/1/location/SR2/element/Lateral Flow/vari...
16 SR2 Upstream Flow Volume Upstream Flow Volume 1 Storage Routing: SR2: Upstream Flow Volume /runs/1/location/SR2/element/Upstream Flow Vol...
17 SR2 Downstream Flow Volume Downstream Flow Volume 1 Storage Routing: SR2: Downstream Flow Volume /runs/1/location/SR2/element/Downstream Flow V...
18 SR2 Mass Balance Mass Balance 1 SR2: Mass Balance /runs/1/location/SR2/element/Mass Balance/vari...
19 SR3 Upstream Flow Flow 1 Storage Routing: SR3: Upstream Flow /runs/1/location/SR3/element/Upstream Flow/var...
20 SR3 Catchment Inflow Flow 1 Storage Routing: SR3: Catchment Inflow /runs/1/location/SR3/element/Catchment Inflow/...
21 SR3 Downstream Flow Flow 1 Storage Routing: SR3: Downstream Flow /runs/1/location/SR3/element/Downstream Flow/v...
22 SR3 Storage Volume Storage Volume 1 Storage Routing: SR3: Storage Volume /runs/1/location/SR3/element/Storage Volume/va...
23 SR3 Live Storage Volume Live Storage Volume 1 Storage Routing: SR3: Live Storage Volume /runs/1/location/SR3/element/Live Storage Volu...
24 SR3 Time Series Flux Flow 1 Storage Routing: SR3: Time Series Flux /runs/1/location/SR3/element/Time Series Flux/...
25 SR3 Loss / Gain Flux Flow 1 Storage Routing: SR3: Loss / Gain Flux /runs/1/location/SR3/element/Loss %2F Gain Flu...
26 SR3 Lateral Flow Flow 1 Storage Routing: SR3: Lateral Flow /runs/1/location/SR3/element/Lateral Flow/vari...
27 SR3 Upstream Flow Volume Upstream Flow Volume 1 Storage Routing: SR3: Upstream Flow Volume /runs/1/location/SR3/element/Upstream Flow Vol...
28 SR3 Downstream Flow Volume Downstream Flow Volume 1 Storage Routing: SR3: Downstream Flow Volume /runs/1/location/SR3/element/Downstream Flow V...
29 SR3 Mass Balance Mass Balance 1 SR3: Mass Balance /runs/1/location/SR3/element/Mass Balance/vari...
... ... ... ... ... ... ...
65 SP Downstream Flow Volume Downstream Flow Volume 1 Supply Point: SP: Downstream Flow Volume /runs/1/location/SP/element/Downstream Flow Vo...
66 SP Mass Balance Mass Balance 1 SP: Mass Balance /runs/1/location/SP/element/Mass Balance/varia...
67 MFR Upstream Flow Flow 1 Minimum Flow Requirement: MFR: Upstream Flow /runs/1/location/MFR/element/Upstream Flow/var...
68 MFR Downstream Flow Flow 1 Minimum Flow Requirement: MFR: Downstream Flow /runs/1/location/MFR/element/Downstream Flow/v...
69 MFR Storage Volume Storage Volume 1 Minimum Flow Requirement: MFR: Storage Volume /runs/1/location/MFR/element/Storage Volume/va...
70 MFR Upstream Flow Volume Upstream Flow Volume 1 Minimum Flow Requirement: MFR: Upstream Flow V... /runs/1/location/MFR/element/Upstream Flow Vol...
71 MFR Downstream Flow Volume Downstream Flow Volume 1 Minimum Flow Requirement: MFR: Downstream Flow... /runs/1/location/MFR/element/Downstream Flow V...
72 MFR Mass Balance Mass Balance 1 MFR: Mass Balance /runs/1/location/MFR/element/Mass Balance/vari...
73 Water User Upstream Flow Flow 1 Water User: Water User: Upstream Flow /runs/1/location/Water User/element/Upstream F...
74 Water User Downstream Flow Flow 1 Water User: Water User: Downstream Flow /runs/1/location/Water User/element/Downstream...
75 Water User Storage Volume Storage Volume 1 Water User: Water User: Storage Volume /runs/1/location/Water User/element/Storage Vo...
76 Water User Upstream Flow Volume Upstream Flow Volume 1 Water User: Water User: Upstream Flow Volume /runs/1/location/Water User/element/Upstream F...
77 Water User Downstream Flow Volume Downstream Flow Volume 1 Water User: Water User: Downstream Flow Volume /runs/1/location/Water User/element/Downstream...
78 Water User Demand & Storage Interface Demand & Storage Interface@Demand Model@Regula... 1 Water User > Water User > Demand Model > Regul... /runs/1/location/Water User/element/Demand & S...
79 Water User Demand & Storage Interface Demand & Storage Interface@Demand Model@Regula... 1 Water User > Water User > Demand Model > Regul... /runs/1/location/Water User/element/Demand & S...
80 Water User Demand Model Demand Model@Crops@Crop Type #0@Area 1 Water User > Water User > Crops > Crop Type #0... /runs/1/location/Water User/element/Demand Mod...
81 Water User Demand Model Demand Model@Crops@Crop Type #0@Crop Production 1 Water User > Water User > Crops > Crop Type #0... /runs/1/location/Water User/element/Demand Mod...
82 Water User Demand Model Demand Model@Crops@Crop Type #0@Crop Yield 1 Water User > Water User > Crops > Crop Type #0... /runs/1/location/Water User/element/Demand Mod...
83 Water User Demand Model Demand Model@Crops@Crop Type #0@Evapo-Transpir... 1 Water User > Water User > Crops > Crop Type #0... /runs/1/location/Water User/element/Demand Mod...
84 Water User Demand Model Demand Model@Crops@Crop Type #0@Requirement 1 Water User > Water User > Crops > Crop Type #0... /runs/1/location/Water User/element/Demand Mod...
85 Water User Demand Model Demand Model@Crops@Crop Type #0@Soil Depletion 1 Water User > Water User > Crops > Crop Type #0... /runs/1/location/Water User/element/Demand Mod...
86 Water User Demand Model Demand Model@Crops@Crop Type #0@Water Supplied 1 Water User > Water User > Crops > Crop Type #0... /runs/1/location/Water User/element/Demand Mod...
87 Water User Mass Balance Mass Balance 1 Water User: Mass Balance /runs/1/location/Water User/element/Mass Balan...
88 End Of System Upstream Flow Flow 1 Gauge: End Of System: Upstream Flow /runs/1/location/End Of System/element/Upstrea...
89 End Of System Downstream Flow Flow 1 Gauge: End Of System: Downstream Flow /runs/1/location/End Of System/element/Downstr...
90 End Of System Storage Volume Storage Volume 1 Gauge: End Of System: Storage Volume /runs/1/location/End Of System/element/Storage...
91 End Of System Upstream Flow Volume Upstream Flow Volume 1 Gauge: End Of System: Upstream Flow Volume /runs/1/location/End Of System/element/Upstrea...
92 End Of System Downstream Flow Volume Downstream Flow Volume 1 Gauge: End Of System: Downstream Flow Volume /runs/1/location/End Of System/element/Downstr...
93 End Of System Mass Balance Mass Balance 1 End Of System: Mass Balance /runs/1/location/End Of System/element/Mass Ba...
94 Scenario Mass Balance Scenario Mass Balance Scenario Mass Balance 1 Scenario Mass Balance Total /runs/1/location/Scenario Mass Balance/element...

95 rows × 6 columns

The easiest way to retrieve time series results is with v.retrieve_multiple_time_series, which takes a set of run results, some search criteria by which it identifies wanted time series. There are also options for retrieve aggregated data and the ability to rename time series as they are retrieved.

The help text for retrieve_multiple_time_series describes the options


In [33]:
help(v.retrieve_multiple_time_series)


Help on method retrieve_multiple_time_series in module veneer.general:

retrieve_multiple_time_series(run='latest', run_data=None, criteria={}, timestep='daily', name_fn=<function name_element_variable at 0x0000000008596A60>) method of veneer.general.Veneer instance
    Retrieve multiple time series from a run according to some criteria.
    
    Return all time series in a single Pandas DataFrame with date time index.
    
    you can an index of run results via run_data. If you don't the method will first retrieve an
    index based on the value of the run parameter (default='latest')
    
    criteria should be regexps for the fields in a Veneer time series record:
      * NetworkElement
      * RecordingElement
      * RecordingVariable
      * TimeSeriesName
      * TimeSeriesUrl
    
    These criteria are used to identify which time series to retrieve.
    
    timestep should be one of 'daily' (default), 'monthly', 'annual'
    
    All retrieved time series are returned in a single Data Frame.
    
    You can specify a function for naming the columns of the Data Frame using name_fn. This function should take
    the results summary (from the index) and return a string. Example functions include:
      * veneer.name_time_series (uses the full name of the time series, as provided by Source)
      * veneer.name_element_variable (DEFAULT: users the name of the network element and the name of the variable)
      * veneer.name_for_location (just use the name of the network element)
      * veneer.name_for_variable (just use the name of the variable)

The following examples retrieve data from the latest run, using the index index we saved, earlier:


In [34]:
# Retrieve Downstream Flow Volume, anywhere it is recorded.
# Name the columns for the network location
ds_flow = v.retrieve_multiple_time_series(run_data=index,criteria={'RecordingVariable':'Downstream Flow Volume'},
                                          name_fn=veneer.name_for_location)
ds_flow[0:10]


Out[34]:
Default Link #4 Default Link #5 End Of System MFR SP SR2 SR3 Storage Ungauged Inflow Water User
1901-01-01 0.000000 514.15 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 514.15 0
1901-01-02 0.000000 483.35 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 483.35 0
1901-01-03 6349.027111 1815.10 6349.027111 6349.027111 6349.027111 6349.027111 6349.027111 6349.027111 1815.10 0
1901-01-04 0.000000 2857.05 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2857.05 0
1901-01-05 0.000000 2763.25 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2763.25 0
1901-01-06 316601.314118 11478.60 316601.314118 316601.314118 316601.314118 316601.314118 316601.314118 316601.314118 11478.60 0
1901-01-07 0.000000 8350.30 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 8350.30 0
1901-01-08 0.000000 5412.40 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 5412.40 0
1901-01-09 0.000000 3761.10 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3761.10 0
1901-01-10 0.000000 2825.20 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2825.20 0

In [35]:
# Retrieve everything available from the Water User node
# Name the columns for the variable
water_user = v.retrieve_multiple_time_series(run_data=index,criteria={'NetworkElement':'Water User'},
                                          name_fn=veneer.name_for_variable)
water_user[0:10]


Out[35]:
Demand & Storage Interface@Demand Model@Regulated Requirements Demand & Storage Interface@Demand Model@Regulated Water Supplied Demand Model@Crops@Crop Type #0@Area Demand Model@Crops@Crop Type #0@Crop Production Demand Model@Crops@Crop Type #0@Crop Yield Demand Model@Crops@Crop Type #0@Evapo-Transpiration Demand Model@Crops@Crop Type #0@Requirement Demand Model@Crops@Crop Type #0@Soil Depletion Demand Model@Crops@Crop Type #0@Water Supplied Downstream Flow Volume Flow Flow 1 Mass Balance Storage Volume Upstream Flow Volume
1901-01-01 9897.6 0 10000000 0 0 0.00099 9897.6 9.897600e-04 0 0 0 0 0 0 0
1901-01-02 0.0 0 10000000 0 0 0.00099 0.0 0.000000e+00 0 0 0 0 0 0 0
1901-01-03 0.0 0 10000000 0 0 0.00099 0.0 -2.168404e-19 0 0 0 0 0 0 0
1901-01-04 6290.0 0 10000000 0 0 0.00099 6290.0 6.290000e-04 0 0 0 0 0 0 0
1901-01-05 0.0 0 10000000 0 0 0.00099 0.0 -2.168404e-19 0 0 0 0 0 0 0
1901-01-06 0.0 0 10000000 0 0 0.00099 0.0 4.336809e-19 0 0 0 0 0 0 0
1901-01-07 9897.6 0 10000000 0 0 0.00099 9897.6 9.897600e-04 0 0 0 0 0 0 0
1901-01-08 19795.2 0 10000000 0 0 0.00099 19795.2 1.979520e-03 0 0 0 0 0 0 0
1901-01-09 29692.8 0 10000000 0 0 0.00099 29692.8 2.969280e-03 0 0 0 0 0 0 0
1901-01-10 39590.4 0 10000000 0 0 0.00099 39590.4 3.959040e-03 0 0 0 0 0 0 0

There are numerous functions and options that are closely related to running simulations:

  • You can call v.run_model() with alternate start and end dates, along with other options related to the simulation, such as specifying an input set
  • You can call v.apply_input_set() to run the commands in a particular input set. This doesn't trigger a run, so its useful in situations where you want to run multiple input sets before a single simulation
  • v.configure_recording() can switch time series recorders on and off
  • You can drop a run from memory (v.drop_run) or drop all runs (v.drop_all_runs())

These actions will all be covered in subsequent tutorials. For now, a simple example of enabling recording of Storage Surface Area and rerunning:


In [36]:
v.drop_all_runs()
v.configure_recording(enable=[{'RecordingVariable':'Storage Surface Area'}])
v.run_model()


Out[36]:
(302, 'runs/1')

In [37]:
surface_area = v.retrieve_multiple_time_series(criteria={'RecordingVariable':'Storage Surface Area'})
surface_area.plot()


Out[37]:
<matplotlib.axes._subplots.AxesSubplot at 0x23ca8588>

Note: We again drop all runs before moving on...


In [38]:
v.drop_all_runs()

In [ ]:

Manipulating model setup and the ‘Allow Scripts’ option

There are various ways to use veneer-py to change the configuration of the currently loaded model in Source

  1. Methods to update input sets with new parameters (v.update_input_set)
  2. Applying a particular input set (v.apply_input_set)
  3. Use functionality under v.model. to directly change model parameters and structure

It is also possible to modify files on disk where Source is configured to 'Reload-On-Run', such as changing time series files or input set command files. This option isn't specific to Veneer/veneer-py and isn't covered in these tutorials.

We can update the input set commands for the default input set.

(Making a single change like this can be a bit fiddly!)


In [39]:
default_input_set = v.input_sets()[0]
default_input_set


Out[39]:
{'Configuration': ['Nodes.Ungauged Inflow.Elevation = 50 m',
  'Nodes.Storage.Elevation = 15 m',
  'Nodes.MFR.Elevation = 5 m'],
 'Filename': None,
 'Name': 'Default Input Set',
 'ReloadOnRun': False,
 'URL': '/inputSets/Default Input Set'}

In [40]:
command_of_interest = default_input_set['Configuration'][0]
command_of_interest


Out[40]:
'Nodes.Ungauged Inflow.Elevation = 50 m'

In [41]:
default_input_set['Configuration'][0] = command_of_interest.replace('25 m','50 m')

In [42]:
default_input_set


Out[42]:
{'Configuration': ['Nodes.Ungauged Inflow.Elevation = 50 m',
  'Nodes.Storage.Elevation = 15 m',
  'Nodes.MFR.Elevation = 5 m'],
 'Filename': None,
 'Name': 'Default Input Set',
 'ReloadOnRun': False,
 'URL': '/inputSets/Default Input Set'}

In [43]:
v.update_input_set('Default Input Set',default_input_set)


Out[43]:
(200, None)

At this point, you can check in the Source user interface (Edit|Scenario Input Sets) to see that the input set has been updated. Alternatively, you can query the input set again


In [44]:
v.input_sets()


Out[44]:
[{'Filename': None, 'ReloadOnRun': False, 'Configuration': ['Nodes.Ungauged Inflow.Elevation = 50 m', 'Nodes.Storage.Elevation = 15 m', 'Nodes.MFR.Elevation = 5 m'], 'Name': 'Default Input Set', 'URL': '/inputSets/Default Input Set'}]

The Default Input Set would be applied when we next run, but if we want those parameters set on the model immediately, we can do so, with v.apply_input_set('Default Input Set')


In [45]:
v.apply_input_set('Default Input Set')


Out[45]:
(200, None)

v.model and the Allow Scripts option

The v.model namespace contains a lot of functionality for modifying the structure of the Source model. This part of veneer-py works by generating IronPython scripts, which run directly within Source and manipulate the .NET objects that Source is built upon.

This capability (to accept IronPython scripts) is disabled, by default, in Veneer. To enable it, click the 'Allow Scripts' checkbox in the Web Server Monitoring window. If you don't enable the 'Allow Scripts' option, then the following instructions will give an error.

As an example of what can be done, the following command queries the routing model used for each link


In [46]:
v.model.link.routing.get_models()


Out[46]:
['RiverSystem.Flow.StraightThroughRouting',
 'RiverSystem.Flow.StorageRouting',
 'RiverSystem.Flow.StraightThroughRouting',
 'RiverSystem.Flow.StorageRouting',
 'RiverSystem.Flow.StraightThroughRouting']

This shows that, for the example model, there are three Straight Through Routing links and two Storage Routing links.

get_models() has returned a list - and this is common within the v.model namespace. It's also common for functions to accept a list when changing the Source model (eg by changing assigned models, or changing parameters).

The list isn't directly useful though, because it doesn't tell you which link is which. That can be checked by asking for the results coded by name


In [47]:
v.model.link.routing.get_models(by_name=True)


Out[47]:
{'Default Link #4': 'RiverSystem.Flow.StraightThroughRouting',
 'Default Link #5': 'RiverSystem.Flow.StraightThroughRouting',
 'Default Link #6': 'RiverSystem.Flow.StraightThroughRouting',
 'SR2': 'RiverSystem.Flow.StorageRouting',
 'SR3': 'RiverSystem.Flow.StorageRouting'}

In [ ]:

PEST and Parallel processing

PEST is a powerful, model independent Parameter ESTimation tool. veneer-py has some initial functionality for configuring and running PEST jobs over Source models using Veneer.

This functionality is currently the best demonstration of parallel processing using Veneer and veneer-py. This is explored in Tutorial 8.


In [ ]:

GUI and Command Line

Veneer is distributed with a command line program, FlowMatters.Source.VeneerCmd.exe, which is an alternative to the eWater supplied RiverSystem.CommandLine.exe. The Veneer command line uses the same protocols as the plugin version of Veneer, making them interchangeable for most applications.

Note: To use the Veneer command line, it needs access to all of the DLLs distributed with Source. Currently, this means that the Veneer command line, and the various DLLs related to Veneer, need to be in the same directory as these eWater supplied files. You can copy all of the eWater files into the Veneer directory, or copy all the Veneer files into the Source installation directory (typically under C:\Program Files\eWater\Source X.Y.ZZ.WWWW). Importantly, if copying the Veneer files to the Source directory, the Veneer files must be in the same directory as the main Source files (eg RiverSystem.Forms.exe), not in the plugins directory

Starting the Veneer Command Line from Python

veneer-py includes a function, start (under veneer.manage) for starting one or more copies of the Veneer command line using a given project file.


In [48]:
from veneer.manage import start

In [49]:
help(start)


Help on function start in module veneer.manage:

start(project_fn, n_instances=1, ports=9876, debug=False, remote=True, script=True, veneer_exe=None)
    Start one or more copies of the Veneer command line progeram with a given project file
    
    Parameters:
    
    - project_fn - Path to a Source project file (.rsproj)
    
    - n_instances - Number of copies of the Veneer command line to start (default: 1)
    
    - ports - A single port number, indicating the port number of the first copy of the Veneer command line,
              OR a list of ports, in which case len(ports)==n_instances  (default: 9876)
    
    - debug - Set to True to echo all output from Veneer Command Line during startup
    
    - remote - Allow remote connections (requires registration)
    
    - script - Allow IronPython scripts
    
    - veneer_exe - Optional (but often required) path to the Veneer Command Line. If not provided,
                   veneer-py will attempt to identify the version of Veneer Command Line to invoke.
                   If there is a source_version.txt file in the same directory as the project file,
                   this text file will be consulted to identify the version of Source.
    
    returns processes, ports
       processes - list of process objects that can be used to terminate the servers
       ports - the port numbers used for each copy of the server

Each copy of the Veneer command line is a copy of the Source engine with a Veneer server.

Each running process will run until terminated, either by the user or by the end of the Python session.

Local and Remote connections

Veneer communicates via network ports, but by default, these connections are restricted to local machine - ie you cannot connect to Veneer on machine A from a Python notebook running on machine B.

If you want to allow remote connections, you need to enable the checkbox in the Web Server Monitoring window. However, in order to do so, you will first need to register the Veneer URL with Windows. Instructions are at https://github.com/flowmatters/veneer.


In [ ]:

Getting help

Many of the functions in veneer-py have built in documentation, which can be accessed in Jupyter/IPython using the ? command, such as:

v.network?

Alternatively, you can use the help() function, as in:


In [50]:
help(v.network)


Help on method network in module veneer.general:

network() method of veneer.general.Veneer instance
    Retrieve the network from Veneer.
    
    The result will be a Python dictionary in GeoJSON conventions.
    
    The 'features' key of the returned dictionary will be a SearchableList, suitable for querying for
    different properties - eg to filter out just nodes, or links, or catchments.
    
    Example: Find all the node names in the current Source model
    
    v = Veneer()
    network = v.network()
    nodes = network['features'].find_by_feature_type('node')
    node_names = nodes._unique_values('name')

<tab> completion is one of the nice features of Jupyter.

In this way, you can navigate veneer-py (and other Python packages) to discover relevant functions:

v.model.<press tab>

In [ ]:


In [ ]: