In the ini file example below several variables are configured to be available via the API. For most settings this only defines what the API will expose to the outside world. However, if you specify 0 (input) as a role for one of the forcing variables the wf_readmap function will no longer read maps from disk for that variable but will return the contents of that variable via the API.
The API section specifies variables that are exposed via the ere. Use the following convention:
variable_name_in_model=variable_role,variable_unit
role: 0 = input (to the model)
1 = is output (from the model)
2 = input/output (state information)
3 = model parameter
unit: 0 = mm/timestep
1 = m^3/sec
2 = m
3 = degree Celcius
4 = mm
5 = -
Use role 0 for input maps to the model (those that are normally read from disk), role 1 for outputs, role 2 for state variables and role3 for model parameters.
# Model parameters and settings
[model]
AnnualDischarge=2290
# Alpha for wiver-width estimation 5 for mountain stream 60 for the river rhine
Alpha=120
ModelSnow=1
ScalarInput=0
InterpolationMethod=inv
Tslice=1
UpdMaxDist=300000.0
# Specify variables that are exposed via the API here. Use the following
# convention:
# variable_name_in_model=variable_role,variable_unit
# role: 0 = input (to the model)
# 1 = is output (from the model)
# 2 = input/output (state information)
# 3 = model parameter
# unit: 0 = mm/timestep
# 1 = m^3/sec
# 2 = m
# 3 = degree Celcius
# 4 = mm
# 5 = -
#
[API]
FreeWater=2,4
SoilMoisture=2,4
UpperZoneStorage=2,4
LowerZoneStorage=2,4
InterceptionStorage=2,4
SurfaceRunoff=2,1
WaterLevel=2,2
DrySnow=2,4
Percolation=1,0
ForecQ_qmec=0,1
PERC=3,5
FC=3,4
# Below are the forcing variables. By putting these here you MUST
# supply them via the API, if not these will default to 0.0
#P=0,0
PET=0,0
TEMP=0,3
[framework]
#debug=1
debug=0
[misc]
#mapSaveInterval=365
[layout]
# if set to zero the cell-size is given in lat/long (the default)
sizeinmetres = 0
[outputmaps]
#self.OldKinWaveVolume=vol
#self.WaterLevel=lev
# List all timeseries in tss format to save in this section. Timeseries are
# produced as averages per subcatchment.
[outputtss]
# self.OldKinWaveVolume=vol
# self.MassBalKinWave=mkin
# self.DrySnow=sno
# self.LowerZoneStorage=low
# self.UpperZoneStorage=upp
# Temperature=tem
# self.BaseFlow=bas
# self.QuickFlow=qui
# self.Percolation=per
# ActEvap=act
# IntEvap=int
# PotEvaporation=pot
Example of how to use the framework to control the wflow_* models from other software, in this case a python script.
In this example case the controlling piece of software (this script) provides the forcing data using the API. It also interrogates the model to get results and display them on screen.
Each wflow_* model should provide a def supplyVariableNamesAndRoles function that returns a list of variables and their roles. This function can than be used by the controlling program to interrogate the model.
Some important things to consider:
"""
Controlling the model via the API
---------------------------------
Example of how to use the framework to control the wflow\_\* models
from other software, in this case a python script.
In this example case the controlling piece of software (this script)
provides the forcing data using the API. It also interrogates the model
to get results and display them on screen.
Each wflow\_\* model should provide a def supplyVariableNamesAndRoles function
that returns a list of variables and their roles. This function can than
be used by the controlling program to interrogate the model.
Some important things to consider:
+ when initialzing the framework you must do so for the maximum number of \
timesteps you want to run the model for. This is needed for the pcraster\
timeseries output functions.
+ the framework internally saves the state variable for the last timesteps. As\
such it is possible to redo the previous timesteps after calling the \
quickresume function. If you want to go back more than one timesteps you \
will need to call the normal resume function wich will restore the states \
to the last time the suspend function was call. Administering this is left \
to the controlling application.
+ Inputs (forcing variables) must be set at the start of a timesteps, results\
should be read after each timestep.
"""
from wflow_hbv import *
npmap0 = []
ltt = []
def main():
global npmap0
global ltt
# define start and stop time of the run
startTime = 1
stopTime = 5
currentTime = 1
# set runid, cl;onemap and casename. Also define the ini file
runId = "memtest"
configfile="wflow_hbv_mem.ini"
wflow_cloneMap = 'wflow_subcatch.map'
caseName="../../../examples/wflow_rhine_hbv"
# Mske a usermodel object
myModel = WflowModel(wflow_cloneMap, caseName,runId,configfile)
# initialise the framework
dynModelFw = wf_DynamicFramework(myModel, stopTime,startTime)
# Load model config from files and check directory structure
dynModelFw.createRunId(NoOverWrite=False)
# Run the initial part of the model (reads parameters and sets initial values)
dynModelFw._runInitial() # Runs initial part
dynModelFw._runResume() # gets the state variables
# Get list of variables supplied by the model
dd = dynModelFw.wf_supplyVariableNamesAndRoles()
print dd
dynModelFw.wf_setValueLdd("TopoLdd",5.0,6.46823,51.6821)
npmap0 = dynModelFw.wf_supplyMapAsNumpy("TopoLdd")
ltt = dynModelFw.wf_supplyMapAsList("SurfaceRunoff")
for ts in range(startTime,stopTime):
# Get value at pit
inflowQ = dynModelFw.wf_supplyScalar("SurfaceRunoff",6.46823,51.6821)
outflowQ = dynModelFw.wf_supplyScalar("SurfaceRunoff",6.43643,51.7226)
# Ass inflow to outflow
#dynModelFw.wf_setValue("ForecQ_qmec", -1.0 * inflowQ ,6.46823,51.6821)
Resoutflow = inflowQ
dynModelFw.wf_setValue("ForecQ_qmec",Resoutflow ,6.43643,51.7226)
dynModelFw.wf_setValues("P",scalar(ts) * 0.1)
#dynModelFw.wf_setValue("ForecQ_qmec",inflowQ * 1000 ,6.47592,51.7288)
# update runoff ONLY NEEDED IF YOU FIDDLE WITH THE KIN_WAVE RESERVOIR
myModel.updateRunOff()
dynModelFw._runDynamic(ts,ts) # runs for all timesteps
#dynModelFw.wf_setValue("SurfaceRunoff",0.0,6.46823,51.6821)
#dynModelFw.wf_setValue("SurfaceRunoff",0.0,6.11535,51.8425)
npmap0 = dynModelFw.wf_supplyMapAsNumpy("ForecQ_qmec")
npmap1 = dynModelFw.wf_supplyMapAsNumpy("P")
dynModelFw.wf_setValuesAsNumpy("xx",npmap1)
npmap2 = dynModelFw.wf_supplyMapAsNumpy("DezeBestaatNiet")
#myModel.updateRunOff()
dynModelFw._runSuspend() # saves the state variables
os.chdir("../../")
if __name__ == "__main__":
main()