Commit cfc6bb67 authored by Peters, Wouter's avatar Peters, Wouter
Browse files

model now does full start, restart, and recover using new classes TM5 and...

model now does full start, restart, and recover using new classes TM5 and CycleControl, IOSaveData implemented correctly also
parent 37baecb4
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
time.restart : False time.restart : False
time.start : 2005-03-05 00:00:00 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.cycle : 1
time.nlag : 2 time.nlag : 2
dir.da_run : ${HOME}/tmp/test_da dir.da_run : ${HOME}/tmp/test_da
......
...@@ -148,6 +148,7 @@ class CycleControl(): ...@@ -148,6 +148,7 @@ class CycleControl():
msg = "DAS end date is %s" % enddate.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 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 = "DAS cycle length is %s" % cyclelength ; logging.info(msg)
msg = "DAS restart is %s" % str(self.da_settings['time.restart']) ; logging.info(msg)
msg = "===============================================================" ; logging.info(msg) msg = "===============================================================" ; logging.info(msg)
return None return None
...@@ -156,7 +157,7 @@ class CycleControl(): ...@@ -156,7 +157,7 @@ class CycleControl():
""" Determine how to proceed with this cycle: """ 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 (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 (c) fresh start : set up the required file structure for this simulation
""" """
...@@ -168,8 +169,6 @@ class CycleControl(): ...@@ -168,8 +169,6 @@ class CycleControl():
dummy = self.SetupFileStructure() dummy = self.SetupFileStructure()
dummy = self.IOSaveData(io_option='restore',save_option='full',filter=[])
dummy = self.RecoverRun() dummy = self.RecoverRun()
# #
# case 2: A continuation, this is signaled by rc-item time.restart = True # case 2: A continuation, this is signaled by rc-item time.restart = True
...@@ -179,8 +178,6 @@ class CycleControl(): ...@@ -179,8 +178,6 @@ class CycleControl():
msg = "Restarting filter from previous step" ; logging.info(msg) msg = "Restarting filter from previous step" ; logging.info(msg)
dummy = self.SetupFileStructure() 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 # case 3: A fresh start, this is signaled by rc-item time.restart = False
# #
...@@ -252,10 +249,11 @@ class CycleControl(): ...@@ -252,10 +249,11 @@ class CycleControl():
""" """
savedir = os.path.join(self.da_settings['dir.save']) # Move all data from the save/one-ago directory to the save/current directory
recoverydir = os.path.join(self.da_settings['dir.save'],'one-ago')
# Replace rc-items with those from the crashed run last rc-file dummy = self.IOSaveData(io_option='restore',save_option='full',filter=[])
# 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') file_rc_rec = os.path.join(self.da_settings['dir.save'],'da_runtime.rc')
rc_rec = rc.read(file_rc_rec) rc_rec = rc.read(file_rc_rec)
...@@ -275,9 +273,9 @@ class CycleControl(): ...@@ -275,9 +273,9 @@ class CycleControl():
Finalize the da cycle, this means writing the save data and rc-files for the next run 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') dummy = self.IOSaveData(io_option='store',save_option='full')
self.WriteNewRCfile() dummy = self.WriteNewRCfile()
self.SubmitNextCycle() dummy = self.SubmitNextCycle()
def IOSaveData(self, io_option='restore', save_option='partial',filter=[]): def IOSaveData(self, io_option='restore', save_option='partial',filter=[]):
...@@ -365,9 +363,12 @@ class CycleControl(): ...@@ -365,9 +363,12 @@ class CycleControl():
msg = " [skip] .... %s " % file ; logging.debug(msg) msg = " [skip] .... %s " % file ; logging.debug(msg)
continue continue
if io_option == 'store' and save_option == 'full': if io_option == 'store' and save_option == 'full':
msg = " [move] .... %s " % file ; logging.info(msg) #msg = " [move] .... %s " % file ; logging.info(msg)
dummy = shutil.move(file,file.replace(sourcedir,targetdir) ) #dummy = shutil.move(file,file.replace(sourcedir,targetdir) )
msg = " [copy] .... %s " % file ; logging.info(msg)
dummy = shutil.copy(file,file.replace(sourcedir,targetdir) )
else: else:
msg = " [copy] .... %s " % file ; logging.info(msg) msg = " [copy] .... %s " % file ; logging.info(msg)
......
...@@ -126,14 +126,31 @@ class TM5(): ...@@ -126,14 +126,31 @@ class TM5():
""" """
Modify parts of the tm5 settings, for instance to give control of file locations to the DA shell 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. 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(): for k,v in NewValues.iteritems():
if self.tm_settings.has_key(k): if self.tm_settings.has_key(k):
# keep previous value
v_orig= self.tm_settings[k]
#replace with new
self.tm_settings[k] = v 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) logging.debug('Replaced tm5 rc-item %s ' % k)
else: 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): def WriteRc(self):
...@@ -281,7 +298,7 @@ class TM5(): ...@@ -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: Prepare a forward model TM5 run, this consists of:
...@@ -311,12 +328,12 @@ def Initialize(rc_da_shell): ...@@ -311,12 +328,12 @@ def Initialize(rc_da_shell):
NewItems = { NewItems = {
'time.start' : rc_da_shell['startdate'] , 'time.start' : rc_da_shell['time.start'] ,
'time.final' : rc_da_shell['sample.enddate'] , 'time.final' : rc_da_shell['time.sample.end'] ,
'rundir' : rc_da_shell['dir.exec.tm5'] , 'rundir' : rc_da_shell['dir.exec.tm5'] ,
'outputdir' : rc_da_shell['dir.output'] , 'outputdir' : rc_da_shell['dir.output'] ,
'savedir' : rc_da_shell['dir.save'] , 'savedir' : rc_da_shell['dir.save'] #,
'das.input.dir' : rc_da_shell['dir.input'] #'das.input.dir' : '/data/CO2/carbontracker/ct08//obsnc/'
} }
if rc_da_shell['time.restart'] == True: NewItems['istart'] = 3 if rc_da_shell['time.restart'] == True: NewItems['istart'] = 3
...@@ -345,24 +362,30 @@ if __name__ == "__main__": ...@@ -345,24 +362,30 @@ if __name__ == "__main__":
import sys import sys
import logging import logging
import tools_da as tools import tools_da as tools
import datetime as dtm
tools.StartLogger() 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()
#dasrc['dir.save']=os.path.join(dasrc['dir.da_run'],'save') #sys.exit(0)
#dasrc['dir.output']=os.path.join(dasrc['dir.da_run'],'output')
#dasrc['dir.exec']=os.path.join(dasrc['dir.da_run'],'exec')
#tm = Initialize(dasrc) dasrc=rc.read('da.rc')
#tm.Run()
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 = DaInitialize(dasrc)
tm.Run()
#tm.SaveData() #tm.SaveData()
......
...@@ -172,7 +172,7 @@ def SetInterval(CycleInfo,run='forecast'): ...@@ -172,7 +172,7 @@ def SetInterval(CycleInfo,run='forecast'):
enddate = AdvanceTime(startdate,cyclelen) 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 = "New simulation interval set : " ; logging.info(msg)
msg = " start date : %s " % startdate.strftime('%F %H:%M') ; logging.info(msg) msg = " start date : %s " % startdate.strftime('%F %H:%M') ; logging.info(msg)
...@@ -262,19 +262,31 @@ def RunForecastModel(CycleInfo,step='forecast'): ...@@ -262,19 +262,31 @@ def RunForecastModel(CycleInfo,step='forecast'):
msg = "Using %s as forecast model" % model.identifier ; logging.debug(msg) 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) 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 # Run the forward model
status = executable.Run() status = executable.Run()
if step =='advance':
status = executable.SaveData()
########################################### RETURN CONTROL TO DA SHELL ######################################### ########################################### RETURN CONTROL TO DA SHELL #########################################
return status return status
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment