Index: wflow-py/UnitTests/TestBMI.py =================================================================== diff -u -r2c1871f08cd7f185412a558a3b0e4faa4ebd224c -r740bbac5af36b92bf4eee534d79267073205edd2 --- wflow-py/UnitTests/TestBMI.py (.../TestBMI.py) (revision 2c1871f08cd7f185412a558a3b0e4faa4ebd224c) +++ wflow-py/UnitTests/TestBMI.py (.../TestBMI.py) (revision 740bbac5af36b92bf4eee534d79267073205edd2) @@ -11,14 +11,6 @@ class MyTest(unittest.TestCase): - def testbmirun(self): - bmiobj = bmi.wflowbmi_csdms() - bmiobj.initialize('wflow_sceleton/wflow_sceleton.ini',loglevel=logging.ERROR) - - et = bmiobj.get_end_time() - bmiobj.update_until(et) - bmiobj.finalize() - def testbmifuncs(self): bmiobj = bmi.wflowbmi_csdms() @@ -137,8 +129,15 @@ bmiobj.finalize() + def testbmirun(self): + bmiobj = bmi.wflowbmi_csdms() + bmiobj.initialize('wflow_sceleton/wflow_sceleton.ini',loglevel=logging.ERROR) + et = bmiobj.get_end_time() + bmiobj.update_until(et) + bmiobj.finalize() + if __name__ == '__main__': unittest.main() Index: wflow-py/UnitTests/TestBMI_Init.py =================================================================== diff -u --- wflow-py/UnitTests/TestBMI_Init.py (revision 0) +++ wflow-py/UnitTests/TestBMI_Init.py (revision 740bbac5af36b92bf4eee534d79267073205edd2) @@ -0,0 +1,44 @@ +__author__ = 'schelle' + +import unittest +import logging +import wflow.wflow_bmi as bmi +import time +import os +import datetime +""" +Simple test for wflow bmi framework +""" + +class MyTest(unittest.TestCase): + + def testbmiinitfuncs(self): + bmiobj = bmi.wflowbmi_csdms() + + bmiobj.initialize_config('wflow_sceleton/wflow_sceleton.ini',loglevel=logging.ERROR) + print("-------------- Time units: ") + print(bmiobj.get_time_units()) + print("-------------- Default current time: ") + print(datetime.datetime.utcfromtimestamp(bmiobj.get_current_time())) + + print("-------------- Set start time to 5: ") + bmiobj.set_start_time(5 * 86400) + print("-------------- Get current time: ") + print(datetime.datetime.utcfromtimestamp(bmiobj.get_current_time())) + + print("-------------- Get timestep: ") + print(bmiobj.get_time_step()) + print("-------------- get endtime: ") + print(datetime.datetime.utcfromtimestamp(bmiobj.get_end_time())) + print("-------------- set endtime: ") + bmiobj.set_end_time(10.0 * 86400) + print("-------------- get endtime: ") + print(datetime.datetime.utcfromtimestamp(bmiobj.get_end_time())) + + print("-------------- get_var_units: ") + print(bmiobj.get_var_units("") + bmiobj.finalize() + + +if __name__ == '__main__': + unittest.main() Index: wflow-py/UnitTests/Testwflow_sbm_nc.py =================================================================== diff -u --- wflow-py/UnitTests/Testwflow_sbm_nc.py (revision 0) +++ wflow-py/UnitTests/Testwflow_sbm_nc.py (revision 740bbac5af36b92bf4eee534d79267073205edd2) @@ -0,0 +1,66 @@ +__author__ = 'schelle' + +import unittest +import wflow.wflow_sbm as wf +import os +""" +Run sceleton for 10 steps and checks if the outcome is approx that of the reference run +""" + +class MyTest(unittest.TestCase): + + def testapirun_netcfd(self): + startTime = 1 + stopTime = 30 + currentTime = 1 + + # set runid, clonemap and casename. Also define the ini file + runId = "unittest" + configfile="wflow_sbm_nc.ini" + wflow_cloneMap = 'wflow_catchment.map' + caseName="wflow_sbm" + + myModel = wf.WflowModel(wflow_cloneMap, caseName,runId,configfile) + # initialise the framework + dynModelFw = wf.wf_DynamicFramework(myModel, stopTime,startTime) + + # Load model config from files and check directory structure + dynModelFw.createRunId(NoOverWrite=False,level=wf.logging.ERROR) + # Run the initial part of the model (reads parameters and sets initial values) + dynModelFw._runInitial() # Runs initial part + + dynModelFw._runResume() # gets the state variables + sump = 0.0 + for ts in range(startTime,stopTime): + if ts <10: + dynModelFw.wf_setValues('P', 0.0) + elif ts <= 15: + dynModelFw.wf_setValues('P', 10.0) + sump = sump + 10.0 + else: + dynModelFw.wf_setValues('P', 0.0) + + dynModelFw.wf_setValues('PET', 2.0) + dynModelFw.wf_setValues('TEMP', 10.0) + dynModelFw._runDynamic(ts,ts) # runs for all timesteps + dynModelFw.logger.info("Doing step: " + str(ts)) + dynModelFw._runSuspend() # saves the state variables + dynModelFw._wf_shutdown() + + # nore read the csv results acn check of they match the first run + # Sum should be approx c 4.569673676 + my_data = wf.genfromtxt(os.path.join(caseName,runId,"wbsurf.csv"), delimiter=',') + + print("Checking surface water budget ....") + self.assertAlmostEquals(-2.4355218783966848e-06,my_data[:,2].sum()) + my_data = wf.genfromtxt(os.path.join(caseName,runId,"wbsoil.csv"), delimiter=',') + print("Checking soil water budget ....") + self.assertAlmostEquals(0.0004235441451676536,my_data[:,2].sum()) + print("Checking precip sum ....") + my_data = wf.genfromtxt(os.path.join(caseName,runId,"P.csv"), delimiter=',') + self.assertAlmostEquals(sump,my_data[:,2].sum()) + + + +if __name__ == '__main__': + unittest.main() Index: wflow-py/wflow/wf_DynamicFramework.py =================================================================== diff -u -r0c107ad8319af1405fc28d9a192a0d6aced12bdb -r740bbac5af36b92bf4eee534d79267073205edd2 --- wflow-py/wflow/wf_DynamicFramework.py (.../wf_DynamicFramework.py) (revision 0c107ad8319af1405fc28d9a192a0d6aced12bdb) +++ wflow-py/wflow/wf_DynamicFramework.py (.../wf_DynamicFramework.py) (revision 740bbac5af36b92bf4eee534d79267073205edd2) @@ -585,6 +585,7 @@ :return: """ + self.framework_setup = True caseName = self._userModel().caseName runId = self._userModel().runId @@ -844,9 +845,10 @@ if hasattr(self._userModel(),'default_summarymaps'): for a in self._userModel().default_summarymaps(): b = a.replace('self.','') - pcrmap = getattr(self._userModel(),b) - #report( pcrmap , os.path.join(self._userModel().Dir, self._userModel().runId, "outsum", b + ".map" )) - self.reportStatic( pcrmap , os.path.join(self._userModel().Dir, self._userModel().runId, "outsum", b + ".map" ), style=1) + if hasattr(self._userModel(),b): + pcrmap = getattr(self._userModel(),b) + #report( pcrmap , os.path.join(self._userModel().Dir, self._userModel().runId, "outsum", b + ".map" )) + self.reportStatic( pcrmap , os.path.join(self._userModel().Dir, self._userModel().runId, "outsum", b + ".map" ), style=1) # These are the ones in the _sum _average etc sections for a in range(0,len(self.statslst)): @@ -1517,10 +1519,10 @@ gets the end time of the model run :return: current time as seconds since epoch """ + seconds_since_epoch = calendar.timegm(self.datetime_laststep.utctimetuple()) - seconds_since_epoch = calendar.timegm(self.datetime_firststep.utctimetuple()) - return seconds_since_epoch + (self._d_lastTimestep - self._d_firstTimestep) * self._userModel().timestepsecs + return seconds_since_epoch def wf_supplyStartTime(self): """ @@ -1539,10 +1541,15 @@ Output: - current model time (since start of the run) - """ - seconds_since_epoch = calendar.timegm(self.currentdatetime.utctimetuple()) + if hasattr(self._userModel(),"currentdatetime"): + dtt = self._userModel().currentdatetime + else: + dtt = self.currentdatetime + + seconds_since_epoch = calendar.timegm(dtt.utctimetuple()) + return seconds_since_epoch def wf_supplyEpoch(self): @@ -1813,7 +1820,7 @@ if gzipit: Gzip(path,storePath=True) else: - self.NcOutput.savetimestep( self._userModel().currentTimeStep(),variable,var=name,name=longname) + self.NcOutput.savetimestep(self._userModel().currentTimeStep(),variable,var=name,name=longname) elif self.outputFormat == 2: numpy.savez(path,pcr2numpy(variable,-999)) Index: wflow-py/wflow/wflow_bmi.py =================================================================== diff -u -re27d0afdd07a07f344b793be87029591128be64c -r740bbac5af36b92bf4eee534d79267073205edd2 --- wflow-py/wflow/wflow_bmi.py (.../wflow_bmi.py) (revision e27d0afdd07a07f344b793be87029591128be64c) +++ wflow-py/wflow/wflow_bmi.py (.../wflow_bmi.py) (revision 740bbac5af36b92bf4eee534d79267073205edd2) @@ -3,6 +3,7 @@ import os import logging import datetime +import parser import wflow.bmi as bmi import numpy as np @@ -305,17 +306,22 @@ datestrimestr = dateobj.strftime("%Y:%m:%d %H:%M:%S") self.dynModel._userModel().config.set("run",'starttime',datestrimestr) + self.dynModel._userModel().datetime_firststep=dateobj + self.dynModel._userModel().currentdatetime = self.dynModel._userModel().datetime_firststep def set_end_time(self, end_time): """ :param end_time: time in units (seconds) since the epoch :return: """ + dateobj = datetime.datetime.utcfromtimestamp(end_time) datestrimestr = dateobj.strftime("%Y:%m:%d %H:%M:%S") - self.dynModel._userModel().config.set("run",'endtime',datestrimestr) + self.dynModel.datetime_laststep=dateobj + + def get_attribute_names(self): """ Get the attributes of the model return in the form of section_name:attribute_name @@ -428,8 +434,10 @@ Shutdown the library and clean up the model. Uses the default (model configured) state location to also save states. """ - self.dynModel._runSuspend() - self.dynModel._wf_shutdown() + # First check if the seconf initilize_states has run + if hasattr(self.dynModel,"framework_setup"): + self.dynModel._runSuspend() + self.dynModel._wf_shutdown() def get_component_name(self): """