diff --git a/da.rc b/da.rc index 13b5639ef9b7181c3797634be1710837ce1f0b77..04361d0724dd50922bcd5e747531fb3d3f1ff4e7 100644 --- a/da.rc +++ b/da.rc @@ -2,7 +2,7 @@ time.restart : False time.start : 2005-03-05 00:00:00 -time.finish : 2005-03-07 00:00:00 +time.finish : 2005-03-08 00:00:00 time.cycle : 1 time.nlag : 2 dir.da_run : ${HOME}/tmp/test_da diff --git a/da_initexit.py b/da_initexit.py index 302a3f23fb8d65d664be21acc847fc981d5dcd76..f71829ed4edb659c27bef7298190df8f6d23844e 100755 --- a/da_initexit.py +++ b/da_initexit.py @@ -143,12 +143,13 @@ class CycleControl(): self.da_settings['finaldate'] = finaldate self.da_settings['cyclelength'] = cyclelength - msg = "===============================================================" ; logging.info(msg) + msg = "===============================================================" ; logging.info(msg) msg = "DAS start date is %s" % startdate.strftime('%Y-%m-%d %H:%M') ; logging.info(msg) msg = "DAS end date is %s" % enddate.strftime('%Y-%m-%d %H:%M') ; logging.info(msg) msg = "DAS final date is %s" % finaldate.strftime('%Y-%m-%d %H:%M') ; logging.info(msg) msg = "DAS cycle length is %s" % cyclelength ; logging.info(msg) - msg = "===============================================================" ; logging.info(msg) + msg = "DAS restart is %s" % str(self.da_settings['time.restart']) ; logging.info(msg) + msg = "===============================================================" ; logging.info(msg) return None @@ -156,7 +157,7 @@ class CycleControl(): """ Determine how to proceed with this cycle: (a) recover from crash : get the save data from the one-ago folder and replace the da_runtime variables with those from the save dir - (b) restart cycle : get the save data from the one-ago folder and use latest da_runtime variables from the exec dir + (b) restart cycle : use latest da_runtime variables from the exec dir (c) fresh start : set up the required file structure for this simulation """ @@ -168,8 +169,6 @@ class CycleControl(): dummy = self.SetupFileStructure() - dummy = self.IOSaveData(io_option='restore',save_option='full',filter=[]) - dummy = self.RecoverRun() # # case 2: A continuation, this is signaled by rc-item time.restart = True @@ -179,8 +178,6 @@ class CycleControl(): msg = "Restarting filter from previous step" ; logging.info(msg) dummy = self.SetupFileStructure() - - dummy = self.IOSaveData(io_option='restore',save_option='full',filter=[]) # # case 3: A fresh start, this is signaled by rc-item time.restart = False # @@ -252,10 +249,11 @@ class CycleControl(): """ - savedir = os.path.join(self.da_settings['dir.save']) - recoverydir = os.path.join(self.da_settings['dir.save'],'one-ago') + # Move all data from the save/one-ago directory to the save/current directory + + dummy = self.IOSaveData(io_option='restore',save_option='full',filter=[]) -# Replace rc-items with those from the crashed run last rc-file + # Replace rc-items with those from the crashed run last rc-file file_rc_rec = os.path.join(self.da_settings['dir.save'],'da_runtime.rc') rc_rec = rc.read(file_rc_rec) @@ -267,7 +265,7 @@ class CycleControl(): msg = "Replaced rc-items.... " ; logging.debug(msg) msg = "Next cycle start date is %s" % self.da_settings['time.start'] ; logging.debug(msg) - + return None def Finalize(self): @@ -275,9 +273,9 @@ class CycleControl(): Finalize the da cycle, this means writing the save data and rc-files for the next run """ - self.IOSaveData(io_option='store',save_option='full') - self.WriteNewRCfile() - self.SubmitNextCycle() + dummy = self.IOSaveData(io_option='store',save_option='full') + dummy = self.WriteNewRCfile() + dummy = self.SubmitNextCycle() def IOSaveData(self, io_option='restore', save_option='partial',filter=[]): @@ -365,9 +363,12 @@ class CycleControl(): msg = " [skip] .... %s " % file ; logging.debug(msg) continue + if io_option == 'store' and save_option == 'full': - msg = " [move] .... %s " % file ; logging.info(msg) - dummy = shutil.move(file,file.replace(sourcedir,targetdir) ) + #msg = " [move] .... %s " % file ; logging.info(msg) + #dummy = shutil.move(file,file.replace(sourcedir,targetdir) ) + msg = " [copy] .... %s " % file ; logging.info(msg) + dummy = shutil.copy(file,file.replace(sourcedir,targetdir) ) else: msg = " [copy] .... %s " % file ; logging.info(msg) diff --git a/tm5_tools.py b/tm5_tools.py index 43b65e1fe1b160d89487bf5ad4b8316a78e85580..b82b61ae2d532303db2c0893db66fd33c24e5adc 100755 --- a/tm5_tools.py +++ b/tm5_tools.py @@ -126,14 +126,31 @@ class TM5(): """ Modify parts of the tm5 settings, for instance to give control of file locations to the DA shell instead of to the tm5.rc script. + + Note that we replace these values in all {key,value} pairs of the tm5.rc file! + """ for k,v in NewValues.iteritems(): if self.tm_settings.has_key(k): + # keep previous value + v_orig= self.tm_settings[k] + #replace with new self.tm_settings[k] = v + #replace all instances of old with new, but only if it concerns a name of a path!!! + if os.path.exists(str(v)): + for k_old,v_old in self.tm_settings.iteritems(): + if not isinstance(v_old,str): + continue + if str(v_orig) in str(v_old): + v_new = str(v_old).replace(str(v_orig),str(v)) + self.tm_settings[k_old] = v_new + logging.debug('Replaced tm5 rc-item %s ' % k) + else: - logging.debug('Skipped new rc-item %s ' % k) + self.tm_settings[k] = v + logging.debug('Added new tm5 rc-item %s ' % k) def WriteRc(self): @@ -281,7 +298,7 @@ class TM5(): -def Initialize(rc_da_shell): +def DaInitialize(rc_da_shell): """ Prepare a forward model TM5 run, this consists of: @@ -311,12 +328,12 @@ def Initialize(rc_da_shell): NewItems = { - 'time.start' : rc_da_shell['startdate'] , - 'time.final' : rc_da_shell['sample.enddate'] , + 'time.start' : rc_da_shell['time.start'] , + 'time.final' : rc_da_shell['time.sample.end'] , 'rundir' : rc_da_shell['dir.exec.tm5'] , 'outputdir' : rc_da_shell['dir.output'] , - 'savedir' : rc_da_shell['dir.save'] , - 'das.input.dir' : rc_da_shell['dir.input'] + 'savedir' : rc_da_shell['dir.save'] #, + #'das.input.dir' : '/data/CO2/carbontracker/ct08//obsnc/' } if rc_da_shell['time.restart'] == True: NewItems['istart'] = 3 @@ -345,24 +362,30 @@ if __name__ == "__main__": import sys import logging import tools_da as tools + import datetime as dtm tools.StartLogger() - tm=TM5('/Users/peters/Modeling/TM5/ct_new.rc') - tm.WriteRc() - tm.WriteRunRc() - tm.Run() - tm.SaveData() - sys.exit(0) - #dasrc=rc.read('da.rc') + #tm=TM5('/Users/peters/Modeling/TM5/ct_new.rc') + #tm.WriteRc() + #tm.WriteRunRc() + #tm.Run() + #tm.SaveData() + + #sys.exit(0) + + dasrc=rc.read('da.rc') - #dasrc['dir.save']=os.path.join(dasrc['dir.da_run'],'save') - #dasrc['dir.output']=os.path.join(dasrc['dir.da_run'],'output') - #dasrc['dir.exec']=os.path.join(dasrc['dir.da_run'],'exec') + dasrc['time.start'] = dtm.datetime(2005,3,5,0,0,0) + dasrc['time.sample.end'] = dtm.datetime(2005,3,5,6,0,0) + dasrc['dir.save'] = os.path.join(dasrc['dir.da_run'],'save') + dasrc['dir.output'] = os.path.join(dasrc['dir.da_run'],'output') + dasrc['dir.exec'] = os.path.join(dasrc['dir.da_run'],'exec') + dasrc['dir.input'] = os.path.join(dasrc['dir.da_run'],'input') - #tm = Initialize(dasrc) - #tm.Run() + tm = DaInitialize(dasrc) + tm.Run() #tm.SaveData() diff --git a/tools_da.py b/tools_da.py index dffc8c6681a99f009715a7ffa02aa3a226cfab5a..4ce2a6ca76f5e4a126b2c89948a768d83365a1a0 100755 --- a/tools_da.py +++ b/tools_da.py @@ -172,7 +172,7 @@ def SetInterval(CycleInfo,run='forecast'): enddate = AdvanceTime(startdate,cyclelen) - CycleInfo.da_settings['sample.enddate'] = enddate + CycleInfo.da_settings['time.sample.end'] = enddate msg = "New simulation interval set : " ; logging.info(msg) msg = " start date : %s " % startdate.strftime('%F %H:%M') ; logging.info(msg) @@ -262,19 +262,31 @@ def RunForecastModel(CycleInfo,step='forecast'): msg = "Using %s as forecast model" % model.identifier ; logging.debug(msg) -# Prepare everything needed to run the forward model + # Prepare everything needed to run the forward model dummy = SetInterval(CycleInfo,step) - executable = model.Initialize(CycleInfo.da_settings) + # Before a forecast step, save all the data to a save/tmp directory so we can later recover it before the propagation step. + # This is especially important for: + # (i) The save*tm5.hdf data which holds the background CO2 concentrations. This is needed to run the model one cycle forward + # (ii) The random numbers (or the seed for the random number generator) so we can recreate the ensembles if needed + + if step =='forecast': + dummy = CycleInfo.IOSaveData(io_option='store',save_option='partial',filter=[]) + msg = "All restart data have been copied to the save/tmp directory for future use" ; logging.debug(msg) + elif step =='advance': + dummy = CycleInfo.IOSaveData(io_option='restore',save_option='partial',filter=[]) + msg = "All restart data have been recovered from the save/tmp directory, this "+ \ + "resets the filter to %s "%CycleInfo.da_settings['time.start'] ; logging.debug(msg) + +# Call a special method that creates a model instance, and overwrites the model settings with those from thr DA cycle + + executable = model.DaInitialize(CycleInfo.da_settings) # Run the forward model status = executable.Run() - if step =='advance': - status = executable.SaveData() - ########################################### RETURN CONTROL TO DA SHELL ######################################### return status