Index: wflow-py/Scripts/mapstack.py =================================================================== diff -u --- wflow-py/Scripts/mapstack.py (revision 0) +++ wflow-py/Scripts/mapstack.py (revision 2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8) @@ -0,0 +1,230 @@ +#!/usr/bin/python + +""" +mapstack.py - process mapstacks +-------------------------------- + +Usage: +mapstack -c inifile -C casename --clone clonemap + + + -c name of the config file (in the case directory) + +$Author: schelle $ +$Id: wflow_sceleton.py 898 2014-01-09 14:47:06Z schelle $ +$Rev: 898 $ +""" + +import numpy +import os +import os.path +import shutil, glob +import getopt + +from wflow.wf_DynamicFramework import * +from wflow.wflow_adapt import * +#import scipy + + + +def usage(*args): + sys.stdout = sys.stderr + for msg in args: print msg + print __doc__ + sys.exit(0) + +class WflowModel(DynamicModel): + """ + The user defined model class. This is your work! + """ + + def __init__(self, cloneMap,Dir,RunDir,configfile): + """ + *Required* + + The init function **must** contain what is shown below. Other functionality + may be added by you if needed. + + """ + DynamicModel.__init__(self) + setclone(os.path.join(Dir,cloneMap)) + self.runId=RunDir + self.caseName=Dir + self.Dir = Dir + self.configfile = configfile + + + def parameters(self): + """ + List all the parameters (both static and forcing here). Use the wf_updateparameters() + function to update them in the initial section (static) and the dynamic section for + dynamic parameters and forcing date. + + Possible parameter types are: + + + staticmap: Read at startup from map + + statictbl: Read at startup from tbl, fallback to map (need Landuse, Soil and TopoId (subcatch) maps! + + 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) + + + :return: List of modelparameters + """ + modelparameters = [] + + return modelparameters + + def stateVariables(self): + """ + *Required* + + Returns a list of state variables that are essential to the model. + This list is essential for the resume and suspend functions to work. + + This function is specific for each model and **must** be present. This is + where you specify the state variables of you model. If your model is stateless + this function must return and empty array (states = []) + + In the simple example here the TSoil variable is a state + for the model. + + """ + states = [] + + return states + + + def supplyCurrentTime(self): + """ + *Optional* + + Supplies the current time in seconds after the start of the run + This function is optional. If it is not set the framework assumes + the model runs with daily timesteps. + + Output: + + - time in seconds since the start of the model run + + """ + + return self.currentTimeStep() * int(configget(self.config,'model','timestepsecs','86400')) + + + def initial(self): + + """ + *Required* + + Initial part of the model, executed only once. It reads all static model + information (parameters) and sets-up the variables used in modelling. + + This function is required. The contents is free. However, in order to + easily connect to other models it is advised to adhere to the directory + structure used in the other models. + + """ + #: pcraster option to calculate with units or cells. Not really an issue + #: in this model but always good to keep in mind. + setglobaloption("unittrue") + + + self.timestepsecs = int(configget(self.config,'model','timestepsecs','86400')) + self.basetimestep=86400 + # Reads all parameter from disk + self.wf_updateparameters() + + + + def resume(self): + """ + *Required* + + This function is required. Read initial state maps (they are output of a + previous call to suspend()). The implementation shown here is the most basic + setup needed. + + """ + pass + + def suspend(self): + """ + *Required* + + Suspends the model to disk. All variables needed to restart the model + are saved to disk as pcraster maps. Use resume() to re-read them + + This function is required. + + """ + + self.wf_suspend(self.Dir) + + def dynamic(self): + """ + *Required* + + This is where all the time dependent functions are executed. Time dependent + output should also be saved here. + """ + self.logger.debug("Processing step: " + str(self.currentTimeStep())) + self.wf_updateparameters() # read the temperature map for each step (see parameters()) + + +# The main function is used to run the program from the command line + +def main(argv=None): + """ + *Optional but needed it you want to run the model from the command line* + + Perform command line execution of the model. This example uses the getopt + module to parse the command line options. + + The user can set the caseName, the runDir, the timestep and the configfile. + """ + global multpars + caseName = "default" + runId = "run_default" + configfile="mapstack.ini" + _lastTimeStep = 10 + _firstTimeStep = 1 + timestepsecs=86400 + wflow_cloneMap = 'wflow_subcatch.map' + + # This allows us to use the model both on the command line and to call + # the model usinge main function from another python script. + + if argv is None: + argv = sys.argv[1:] + if len(argv) == 0: + usage() + return + + opts, args = getopt.getopt(argv, 'C:S:T:c:s:R:',['clone=']) + + for o, a in opts: + if o == '-C': caseName = a + if o == '-R': runId = a + if o == '-c': configfile = a + if o == '-s': timestepsecs = int(a) + if o == '-T': _lastTimeStep=int(a) + if o == '-S': _firstTimeStep=int(a) + if o == '--clone': wflow_cloneMap= a + + if (len(opts) <=1): + usage() + + myModel = WflowModel(wflow_cloneMap, caseName,runId,configfile) + dynModelFw = wf_DynamicFramework(myModel, _lastTimeStep,firstTimestep=_firstTimeStep) + dynModelFw.createRunId(NoOverWrite=False,level=logging.DEBUG) + dynModelFw._runInitial() + dynModelFw._runResume() + dynModelFw._runDynamic(_firstTimeStep,_lastTimeStep) + dynModelFw._runSuspend() + dynModelFw._wf_shutdown() + + +if __name__ == "__main__": + main() Index: wflow-py/Scripts/wflow_prepare_step2.py =================================================================== diff -u -r19ba123a81340a60d1901a26ad6b0af20496b933 -r2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8 --- wflow-py/Scripts/wflow_prepare_step2.py (.../wflow_prepare_step2.py) (revision 19ba123a81340a60d1901a26ad6b0af20496b933) +++ wflow-py/Scripts/wflow_prepare_step2.py (.../wflow_prepare_step2.py) (revision 2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8) @@ -31,6 +31,7 @@ import getopt import ConfigParser import sys +import numpy as np tr.Verbose=1 @@ -249,8 +250,8 @@ # make subcatchments #os.system("col2map --clone " + step2dir + "/cutout.map gauges.col " + step2dir + "/wflow_gauges.map") - exec "X=tr.array(" + gauges_x + ")" - exec "Y=tr.array(" + gauges_y + ")" + exec "X=np.array(" + gauges_x + ")" + exec "Y=np.array(" + gauges_y + ")" tr.setglobaloption("unittrue") Index: wflow-py/UnitTests/TestBMI.py =================================================================== diff -u -reb5531aa1d2fd1da6de0ad4d35e1a4b63bc70951 -r2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8 --- wflow-py/UnitTests/TestBMI.py (.../TestBMI.py) (revision eb5531aa1d2fd1da6de0ad4d35e1a4b63bc70951) +++ wflow-py/UnitTests/TestBMI.py (.../TestBMI.py) (revision 2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8) @@ -54,6 +54,9 @@ print("-------------- Current time: ") print(bmiobj.get_current_time()) + print("-------------- Grid shape: ") + print(bmiobj.get_grid_shape('Altitude')) + print("-------------- End time: ") print(bmiobj.get_end_time()) Index: wflow-py/wflow/wf_DynamicFramework.py =================================================================== diff -u -rf0f9c075d66820b08dfbce3e1ab773b04a84df83 -r2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8 --- wflow-py/wflow/wf_DynamicFramework.py (.../wf_DynamicFramework.py) (revision f0f9c075d66820b08dfbce3e1ab773b04a84df83) +++ wflow-py/wflow/wf_DynamicFramework.py (.../wf_DynamicFramework.py) (revision 2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8) @@ -325,6 +325,7 @@ if par.type == 'timeseries': if not hasattr(self._userModel(),par.name): self._userModel().logger.info("Adding " + par.name + " to model.") + theparmap = self.wf_readmap(os.path.join(self._userModel().caseName,par.stack), par.default,verbose=par.verbose) theparmap = cover(theparmap,par.default) setattr(self._userModel(),par.name,theparmap) @@ -558,7 +559,7 @@ self.ncoutfile = configget(self._userModel().config,'framework','netcdfoutput',"None") - # Set teh re-init hint fro the local model + # Set the re-init hint for the local model self.reinit = int(configget(self._userModel().config,'run','reinit',str(self.reinit))) self._userModel().reinit = self.reinit # Now finally set the start end time. First check if set in ini otherwise check if the ini defines @@ -620,7 +621,7 @@ for sttype in _type.availtypes: _maps = configsection(self._userModel().config,"summary_" + sttype) for thismap in _maps: - thismapname = caseName + "/" + runId + "/outsum/" + self._userModel().config.get("summary_" + sttype,thismap) + thismapname = os.path.join(caseName,runId,'outsum',self._userModel().config.get("summary_" + sttype,thismap)) thismap = thismap.split('self.')[1] self.statslst.append(wf_sumavg(thismap,mode=sttype,filename=thismapname)) Index: wflow-py/wflow/wf_netcdfio.py =================================================================== diff -u -rbf65fb743568cb9c44c6e4d96791dcc1c332a015 -r2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8 --- wflow-py/wflow/wf_netcdfio.py (.../wf_netcdfio.py) (revision bf65fb743568cb9c44c6e4d96791dcc1c332a015) +++ wflow-py/wflow/wf_netcdfio.py (.../wf_netcdfio.py) (revision 2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8) @@ -124,7 +124,6 @@ globmetadata.update(metadata) - prepare_nc(self.ncfile,timeList,x,y,globmetadata,logger,Format=netcdfformat) Index: wflow-py/wflow/wflow_bmi.py =================================================================== diff -u -r043cc93152a2b84e31b26a39f523e4930957b981 -r2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8 --- wflow-py/wflow/wflow_bmi.py (.../wflow_bmi.py) (revision 043cc93152a2b84e31b26a39f523e4930957b981) +++ wflow-py/wflow/wflow_bmi.py (.../wflow_bmi.py) (revision 2aef8b1c3a3d5c674d3112cc60a67f20594c2cb8) @@ -555,7 +555,7 @@ dim = self.dynModel.wf_supplyGridDim() #[ Xul, Yul, xsize, ysize, rows, cols] - return dim[4,5] + return [dim[4], dim[5]] def get_grid_spacing(self, long_var_name): """ @@ -565,8 +565,9 @@ :return: The size of a grid cell for each of the dimensions of the given variable, e.g. [width, height]: for a 2D grid cell. """ - raise NotImplementedError + return self.dynModel.wf_supplyGridDim()[2:4] + def get_grid_origin(self, long_var_name): """ gets the origin of the model grid.