HWRF  trunk@4391
master.py
1 #!/usr/bin/env python
2 
3 ##@namespace pom.master
4 #Main script to for running ocean spin up: Phase1 and Phase2 (also
5 #known as Phase3 and Phase4). It assumes that all parent HWRF
6 #directory tree (CSTREAM, COMIN), exists and the necessary inputs sets
7 #are available in PARMhwrf, FIXhwrf, VITDIR , GFSDIR, LCDIR
8 #directories. I assume that python based HWRF directory structure is
9 #same as in the unix/linux based one. Otherwise, it can be changed
10 #based on the python version.
11 #
12 #@note Please report bugs/questions/comments to bijuthomas(at)mail(dot)uri(dot)edu.
13 #
14 #@author Biju Thomas, GSO, University of Rhode Island on June 12, 2014.
15 #
16 #@author Richard Yablonsky, GSO, University of Rhode Island on 10/1/14
17 #to allow for domains in additional basins.
18 #
19 #@author Richard Yablonsky, GSO, University of Rhode Island on 12/1/14 to
20 #allow for NCODA initialization as an alternative to the GDEM/F-B initialization.
21 
22 import logging
23 from init import Oceanini, fbtr, g3, na, pget, prun, phase, psend
24 from util import dateplushours, ysplitter, logi2int, jn2r
25 from nml import nml
26 from track import get_vitals, track_shorten
27 from exceptions import *
28 
29 # To use default initialization in a given basin, enter "GDEM" after the : below
30 # To use NCODA initialization in a given basin, enter "NCODA" after the : below
31 
32 ##@var oinit_d
33 # Mapping from basin name to initialization method for that basin.
34 oinit_d = {"transatl":"GDEM", "eastpac":"GDEM", "westpac":"GDEM",
35  "northind":"GDEM", "southind":"GDEM", "swpac":"GDEM",
36  "sepac":"GDEM", "southatl":"GDEM"}
37 
38 ##@var odata_d
39 # Mapping from basin letter to the list of available initializations for the basin.
40 odata_d = {"L":("fbtr","natr","idtr"), "E":("g3ep","naep","idep"),
41  "W":("g3wp","nawp","idwp"), "A":("g3ni","nani","idni"),
42  "S":("g3si","nasi","idsi"), "P":("g3sw","nasw","idsw"),
43  "X":("g3se","nase","idse"), "C":("g3ep","naep","idep"),
44  "O":("g3wp","nawp","idwp"), "B":("g3ni","nani","idni"),
45  "U":("g3sw","nasw","idsw"), "T":("g3wp","nawp","idwp"),
46  "Q":("g3sa","nasa","idsa")}
47 
48 ##@var domain_d
49 # Mapping from basin letter to long basin name.
50 domain_d = {"L":"transatl", "E":"eastpac", "W":"westpac",
51  "A":"northind", "S":"southind", "P":"swpac",
52  "X":"sepac", "C":"eastpac", "O":"westpac",
53  "B":"northind", "U":"swpac", "T":"westpac",
54  "Q":"southatl"}
55 
56 def run_init(STORMNAME,STORMID,STARTDATE,
57  EXEChwrf,PARMhwrf,FIXhwrf,VITDIR,GFSDIR,
58  LCDIR,CSTREAM,COMIN,init_method=None,logger=None,
59  fcstlen=None,outstep=None,sync_frequently=False,
60  **kwargs):
61  """!Run the ocean initialization.
62 
63  This is a wrapper around the pom.init module that selects the
64  right ocean initialization for the chosen basin and delivers the
65  output to the specified location.
66 
67  @param STORMNAME Upper-case storm name for filenames (KATRINA)
68  @param STORMID Three character storm number and basin, upper-case (12L)
69  @param STARTDATE Simulation analysis time as a string, YYYYMMDDHH (2005082918)
70  @param EXEChwrf Directory with HWRF executables.
71  @param PARMhwrf Directory with HWRF parameter files.
72  @param FIXhwrf Directory with HWRF fixed files.
73  @param GFSDIR Directory with input files from GFS.
74  @param LCDIR Directory with loop current files
75  @param CSTREAM Directory to place files for the POM forecast to read.
76  @param COMIN HWRF final output directory.
77  @param sync_frequently If True, "sync" is run frequently
78  @param init_method The string name of the initialization method to
79  use. If this is unspecified, a suitable default is chosen. Allowed values: GDEM, NCODA.
80 
81  @param logger a logging.Logger for log messages
82 
83  @param fcstlen forecast length in hours
84  @param outstep output frequency in seconds (an integer)
85 
86  @param kwargs Additional keyword arguments are passed to Oceanini subclass constructors."""
87  assert(GFSDIR.find('pom/output')<0)
88  sync_frequently=bool(sync_frequently)
89  if logger is None: logger=logging.getLogger('pom')
90  if fcstlen is None: fcstlen=126 # forecast length in hours
91  if outstep is None: outstep=86400
92  if outstep<540: outstep=540
93  prtd1=outstep/86400.0
94 
95  (y4,mm,mm1,dd,hh)=ysplitter(STARTDATE)
96  BASIN=STORMID[2].upper()
97  if BASIN == "L":
98  CENTERID = "NHC"
99  DOMAIN = domain_d[BASIN]
100  if init_method is None: init_method=oinit_d[domain_d[BASIN]]
101  if init_method == 'GDEM':
102  GEOVEL = True
103  SSTASIM = True
104  NL = 33
105  ODATA = odata_d[BASIN][0]
106  prep = fbtr("OCEAN",DOMAIN,ODATA, SSTASIM,STORMNAME,STORMID,STARTDATE,
107  EXEChwrf,PARMhwrf,FIXhwrf,LCDIR,GFSDIR,CSTREAM,COMIN,
108  sync_frequently=sync_frequently,**kwargs)
109  elif init_method == 'NCODA':
110  GEOVEL = True
111  SSTASIM = False
112  NL = 34
113  ODATA = odata_d[BASIN][1]
114  prep = na("OCEAN",DOMAIN,ODATA,SSTASIM,STORMNAME,STORMID,STARTDATE,
115  EXEChwrf,PARMhwrf,FIXhwrf,LCDIR,GFSDIR,CSTREAM,COMIN,
116  sync_frequently=sync_frequently,**kwargs)
117  else:
118  msg=("%s:ODATA is NOT Supported" %(oinit_d[domain_d[BASIN]]))
119  logger.critical(msg)
120  raise POMConfigError(msg)
121  (DATA,DATA1) = prep.setpath()
122  ymdh = STARTDATE
123  infiles = pget()
124  infiles.getinp(prep,DATA)
125  runexes = prun()
126  if not runexes.setrun(prep,DATA):
127  msg='setrun failed for L domain prep'
128  logger.warning(msg)
129  raise POMInitFailed(msg)
130  elif BASIN == "E" or BASIN == "C":
131  CENTERID = "NHC"
132  DOMAIN = domain_d[BASIN]
133  if init_method is None: init_method=oinit_d[domain_d[BASIN]]
134  if init_method == 'GDEM':
135  GEOVEL = True
136  SSTASIM = True
137  NL = 73
138  ODATA = odata_d[BASIN][0]
139  prep = g3("OCEAN",DOMAIN,ODATA,SSTASIM,STORMNAME,STORMID,STARTDATE,
140  EXEChwrf,PARMhwrf,FIXhwrf,LCDIR,GFSDIR,CSTREAM,COMIN,
141  sync_frequently=sync_frequently,**kwargs)
142  elif init_method == 'NCODA':
143  GEOVEL = True
144  SSTASIM = False
145  NL = 34
146  ODATA = odata_d[BASIN][1]
147  prep = na("OCEAN",DOMAIN,ODATA,SSTASIM,STORMNAME,STORMID,STARTDATE,
148  EXEChwrf,PARMhwrf,FIXhwrf,LCDIR,GFSDIR,CSTREAM,COMIN,
149  sync_frequently=sync_frequently,**kwargs)
150  else:
151  msg=("%s:ODATA is NOT Supported" %(oinit_d[domain_d[BASIN]]))
152  logger.critical(msg)
153  raise POMConfigError(msg)
154  (DATA,DATA1) = prep.setpath()
155  ymdh = STARTDATE
156  infiles = pget()
157  infiles.getinp(prep,DATA)
158  runexes = prun()
159  if not runexes.setrun(prep,DATA):
160  msg='setrun failed for E domain prep'
161  logger.warning(msg)
162  raise POMInitFailed(msg)
163  elif BASIN in ("W", "A", "S", "P", "X", "O", "B", "U", "T", "Q"):
164  CENTERID = "JTWC"
165  DOMAIN = domain_d[BASIN]
166  if init_method is None: init_method=oinit_d[domain_d[BASIN]]
167  if init_method == 'GDEM':
168  GEOVEL = False
169  SSTASIM = True
170  NL = 73
171  ODATA = odata_d[BASIN][0]
172  prep = g3("OCEAN",DOMAIN,ODATA,SSTASIM,STORMNAME,STORMID,STARTDATE,
173  EXEChwrf,PARMhwrf,FIXhwrf,LCDIR,GFSDIR,CSTREAM,COMIN,
174  sync_frequently=sync_frequently,**kwargs)
175  elif init_method == 'NCODA':
176  GEOVEL = False
177  SSTASIM = False
178  NL = 34
179  ODATA = odata_d[BASIN][1]
180  prep = na("OCEAN",DOMAIN,ODATA,SSTASIM,STORMNAME,STORMID,STARTDATE,
181  EXEChwrf,PARMhwrf,FIXhwrf,LCDIR,GFSDIR,CSTREAM,COMIN,
182  sync_frequently=sync_frequently,**kwargs)
183  else:
184  msg=("%s:ODATA is NOT Supported" %(oinit_d[domain_d[BASIN]]))
185  logger.critical(msg)
186  raise POMConfigError(msg)
187  (DATA,DATA1) = prep.setpath()
188  ymdh = STARTDATE
189  infiles = pget()
190  infiles.getinp(prep,DATA)
191  runexes = prun()
192  if not runexes.setrun(prep,DATA):
193  msg='setrun failed for W/A/S/P/X/O/B/U/T/Q domain prep'
194  logger.warning(msg)
195  raise POMUnsupportedBasin(msg)
196  else:
197  msg=("%s : Domain is NOT Supported" %(STORMID))
198  logger.critical(msg)
199  raise POMUnsupportedBasin(msg)
200 
201  diag = phase("OCEAN",DOMAIN,ODATA,SSTASIM,STORMNAME,STORMID,STARTDATE,
202  EXEChwrf,PARMhwrf,FIXhwrf,LCDIR,GFSDIR,CSTREAM,COMIN,
203  sync_frequently=sync_frequently,**kwargs)
204  (DATA,DATA1) = diag.setpath("PHASE1")
205  namelst=nml()
206  namelst("'MPIPOM-TC:"+STORMNAME+STORMID+"'", STORMNAME,
207  "'"+y4+"-"+mm+"-"+dd+" "+hh+":00:00 +00:00'",0,
208  "'restart.phase0.nc'",2.0,2.0,prtd1,3,0.,logi2int(GEOVEL),NL)
209  namelst.make(DATA1)
210  infiles.getinp(diag,DATA1)
211  if not runexes.setrun(diag,DATA1):
212  msg='setrun failed for diag'
213  logger.warning(msg)
214  raise POMInitFailed(msg)
215  outfiles = psend()
216  prog = phase("OCEAN",DOMAIN,ODATA,SSTASIM,STORMNAME,STORMID,STARTDATE,
217  EXEChwrf,PARMhwrf,FIXhwrf,LCDIR,GFSDIR,CSTREAM,COMIN,
218  sync_frequently=sync_frequently,**kwargs)
219  ymdh = dateplushours(ymdh, -72)
220  (DATA,DATA2) = prog.setpath("PHASE2")
221  (y4,mm,mm1,dd,hh)=ysplitter(ymdh)
222  namelst("'MPIPOM-TC:"+STORMNAME+STORMID+"'", STORMNAME,
223  "'"+y4+"-"+mm+"-"+dd+" "+hh+":00:00 +00:00'",1,
224  "'restart.phase1.nc'",3.0,3.0,prtd1,1,9999.,logi2int(GEOVEL),NL)
225  namelst.make(DATA2)
226  if outfiles.sendout(diag,DATA1,"restart.0001.nc",DATA2,"restart.phase1.nc"):
227  vitfile = jn2r(VITDIR,"syndat_tcvitals." + y4)
228  trackfile = jn2r(DATA2,"track.full")
229  trackshort = jn2r(DATA2,"track")
230  nvit = get_vitals(vitfile, CENTERID, STORMID, y4,trackfile)
231  nvit = track_shorten(trackfile,trackshort,STARTDATE)
232  if nvit >= 2:
233  infiles.getinp(prog,DATA2)
234  if runexes.setrun(prog,DATA2):
235  outfiles.sendout(prog,DATA2,"restart.0001.nc",DATA,"restart.phase2.nc")
236  else:
237  outfiles.sendout(prog,DATA2,"restart.phase1.nc",DATA,"restart.phase2.nc")
238  else:
239  outfiles.sendout(prog,DATA2,"restart.phase1.nc",DATA,"restart.phase2.nc")
240  else:
241  msg='sendout failed'
242  logger.warning(msg)
243  raise POMInitFailed(msg)
244 
245  # Make a namelist for the forecast model as pom.nml in the top-level directory:
246  namelst=nml()
247  (y4,mm,mm1,dd,hh)=ysplitter(STARTDATE)
248  namelst("'MPIPOM-TC:"+STORMNAME+STORMID+"'", STORMNAME,
249  "'"+y4+"-"+mm+"-"+dd+" "+hh+":00:00 +00:00'",1,
250  "'restart.phase2.nc'",9999.,fcstlen/24.,prtd1,1,9999.,logi2int(GEOVEL),NL)
251  namelst.make('.')
252  return True
253 
254 def main(STORMNAME, STORMID, STARTDATE,fcstlen=None):
255  """!Main program for testing the POM initialization outside of the HWRF workflow.
256 
257  @warning Has many hard-coded paths that will need to be changed.
258  @param STORMNAME Upper-case storm name for filenames (KATRINA)
259  @param STORMID Three character storm number and basin, upper-case (12L)
260  @param STARTDATE Simulation analysis time as a string, YYYYMMDDHH (2005082918)
261  @param fcstlen forecast length in hours """
262  EXEChwrf = "/mnt/pan2/projects/hur-uri/Biju.Thomas/trunk/exec/"
263  PARMhwrf ="/mnt/pan2/projects/hur-uri/Biju.Thomas/parm/"
264  FIXhwrf = "/mnt/pan2/projects/hur-uri/Biju.Thomas/fix/"
265 # FIXhwrf = "/mnt/lfs1/projects/hwrf-vd/fix-files/hwrf-20140312-fix/fix/hwrf-pom/"
266  VITDIR = "/mnt/lfs1/projects/hwrf-vd/hwrf-input/SYNDAT/"
267  GFSDIR = "/pan2/projects/hur-uri/Biju.Thomas/ptmp/Biju.Thomas/./DATA/OCEAN/gfs."+STARTDATE+'/'+STARTDATE
268  LCDIR = "/mnt/lfs1/projects/hwrf-vd/hwrf-input/LOOP-CURRENT/"
269  LCDIR = "/lfs1/projects/hwrf-vd/fix-files/hwrf-20130917-fix/fix/loop_curr/"
270  CSTREAM = "/mnt/pan2/projects/hur-uri/Biju.Thomas/ptmp/Biju.Thomas/hwrf"+\
271  "/"+STARTDATE+"/"+STORMID.lower()+"/"+STORMNAME.upper()+\
272  "."+STARTDATE+"/"
273  COMIN = "/mnt/pan2/projects/hur-uri/Biju.Thomas/ptmp/Biju.Thomas/hwrf/com/"+\
274  STARTDATE+"/"+STORMID.lower()+"/"
275  return run_init(STORMNAME,STORMID,STARTDATE,
276  EXEChwrf,PARMhwrf,FIXhwrf,VITDIR,GFSDIR,
277  LCDIR,CSTREAM,COMIN,fcstlen)
278 
def main
Main program for testing the POM initialization outside of the HWRF workflow.
Definition: master.py:254
Raised when an unsupported basin is requested.
Definition: exceptions.py:32
Raised when an impossible configuration is requested, such as an unsupported tropical basin...
Definition: exceptions.py:28
def run_init(STORMNAME, STORMID, STARTDATE, EXEChwrf, PARMhwrf, FIXhwrf, VITDIR, GFSDIR, LCDIR, CSTREAM, COMIN, init_method=None, logger=None, fcstlen=None, outstep=None, sync_frequently=False, kwargs)
Run the ocean initialization.
Definition: master.py:60
Raised when a POM initialization program unexpectedly fails.
Definition: exceptions.py:19