U $g@sdZddgZddlZddlZddlZddlZddlZddlZ ddl Z ddl Z ddl Z ddl Z ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlmZm Z ddl m!Z!ddl m"Z"m#Z#m$Z$ddl m%Z%dd lm&Z&m'Z'm(Z(m)Z)m*Z*d d Z+d d Z,ddZ-Gddde j.j/Z0Gddde j.j/Z1Gddde2Z3Gddde3Z4dS)a*!Combines multiple tasks together to make the HWRF post-processing system. This is a wrapper around the hwrf.post, hwrf.gribtask, hwrf.tracker, hwrf.nhc_products and hwrf.gsipost that creates customizable post-processing tasks. The main purpose of this module is to simplify the hwrf_expt module.HWRFGSIPostProcessingHWRFForecastPostProcessingN)exealias)to_datetime_rel) WRFDomain WRFSimulationExternalWRFTask) PostManyWRF) RegribManyigrb1clatlonGRIB2SATGRIB2c Cs||d}|d}t|dks(tt|d}t|d}t|d}t|d} t|d} t|d } t|d } ||t|||g|| g| | | gd d S) ag!Add a domain-centered lat-lon grid to a RegribMany object. Adds to the given hwrf.regrib.RegribMany object a latitude-longitude grid centered on some GRIB product. The grid will be re-centered at every forecast time, so the grid is allowed to move. Centering information comes from the name+"_grid" option in the task's section. The value should be a comma-separated list of seven values: * res1,res2 - grid resolution for GRIB1 grid 255 * size1,size2 - size in degrees for GRIB1 grid 255 * scan - scanning mode flags for GRIB1 grid 255 * n1,n2 - gridpoint count for GRIB1 grid 255 @param task the task that provides configuration information @param r the hwrf.regrib.RegribMany object to receive the grid @param name the name of the new grid @param rel the GRIB product in r on which this grid is centered_grid,r)ressizescannN)confstrrsplitlenAssertionErrorfloatintaddr ) taskrnamerelcontentssplitres1res2Zsize1Zsize2rn1n2r.=/lfs/h1/ops/prod/packages/hwrf.v13.2.9/ush/hwrf/hwrfsystem.pyadd_clatlon_grids        r0c Cs||d}|d}t|dks(tt|d}t|d}t|d}t|d} t|d} t|d } t|d } t|d } t|d }||tjj | ||||| | | g| | |gd dS)a!Adds a grid-centered lat-lon grid to a RegribMany object Adds a new grid to an hwrf.regrib.RegribMany object, centered on a prior existing grid but with a border added around its edges. The grid is recalculated at every forecast time so it works with moving grids as well. Grid expansion information comes from the name+"_expand" option in the given task's section. The value should be a comma-separated list of nine values: * west extension in degrees * east extension in degrees * north extension in degrees * south extension in degrees * n1,n2 - new gridpoint count for GRIB1 grid 255 * scan - new scanning mode flags for GRIB1 grid 255 * res1,res2 - new resolution for GRB1 grid 255 @param task the task that provides configuration information @param r the hwrf.regrib.RegribMany object to receive the grid @param name the name of the new grid @param rel the grid on which this grid is centered._expandr rrrrrrrr)westeastnorthsouthrrrN) rrrr r!r"r#hwrftracker expandlatlonGRIB)r$r%r&r'r(r)r4r5r6r7r,r-rr*r+r.r.r/add_expandlatlon_grid<s,           r<cCsL|d}|d}||d}||d}|r8||||rH|||dS)a=!Requests deliver to com and/or intercom of a RegribMany product. Utility function for deliveries. Given what="hwrftrk" this will look for options "hwrftrk%com" and "hwrftrk%intercom" in the given task's config section. If each option is present and non-empty, the corresponding delivery is enabled and the option's value is used as the delivery location. @param task the task that provides configuration information @param what the RegribMany product being delivered @param r the hwrf.regrib.RegribMany whose products are being deliveredz%comz %intercomN)confrawto_com to_intercom)r$whatr%ZcomvarZ intercomvarZcomlocZ intercomlocr.r.r/to_com_intercomas    rBcs*eZdZdZfddZdddZZS) ra`!Configures the GSI post-processing and regribbing. Constructs tasks that will run the post-processing and regribbing on the inputs and outputs of GSI. Arranges for the standard HWRF GSI diagnostic output grids, and makes them configurable by the HWRF config files. This class uses a config section to define many aspects of the GSI post-processing. @code{.unformatted} [gsi_products] # Settings for GRIB1 grid 255 for each grid: d3_grid=0.02,0.02,12.,12.,136,600,600 d2_grid=0.06,0.06,30.,30.,136,500,500 # GRIB2 compression method grib2_compression=32 ; complex packing with second-order differences # grib2_compression=40 ; "lossless" jpeg 2000 # Delivery settings: hwrforg_n%com={out_prefix}.hwrforg_n.grb2f00 hwrforg_i%com={out_prefix}.hwrforg_i.grb2f00 hwrfges_n%com={out_prefix}.hwrfges_n.grb2f00 hwrfges_i%com={out_prefix}.hwrfges_i.grb2f00 hwrfanl_n%com={out_prefix}.hwrfanl_n.grb2f00 hwrfanl_i%com={out_prefix}.hwrfanl_i.grb2f00 @endcode The d2_grid and d3_grid options configure the intermediate and innermost domain output grids. They are sent into add_clatlon_grid() to generate the GRIB1 grid 255 (user-defined regular latitude-longitude) grid definition for interpolation.c stt|j|||f|dS)a<!HWRFGSIPostProcessing constructor @param ds passed to Datum: the Datastore object for this Task @param conf the conf object for this task (passed to HWRFTask) @param section the conf section for this task (passed to HWRFTask) @param kwargs more keyword arguments passed to superclassN)superr__init__)selfdsconfsectionkwargs __class__r.r/rDs zHWRFGSIPostProcessing.__init__gsipost gsigribberc  Cs|j} |j} tj| | |} |rR| j||j||j||j |||d| j||j||j||j |||dd| ddf} t t t | djdddt t | djdddt t | d jdddt t | d jdddd d | ft t | d jdddd d d | ft t | djdddt t | djdddd} t| |tjjd}t| |tjjd}t|| d|t|| d|| dt| |tjjd| dt| dt| |tjjd| dt| dt| |tjjd| dt| dt| |tjjd| dt| dt| |tjjd| dt| dt| |tjjd| dtdD]*}dD]}d||f}t||| qqtjj| | || | jddd}| |_||_| |fS)a!Creates the gsi post-processor and regribber tasks. Creates the gsipost member variable, an hwrf.gsipost.GSIPost; and the gsigribber member variable, an hwrf.gribtask.GRIBTask. The gsipost converts GSI input and output files (wrfinput, ghost or wrfanl) to native E grid GRIB1 files. The gsigribber converts the E grid GRIB1 files to GRIB2 files on selected output grids. @param gsi_d02 the hwrf.gsi.FGATGSI that runs the intermediate domain data assimilation @param gsi_d03 the hwrf.gsi.FGATGSI that runs the innermost domain data assimilation @param storm1ghost the hwrf.wrf.WRFDomain that represents the innermost ghost domain @param storm1ghost_parent the hwrf.wrf.WRFDomain that represents the intermediate ghost domain @param ceninit the hwrf.init.InitBeforeGSI that runs the analysis time (FGAT 0 hour) initialization off of the GDAS 6hr forecast. @param gsid03_flag True=domain 3 gsi was run, False otherwise @param gsipost_name the section and task name for the gsipost @param gsigribber_name the section and task name for the gsigribber)orggesanl%dgrib2_compression copygbrOMP_NUM_THREADSMKL_NUM_THREADSwgrib2wgribcnvgrib-g12-p-nvsatgrib2hwrf_regrid_merge)rTrXrY cnvgrib_g12cnvgrib_g12_nvr^ regridmerge)domain which_stepZd3d2Z hwrforg_nZ hwrforg_iZ hwrfges_nZ hwrfges_iZ hwrfanl_nZ hwrfanl_iinz hwrf%s_%srstartstepend)dstorerGr8rLGSIPostadd_caserunghost get_ghout get_ghostrstage3confintr rrgetexeenvr F_ORGr0r#gridrF_GESF_ANLrBgribtaskGRIBTaskcyclerM)rEgsi_d02gsi_d03 storm1ghoststorm1ghost_parentceninit gsid03_flagZ gsipost_nameZgsigribber_namerFrGrLg2pgZstorm1ghost_gribZstorm1ghost_parent_gribwgrbaserMr.r.r/ make_gsi_posts      &(        z#HWRFGSIPostProcessing.make_gsi_post)rLrM)__name__ __module__ __qualname____doc__rDr __classcell__r.r.rJr/rvs ! csPeZdZdZfddZdddZddd Zdd d ZdddZddZ Z S)ra!Creates the post-processing for the HWRF forecast job. Creates and configures all tasks related to the post-processing system. This includes the post, regribber, trackers, and any NHC-specific product generation, as well as some data delivery settings. Everything is made configurable via the hwrf.config.HWRFConfig system. This class is configurable through config file options: @code[.conf] [forecast_products] # Post-processing start, end and step for various components: tracker_step=1 # hours between tracker inputs nonsatpost_step=1 # hours between non-satellite post inputs satpost_step=6 # hours between satellite post inputs wrfcopier_start=0 # first WRF native output time to copy to COM wrfcopier_end=9 # last native output time to copy to COM wrfcopier_step=3 # hours between WRF native outputs copied to COM combinetrack_fhr=12 # length of cycling track in hours # Settings for GRIB1 grid 255 (native lat-lon) for each grid: d23_grid=0.02,0.02,12.,15.,136,751,601 d123low_grid=0.20,0.20,90.,110.,136,551,451 d123high_grid=0.06,0.06,90.,110.,136,1834,1500 d2_grid=0.06,0.06,12.,14.,136,234,201 d3_grid=0.02,0.02,7.5,9.0,136,450,375 d2t_grid=0.06,0.06,30.,30.,128,500,500 d1t_grid=0.10,0.10,30.,30.,128,301,301 # Tracker grid expansion settings: trk_expand=2.5,2.5,4.0,4.0,1000,1000,128,0.02,0.02 # GRIB2 compression method: grib2_compression=32 ; complex packing with second-order differences # grib2_compression=40 ; alternative: "lossless" jpeg 2000 # Output filenames: hwrftrk%com={out_prefix}.hwrftrk.f{fahr:03d}.grb hwrftrk%intercom={out_prefix}.hwrftrk.grbf{fahr:02d} anl_outer={out_prefix}.wrfanl_d02 anl_inner={out_prefix}.wrfanl_d03 hwrfprs_m%intercom={out_prefix}.hwrfprs.d23.0p02.f{fahr:03d}.grb hwrfprs_n%intercom={out_prefix}.hwrfprs.d3.0p02.f{fahr:03d}.grb hwrfprs_i%intercom={out_prefix}.hwrfprs.d2.0p06.f{fahr:03d}.grb hwrfprs_p%intercom={out_prefix}.hwrfprs.d1.0p20.f{fahr:03d}.grb hwrfprs_c%intercom={out_prefix}.hwrfprs.d123.0p06.f{fahr:03d}.grb hwrfprs_g%intercom={out_prefix}.hwrfprs.d123.0p25.f{fahr:03d}.grb hwrfsat_m%intercom={out_prefix}.hwrfsat.d23.0p02.f{fahr:03d}.grb hwrfsat_n%intercom={out_prefix}.hwrfsat.d3.0p02.f{fahr:03d}.grb hwrfsat_i%intercom={out_prefix}.hwrfsat.d2.0p06.f{fahr:03d}.grb hwrfsat_p%intercom={out_prefix}.hwrfsat.d1.0p20.f{fahr:03d}.grb hwrfsat_c%intercom={out_prefix}.hwrfsat.d12.0p06.f{fahr:03d}.grb hwrfsat_g%intercom={out_prefix}.hwrfsat.d123.0p25.f{fahr:03d}.grb hwrf2prs_m%com={out_prefix}.hwrfprs.d23.0p02.f{fahr:03d}.grb2 hwrf2prs_n%com={out_prefix}.hwrfprs.d3.0p02.f{fahr:03d}.grb2 hwrf2prs_i%com={out_prefix}.hwrfprs.d2.0p06.f{fahr:03d}.grb2 hwrf2prs_p%com={out_prefix}.hwrfprs.d1.0p20.f{fahr:03d}.grb2 hwrf2prs_c%com={out_prefix}.hwrfprs.d123.0p06.f{fahr:03d}.grb2 hwrf2prs_g%com={out_prefix}.hwrfprs.d123.0p25.f{fahr:03d}.grb2 hwrf2sat_m%com={out_prefix}.hwrfsat.d23.0p02.f{fahr:03d}.grb2 hwrf2sat_n%com={out_prefix}.hwrfsat.d3.0p02.f{fahr:03d}.grb2 hwrf2sat_i%com={out_prefix}.hwrfsat.d2.0p06.f{fahr:03d}.grb2 hwrf2sat_p%com={out_prefix}.hwrfsat.d1.0p20.f{fahr:03d}.grb2 hwrf2sat_c%com={out_prefix}.hwrfsat.d12.0p06.f{fahr:03d}.grb2 hwrf2sat_g%com={out_prefix}.hwrfsat.d123.0p25.f{fahr:03d}.grb2 @endcode Config options have certain formats: * product%com and product%intercom --- delivery location in com and intercom for each regribber output product * *_grid --- GRIB1 grid 255 grid descriptions sent to add_clatlon_grid() * *_expand --- GRIB1 grid 255 grid expansions sent to add_expandlatlon_grid() * *_step and *_fhr --- times or timespans in hours. All delivery filenames are relative to {com} and are subject to string expansion by hwrf.config.HWRFConfig.timestrinterp(). Hence everything in the [config] and [dir] sections are available, as well as standard time values. The product names in product%com and product%intercom follow a certain pattern: @code hwrfprs_m hwrf2sat_g @endcode In the second example, here is what each component means: * hwrf or hwrf2 -- GRIB1 or GRIB2 file? The GRIB1 files are created first, and are later converted to GRIB2 * prs or sat -- non-satellite post (prs) or satellite post (sat) * m, n, i, p, c or g -- the grid Here are the grid meanings: * n -- innermost domain only at its resolution * i -- intermediate domain only at its resolution * p -- parent domain only at its resolution * m -- innermost and intermediate domains, at innermost domain resolution * c -- if prs, parent and intermediate domains; if sat, all three domains. This is at the intermediate domain resolution. * g -- global quarter degree grid, GRIB1 grid 193. That is the output grid for the GFS master GRIB files.c  sFtt|j|||f| ||_||_||_||_||_| |_| |_ dS)aK!Constructor for HWRFForecastPostProcessing @param ds the produtil.datastore.Datastore to use @param conf the HWRFConfig to use for configuration options. This conf is passed down to the RegribMany during regribbing operations. @param section the config section to use. @param runwrf the object that runs the forecast, such as an hwrf.fcsttask.WRFAtmos or hwrf.mpipomtc.WRFCoupledPOM @param wrf the hwrf.wrf.WRFSimulation that represents the forecast model. @param postdoms a list of domains to post-process in order of GRID id. @param wrfdoms a list of WRF domains in order of GRID id @param moad the Mother Of All Domains (MOAD), an hwrf.wrf.WRFDomain @param storm1inner the first storm's intermediate domain, an hwrf.wrf.WRFDomain @param storm1outer the first storm's innermost domain, an hwrf.wrf.WRFDomain @param kwargs additional keyword arguments are passed to the superclass constructorN) rCrrDrunwrfwrfpostdomswrfdomsmoad storm1inner storm1outer) rErFrGrHrrrrrrrrIrJr.r/rDis z#HWRFForecastPostProcessing.__init__?c Cs:|d|d}t|j|j|jd|ddddgd|_|jS) a!Creates the non-satellite post-processor. Creates the nonsatpost member, which runs the non-satellite post processing. That is the object that runs everything except the synthetic satellite brightness temperatures. This is a hwrf.post.PostManyWRF object. @return the created object @param default_step non-satellite post-processor input step, if none is provided in the config file.Znonsatpost_steprg nonsatpostFhistoryauxhist2auxhist3needcrtmstreams) conffloatr rrrGrrEZ default_steprjr.r.r/make_nonsatposts z*HWRFForecastPostProcessing.make_nonsatpostrc Cs:|d|d}t|j|j|jd|ddddgd|_|jS) a/!Creates the satellite post-processor Creates the satpost member, an hwrf.post.PostManyWRF object that runs the satellite post-processing. @return the created object @param default_step satellite post-processor input step, if none is provided in the config file.Z satpost_steprgsatpostTrrrr)rr rrrGrrr.r.r/ make_satposts z'HWRFForecastPostProcessing.make_satpostcopywrfFc Cs|dd}|dd}|dd}|jddd }|dks@t|j}|j}|rttj|j |j|||j dd } n"tj |j |j|||j dd } | d | d | d | d| j ||j|dd| j ||j|ddd} |} | d|krl| ddkrdnd} |jd| | dD]} | j| dddd} q4| |}|| ksft|} q| svt| d|j ddd}|jddd}|r$|dkr$|d d!}|d"}|d#}ttt||d$D]:}d%|}|jd&|d'}|jd(|d'}| j|d|dq|d)d*}|d+krt|d|jj}|jd,d-D]*}|d.}t|}| j|dd/|dqX|jd0d-D]}| |q| |_| S)1ay!Generates the WRF input/output copier task. Creates the wrfcopier member variable which copies inputs and outputs of the forecast job directly to COM. This is an hwrf.copywrf.WRFCopyTask object. @return the created object @param wrfcopier_name the section and task name to use for the hwrf.copywrf.WRFCopyTask that is created.Zwrfcopier_startrZ wrfcopier_endr2Zwrfcopier_steprconfigcycling_intervalg@ out_prefixznamelist.input wrfinput_d01 wrfbdy_d01zfort.65Z anl_outer)destnameZ anl_innerFgMbP?rrrg)timestreamz2{vit[stnum]:02d}{vit[basin1lc]}.{inname_colon_s00})checkrTztrack_d03.patcf ocean_modelZno_ocean_model_specified run_oceanPOMforecast_length~pom_output_stepg @g{Gz?z%04d.ncz{vit[stormname]}.{ocrest})ocrestz{out_prefix}.pom.{ocrest}run_wavenoyesZww3rst)rZ restarttimez#{vit[stormid3lc]}.restart.f%03d.ww3Zww3out) rrGgetfloatr rrr8 multistorm WRFCopyTaskMSrlgetstrr WRFCopyTask d_initial analysis_namerr>rproducts d_wrfprodd_finalgetboolrsranger"mathfloortimestrrrr| wrfcopier)rEZwrfcopier_namerZ copystartZcopyendZcopysteprrrrcopiedfhrZ prodstreamproductZfhr2rrfcstlenZpom_output_secZpom_output_hrsZioutrfromnametonamerctimepZrstimer.r.r/make_wrfcopiers                  z)HWRFForecastPostProcessing.make_wrfcopierTc! Cs|j|j}}|j|j|j}}}|j} |dd} |dd} t||d} t||d} t||d}t||d}t||d}t||d}t j dt j j d}t j dt j jd}t j j| d| d d }| jj}|d ks|d kr|jd kr|jd 7_d|ddf}ttt| djdddtt| djdddtt| djdddtt| djdddtt| djddddd|ftt| djdddddd|ftt| djdddd}t||d| |d}t||d| |d}t||d| |d}t||d ||d }t j j}|d!||| | t|d"||| | t|d#||| | t|d$||| | |d%|d$tt|d!|t|d%|t|d#|t|d"||d&|||| || ||d't j |d&t|d'||r|d(||||t!|d)||||t!|d*||||t!|d+||||t!t|d(|t|d+|t|d*|t|d)||r`|d,|||| ||d-t j |d,|d.||||d/t j |d.t|d/|t|d-|t j"j#|j$| d0|| j%d1| d1d2}t j j&|j$| d3| j%|d4dd1| d1d2}|'| j|d'|(d5| )d6d7|*d8| )d6d9}|j+d:d;| )d6d<d=|j+d>d?d@| )d6dAdB|j+dCdD| )d6dEdF|j+dGdD| )d6dHdF|rj|j+dIdD| j)d6dJdKdLdFt j,j-|j$| dM|j.||j/|jj| dN} | |_0||_1||_ ||_2|||| fS)Oa !Generate the regribbing objects and the main tracker. Generates the gribber, tracker, track and nhcp member variables and returns them in a tuple: * nhcp --- the hwrf.nhc_products.NHCProducts object that makes NHC-specific output products and validates the wrfdiag files. * track --- the final track file output by the tracker, returned by hwrf.tracker.send_atcfunix() called on the new tracker object * tracker --- the hwrf.tracker.TrackerTask that runs the GFDL vortex tracker * gribber --- the hwrf.gribtask.GRIBTask that runs the regribbing on the post-processors created by make_satpost() and make_nonsatpost() @param extra_trackers logical flag: are the parent and intermediate domain trackers also desired? If so, extra regribbing is arranged, that will be required by make_extra_trackers() @param satpost_flag logical flag: is satellite post-processing desired @pre The make_nonsatpost() must have been called. If the satpost_flag=True, then make_satpost() must also have been called. @returns a tuple (nhcp,track,tracker,gribber) of the objects that were createdrrcombinetrack_fhrg(@)rcpartN)rdomlat)rdomlon)latlonALEPgv@rQrRrSrTrrUrXrYr^rZr[r\r]r_)rTrXrYr^r`rarbZstormcoreZtrkd3ZsynopZ p123_coreZ p123_synopZ p123_globalZp123_storm_grib1Z p123_stormZtrkin123hwrftrkZ s123_coreZ s123_synopZ s123_globalZ s123_stormZtrkin12 hwrftrkd02Ztrkin1 hwrftrkd01 regribberrgrhr9 tracker_step rawatcfunixdirz {com}/{out_prefix}.trak.hwrf.raw cleanatcfunixz%{com}/{out_prefix}.trak.hwrf.atcfunixZ atcf3hourlyrz${com}/{out_prefix}.trak.hwrf.3hourly)freqlocationZ atcfshort6hrrpz%{com}/{out_prefix}.trak.hwrf.short6hr)rcutrZ combinetrack zB{com}/{vit[stnum]:02d}{basin1lc}.trak.hwrf.atcfunix.{YMDH}.combine)rrZcombinetrack_ucz@{com}/{vit[stnum]:02d}{basin1}.trak.hwrf.atcfunix.{YMDH}.combineZcombinetrack_00z&{realstormcom}/relocate.trak.{YMDH}.goz {fakestormid}) realstorm nhc_products)r)3rrrrrrGrsrr r8regrib GRIBSubsetterr9hwrf_combine_subsettracker_subset FixedLocationsyndat pubbasin2ewcenterr rrrtrur0rw quarterDegreer#rbrr;rBvinttaverrzr{rlr| TrackerTaskadd_moving_gridsend_raw_atcfunix strinterp send_atcfunixsend_atcfunix_subsetr NHCProductsrrnhcptrackgribber)!rEextra_trackers satpost_flag gofile_flagrrrrrrGrrZgrid3grid2grid1ZsatE3ZsatE2ZsatE1Zhwrfsubtrksubdomlocbasinrr%Z stormgridZcoregridZ trkd3gridZ synopgridZqdrr9rrr.r.r/make_gribber_trackers$         &(                     z/HWRFForecastPostProcessing.make_gribber_trackercCs|j}|j}|j}|ddd}|dd}tjj||d|j||dd}| |j |d| d | d d | d | d d tjj||d|j||dd}| |j |d| d | d d| d | d d||_||_||fS)a(!Generates intermediate and outermost domain trackers. Generates trackers that use intermediate and outermost domain data to track the storm and analyze its intensity. These are intended for use in analyzing the effects of resolution and upscale feedback on hurricane track, structure and intensity. Creates these member variables and returns them: * trackerd01 --- a tracker that just uses the outermost domain data * trackerd02 --- a tracker that uses the outermost and intermediate domain data @return A tuple (trackerd01,trackerd02) of the new trackers @pre The make_gribber_tracker() must have been called with extra_trackers=True, so it will add the extra GRIB products needed by the new trackers.rrrrrg trackerd02rhrrrz#{com}/{out_prefix}.trak.hwrfd02.rawrz({com}/{out_prefix}.trak.hwrfd02.atcfunix trackerd01rz#{com}/{out_prefix}.trak.hwrfd01.rawz({com}/{out_prefix}.trak.hwrfd01.atcfunix)rlrGrgetintrr8r9rr|rrrrrrr)rErFrGrrrrrr.r.r/make_extra_trackerss@      z.HWRFForecastPostProcessing.make_extra_trackers)r)r)rF)FTF) rrrrrDrrrrrrr.r.rJr/rsg 7   W =cs$eZdZfddZddZZS) ForecastBasecsZtt||||||f\|_|_|_|_|_|||_|_ d|_ d|_ d|_ d|_ dSN)rCrrDrGrFrpominitww3init hycominitocstatusrww3post hycompostrealwrf)rErGrFrr r r r rJr.r/rD s zForecastBase.__init__c Cs|jdd}|jddd}|jdd}|jddd}|jddd }|jd d d }|jd d d }|jddd}|r|dkr|r|dkrtjj|j|j||j|j d |j |j d|_ n&tj j|j|j||j|j d |j d|_ n|rT|dkrT|r0|dkr0tjj|j|j||jd |j|j d|_ n"tjj|j|j||jd |jd|_ ntjj|j|j||jd d|_ |r|dkrtjj|j|jd|||j d|_|r|dkrtj j|j|jd||j d|_|j |_|jS)Nrrrrr wave_modelWW3forecast_sectionrforecast_productsww3_output_stepi`Tww3_pntout_steprrHYCOM)tasknamer r )rr )rr r )rr rr)outsteppntstepww3r)rhycom)rGrrrr8rZ WRFWW3HYCOMrFrr r r rrZWRFCoupledHYCOMZ WRFWW3POMr mpipomtc WRFCoupledPOMfcsttaskWRFAtmosZWW3PostrZ HYCOMPostrr) rE ocean_flagocean wave_flagwavefcst_secrrrr.r.r/ make_forecasts      zForecastBase.make_forecastrrrrDr'rr.r.rJr/r s rcs$eZdZfddZddZZS)FakeStormForecastc s8tt||||dddd||_||_||_||_dSr )rCr)rDmultistorm_sids finalmerge stormNouter stormNinner)rErGrFrr*r+r,r-rJr.r/rDBs zFakeStormForecast.__init__c Cs.|jdd}|jdd}|jddd}|jd}t|j}|sH|rTtjdtjj |j |j||j dd}tj |j |jd |j ||j |j}||||||j||td |d D]L}|j|d } |j|| |||jd ||||j d |q||j||_dS) NrrrrrrzmOcean and wave must be disabled when running in multi-storm mode ([config] run_ocean and run_wave must = no).rfakeinitrz storm%souterz storm%sinner)rGrrr*rr8 exceptionsHWRFConfigUnsupportedrWRFAtmosMultiStormrFrFakeInitr-r, add_metgrid add_geogrid add_fort65 add_wrfbdyr+ add_wrfinputr add_merge add_wrfanlr) rEr"r$r&Z prioritystormnum_realstormsrr.istormidr.r.r/r'JsL   zFakeStormForecast.make_forecastr(r.r.rJr/r)As r))5r__all__ossysrprodutil.datastoreprodutil produtil.run hwrf.configr8hwrf.wrf hwrf.post hwrf.numerics hwrf.launcher hwrf.regrib hwrf.gribtask hwrf.trackerhwrf.storminfohwrf.wpshwrf.nhc_products hwrf.copywrf hwrf.fcsttask hwrf.ensda hwrf.relocate hwrf.init hwrf.prephwrf.gsi hwrf.mpipomtc hwrf.bufrprep hwrf.hwrftaskhwrf.multistormrrrrrr r r r r rrr0r<rBhwrftaskHWRFTaskrrobjectrr)r.r.r.r/s2 ( ((  % 6