HWRF  trunk@4391
ww3.py
1 """This module handles WW3 related scripts for HWRF system."""
2 
3 __all__ = ['WW3Init', 'WRFWW3POM', 'WW3Post']
4 
5 import os, re
9 
10 from produtil.datastore import FileProduct, RUNNING, COMPLETED, FAILED, UpstreamFile
11 from produtil.fileop import make_symlink, deliver_file, wait_for_files
12 from produtil.cd import NamedDir
13 from produtil.run import runstr, checkrun, exe, bigexe, alias
14 from hwrf.numerics import to_datetime, to_datetime_rel, to_fraction, to_timedelta
15 from hwrf.exceptions import WaveInitFailed, WW3InputError
16 
17 prodnames={
18  'mod_def': ( './mod_def.ww3', '{com}/{out_prefix}.mod_def.ww3' ),
19  'wind': ( './wind.ww3', '{com}/{out_prefix}.wind.ww3' ),
20  'current': ( './current.ww3', '{com}/{out_prefix}.current.ww3' ),
21  'restart': ( './restart.ww3', '{com}/{out_prefix}.restart_init.ww3' ),
22  'ww3_shel': ( './ww3_shel.inp', '{com}/{out_prefix}.ww3_shel.inp' ) }
23 
24 ########################################################################
26  def __init__(self,dstore,conf,section,taskname=None,fcstlen=126,
27  outstep=21600, rststep=21600, **kwargs):
28  """Creates a WW3Init
29  dstore - the produtil.datastore.Datastore to use
30  conf - the HWRFConfig to use
31  section - the section name for this task
32  taskname - the task name. Default: section
33  fcstlen - the forecast length in hours
34  outstep - the output step in seconds
35  rststep - the restart output step in seconds
36  Other keyword arguments are passed to the superclass constructor."""
37  super(WW3Init,self).__init__(dstore,conf,section,taskname=taskname,**kwargs)
38  self._make_products()
39  self.fcstlen=float(fcstlen)
40  self.outstep=int(outstep)
41  self.rststep=int(rststep)
42  def _make_products(self):
43  """Creates FileProduct objects for all output files. The
44  outdir is the directory to which the pom package output its
45  final files."""
46  self._products=dict()
47  atime=hwrf.numerics.to_datetime(self.conf.cycle)
48  with self.dstore.transaction():
49  for prodname,filepaths in prodnames.iteritems():
50  (localpath,compath)=filepaths
52  self.dstore,prodname,self.taskname)
53  prod.location=self.timestr(compath,atime,atime)
54  prod['localpath'] = localpath
55  self._products[prodname]=( prod,localpath )
56  def products(self,name=None,**kwargs):
57  """Iterate over all products."""
58  for prodname,stuff in self._products.iteritems():
59  (prod,localpath)=stuff
60  if name is None or name==prod.prodname:
61  yield prod
62 
63  def inputiter(self):
64  atime=to_datetime(self.conf.cycle)
65  etime=to_datetime_rel(3600*self.fcstlen,atime)
66  interval=to_fraction(self.confint('input_step',6*3600))
67 
68  dataset=self.confstr('gfs_dataset','gfs')
69  item=self.confstr('gfs_item','gfs')
70 
71  epsilon=to_timedelta(interval/10)
72  ende=to_datetime_rel(epsilon,etime)
73  when=atime
74  while when<ende:
75  yield dict(self.taskvars,dataset=dataset,item=item,ftime=when,atime=atime)
76  when=to_datetime_rel(interval,when)
77 
78  def gfsgrib2iter(self):
79  logger=self.log()
80  atime=to_datetime(self.conf.cycle) # sim start time
81  etime=to_datetime_rel(self.fcstlen*3600,atime) # sim end time
82  interval=to_fraction(self.confint('input_step',6*3600))
83  dataset=self.confstr('gfs_dataset','gfs')
84  item=self.confstr('gfs_item','gfs')
85  hd=self.confstr('catalog','hwrfdata')
86  dc=hwrf.input.DataCatalog(self.conf,hd,atime)
87  epsilon=to_timedelta(interval/10)
88  ende=to_datetime_rel(epsilon,etime)
89  when=atime
90  fhour=0
91  maxwait=self.confint('max_grib_wait',1800)
92  sleeptime=self.confint('grib_sleep_time',20)
93  min_size=self.confint('min_grib_size',1)
94  min_mtime_age=self.confint('min_grib_age',30)
95  while when<ende:
96  thefile=dc.locate(dataset=dataset,item=item,ftime=when,atime=atime,**self.taskvars)
97  if self.realtime:
98  waited=wait_for_files(
99  [thefile],logger,maxwait=maxwait,sleeptime=sleeptime,
100  min_size=min_size,min_mtime_age=min_mtime_age)
101  if not waited:
102  msg='%s: did not exist or was too small after %d seconds'%(
103  thefile,min_size)
104  self.log().error(msg)
106  yield thefile
107  fhour=fhour+interval/3600
108  when=to_datetime_rel(interval,when)
109 
110  def deliver_products(self):
111  logger=self.log()
112  for prodname,stuff in self._products.iteritems():
113  (prod,localpath)=stuff
114  prod.deliver(frominfo=localpath,keep=False,logger=logger)
115 
116  def run(self):
117  """Runs the WW3 initialization"""
118  logger=self.log()
119  dummycurr=True
120  usegfswind=self.confstr('usegfswind','yes')
121  if usegfswind == 'yes':
122  dummywind=False
123  elif usegfswind == 'no':
124  dummywind=True
125  else:
126  # Wrong usegfswind value
127  logger.warning('Wrong usegfswind value: %s. Assume usegfswind=yes.'
128  'Set dummywind to False.'%(usegfswind,))
129  usegfswind='yes'
130  dummywind=False
131  try:
132  self.state=RUNNING
133  redirect=self.confbool('redirect',True)
134  with NamedDir(self.workdir,keep=not self.scrub,logger=logger,rm_first=True) as d:
135  # Run ww3_grid
136  def link(s,t):
137  make_symlink(s,t,force=True,logger=logger)
138  deliver_file(self.icstr('{grid_inp}'),'ww3_grid.inp',keep=True,logger=logger)
139  link(self.icstr('{grid_bot}'),'.')
140  link(self.icstr('{grid_msk}'),'.')
141  link(self.icstr('{grid_obr}'),'.')
142  link(self.getexe('ww3_grid'),'ww3_grid')
143  #checkrun(exe(self.getexe('ww3_grid'))>='ww3_grid.log',logger=logger)
144  cmd=exe('./ww3_grid')
145  if redirect: cmd = cmd>='ww3_grid.log'
146  checkrun(cmd,logger=logger)
147 
148  if usegfswind == 'yes':
149  # Extract gfs wind from gfs grib2 data
150  ncfile='gfs.uvgrd10m.nc'
151  produtil.fileop.remove_file(ncfile,logger=logger)
152  cmd=alias(bigexe(self.getexe('wgrib2','wgrib2')))
153  for f in self.gfsgrib2iter():
154  logger.info('Extracting wind at 10 m from %s'%(f))
155  subset=''
156  for line in runstr(cmd[f],logger=logger).splitlines(True):
157  if re.search(':[UV]GRD:10 m above ground:',line):
158  subset+=line
159  runme=cmd[f,'-i', '-append', '-netcdf', ncfile] << subset
160  checkrun(runme, logger=logger)
161 
162  if produtil.fileop.isnonempty(ncfile):
163  dummywind=False
164  else:
165  dummywind=True
166  produtil.log.jlogger.warning(
167  'ww3init: will use dummy wind because %s is missing '
168  'or empty.'%(ncfile,))
169 
170  if dummywind:
171  # Run ww3_prep for dummy wind
172  deliver_file(self.icstr('{wind_inp}'),'ww3_prep.inp',keep=True,logger=logger)
173  link(self.getexe('ww3_prep'),'ww3_prep')
174  #checkrun(exe(self.getexe('ww3_prep'))>='ww3_prep_wind.log',logger=logger)
175  cmd=exe('./ww3_prep')
176  if redirect: cmd = cmd>='ww3_prep_wind.log'
177  checkrun(cmd,logger=logger)
178  else:
179  # Run ww3_prnc for prep gfs wind
180  deliver_file(self.icstr('{prnc_inp_gfswind}'),'ww3_prnc.inp',keep=True,logger=logger)
181  link(self.getexe('ww3_prnc'),'ww3_prnc')
182  cmd=exe('./ww3_prnc')
183  if redirect: cmd = cmd>='ww3_prnc_wind.log'
184  checkrun(cmd,logger=logger)
185 
186  if dummycurr:
187  # Run ww3_prep for dummy current
188  deliver_file(self.icstr('{curr_inp}'),'ww3_prep.inp',keep=True,logger=logger)
189  link(self.getexe('ww3_prep'),'ww3_prep')
190  #checkrun(exe(self.getexe('ww3_prep'))>='ww3_prep_curr.log')
191  cmd=exe('./ww3_prep')
192  if redirect: cmd = cmd>='ww3_prep_curr.log'
193  checkrun(cmd,logger=logger)
194  else:
195  # Extract current from global ocean model
196  logger.error('Not implemented yet')
197 
198  have_restart=False
199  oldrst='(unknown)'
200  try:
201  oldrst=self.icstr('{oldcom}/{oldvit[stormid3lc]}.restart.f006.ww3')
202  if produtil.fileop.isnonempty(oldrst):
203  produtil.fileop.deliver_file(oldrst,'restart.ww3',logger=logger)
204  have_restart=True
205  produtil.log.jlogger.info('%s: warm start for wave'%(oldrst,))
206  else:
207  produtil.log.jlogger.warning(
208  'restart.ww3: will generate dummy because %s is missing '
209  'or empty.'%(oldrst,))
210  except Exception as ee:
211  produtil.log.jlogger.warning(
212  'restart.ww3: will generate dummy because %s is missing '
213  'or could not be copied; %s'%(oldrst,str(ee)),exc_info=True)
214 
215  if not have_restart:
216  logger.info('restart.ww3: generating dummy with ww3_strt')
217  # Run ww3_strt
218  deliver_file(self.icstr('{strt_inp}'),'ww3_strt.inp',keep=True,logger=logger)
219  link(self.getexe('ww3_strt'),'ww3_strt')
220  cmd=exe('./ww3_strt')
221  if redirect: cmd = cmd>='ww3_strt.log'
222  checkrun(cmd,logger=logger)
223 
224  if redirect: self._copy_log()
225 
226  # Prepare ww3_shel.inp
228  shel_inp=self.icstr('{shel_inp}')
229  atime=to_datetime(self.conf.cycle) # sim start time
230  etime=to_datetime_rel(self.fcstlen*3600,atime) # sim end time
231  ci=self.conf.getfloat('config','cycling_interval',6)
232  retime=to_datetime_rel(ci*3600*1,atime) # restart end time
233  invars=dict()
234  invars.update(RUN_BEG=atime.strftime('%Y%m%d %H%M%S'),
235  RUN_END=etime.strftime('%Y%m%d %H%M%S'),
236  FLD_BEG=atime.strftime('%Y%m%d %H%M%S'),
237  FLD_END=etime.strftime('%Y%m%d %H%M%S'),
238  FLD_DT=int(self.outstep),
239  PNT_BEG=atime.strftime('%Y%m%d %H%M%S'),
240  PNT_END=etime.strftime('%Y%m%d %H%M%S'),
241  PNT_DT=0,
242  RST_BEG=atime.strftime('%Y%m%d %H%M%S'),
243  RST_END=retime.strftime('%Y%m%d %H%M%S'),
244  RST_DT=int(self.rststep) )
245 
246  with open(shel_inp,'rt') as nf:
247  with open('ww3_shel.inp','wt') as of:
248  of.write(ni.parse(nf,logger=logger,source=shel_inp,
249  raise_all=True,atime=self.conf.cycle,**invars))
250 
251  self.deliver_products()
252  self.state=COMPLETED
253  except Exception as e:
254  logger.error('Unhandled exception in wave init: %s'
255  %(str(e),),exc_info=True)
256  self.state=FAILED
257  self._copy_log()
258  raise
259 
260  def _copy_log(self):
261  logger=self.log()
262  for lf in [ 'ww3_grid.log', 'ww3_prep_wind.log', 'ww3_prep_curr.log'
263  'ww3_strt.log' ]:
264  comloc=self.icstr('{com}/{out_prefix}.{lf}.ww3',lf=lf)
265  if os.path.exists(lf):
266  deliver_file(lf,comloc,keep=True,logger=logger)
267 
268 ########################################################################
270  """This is an internal implementation class that should never be
271  used directly. It instructs the hwrf.coupling.CoupledWRF to call
272  the WRFWW3POM.copy_ww3_inputs to check or link WW3 input data."""
273  def __init__(self,wcp):
274  """Creates a WW3Initer that will pass control to the given
275  WRFWW3POM object, stored as self.wcp."""
276  self.wcp=wcp
277  def check_coupled_inputs(self,logger):
278  """Calls the WRFWW3POM.copy_ww3_inputs with just_check=True."""
279  return self.wcp.copy_ww3_inputs(just_check=True)
280  def link_coupled_inputs(self,just_check,logger):
281  """Calls the WRFWW3POM.copy_ww3_inputs passing just_check."""
282  return self.wcp.copy_ww3_inputs(bool(just_check))
283 
284 ########################################################################
285 
286 def copy_ww3_inputs(ww3init,just_check=False):
287  n_copied=0
288  logger=ww3init.log()
289  for prod in ww3init.products():
290  localname=prod['localpath']
291  loc=prod.location
292  avail=prod.available
293  if not avail or not loc or not localname:
294  prod.update()
295  localname=prod['localpath']
296  loc=prod.location
297  avail=prod.available
298  if not avail or not loc or not localname:
299  msg='WW3 product %s (available=%s location=%s localname=%s)'\
300  ' is not available or has an empty location'%(
301  prod.did,repr(prod.available), repr(prod.location),
302  repr(localname))
303  if just_check:
304  logger.warning(msg)
305  return False
306  else:
307  logger.error(msg)
309  if not just_check:
310  deliver_file(loc,os.path.basename(localname),keep=True,
311  logger=logger)
312  n_copied+=1
313  logger.info('Copied %d WW3 inputs. Returning True.'%(n_copied))
314  return True
315 
316 def add_ww3_product(task,rstbeg,rstdt,rstend,stream='ww3rst',fmt='restart%03d.ww3'):
317  atime=task.conf.cycle
318  beg=to_datetime_rel(rstbeg,atime)
319  end=to_datetime_rel(rstend,atime)
320  dt=to_fraction(rstdt)
321  epsilon=dt/10
322  eend=to_datetime_rel(epsilon,end)
323  times=list()
324  now=beg
325  while now<eend:
326  assert(now>atime)
327  times.append(now)
328  now=to_datetime_rel(dt,now)
329  task.add_coupled_stream(stream,times)
330  itime=0
331  with task.dstore.transaction() as t:
332  for time in times:
333  # itime = 1, 2, 3, 4, ...
334  # time = rstbeg, rstbeg+dt, rstbeg+2dt, ...
335  itime+=1
336  if '%' in fmt:
337  filename=fmt % itime # restart001.ww3
338  else:
339  filename=fmt
340  prodname=filename # restart001.ww3
341  location=os.path.join(task.location,filename) # /path/to/runwrf/restart001.ww3
342 
343  # The prod is the product that represents the restart output file.
344  prod=UpstreamFile(task.dstore,category=task.taskname,
345  prodname=prodname,location=location)
346  prod['stream']=stream
347  prod['location']=location
348  prod['minsize']=72
349  prod['restarttime']=round(to_fraction(time-atime)/3600)
350  prod['minage']=30
351 
352  task.add_coupled_product(stream,time,prod)
353  # Say something like:
354  # Created 4 output ww3rst products from 201508160600 to 201508170000
355  task.log().info('Created %d output %s products from %s to %s'%(
356  itime, stream, beg.strftime('%Y%m%d%H%M'), end.strftime('%Y%m%d%H%M')))
357 
358 ########################################################################
360  """Runs a WRF-WW3 coupled simulation (no ocean). Most of the work
361  of this class is done by the superclasses. This class adds code
362  to copy the inputs needed by WW3 and the coupler. There are three
363  critical new config section values:
364 
365  wm3c_ranks = number of coupler ranks. Default: 1
366  ww3_ranks = number of WW3 ranks. Default: 24
367  wrf_ranks = nubmer of WRF ranks. No default. This one is
368  mandatory."""
369  def __init__(self,dstore,conf,section,wrf,keeprun=True,
370  wrfdiag_stream='auxhist1',ww3init=None,**kwargs):
371  if not isinstance(ww3init,WW3Init):
372  raise TypeError(
373  'The ww3init argument to WRFCoupledWW3.__init__ must be a '
374  'WW3Init object. You passed a %s %s.'%
375  (type(ww3init).__name__,repr(ww3init)))
376  super(WRFCoupledWW3,self).__init__(dstore,conf,section,wrf,keeprun,
377  wrfdiag_stream,**kwargs)
378  self.ww3init=ww3init
379  ww3initer=WW3Initer(self)
380  self.couple('coupler','hwrf_wm3c','wm3c_ranks',1)
381  self.couple('ww3','hwrf_ocean_fcst','ww3_ranks',48,ww3initer)
382  self.couple('wrf','wrf','wrf_ranks')
383 
384  ci=self.conf.getfloat('config','cycling_interval',6)
385  rstdt=ww3init.rststep
386  if rstdt>0:
387  # Currently only ouput one restart file from wave model
388  add_ww3_product(self,rstdt,rstdt,ci*1*3600,'ww3rst','restart%03d.ww3')
389 
390  add_ww3_product(self,wrf.simend(),3600,wrf.simend(),'ww3out','out_grd.ww3')
391  add_ww3_product(self,wrf.simend(),3600,wrf.simend(),'ww3mdldef','mdl_def.ww3')
392  def remove_wave(self):
393  self.uncouple()
394 
395  def copy_ww3_inputs(self,just_check=False):
396  return copy_ww3_inputs(self.ww3init,just_check)
397 
398 ########################################################################
399 
401  def __init__(self,dstore,conf,section,wrf,keeprun=True,
402  wrfdiag_stream='auxhist1',pominit=None,ww3init=None,
403  **kwargs):
404  if not isinstance(ww3init,WW3Init):
405  raise TypeError(
406  'The ww3init argument to WRFCoupledWW3.__init__ must be a '
407  'WW3Init object. You passed a %s %s.'%
408  (type(ww3init).__name__,repr(ww3init)))
409  self.ww3init=ww3init
410  self.ww3initer=WW3Initer(self)
411  super(WRFWW3POM,self).__init__(dstore,conf,section,wrf,keeprun,wrfdiag_stream,pominit,**kwargs)
412 
413  ci=self.conf.getfloat('config','cycling_interval',6)
414  rstdt=ww3init.rststep
415  if rstdt>0:
416  # Currently only ouput one restart file from wave model
417  add_ww3_product(self,rstdt,rstdt,ci*1*3600,'ww3rst','restart%03d.ww3')
418 
419  add_ww3_product(self,wrf.simend(),3600,wrf.simend(),'ww3out','out_grd.ww3')
420  add_ww3_product(self,wrf.simend(),3600,wrf.simend(),'ww3moddef','mod_def.ww3')
421 
422  def remove_ocean(self):
423  self.uncouple('pom')
424 
425  def remove_wave(self):
426  self.uncouple('ww3')
427 
428  def _add_wave(self):
429  self.couple('ww3','ww3_shel','ww3_ranks',48,self.ww3initer)
430 
431  def copy_ww3_inputs(self,just_check=False):
432  return copy_ww3_inputs(self.ww3init,just_check)
433 
434 ########################################################################
436  """Run WW3 post-process."""
437  def __init__(self,ds,conf,section,poststep,ww3,**kwargs):
438  super(WW3Post,self).__init__(ds,conf,section,**kwargs)
439  self.poststep=poststep
440  self.ww3=ww3 # the WW3-coupled subclass of WRFAtmos
441  self.make_products()
442  self._ncks_path=False
443 
444  def products(self,**kwargs):
445  yield self._ww3ounfprod
446  redirect=self.confbool('redirect',True)
447  if redirect: yield self._ww3ounflog
448 
449  def make_products(self):
450  redirect=self.confbool('redirect',True)
452  self.dstore,"ww3ounf.nc",self.taskname)
453  if redirect:
455  self.dstore,"ww3ounf.log",self.taskname)
456 
457  def __copy_ounf(self,source,target,ignore):
458  ncks=self.ncks_path
459  logger=self.log()
460  produtil.fileop.remove_file(target,logger=logger)
461  checkrun(bigexe(ncks)['-4','-L','6',source,target]<'/dev/null',
462  logger=logger)
463 
464  @property
465  def ncks_path(self):
466  """Returns the path to ncks. Returns None if ncks cannot be
467  found. This function will only search for ncks once, and will
468  cache the result. Set self._ncks_path=False to force a
469  recheck."""
470  if self._ncks_path is False:
471  ncks=self.getexe('ncks','')
472  if not self._ncks_path:
473  ncks=produtil.fileop.find_exe('ncks',raise_missing=False)
474  assert(ncks is None or
475  (isinstance(ncks,basestring) and ncks!=''))
476  self._ncks_path=ncks
477  return self._ncks_path
478 
479  def run(self):
480  """Run the WW3 post."""
481  logger=self.log()
482  redirect=self.confbool('redirect',True)
483  self.state=RUNNING
484  try:
485  with NamedDir(self.workdir,keep=True,logger=logger,rm_first=True) as d:
486  mdprod=[ p for p in self.ww3.products(stream='ww3moddef') ] [0]
487  ogprod=[ p for p in self.ww3.products(stream='ww3out') ] [0]
488  mdprod.check()
489  if not mdprod or not mdprod.available or not mdprod.location:
490  logger.error('%s: mod_def.ww3 not yet available from forecast'%(
491  repr(mdprod),))
492  ogprod.check()
493  if not ogprod or not ogprod.available or not ogprod.location:
494  logger.error('%s: mod_def.ww3 not yet available from forecast'%(
495  repr(ogprod),))
496  make_symlink(mdprod.location,'mod_def.ww3')
497  make_symlink(ogprod.location,'out_grd.ww3')
498  make_symlink(self.getexe('ww3_ounf'),'ww3_ounf')
499 
500  # Prepare the namelist
501  self.make_ounf_inp(logger)
502 
503  # Run ww3_ounf
504  cmd=exe('./ww3_ounf')
505  if redirect: cmd = cmd>='ww3_ounf.log'
506  checkrun(cmd,logger=logger)
507 
508  #ww3_ounf_out=self.conf.cycle.strftime('ww3.%Y%m%d %H.nc')
509  ww3_ounf_out=self.conf.cycle.strftime('ww3.%Y.nc')
510  ww3_ounf_out_com=self.icstr('{com}/{out_prefix}.ww3_ounf.nc')
511 
512  self._ww3ounfprod.deliver(frominfo=ww3_ounf_out,
513  location=ww3_ounf_out_com,
514  logger=logger,copier=self.__copy_ounf)
515  self.state=COMPLETED
516  except Exception as e:
517  self.state=FAILED
518  logger.error("WW3 post failed: %s"%(str(e),),exc_info=True)
519  raise
520 
521  def make_ounf_inp(self,logger):
522  # Prepare ww3_ounf.inp
524  ounf_inp=self.confstr('ounf_inp','')
525  if not ounf_inp: ounf_inp=self.icstr('{PARMhwrf}/ww3_ounf.inp_tmpl')
526  atime=to_datetime(self.conf.cycle) # sim start time
527  invars=dict()
528  invars.update(FLD_BEG=atime.strftime('%Y%m%d %H%M%S'),
529  FLD_DT=int(self.poststep))
530 
531  with open(ounf_inp,'rt') as nf:
532  with open('ww3_ounf.inp','wt') as of:
533  of.write(ni.parse(nf,logger=logger,source=ounf_inp,
534  raise_all=True,atime=self.conf.cycle,**invars))
Runs the POM initialization and POM-WRF coupled forecast.
Definition: mpipomtc.py:1
Change directory, handle temporary directories.
Definition: cd.py:1
This module provides a set of utility functions to do filesystem operations.
Definition: fileop.py:1
def deliver_file
This moves or copies the file "infile" to "outfile" in a unit operation; outfile will never be seen i...
Definition: fileop.py:359
def _copy_log(self)
Definition: ww3.py:260
def gfsgrib2iter(self)
Definition: ww3.py:78
def check_coupled_inputs(self, logger)
Definition: ww3.py:277
def getexe
Alias for hwrf.config.HWRFConfig.get() for the "exe" section.
Definition: hwrftask.py:403
def __copy_ounf(self, source, target, ignore)
Definition: ww3.py:457
taskname
Read-only property: the name of this task.
Definition: datastore.py:1134
def make_ounf_inp(self, logger)
Definition: ww3.py:521
A subclass of Product that represents file delivery.
Definition: datastore.py:856
The base class of tasks run by the HWRF system.
Definition: hwrftask.py:25
def _make_products(self)
Definition: ww3.py:42
def remove_file
Deletes the specified file.
Definition: fileop.py:251
conf
This HWRFTask's hwrf.config.HWRFConfig object.
Definition: hwrftask.py:415
dstore
Read-only property, an alias for getdatastore(), the Datastore in which this Datum resides...
Definition: datastore.py:557
def products(self, name=None, kwargs)
Definition: ww3.py:56
def confbool
Alias for self.conf.getbool for section self.section.
Definition: hwrftask.py:287
section
The confsection in self.section for this HWRFTask (read-only)
Definition: hwrftask.py:422
Base class of tasks run by HWRF.
Definition: hwrftask.py:1
A shell-like syntax for running serial, MPI and OpenMP programs.
Definition: run.py:1
def make_products(self)
Definition: ww3.py:449
def link_coupled_inputs(self, just_check, logger)
Definition: ww3.py:280
def isnonempty(filename)
Returns True if the filename refers to an existent file that is non-empty, and False otherwise...
Definition: fileop.py:333
Stores products and tasks in an sqlite3 database file.
Definition: datastore.py:1
def to_datetime(d)
Converts the argument to a datetime.
Definition: numerics.py:346
This subclass of TempDir takes a directory name, instead of generating one automatically.
Definition: cd.py:228
Obtains input data needed by various subclasses of hwrf.hwrftask.HWRFTask.
Definition: input.py:1
Time manipulation and other numerical routines.
Definition: numerics.py:1
def deliver_products(self)
Definition: ww3.py:110
workdir
The directory in which this task should be run.
Definition: hwrftask.py:156
def run(self)
Definition: ww3.py:116
def confint
Alias for self.conf.getint for section self.section.
Definition: hwrftask.py:248
This module provides two different ways to generate Fortran namelist files from HWRFConfig sections: ...
Definition: namelist.py:1
def timestr(self, string, ftime, atime=None, section=None, kwargs)
Expands a string in the given conf section, including time vars.
Definition: hwrftask.py:367
def scrub(self)
Should temporary files be deleted as soon as they are not needed?
Definition: hwrftask.py:195
def log
Obtain a logging domain.
Definition: hwrftask.py:425
Insert config file data into a Fortran namelist file.
Definition: namelist.py:154
def run(self)
Definition: ww3.py:479
def __init__(self, dstore, conf, section, taskname=None, fcstlen=126, outstep=21600, rststep=21600, kwargs)
Definition: ww3.py:27
Configures logging.
Definition: log.py:1
def __init__(self, wcp)
Definition: ww3.py:273
def uncouple
Removes a component, or all components, from the coupling.
Definition: coupling.py:286
Provides the location of a file in an archive, on disk or on a remote server via sftp or ftp...
Definition: input.py:109
Exceptions raised by the hwrf package.
Definition: exceptions.py:1
def confstr
Alias for self.conf.getstr for section self.section.
Definition: hwrftask.py:261
def ncks_path(self)
Definition: ww3.py:465
def find_exe
Searches the $PATH or a specified iterable of directory names to find an executable file with the giv...
Definition: fileop.py:573
def taskvars(self)
The dict of object-local values used for string substitution.
Definition: hwrftask.py:243
def realtime(self)
Is this job a real-time forecast job?
Definition: hwrftask.py:180
def icstr(self, string, section=None, kwargs)
Expands a string in the given conf section.
Definition: hwrftask.py:351
Runs a WRF-POM coupled simulation.
Definition: mpipomtc.py:360
Represents a Product created by an external workflow.
Definition: datastore.py:915