51 from hwrf.wrf import WRFDomain,WRFSimulation,ExternalWRFTask
53 from hwrf.regrib import RegribMany,igrb1,clatlon,GRIB2
56 """!This function makes per-cycle modifications to the
57 configuration file storm1.conf.
59 This is called in scripts.exhwrf_launch and run_hwrf.py by
60 hwrf.launcher.launch() on the configuration object
61 (hwrf.launcher.HWRFLauncher, a subclass of
62 hwrf.config.HWRFConfig), before the per-cycle storm1.conf
63 configuration file is written. Any changes made to the conf
64 object will be stored in storm1.conf file and used in later jobs.
65 This allows modifications to the configuration on a per-cycle
66 basis. Note that cycle=None and conf.cycle is unavailable when
67 run_hwrf.py calls prelaunch.
68 @param conf the hwrf.launcher.HWRFLauncher to modify
69 @param logger a logging.Logger for log messages
70 @param cycle the cycle to run, or None if this is being
71 run from run_hwrf.py or the ush.psychoanalyst"""
76 if cycle
is None:
return
84 """!Runs a sanity check on this module's contents. This should be
85 called after init_module.
87 This sanity check routine is called automatically by
88 hwrf.launcher.HWRFLauncher.sanity_check_expt() as part of the
89 standard sanity checks in the scripts.exhwrf_launch job. It
90 checks to see if all expected module-scope variables are present
91 and initialized correctly.
93 @param logger a logging.Logger for log messages"""
94 logger.info(
'The runwrf object = %s'%(repr(runwrf),))
95 logger.info(
'The gribber object = %s'%(repr(gribber),))
96 logger.info(
'The datastore (ds) object = %s'%(repr(ds),))
97 logger.info(
'The wrf object = %s'%(repr(wrf),))
100 gsi_flag=conf.getbool(
'config',
'run_gsi')
101 ocean_flag=conf.getbool(
'config',
'run_ocean')
102 ocean=conf.getstr(
'config',
'ocean_model')
103 wave_flag=conf.getbool(
'config',
'run_wave')
104 wave=conf.getstr(
'config',
'wave_model')
105 reloc_flag=conf.getbool(
'config',
'run_relocation')
106 spectral_flag=conf.getbool(
'config',
'use_spectral')
107 spectral_bdy=conf.getbool(
'config',
'spectral_bdy')
and spectral_flag
108 fallbacks_flag=conf.getbool(
'config',
'allow_fallbacks')
109 extra_trackers=conf.getbool(
'config',
'extra_trackers',
False)
110 wrf_output_step=conf.getint(
'forecast_products',
'wrf_output_step',10800)
115 logger.info(
'The hycominit object = %s'%(repr(hycominit),))
116 logger.info(
'The hycompost object = %s'%(repr(hycompost),))
118 logger.info(
'The pominit object = %s'%(repr(pominit),))
121 '[config] ocean_model=%s but should be POM or HYCOM'%(
124 if wrf_output_step<1:
126 'The wrf_output_step must be at least 1 second')
127 elif wrf_output_step!=10800
and 0 != (3600%wrf_output_step):
129 'One hour (3600 seconds) must be divisable by the WRF '
130 'output timestep. You specified %d.'%(wrf_output_step,))
135 logger.info(
'The ww3init object = %s'%(repr(ww3init),))
136 logger.info(
'The ww3post object = %s'%(repr(ww3post),))
139 '[config] wave_model=%s but should be WW3'%(
143 if gsi_flag
and not reloc_flag:
144 logger.error(
"Cannot use GSI without relocation.")
146 "Cannot use GSI without relocation.")
149 """!Iterates over all inputs required by this configuration.
151 Calls the inputiter() function on all tasks in the module scope
152 that are expected to have input data. The result can be passed
153 into the "data" argument of hwrf.input.InputSource.get. Iterates
154 over dicts that contain the following:
155 * dataset --- string name of the dataset (gfs, gdas1, gefs,
157 * item --- string name of the object (ie.: gfs_sf, gfs_sfcanl, bufr)
158 * atime --- self.conf.cycle
159 * ftime --- only present when relevant: the forecast time, in a
160 format accepted by to_datetime_rel
161 * enkfmem --- only present when relevant: the ENKF member ID
162 * obstype --- only present when relevant: the bufr data type.
163 * optional --- True if the absence of this data is not considered a failure."""
164 gsi_flag=conf.getbool(
'config',
'run_gsi')
165 run_ensemble_da=conf.getbool(
'config',
'run_ensemble_da',
False)
166 spectral_flag=conf.getbool(
'config',
'use_spectral')
167 spectral_bdy=conf.getbool(
'config',
'spectral_bdy')
and spectral_flag
168 ocean_flag=conf.getbool(
'config',
'run_ocean')
169 ocean=conf.getstr(
'config',
'ocean_model',
'POM')
170 wave_flag=conf.getbool(
'config',
'run_wave')
171 wave=conf.getstr(
'config',
'wave_model',
'WW3')
172 conditional_gsid03=conf.getbool(
'config',
'conditional_gsid03',
False)
173 tdrflagfile=conf.strinterp(
'dir',
'{com}/{stormlabel}.tdr')
174 realtime=conf.getbool(
'config',
'realtime')
175 if not conditional_gsid03
or (conditional_gsid03
and isnonempty(tdrflagfile)):
182 for d
in hycominit.inputiter():
yield d
184 for d
in pominit.inputiter():
yield d
187 for d
in ww3init.inputiter():
yield d
188 for d
in gfs_init.inputiter():
yield d
190 for d
in gsi_d02.inputiter():
yield d
192 for d
in gsi_d03.inputiter():
yield d
193 for d
in fgat_init.inputiter():
yield d
195 for d
in ensda.inputiter():
yield d
196 if not realtime
or not os.path.isdir(
'/dcom/us007003'):
197 for d
in ensda_pre.inputiter():
yield d
306 non_ocean_basins=
None
356 da_ensemble_size=
None
384 def init_module(CONFhwrf=None,make_ensemble_da=True,make_post=True):
385 """!Initializes the HWRF object structure.
387 This function is called from all scripts and the
388 hwrf.launcher.HWRFLauncher to initialize the HWRF object
389 structure. The created objects know how to run various parts of
390 the system, and this function connects those objects to one
392 @param CONFhwrf the configuration filename
393 @param make_ensemble_da if True, the ensemble data assimilation objects
395 @param make_post if True, the post-processing objects are created"""
396 global conf,ds,moad,storm1outer,storm1inner,wrf, anl4trak
397 global runwrf,nonsatpost,satpost,hwrfsub,stormloc,domloc, gfs_init
398 global gribber, tracker, WRFOUThwrf, coupled, pominit
399 global nhcp, wrfcopier, real12, real126, WORKhwrf, HOMEhwrf
400 global rel_stage1, rel_stage2, rel_stage3, fgat_init, non_ocean_basins
401 global bufrprep, gsi_d02, gsi_d03, gsid03_flag, gdas_merge, cycle, prior_ensda
402 global ensda, entest, da_ensemble_size, trackerd01, trackerd02
403 global gsigribber, gsipost, ensda_pre, ocstatus, finalmerge, multistormin
404 global run_multistorm, run_multistorm_00flag
405 global fcstlen, hycominit, hycompost, ww3init, ww3post, wvstatus
410 CONFhwrf=os.environ[
'CONFhwrf']
417 logger.info(
'Initializing hwrf_expt module...')
419 sync_frequently=conf.getbool(
'config',
'sync_frequently',
True)
420 produtil.fileop.sync_frequently=sync_frequently
426 run_multistorm=conf.getbool(
'config',
'run_multistorm',
False)
427 run_multistorm_00flag =
False
429 fakestormid=conf.getstr(
'config',
'fakestormid',
'nofakeid')
430 this_stormid=conf.getstr(
'config',
'STID',
'nosid')
431 if fakestormid !=
'nofakeid' and fakestormid == this_stormid:
432 run_multistorm_00flag =
True
434 multistorm_sids = conf.getstr(
435 'config',
'multistorm_sids',
'nosids').split()
436 if multistorm_sids[0]==
'nosids':
438 'No sids provided for multistorm run.')
439 num_realstorms = len(multistorm_sids)
443 WORKhwrf=conf.getdir(
'WORKhwrf')
444 HOMEhwrf=conf.getdir(
'HOMEhwrf')
447 gsi_flag=conf.getbool(
'config',
'run_gsi')
448 run_ensemble_da=conf.getbool(
'config',
'run_ensemble_da',
False)
449 make_ensemble_da=make_ensemble_da
and run_ensemble_da
450 satpost_flag=conf.getbool(
'config',
'run_satpost',
True)
451 ocean_flag=conf.getbool(
'config',
'run_ocean')
452 ocean=conf.getstr(
'config',
'ocean_model',
'POM')
453 wave_flag=conf.getbool(
'config',
'run_wave')
454 wave=conf.getstr(
'config',
'wave_model',
'WW3')
455 reloc_flag=conf.getbool(
'config',
'run_relocation')
456 spectral_flag=conf.getbool(
'config',
'use_spectral')
457 spectral_bdy=conf.getbool(
'config',
'spectral_bdy')
and spectral_flag
458 fallbacks_flag=conf.getbool(
'config',
'allow_fallbacks')
459 gofile_flag=conf.getbool(
'config',
'make_gofile',
False)
460 extra_trackers=conf.getbool(
'config',
'extra_trackers',
False)
461 conditional_gsid03=conf.getbool(
'config',
'conditional_gsid03',
False)
462 conditional_gsid02=conf.getbool(
'config',
'conditional_gsid02',
False)
463 fcstlen=conf.getint(
'config',
'forecast_length',126)
464 fgatstr=conf.getint(
'fgat',
'FGATSTR',-3)
465 fgatend=conf.getint(
'fgat',
'FGATEND',3)
466 fgatinv=conf.getint(
'fgat',
'FGATINV',3)
467 tdrflagfile=conf.strinterp(
'dir',
'{com}/{stormlabel}.tdr')
471 ww3_output_step=conf.getint(
'forecast_products',
'ww3_output_step',21600)
472 ww3_restart_step=conf.getint(
'forecast_products',
'ww3_restart_step',21600)
474 ens_reloc_flag=conf.getbool(
'config',
'run_ens_relocation',
False)
475 if not conditional_gsid03
or (conditional_gsid03
and isnonempty(tdrflagfile)):
489 with ds.transaction():
492 storm1outer=
WRFDomain(conf,
'storm1outer')
493 storm1inner=
WRFDomain(conf,
'storm1inner')
494 storm1ghost_parent=
WRFDomain(conf,
'storm1ghost_parent')
495 storm1ghost=
WRFDomain(conf,
'storm1ghost')
496 storm1ghost_parent_big=
WRFDomain(conf,
'storm1ghost_parent_big')
497 storm1ghost_big=
WRFDomain(conf,
'storm1ghost_big')
498 postdoms=[moad,storm1outer,storm1inner]
502 wrf.add(storm1outer,moad)
503 wrf.add(storm1inner,storm1outer)
511 if run_multistorm_00flag:
513 stormNinner = {}; stormNouter = {}
514 for i
in range(2,num_realstorms + 1):
515 stormNinner[
'storm%sinner'%i]=
WRFDomain(conf,
'storm%sinner'%i)
516 stormNouter[
'storm%souter'%i]=
WRFDomain(conf,
'storm%souter'%i)
517 wrf.add(stormNouter[
'storm%souter'%i], moad)
518 wrf.add(stormNinner[
'storm%sinner'%i],stormNouter[
'storm%souter'%i])
519 stormNinner[
'storm1inner']=storm1inner
520 stormNouter[
'storm1outer']=storm1outer
523 wrf.analysis_in(
None)
525 wrf_output_step=conf.getint(
'forecast_products',
'wrf_output_step',10800)
526 pom_output_step=conf.getint(
'forecast_products',
'pom_output_step',86400)
527 if wrf_output_step<10800:
529 wrf.add_output(
'history',step=wrf_output_step)
533 wrf.add_output(
'history',step=3600*3,end=9*3600)
534 wrf.add_output(
'auxhist2',step=3600,end=9*3600,
535 outname=
'wrfout_d<domain>_<date>')
536 wrf.add_output(
'auxhist3',step=3600*3,
537 outname=
'wrfout_d<domain>_<date>')
538 wrf.add_output(
'auxhist1',step=3600,outname=
'wrfdiag_d<domain>', \
539 frames_per_outfile=999,io_form=202)
546 wrfdoms=[d
for d
in wrf]
550 if run_multistorm_00flag:
552 'finalmerge', taskname=
'finalmerge')
559 wrfghost.add(storm1ghost_parent,moad)
560 wrfghost.add(storm1ghost,storm1ghost_parent)
564 wrfghost_big.add(storm1ghost_parent_big,moad)
565 wrfghost_big.add(storm1ghost_big,storm1ghost_parent_big)
567 if run_multistorm_00flag:
570 ds,conf,
'gfsinit',wrf,6*3600,fcstlen*3600,ibdystep=6*3600,
571 realfcst=
True, relocate=
False, prep=spectral_flag, prepfcst=spectral_bdy, track=
False)
574 ds,conf,
'gfsinit',wrf,6*3600,fcstlen*3600,ibdystep=6*3600,
575 wrfghost=wrfghost_big,prep=spectral_flag,track=
True,
576 realfcst=
True,relocate=reloc_flag,prepfcst=spectral_bdy)
580 ds,conf,
'tdrcheck',next_cycle)
591 conf,
'enswrf',moad,conf.cycle,next_cycle)
592 ensdawrf.add(ensdadom,moad)
593 ensdawrf.add_output(
'history',step=3600*3,end=9*3600)
594 ensdadoms=[ ensdawrf[moad], ensdawrf[ensdadom] ]
595 for dom
in ensdadoms:
596 assert(dom.get_grid_id()
is not None)
598 def makememb(clazz,ienkf,topname='ensda',priorcycle=None):
599 assert(isinstance(topname,basestring))
600 assert(isinstance(ienkf,int))
602 ds,conf,
"hwrf_da_ens",gfs_init,ienkf,ensdawrf,
603 "%s.%03d"%(topname,ienkf),relocate=ens_reloc_flag,
604 priorcycle=priorcycle,track=ens_reloc_flag,
605 workdir=conf.getdir(
'WORKhwrf')+
'/%s/%03d'%(
607 outdir=conf.getdir(
'intercom')+
'/%s/%03d'%(
613 ds,conf,
'hwrf_da_ens',conf.cycle,
'prior_ensda')
614 da_ensemble_size=prior_ensda.confint(
'ensda_size',40)
615 for i
in xrange(da_ensemble_size):
616 prior_ensda.set_member(
618 ds,conf,
"hwrf_da_ens",ensdadoms,
619 i+1,conf.cycle,taskname=
'%s.%03d'%(
623 ds,conf,
'hwrf_da_ens',conf.cycle,
'ensda')
624 for i
in xrange(da_ensemble_size):
626 priorcycle=prior_ensda.member(conf.cycle,i+1)
629 ensda.set_member(conf.cycle,i+1,makememb(
640 ds,conf,
'fgat',wrf,3*3600,fcstlen*3600,wrfghost=wrfghost,
641 prep=spectral_flag,track=
True,realfcst=
False,ibdystep=3*3600,
642 in_dataset=
'gdas1',relocate=reloc_flag,gsi_d02=
True,
643 gsi_d03=gsid03,prepfcst=spectral_bdy)
644 ceninit=fgat_init.init_at_time(conf.cycle)
647 ds,conf,
'bufrprep',taskname=
'bufrprep')
649 ingsi_d02=fgat_init.get_relocates(storm1ghost_parent)
651 ds,conf,
'gsi_d02',storm1ghost_parent,
652 ceninit.rstage3.get_ghost(storm1ghost_parent),
656 ingsi_d03=fgat_init.get_relocates(storm1ghost)
658 ds,conf,
'gsi_d03',storm1ghost,
659 ceninit.rstage3.get_ghost(storm1ghost),
667 gsi_d02.set_ensda(ensda,ensdadoms)
669 gsi_d02.set_ensda(prior_ensda,ensdadoms)
672 gsi_d03.set_ensda(ensda,ensdadoms)
674 gsi_d03.set_ensda(prior_ensda,ensdadoms)
677 ds,conf,
'merge',ceninit.rstage3,
678 wrfinput=gfs_init.realinit,
679 wrfanl=gfs_init.runwrfanl,
680 taskname=
'gdas_merge',
681 gsi_d02=gsi_d02, gsi_d03=gsi_d03)
684 ges_d02=ceninit.rstage3.get_ghost(storm1ghost_parent)
686 ges_d03=ceninit.rstage3.get_ghost(storm1ghost)
688 ges_d03=ceninit.rstage3.get_wrfanl(storm1inner)
689 gdas_merge.set_ges(ges_d02,ges_d03)
695 ds,conf,
'gsi_products')
696 (gsipost,gsigribber)=hgpp.make_gsi_post(
697 gsi_d02,gsi_d03,storm1ghost,storm1ghost_parent,ceninit,
704 non_ocean_basins=conf.getstr(
'config',
'non_ocean_basins',
'Q')
712 outstep=pom_output_step)
722 if wave_flag
and wave==
'WW3':
724 outstep=ww3_output_step, rststep=ww3_restart_step)
725 for p
in ww3init.products():
726 print 'WW3INIT product = ',str(p)
732 fcst_sec=conf.getstr(
'config',
'forecast_section',
'runwrf')
733 if not run_multistorm:
735 conf,ds,wrf,pominit,ww3init,hycominit,ocstatus)
736 hfcst.make_forecast()
738 hycompost=hfcst.hycompost
739 ww3post=hfcst.ww3post
741 if run_multistorm_00flag:
743 conf,ds,wrf,multistorm_sids,finalmerge,
744 stormNouter,stormNinner)
745 hfcst.make_forecast()
754 ds,conf,fakestormid,fcst_sec,wrf,
'runwrf')
756 ds,conf,fcst_sec,wrf,keeprun=
False,taskname=
'multistorm_init')
758 realwrf.add_orig_wrfinput(gfs_init.realinit)
763 if not run_multistorm_00flag:
764 realwrf.add_metgrid(gfs_init.metgrid) \
765 .add_geogrid(gfs_init.geogrid) \
766 .add_fort65(gfs_init.realinit) \
767 .add_wrfbdy(gfs_init.realfcst)
771 if gsi_flag
and not run_multistorm_00flag:
772 realwrf.add_wrfinput(gdas_merge) \
773 .add_wrfanl(gdas_merge,storm1outer) \
774 .add_wrfanl(gdas_merge,storm1inner)
776 if (
not gsi_flag
or fallbacks_flag
777 or (conditional_gsid03
and
778 conditional_gsid02
and gsi_flag)
779 )
and not run_multistorm_00flag:
780 if reloc_flag
or (conditional_gsid03
and \
782 realwrf.add_wrfinput(gfs_init.rstage3) \
783 .add_wrfanl(gfs_init.rstage3,storm1outer) \
784 .add_wrfanl(gfs_init.rstage3,storm1inner)
790 realwrf.add_wrfinput(gfs_init.realinit) \
791 .add_wrfanl(gfs_init.runwrfanl,storm1outer) \
792 .add_wrfanl(gfs_init.runwrfanl,storm1inner)
799 logger.info(
'make_post=False, will not make post. '
800 'Done in hwrf_expt module.')
810 ds,conf,
'forecast_products',runwrf,wrf,postdoms,
811 wrfdoms,moad,storm1inner,storm1outer)
812 nonsatpost=hfpp.make_nonsatpost()
813 satpost=hfpp.make_satpost()
814 wrfcopier=hfpp.make_wrfcopier(multistorm=run_multistorm)
815 assert(wrfcopier
is not None)
816 (gribber,tracker,track,nhcp)=\
817 hfpp.make_gribber_tracker(extra_trackers,satpost_flag,gofile_flag)
819 (trackerd01,trackerd02)=\
820 hfpp.make_extra_trackers()
822 logger.info(
'Done in hwrf_expt module.')
Runs the POM initialization and POM-WRF coupled forecast.
This module provides a set of utility functions to do filesystem operations.
Create namelists, monitor wrf simulations, generate filenames.
def prelaunch_basin(conf, logger, cycle)
Modifies the configuration for the basin.
def load(filename)
Loads the HWRFLauncher created by the launch() function.
def to_timedelta
Converts an object to a datetime.timedelta.
Represents a two-dimensional ensemble-vs-time array of hwrf.hwrftask.HWRFTask objects.
def prelaunch_ensid(conf, logger)
Changes the ungrib item and item2 based on the ensemble ID.
Functions called automatically before a cycle is launched.
def init_module
Initializes the HWRF object structure.
Runs the GSI based on the HWRF FGAT scheme.
def sanity_check(logger)
Runs a sanity check on this module's contents.
Defines StormInfo and related functions for interacting with vitals ATCF data.
A shell-like syntax for running serial, MPI and OpenMP programs.
Combines multiple tasks together to make the HWRF post-processing system.
Raised when the user requests a configuration that makes sense, but is not supported.
PrepHybrid runs the prep_hybrid program to transform GFS spectral files to the HWRF grid...
def inputiter()
Iterates over all inputs required by this configuration.
Contains the WRFCopyTask, which delivers WRF output and input.
Utilities for ensemble-based data assimilation.
Runs the real_nmm or wrf executables.
Stores products and tasks in an sqlite3 database file.
Runs the GSI data assimilation on the HWRF system.
Called when one hour is not divisable by the WRF output timestep.
Time manipulation and other numerical routines.
Declares GRIBTask, which automates regribbing operations.
This module contains Tasks to run the WRF Preprocessing System (WPS): Geogrid, Ungrib and Metgrid...
Forecast ensemble member based on the GFS ENKF.
Raised when a time was requested with higher precision than available.
parses UNIX conf files and makes the result readily available
Represents an ensemble member from the previous forecast cycle.
Combines Tasks from multiple modules into a single initialization object.
A wrapper around the pom package that runs the POM initialization.
Runs the deterministic model initialization.
Creates the initial HWRF directory structure, loads information into each job.
Generates NHC-specific products and validates wrfdiag files.
def enada_pre_object_for(ds, conf, section, next_cycle)
Generates a CycleTDRCheck or AlwaysRunENSDA based on configuration settings.
def prelaunch_ungrib(conf, logger, cycle)
Change the ungrib table based on the year.
Creates the post-processing for the HWRF forecast job.
def prelaunch(conf, logger, cycle)
This function makes per-cycle modifications to the configuration file storm1.conf.
Runs the Unified Post Processor on outputs from the WRF-NMM, producing E grid GRIB files as EGRIB1Pro...
This module contains tasks to prepare input for the GFDL Vortex Tracker, run the tracker and deliver ...
The FGATInit represents an array of InitBeforeGSI objects, each run for one forecast hour of some par...
generate and manipulate wrf namelists, predict output filenames
Describes regribbing operations using an algebraic structure.
This is a HWRF task that merges the WRF analysis files.
def prelaunch_rsmc(conf, logger, cycle)
Modifies the configuration for the RSMC (JTWC, NHC, etc.)
Post-processes GSI input and output for data assimilation diagnostics.
This module implements Python classes that run the 2014 HWRF Relocation.
def runsync
Runs the "sync" command as an exe().
Raised when the requested configuration conf or hwrf_expt files fail a sanity check.
Contains Bufrprep, which converts data tanks to bufr files, and otherwise preprocesses the prepbufr a...
Configures the GSI post-processing and regribbing.
A domain in a WRF simulation.
This is a HWRF task that preprocesses observations in data tanks to create bufr files suitable for in...