Index: wflow-py/Scripts/bmi2runner.py =================================================================== diff -u -r12ea40dc08628f654753679e0972e87b7bb12f7a -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/Scripts/bmi2runner.py (.../bmi2runner.py) (revision 12ea40dc08628f654753679e0972e87b7bb12f7a) +++ wflow-py/Scripts/bmi2runner.py (.../bmi2runner.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -26,67 +26,81 @@ import wflow.pcrut as pcrut import os import time +import sys +import getopt +import logging +def usage(*args): + sys.stdout = sys.stderr + """Way""" + for msg in args: print msg + print __doc__ + sys.exit(0) -""" -Perform command line execution of the model. -""" -configfile = "bmi2runner.ini" +def main(argv=None): + """ + Perform command line execution of the model. + """ -loglevel = "INFO" -combilogger = pcrut.setlogger("bmi2runner.log", "bmi2runner_logging", thelevel=loglevel) + configfile = "bmirunner.ini" -# Construct object and initilize the models -combilogger.info("Starting combined bmi object") -bmiobj = wfbmi.wflowbmi_csdms() -# this line is needed when running from batch script -# os.sys.path.append(os.getcwd() +'\\rtc\\rtc_brantas\\bin\\') + if argv is None: + argv = sys.argv[1:] + if len(argv) == 0: + usage() + return + ######################################################################## + ## Process command-line options # + ######################################################################## + try: + opts, args = getopt.getopt(argv, 'c:l:') + except getopt.error, msg: + usage(msg) -bmiobj.initialize_config(configfile, loglevel=loglevel) -bmiobj.initialize_model() + loglevel=logging.WARN + for o, a in opts: + if o == '-c': configfile = a + if o == '-l': exec "loglevel = logging." + a -# Get and set start and end times -start = bmiobj.get_start_time() -end = bmiobj.get_end_time() -bmiobj.set_start_time(start) -bmiobj.set_end_time(end) -# Update models (if necessary) to start time -bmiobj.update_to_start_time(start) -# Number of steps to run models -ts = bmiobj.get_time_step() -steps = int((end - start) / ts + 1) - -print "start = ", start # time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(start)) -print "start time rtc =", time.strftime( - "%Y-%m-%d %H:%M:%S", time.gmtime(bmiobj.bmimodels["RTC-Tools"].get_start_time()) -) -print "start time wflow =", time.strftime( - "%Y-%m-%d %H:%M:%S", time.gmtime(bmiobj.bmimodels["wflow_sbm"].get_start_time()) -) -print "start time lintul =", time.strftime( - "%Y-%m-%d %H:%M:%S", time.gmtime(bmiobj.bmimodels["wflow_lintul"].get_start_time()) -) - - -cts = bmiobj.currenttimestep -# Loop over the time duration -while cts < steps: - - bmiobj.update() + combilogger = pcrut.setlogger("bmi2runner.log", "bmi2runner_logging", thelevel=loglevel) + + # Construct object and initilize the models + combilogger.info("Starting combined bmi object") + bmiobj = wfbmi.wflowbmi_csdms() + + bmiobj.initialize_config(configfile, loglevel=loglevel) + bmiobj.initialize_model() + + # Get and set start and end times + start = bmiobj.get_start_time() + end = bmiobj.get_end_time() + bmiobj.set_start_time(start) + bmiobj.set_end_time(end) + + # Update models (if necessary) to start time + bmiobj.update_to_start_time(start) + + # Number of steps to run models + ts = bmiobj.get_time_step() + steps = int((end - start) / ts + 1) + cts = bmiobj.currenttimestep + # Loop over the time duration + while cts < steps: + combilogger.info("time is: " + str(bmiobj.get_current_time())) + bmiobj.update() + cts = bmiobj.currenttimestep + + + bmiobj.finalize() + combilogger.info("Finishing run") -# else: -# bmiobj.bmimodels['RTC-Tools'].update() -# bmiobj.bmimodels['wflow_sbm'].update() -# bmiobj.bmimodels['wflow_lintul'].update() -# cts = bmiobj.currenttimestep +if __name__ == "__main__": + main() -bmiobj.bmimodels["RTC-Tools"].finalize() -bmiobj.bmimodels["wflow_sbm"].finalize() -bmiobj.bmimodels["wflow_lintul"].finalize() -combilogger.info("Finishing run") + Index: wflow-py/UnitTests/TestBMI.py =================================================================== diff -u -r12ea40dc08628f654753679e0972e87b7bb12f7a -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/UnitTests/TestBMI.py (.../TestBMI.py) (revision 12ea40dc08628f654753679e0972e87b7bb12f7a) +++ wflow-py/UnitTests/TestBMI.py (.../TestBMI.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -211,7 +211,7 @@ def testbmirun_space_in_name(self): print "Run with update(-1)" bmiobj = bmi.wflowbmi_light() - bmiobj.initialize("wflow sceleton/wflow_sceleton.ini", loglevel=logging.ERROR) + bmiobj.initialize("wflow_sceleton/wflow_sceleton.ini", loglevel=logging.ERROR) et = bmiobj.get_end_time() st = bmiobj.get_start_time() bmiobj.update(et - st) Index: wflow-py/UnitTests/Testwflow_hbv.py =================================================================== diff -u -r12ea40dc08628f654753679e0972e87b7bb12f7a -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/UnitTests/Testwflow_hbv.py (.../Testwflow_hbv.py) (revision 12ea40dc08628f654753679e0972e87b7bb12f7a) +++ wflow-py/UnitTests/Testwflow_hbv.py (.../Testwflow_hbv.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -63,7 +63,7 @@ my_data = wf.genfromtxt(os.path.join(caseName, runId, "run.csv"), delimiter=",") print ("Checking discharge ....") - self.assertAlmostEquals(1092.849374135335, my_data[:, 2].mean(), places=4) + self.assertAlmostEquals(1086.9438420613608, my_data[:, 2].mean(), places=4) if __name__ == "__main__": Index: wflow-py/UnitTests/Testwflow_hbv2.py =================================================================== diff -u -r12ea40dc08628f654753679e0972e87b7bb12f7a -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/UnitTests/Testwflow_hbv2.py (.../Testwflow_hbv2.py) (revision 12ea40dc08628f654753679e0972e87b7bb12f7a) +++ wflow-py/UnitTests/Testwflow_hbv2.py (.../Testwflow_hbv2.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -65,7 +65,7 @@ my_data = wf.genfromtxt(os.path.join(caseName, runId, "run.csv"), delimiter=",") print ("Checking discharge ....") - self.assertAlmostEquals(1837.7918265024821, my_data[:, 2].mean(), places=4) + self.assertAlmostEquals(1811.1795542081197, my_data[:, 2].mean(), places=4) if __name__ == "__main__": Fisheye: Tag 5bc2c6406fea89698faa5d0ca1488dc25760b5e3 refers to a dead (removed) revision in file `wflow-py/UnitTests/Testwflow_sbm2.py'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 5bc2c6406fea89698faa5d0ca1488dc25760b5e3 refers to a dead (removed) revision in file `wflow-py/UnitTests/Testwflow_sbm2bmi.py'. Fisheye: No comparison available. Pass `N' to diff? Index: wflow-py/UnitTests/Testwflow_sbm_dynveg.py =================================================================== diff -u -r36b469410a4a5af24c3902cbebb595e9da83c7bb -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/UnitTests/Testwflow_sbm_dynveg.py (.../Testwflow_sbm_dynveg.py) (revision 36b469410a4a5af24c3902cbebb595e9da83c7bb) +++ wflow-py/UnitTests/Testwflow_sbm_dynveg.py (.../Testwflow_sbm_dynveg.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -60,7 +60,7 @@ os.path.join(caseName, runId, "wbsoil.csv"), delimiter="," ) print("Checking soil water budget ....") - self.assertAlmostEquals(0.0006305182757557759, my_data[:, 2].sum(), places=4) + self.assertAlmostEquals(0.00040802343085033499, my_data[:, 2].sum(), places=4) print("Checking precip sum ....") my_data = wf.genfromtxt(os.path.join(caseName, runId, "P.csv"), delimiter=",") self.assertAlmostEquals(sump, my_data[:, 2].sum()) Index: wflow-py/UnitTests/Testwflow_sbm_example.py =================================================================== diff -u -r36b469410a4a5af24c3902cbebb595e9da83c7bb -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/UnitTests/Testwflow_sbm_example.py (.../Testwflow_sbm_example.py) (revision 36b469410a4a5af24c3902cbebb595e9da83c7bb) +++ wflow-py/UnitTests/Testwflow_sbm_example.py (.../Testwflow_sbm_example.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -47,7 +47,7 @@ ) print("Checking specific runoff ....") - self.assertAlmostEquals(46.839179277420044, my_data[:, 2].sum(), places=4) + self.assertAlmostEquals(46.861992001533508, my_data[:, 2].sum(), places=4) os.chdir(orgdir) Index: wflow-py/UnitTests/Testwflow_sbm_nc.py =================================================================== diff -u -r36b469410a4a5af24c3902cbebb595e9da83c7bb -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/UnitTests/Testwflow_sbm_nc.py (.../Testwflow_sbm_nc.py) (revision 36b469410a4a5af24c3902cbebb595e9da83c7bb) +++ wflow-py/UnitTests/Testwflow_sbm_nc.py (.../Testwflow_sbm_nc.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -62,7 +62,7 @@ os.path.join(caseName, runId, "wbsoil.csv"), delimiter="," ) print("Checking soil water budget ....") - self.assertAlmostEquals(0.002721056049267645, my_data[:, 2].sum(), places=4) + self.assertAlmostEquals(0.0027717916473193327, my_data[:, 2].sum(), places=4) print("Checking precip sum ....") my_data = wf.genfromtxt(os.path.join(caseName, runId, "P.csv"), delimiter=",") self.assertAlmostEquals(sump, my_data[:, 2].sum()) Index: wflow-py/UnitTests/wflow_sbm/wflow_sbm_dynveg.ini =================================================================== diff -u -rb62f2744579dcd9ef1e9033d0cbd32ac2cf4f007 -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/UnitTests/wflow_sbm/wflow_sbm_dynveg.ini (.../wflow_sbm_dynveg.ini) (revision b62f2744579dcd9ef1e9033d0cbd32ac2cf4f007) +++ wflow-py/UnitTests/wflow_sbm/wflow_sbm_dynveg.ini (.../wflow_sbm_dynveg.ini) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -49,7 +49,7 @@ # - hourlyclim: read a map corresponding to the current hour of the day (24 in total) (not implemented yet) # - tss: read a tss file and link to lookupmap (only one allowed) a map using timeinputscalar Sl=inmaps/clim/LCtoSpecificLeafStorage.tbl,tbl,0.5,1,inmaps/clim/LC.map -Kext=inmaps/clim/LCtoSpecificLeafStorage.tbl,tbl,0.5,1,inmaps/clim/LC.map +Kext=inmaps/clim/LCtoExtinctionCoefficient.tbl,tbl,0.5,1,inmaps/clim/LC.map Swood=inmaps/clim/LCtoBranchTrunkStorage.tbl,tbl,0.5,1,inmaps/clim/LC.map LAI=inmaps/clim/LAI,monthlyclim,1.0,1 @@ -138,12 +138,13 @@ self.QCatchmentMM=avgQmm.map - -[outputcsv_0] -samplemap=staticmaps/wflow_landuse.map -self.Transfer=tra_lu.csv - # gauge output +[outputcsv_0] +samplemap=staticmaps/wflow_subcatch.map +self.SoilWatbal=wbsoil.csv +self.SurfaceWatbal=wbsurf.csv +self.Precipitation=P.csv +function=average [outputtss_0] samplemap=staticmaps/wflow_gauges.map self.SurfaceRunoff=run.tss Fisheye: Tag 5bc2c6406fea89698faa5d0ca1488dc25760b5e3 refers to a dead (removed) revision in file `wflow-py/UnitTests/wflow_sceleton/intss/Temp.tss'. Fisheye: No comparison available. Pass `N' to diff? Index: wflow-py/UnitTests/wflow_sceleton/wflow_sceleton_hr.ini =================================================================== diff -u --- wflow-py/UnitTests/wflow_sceleton/wflow_sceleton_hr.ini (revision 0) +++ wflow-py/UnitTests/wflow_sceleton/wflow_sceleton_hr.ini (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -0,0 +1,76 @@ + +[API] +IF = 0,1 +InwaterMM = 2,4 +TEMP=0,3 + + + + +[framework] +# outputformat for the *dynamic* mapstacks (not the states and summary maps) +# 1: pcraster +# 2: numpy +# 3: matlab +outputformat=1 + +[run] +# either a runinfo file or a start and end-time are required +#runinfo=runinfo.xml +starttime= 1995-02-01 00:00:00 +endtime= 1995-02-03 00:00:00 +# required, base timestep of the model +timestepsecs = 3600 +#start model with cold state +reinit=0 +runlengthdetermination=steps + +[model] +modeltype = wflow_sceleton + + +[modelparameters] +# Format: +# name=stack,type,default,verbose[lookupmap_1],[lookupmap_2],lookupmap_n] +# example: +# RootingDepth=monthlyclim/ROOT,monthyclim,100,1 + +# - name - Name of the parameter (internal variable) +# - stack - Name of the mapstack (representation on disk or in mem) relative to case +# - type - Type of parameter (default = static) +# - default - Default value if map/tbl is not present +# - set to 1 to be verbose if a map is missing +# - lookupmap - maps to be used in the lookuptable in the case the type is statictbl + +#Possible types are:: +# - staticmap: Read at startup from map +# - statictbl: Read at startup from tbl +# - tbl: Read each timestep from tbl and at startup +# - timeseries: read map for each timestep +# - monthlyclim: read a map corresponding to the current month (12 maps in total) +# - dailyclim: read a map corresponding to the current day of the year +# - hourlyclim: read a map corresponding to the current hour of the day (24 in total) (not implemented yet) +# - tss: read a tss file and link to lookupmap (only one allowed) a map using timeinputscalar +AltTemperature=intss/Temp.tss,tss,0.0,1,staticmaps/wflow_subcatch.map + + + + + +[layout] +# if set to zero the cell-size is given in lat/long (the default) +sizeinmetres = 0 + +[outputmaps] +self.TSoil=tes +self.AltTemperature=_tes +self.TSoil_mean_5=tesm + +[outputcsv_0] +samplemap=staticmaps/wflow_catchment.map +self.TSoil=tes.csv +self.TSoil_mean_5=tes_mean_5.csv +self.AltTemperature=AltTemp.cvs + +[rollingmean] +self.TSoil=5 Index: wflow-py/wflow/wflow_bmi_combined.py =================================================================== diff -u -r12ea40dc08628f654753679e0972e87b7bb12f7a -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/wflow/wflow_bmi_combined.py (.../wflow_bmi_combined.py) (revision 12ea40dc08628f654753679e0972e87b7bb12f7a) +++ wflow-py/wflow/wflow_bmi_combined.py (.../wflow_bmi_combined.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -122,7 +122,7 @@ # mappingdir = self.datadir + '\\bmi_mapping\\' mappingdir = ( - os.path.join(self.datadir, self.config.get("IdMapping", "folder")) + "\\" + os.path.join(self.datadir, wfbmi.configget(self.config,"IdMapping", "folder", "bmi_mapping")[0]) + "\\" ) self.models = configsection(self.config, "models") Index: wflow-py/wflow/wflow_routing.py =================================================================== diff -u -r12ea40dc08628f654753679e0972e87b7bb12f7a -r5bc2c6406fea89698faa5d0ca1488dc25760b5e3 --- wflow-py/wflow/wflow_routing.py (.../wflow_routing.py) (revision 12ea40dc08628f654753679e0972e87b7bb12f7a) +++ wflow-py/wflow/wflow_routing.py (.../wflow_routing.py) (revision 5bc2c6406fea89698faa5d0ca1488dc25760b5e3) @@ -205,7 +205,10 @@ :var self.SurfaceRunoff: Surface runoff in the kin-wave resrvoir [m^3/s] :var self.WaterLevel: Water level in the kin-wave resrvoir [m] """ - states = ["SurfaceRunoff", "WaterLevelCH", "WaterLevelFP", "ReservoirVolume"] + states = ["SurfaceRunoff", "WaterLevelCH", "WaterLevelFP"] + + if hasattr(self, "ReserVoirSimpleLocs"): + states.append("ReservoirVolume") return states @@ -406,15 +409,27 @@ self.wf_updateparameters() # Check if we have reservoirs - tt = pcr2numpy(self.ReserVoirLocs, 0.0) - self.nrres = tt.max() - if self.nrres > 0: - self.logger.info("A total of " + str(self.nrres) + " reservoirs found.") - self.ReserVoirDownstreamLocs = downstream(self.TopoLdd, self.ReserVoirLocs) + if hasattr(self, "ReserVoirSimpleLocs"): + tt = pcr2numpy(self.ReserVoirSimpleLocs, 0.0) + self.nrresSimple = tt.max() + self.logger.info("A total of " + str(self.nrresSimple) + " reservoirs found.") + areamap = self.reallength * self.reallength + res_area = areatotal(spatial(areamap), self.ReservoirSimpleAreas) + + resarea_pnt = ifthen(boolean(self.ReserVoirSimpleLocs), res_area) + self.ResSimpleArea = ifthenelse( + cover(self.ResSimpleArea, scalar(0.0)) > 0, + self.ResSimpleArea, + cover(resarea_pnt, scalar(0.0)), + ) + + self.ReserVoirDownstreamLocs = downstream(self.TopoLdd, self.ReserVoirSimpleLocs) self.TopoLddOrg = self.TopoLdd self.TopoLdd = lddrepair( - cover(ifthen(boolean(self.ReserVoirLocs), ldd(5)), self.TopoLdd) + cover(ifthen(boolean(self.ReserVoirSimpleLocs), ldd(5)), self.TopoLdd) ) + else: + self.nrresSimple = 0 # Check if we have irrigation areas tt = pcr2numpy(self.IrrigationAreas, 0.0) @@ -608,6 +623,14 @@ self.Inflow_mapstack = self.Dir + configget( self.config, "inputmapstacks", "Inflow", "/inmaps/IF" ) # timeseries for rainfall "/inmaps/IF" # in/outflow locations (abstractions) + + self.P_mapstack = self.Dir + configget( + self.config, "inputmapstacks", "Precipitation", "/inmaps/P" + ) # timeseries for rainfall + + self.PET_mapstack = self.Dir + configget( + self.config, "inputmapstacks", "EvapoTranspiration", "/inmaps/PET" + ) # timeseries for rainfall"/inmaps/PET" # potential evapotranspiration # Meteo and other forcing modelparameters.append( @@ -632,66 +655,26 @@ ) modelparameters.append( self.ParamType( - name="ReserVoirLocs", - stack="staticmaps/wflow_reservoirlocs.map", - type="staticmap", + name="Precipitation", + stack=self.P_mapstack, + type="timeseries", default=0.0, - verbose=False, + verbose=True, lookupmaps=[], ) ) modelparameters.append( self.ParamType( - name="ResTargetFullFrac", - stack="intbl/ResTargetFullFrac.tbl", - type="tblsparse", - default=0.8, - verbose=False, - lookupmaps=["staticmaps/wflow_reservoirlocs.map"], - ) - ) - modelparameters.append( - self.ParamType( - name="ResTargetMinFrac", - stack="intbl/ResTargetMinFrac.tbl", - type="tblsparse", - default=0.4, - verbose=False, - lookupmaps=["staticmaps/wflow_reservoirlocs.map"], - ) - ) - modelparameters.append( - self.ParamType( - name="ResMaxVolume", - stack="intbl/ResMaxVolume.tbl", - type="tblsparse", + name="PotenEvap", + stack=self.PET_mapstack, + type="timeseries", default=0.0, - verbose=False, - lookupmaps=["staticmaps/wflow_reservoirlocs.map"], + verbose=True, + lookupmaps=[], ) ) modelparameters.append( self.ParamType( - name="ResMaxRelease", - stack="intbl/ResMaxRelease.tbl", - type="tblsparse", - default=1.0, - verbose=False, - lookupmaps=["staticmaps/wflow_reservoirlocs.map"], - ) - ) - modelparameters.append( - self.ParamType( - name="ResDemand", - stack="intbl/ResDemand.tbl", - type="tblsparse", - default=1.0, - verbose=False, - lookupmaps=["staticmaps/wflow_reservoirlocs.map"], - ) - ) - modelparameters.append( - self.ParamType( name="IrrigationAreas", stack="staticmaps/wflow_irrigationareas.map", type="staticmap", @@ -731,7 +714,8 @@ self.WaterLevelFP = self.ZeroMap self.SurfaceRunoff = self.ZeroMap self.WaterLevel = self.WaterLevelCH + self.WaterLevelFP - self.ReservoirVolume = self.ResMaxVolume * self.ResTargetFullFrac + if hasattr(self, "ReserVoirSimpleLocs"): + self.ReservoirVolume = self.ResMaxVolume * self.ResTargetFullFrac else: self.logger.info("Setting initial conditions from state files") self.wf_resume(os.path.join(self.Dir, self.instate)) @@ -806,18 +790,24 @@ # The MAx here may lead to watbal error. However, if inwaterMMM becomes < 0, the kinematic wave becomes very slow...... self.InwaterMM = max(0.0, self.InwaterForcing) self.Inwater = self.InwaterMM * self.ToCubic # m3/s + + self.Precipitation = max(0.0, self.Precipitation) # only run the reservoir module if needed - if self.nrres > 0: - self.ReservoirVolume, self.Outflow, self.ResPercFull, self.DemandRelease = simplereservoir( + if self.nrresSimple > 0: + self.ReservoirVolume, self.OutflowSR, self.ResPercFull, self.ResPrecipSR, self.ResEvapSR, self.DemandRelease = simplereservoir( self.ReservoirVolume, self.SurfaceRunoff, + self.ResSimpleArea, self.ResMaxVolume, self.ResTargetFullFrac, self.ResMaxRelease, self.ResDemand, self.ResTargetMinFrac, - self.ReserVoirLocs, + self.ReserVoirSimpleLocs, + self.Precipitation, + self.PotenEvap, + self.ReservoirSimpleAreas, timestepsecs=self.timestepsecs, ) self.OutflowDwn = upstream(