U  g @s dZdddddddgZdd lZdd lZdd lZdd lZdd lZdd lZdd lZdd l Z dd l Z dd l Z dd l Z dd lZdd lZdd lZdd lZdd lmZdd l mZmZmZmZmZmZdd l mZmZdd lmZmZmZm Z ddlm!Z!m"Z"ddlm#Z#m$Z$ddl m%Z%m&Z&m'Z'm(Z(m)Z)dEddZ*dFddZ+ddZ,ddZ-ddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7g Z.d8dZ/d9d:Z0dGd;dZ1Gdd>ej4j5Z6Gd?d@d@ej4j5Z7GdAdBdBej4j8Z9dCZ:GdDdde j;j<Z=d S)Hzr!This module contains tasks to prepare input for the GFDL Vortex Tracker, run the tracker and deliver its results.hwrf_combine_subsettracker_subset expandlatlonvinttave TrackerTask GRIB1VintTave jtwc_rewriteN)set_ecflow_meter) TimeArray to_fraction to_datetimeto_datetime_relpartial_ordering to_timedelta)GRIBOpGRIB1Op)runstrbigexealiascheckrun)TempDirNamedDir) isnonempty deliver_file) TrackerErrorTrackerModeErrorTrackerStormErrorMissingGRIBErrorGRIBLocationErrorc Cst|d}t|d}|D]}|ddddddddd d d d d ddddd}|dd}t|}|ddkr|dk r|d|ft||dq|dk r|d|fqW5QRXW5QRXdS)z!Rewrites track files as used by the HWRF WPAC parallels from 2013-2015 @param inatcf input ATCF file @param outatcf output ATCF file @param logger a logging.Logger for log messagesrtwtAAIOBBZSPSHZSIz-9,z 0,z-99,z 0,z-999,z 0,z-9999,z 0,rp!Nz ATCF LINE: %s)filez SKIP LINE: %s)openrstripreplaceintinfoprint)ZinatcfZoutatcfloggerinfoutflinehourZihourr59/lfs/h1/ops/prod/packages/hmon.v3.2.7/ush/hwrf/tracker.pyrsN     Fccs|rddddg}ndddddddg}dD]4}|D]*}|D] }|d ||fd kr8|Vq8q0q(|rd D]4}d D]*}|D] }|d ||fd krv|Vqvqnqf|D]$}|d d krtd|r|VqdS)a!Selects lines for the hwrfprs_c files. This subroutine parses an array of lines from wgrib -s and selects lines to send into the hwrfprs_c and hwrfsat_c GRIB1/2 output files (hurricane_region=True) or hwrfprs_g and hwrfsat_g files (hurricane_region=False). Long ago (in 2011) this was the input to the tracker. In the current system, it contains fields the tracker does not need, lacks some fields it does need, and is in the wrong order for it to be accepted as tracker input. It contains synthetic satellite and other diagnostic quantities that are useful for various data analysis in the high resolution combined grid. The tracker scripts no longer use this output set for any purpose, but it is still valuable for diagnostics. This is in the hwrf.tracker module for historical reasons: the hwrfprs_c files were originally intended for the tracker. @param wgribout output from wgrib @param hurricane_region if True, a more limited set of variables is keptZUGRDZVGRDZRHZABSVZSPFHHGTTMP)Rz %s:%d mb:r) r=i,i^iir<iXr;r:r9)r7r8z mb:zoPRMSL|SBT|BRT|AMSRE|trop|HPBL|PWAT|CAPE|CIN|column|REFC|HLCY|GRD:10 m above|TPCP:sfc|TMP:2 m above|RH:2 m aboveN)findresearch)wgriboutZhurricane_regionZvar3dZlevvarr3r5r5r6hwrf_diagnostic_subset;s*  rCccst|dD] }|Vq dS)z!A simple wrapper around hwrf_diagnostic_subset that provides a subset of the HWRF fields and vertical levels suitable for analyzing the large-scale hurricane structure. @param w output from wgribTNrCwr3r5r5r6rpsccst|dD] }|Vq dS)z!A simple wrapper around hwrf_diagnostic_subset that provides a subset of the HWRF fields and vertical levels suitable for analyzing the synoptic-scale or global fields and comparison to the parent global model. @param w output from wgribFNrDrEr5r5r6hwrf_global_subsetxsrGzHGT:925zHGT:850zHGT:700zUGRD:850zUGRD:700zUGRD:500zVGRD:850zVGRD:700zVGRD:500z UGRD:10 m z VGRD:10 m zABSV:850zABSV:700ZPRMSLzHGT:900zHGT:800zHGT:750zHGT:650zHGT:600zHGT:550zHGT:500zHGT:450zHGT:400zHGT:350zHGT:300zHGT:250zTMP:500zTMP:450zTMP:400zTMP:350zTMP:300zTMP:250ccs*tD] }|D]}||kr |Vqq qdS)aq!This is a GRIB subsetter intended to be sent to the subset operator of an hwrf.regrib.GRIB1Op object, to produce GRIB1 files that contain only fields needed by the tracker. This function iterates over wgrib -s output lines. It subsets the lines, returning the ones the tracker expects, in the exact order the tracker expects them. The input is an array of lines from wgrib -s. This is intended to be used with the gribtask and regrib modules by doing gribop/tracker_subset to produce a GRIB1Op that will make a tracker subset of the given GRIB1 file. @param wgribout output from wgribN)TRACKER_SUBSET)rAZfindmer3r5r5r6rs c # Ks|j}|jdk r"|jd|fdd|D}|\ }}}}}}}}}}}}d|d@krf||}}d|d@kr|||}}d|d@kr||}}|td ||td |}}|td ||td |}} t| }!d|!d@kr||}}d|!d@kr|| } }d|!d@kr&| |}} d t|t| | ||!||td | td | f }"|jdk rv|jd |"ftj||"dS) af!Internal function that expands a lat-lon grid to make a bigger one. This is part of the implementation of expandlatlon and should not be called directly. Given the input grid from center.grib1grid, expand the grid in all four compass directions by a specified number of degrees, and produce a new grid with a different resolution, scanning mode and gridpoint count @param op the hwrf.regrib.GRIBOp being run @param regrib the hwrf.regrib.Regrib for data storage @param name the grid name @param center the GRIB1 product being centered upon @param west,east,north,south how many degrees to add in each direction (a float) @param n0,n1 gridpoint counts for the GRIB1 grid 255 @param scan scanning mode flags for the GRIB1 grid 255 @param res0,res1 resolution information for GRIB1 grid 255 @param kwargs Ignored.Nzexpandlatlon of input grid %scSsg|] }t|qSr5)r-).0xr5r5r6 sz'action_expandlatlon..r@ r9z"255 0 %d %d %d %d %d %d %d %d %d 0zexpandlatlon output grid is %s) grib1gridr0r.splitr-hwrfregribGRIBGrid)#oprRnamecenterwesteastnorthsouthZn0Zn1scanZres0Zres1kwargsingridZoldgridogidZojunk1ZonscountZoewcountZonlatZoelonZoscanZoslatZowlonZonsresZoewresZojunk2Zosloniwlonielonislatinlatiscansr5r5r6action_expandlatlonsD    ""     rec Cst|dkr$|ddkr$|ddks(t|dkr8|dkssz,GRIB1VintTave.action_vinttave..runitzgenerate grbindex file %sr z7&timein ifcsthour=%s, iparm=7 , gribver=1, g2_jpdtn=0/ z znamelist: Zhgt_levs) 3Tforcez8&timein ifcsthour=%s, iparm=11 , gribver=1, g2_jpdtn=0/ z tnamelist: Ztmp_levs)rrrz-g%sz-k4*-1 33 100 850z.u850z-k4*-1 33 100 700z.u700z-k4*-1 33 100 500z.u500z-k4*-1 33 105 10z.u10mz-k4*-1 7 100 850z.z850z-k4*-1 7 100 700z.z700z-k4*-1 2 102 0z.mslpz.phasez.tavewb) Zu850Zu700Zu500Zz850Zz700ZmslpZu10mphaserz%s.%sz1%s: input file is empty! Things may break later.rbz1vint-tave completed: infile=%s inindex=%s grid=%s) grib1grbindex) grib1filerOrqr{rjtempfilegribtempr0r.rcopygbwgribrrgetexeprodutilfileopfortlinkstrconftimestrinterprr*writeconfstrrwarningshutil copyfileobjrQrR GRIB1File)'rrrRrxtimetask blocksizer{r\infilegridinindexZ znamelistZ tnamelistZ tave_namelistZzfileZzindexZtfileZtindexZtavefileZ taveindexoutfileoutindexZ outgrbindexrrr~rr}ZflfahrrfZnmltxtZdashgr2extZpartnamer1retvalr5rr6rws                              $  zGRIB1VintTave.action_vinttave)NNrzN)__name__ __module__ __qualname____doc__rprvrw __classcell__r5r5rsr6rs  c@seZdZdZdddZdS)RawATCFProductz!A FileProduct for tracker output. This is part of the internal implementation of TrackerTask and should not be used directly. It is a FileProduct that contains the raw, unmodified tracker outputNcCsjd}|dkr|}t||jd|dd|_|sH|d|jfn|d|jf|j|ddS)a !Copies the tracker output to its destination without modification. Sets availability and calls callbacks. @param tracker the Task that ran the tracker @param fhr the forecast hour,ignored @param logger a logging.Logger for log messagesoutput.atcfunixNTkeepr03%s: has no callbacks, so no DBN and no NHC delivery#%s: has callbacks. Will call them.r) logrlocation available has_callbacksdebugdidr.call_callbacks)rrtrackerfhrr0rr5r5r6deliverszRawATCFProduct.deliver)N)rrrrrr5r5r5r6rsrcs2eZdZdZfddZd ddZddZZS) CleanATCFSubsetProductz!A FileProduct that delivers a subset of a track. This is part of the internal implementation of TrackerTask and should not be used directly. It is a FileProduct that delivers a cleaned-up, subsetted version of the tracker output.c stt|jf|dS)z!Create a CleanATCFSubsetProduct that will deliver a track with the specified last allowable forecast hour. @param kwargs passed to produtil.datastore.FileProduct.__init__()N)rorrp)rrr\rsr5r6rpszCleanATCFSubsetProduct.__init__Nc s>|dkr|}d}fdd}|d|}|dd}|dd}t|d }tjd d dtjd d j} | j} t| } t | | j dB|D]4} ||||| \} }|rq| dk r| | qW5QRXW5QRX|}t| jd |dd_s|djfn|djfj|ddS)a]!Reads the tracker output, discarding everything after the specified forecast hour. If an invalid line is found after time 0, that line and everything after it is discarded. @param tracker the task that ran the tracker @param fhr the last forecast hour to include @param logger a logging.Logger for messagesNrc sL|krHzt|WStttfk rF}z |WYSd}~XYnXdSr)r-KeyError TypeError ValueError)rdverrr5r6gets z+CleanATCFSubsetProduct.deliver..get subset_fhr subset_freqrgline_cutrFzw+t.)deletemodebufsizeprefixdirirTrrr)rr*rNamedTemporaryFilerrrUosfstatfilenofchmodst_mode process_linerrrrr.rr)rrrrr0rrfreqcutZfinZfoutrofstatZinlineZoutlinestopr5rr6rsJ       zCleanATCFSubsetProduct.deliverc Cs zt|dd}t|dd}|dkrR|dkr|dt|fWdSnN|dkrlt||dkrln4|d k r|d|d ||kfWS|||kfWSWnbttfk r}z>|} |d | f|jd | t |fd dW5d }~XYnXdS)a!Processes one line of the track file. Decides if it is time to cease processing of the track file (cut off the track) or continue parsing. @param tracker the task that ran the tracker @param lastfhr the last forecast hour to include @param freq the output frequency in hours. This allows one to turn an hourly track into a six hourly track @param cut index of the last character to include from each line For example, 112 would only include up to the RMW field. @param line the line to process. @return A tuple (line,stop) where "line" is the line to append to the output track, and "stop" is true iff it is time to stop parsing.r'/rrznInvalid wind in track file: wind is 0 at forecast hour %s. Will cut off the track file at this forecast hour.)NTrgN zIgnoring invalid ATCF line: %sz`Invalid ATCF line found. Wind or forecast hour are missing or invalid. Line: %s Error: %sTexc_info)NF) r-rerrorrabsr+rrrr) rrrZlastfhrrrr3rZwindrZrliner5r5r6rs2  z#CleanATCFSubsetProduct.process_line)N)rrrrrprrrr5r5rsr6rs  +rcs*eZdZdZdfdd ZddZZS) TrackerViewa.!This Task is used by the delivery script executed by the gettrk program itself. It derives directly from Task and has no knowledge of the surrounding HWRF workflow: it only knows about the local track filename, destination filenames and final forecast hours for each destination file.Nc s6tt|jf|||d|t||_t||_dS)a!Creates a TrackerView for the specified datastore and taskname. It will deliver a file subsetted to the specified forecast hour and minute. @param dstore the produtil.datastore.Datastore for database info @param taskname the task name in the database @param fhr,fmin the last expected forecast time @param logger The given logger is used to log messages. @param kwargs Other keywoard arguments are passed to the produtil.datastore.Task.__init__() constructor.)dstoretasknamer0N)rorrpr-rfmin)rrrrrrr0r\rsr5r6rps  zTrackerView.__init__c Cs|j}|}t}|j}|jd}tdt|j||}| d|jd}|D]\}} | d|| ft d|} | s| d|f| \} } | |kr|d||| fqZ| d krt|| | d } || jqZ| d krzt|| | d } | jr|d |fWqZd | krjt| d }||krT| d|||fWqZn|d|||fn| d|f|| jWn@tk r}z |jd|t|fddW5d}~XYnXqZ| d|| fqZW5QRX|jdkr|j}n |jd}|D]}||||dq t|dksP|dkrrt|dddkrr|d|jt|jt|jf|d|jt|jt|jfdS)aX!Performs the actual delivery. Queries the database for all products for this task that match certain requirements. All of this task's RawATCFProduct products are delivered, as well as any CleanATCFSubsetProduct products that have the right forecast time. Type name is obtained from the database's prodtype column in the PRODUCTS table. It is assumed that the products for this task have a database id beginning with "taskname::" where "taskname" is this task's name. These assumptions match what is done by the TrackerTask.gN@rz,SELECT id,type FROM products WHERE id LIKE "z%"z%s: prodtype=%sz (.*)::(.*)z8%s: product id does not match category::prodname patternz*%s: not my track (want category %s got %s)r)rprodnamecategoryrz(%s: already delivered. Will not recopy.rz1%s: not delivering yet. Too early: %fhrs > %fhrsz?%s: It is time to deliver now. Deliver at %fhrs, time is %fhrsz-%s: CleanATCFSubsetProduct has no subset_fhr.z%s: unexpected exception: %sTrNz%s: unrecognized prod type "%s" (only RAWATCFProduct or CleanATCFSubsetProduct allowed). Will not deliver this while gettrk is running.gMbP?rrg@g8@z%s reached fhr=%s fmin=%s)rrlistrrr r-r transactionqueryrr?matchrgroupsr.rappendrrrfloat Exceptionrrrpostmsgr)rrdsr0workmenowtZprodidsZprodidprodtypemrrZprodobjrrfuncr5r5r6run&s           .zTrackerView.run)N)rrrrrprrr5r5rsr6r srao#! /usr/bin/env python import sys, logging import produtil.setup, produtil.datastore import hwrf.tracker produtil.setup.setup(eloglevel=logging.INFO) t=hwrf.tracker.TrackerView( dstore=produtil.datastore.Datastore("""{dstorepath}"""), taskname="""{taskname}""", fhr=int(sys.argv[1]), fmin=int(sys.argv[2]) ) t.log().info("In ./deliver script") t.run()cseZdZdZdZd4fdd Zd5dd Zd d Zd6d d Zd7ddZ d8ddZ ddZ e e dddZ ddZe edddZddZe edddZddZe edddZdd Ze eddd!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd9d2d3ZZS):ra!This task runs the GFDL Vortex Tracker on HWRF output. It is intended to be used with the GRIBTask. At present, this only supports a moving grid tracker. Placeholders are present for a stationary grid tracker invocation, but those are not tested.r|TFNc  stt|j|||f| t|t|t| t| t| d|_t|_t|_t||_ t |||_ t ||_ d|_t|_t|_tjj|j|jd|_|jdd|_|jdd|_|jddt|j d | dkrtjj } | |_ dS) a!Creates a new TrackerTask @param ds the produtil.datastore.Datastore to use @param conf the hwrf.config.HWRFConfig for configuration options @param section the HWRFConfig section to use @param start,end,step the times at which data may be available from the GRIBTasks. @param realtime the tracker should wait for data to appear and call delivery scripts at every forecast time. @param write_vit,phaseflag,structflag,ikeflag Passded on to the tracker namelist. @param kwargs passed to hwrf.hwrftask.HWRFTask.__init__() See the tracker documentation for details.) write_vit phaseflag structflagikeflagrealtimeN)confsection fnameinfogmodnamerundescratcfinfoatcfymdhz%Y%m%d%H)!rorrpbool_flagsdict_vitals_gridsr _startr _endr_step_movingr _deliveries _productsrQnamelist Conf2Namelistrr_nmlnl_get _gmodname _rundescrnl_set_if_unsetr-strftimerr masterlogger)rrrrrstartendsteprrrrrrr\rsr5r6rps0    zTrackerTask.__init__cCsR|dk r |n|j}||}t|j|||d}||_|jd|f||j|<|S)a!Requests delivery of the raw, unmodified atcfunix file to the specified location. This creates a new RawATCFProduct with the specified product name and category. If the category is unspecified or None, then this class's taskname will be used. Note that the taskname MUST be used if running in realtime=True mode. @param prodname the name of the new product @param location the output file location, which will be sent through confstrinterp() to do string replacement on forecast and analysis times, and other variables @param category if specified, the product category. By default, this task's taskname is used.Nrrrr)r confstrinterprrrrrr)rrrrrslocprodr5r5r6send_raw_atcfunixs   zTrackerTask.send_raw_atcfunixcCs |j|S)z!Returns the tracker Product with the specified product name or raises KeyError if none is found. @param name the product name)r)rrrUr5r5r6productszTrackerTask.productccs>|dk r ||jkr |j|Vn|jD]\}}|Vq*dS)z]!Iterates over all tracker Products. @param name only iterate over this named productN)ritems)rrrUrlpr5r5r6productsszTrackerTask.productsrgc Cs4|dkr.tt|j|jd}|dks\tn.t|tjrNt t|d}ntt |}|dkrl|dkspt|dk r||n|j }| |}|dk stt |j |||d}t||d<t||d<|dk rt||d<nd |d<||_d|kst|ddk st|dd kst|j||f||j|<|S) aL!Requests delivery of a cleaned subset of the tracker atcfunix file, only up to the specified forecast hour. This creates a new CleanATCFSubsetProduct with the specified product name and category. If the category is unspecified or None, then this class's taskname will be used. Note that the taskname MUST be used if running in realtime=True mode. @param prodname the name of the product @param location the delivery location, which will be sent through confstrinterp() to perform string replacement @param fhr the last forecast hour @param category the product category to use instead of self.taskname @param freq the output ATCF frequency in hours @param cut the last character to include in each line. For example, 112 is the RMWNg @r~r!rrrZ9999r|)r-r rrrj isinstancedatetime timedeltamathceilrr"rrrrrrr) rrrrrrrrr#r$r5r5r6send_atcfunix_subsets6       z TrackerTask.send_atcfunix_subsetcCs|j|||j|j|dS)a!Requests delivery of a cleaned-up version of the full length atcfunix file. This is the same as calling send_atcfunix_subset with the full simulation length as the end time. The prodname will be the Product's name, and the location is the delivery location. If specified and not None, the category will be the Product's category, otherwise it will be this Task's taskname. Note that if realtime=True is enabled, the category must be the taskname. @param prodname the new product's name @param location the delivery location @param category the product category instead of self.taskname)r)r0rr)rrrrrr5r5r6 send_atcfunix s  zTrackerTask.send_atcfunixcCs |jdS)z!Flag: output genesis vitals?rr rr5r5r6 getwrite_vitszTrackerTask.getwrite_vitzFlag: output genesis vitals?cCs |jdS)z!Flag: output phase info?rr2rr5r5r6 getphaseflag!szTrackerTask.getphaseflagzFlag: output phase info?cCs |jdS)z!Flag: output structure info?rr2rr5r5r6 getstructflag'szTrackerTask.getstructflagz)Flag: output storm structure information?cCs |jdS)z!Flag: output IKE info?rr2rr5r5r6 getikeflag.szTrackerTask.getikeflagz#Flag: output storm IKE information?cCs |jdS)z!Flag: run in real-time mode?rr2rr5r5r6 getrealtime6szTrackerTask.getrealtimezFlag: run in real-time mode?c Cst|j|j|j}t|jd}|D]}|j||ddD]\}}tt||dd}| d|t || df||kr| d|j || dfqs6     zTrackerTask.grab_gribscCs|jdkrtd|jdkr$td|jdkr4||_d|_|||}|j}||jks`||jkrntd|fz||j|<||j|<Wn:tk r||jkr|j|=||jkr|j|=YnXdS)a!Tells the tracker to run in moving grid mode, for the specified storm. @param tcvitals The tcvitals must be an hwrf.storminfo.StormInfo. @param gribtask The gribtask must be an hwrf.gribtask.GRIBTask. @param gribname The gribname is the name in the hwrf.regrib.RegribMany of the operation that produces the tracker input for this moving storm.FJCannot mix stationary regional and moving grids in one tracker invocation.TzCannot have multiple moving grids: the current tracker implementation does not support that. Use multiple TrackerTask objects instead.Nz*%s: More than one of this storm specified.) rr _storminforA longstormidrr rr)rrtcvitalsr<r=r>stidr5r5r6add_moving_grid\s4       zTrackerTask.add_moving_gridcCs4|jdkrtdd|_|||}||j|j<dS)a!!Adds a stationary grid on which to run the tracker. @param gribtask The gribtask must be an hwrf.gribtask.GRIBTask to create the input. @param gribname The gribname is the operation name in the grib task's hwrf.regrib.RegribMany for the GRIB data source.TrBFN)rrrArNOVITALS)rrr<r=r>r5r5r6add_regional_grid}s  zTrackerTask.add_regional_gridcCs4|jdkrtd|jdkr$td||j|j<dS)zi!Specifies the tcvitals for a storm to track. @param tcvitals the hwrf.storminfo.StormInfo to useNzfSpecify tracker mode before adding storms. Call add_moving_grid or add_regional_grid before add_stormTzfIn moving grid mode, storms must have associated grid data. Use add_moving_grid instead of add_storm.)rrr rD)rrrEr5r5r6 add_storms  zTrackerTask.add_stormc Cs|}t|jD]^}t|}|d|f||jkrPt|j|j}nd}|j|}t|j dd}d|j |j ||f}| D]\} } |d|t| f|js| s|dtdq| j} | j} | d ks| d krtd | jftt| |jd } tjj| d || f|d| d ks>| d krZ|d| jfd| f} tjj| d|| f|dqqt|d^}d}|jt|jdD]6} |d7}tt| |jd }|d||fqW5QRXd S)a!Symbolically links all input GRIB1/2 files to the current working directory using the file naming convention expected by the tracker. If self.realtime=False, then will also check for the files' existence and will raise MissingGRIBError if one is missing. If self.realtime=True, then it is assumed the tracker is being run in waitfor mode and will wait for the data on its own. In either case, GRIBLocationError will be raised if any GRIB's Product.location is None or '' (the location must be known to make the symlink). @param inputlist a file to create with the list of tracker input fileszprocess storm %sregionalrr z%s.%s.%s.%10d.fzstorm %s time %sz!%s: not yet available. Sleeping.Nr|z0%s: no location specified for this GRIB product.<z%s%05.5drzn%s: no grbindex file location specified for this GRIB product. Assuming .grbindex extension of the GRIB file.z %s.grbindexz %s%05.5d.ixr rrgz%4d %5d )rrrkeysrr.r rDr-rrrrr'rcheckrsleeprrrrr rrr make_symlinkr* datatimesr)rrZ inputlistr0rFZstrstidrDZgridsr Z linkstartrgriblocZlocixminutesriminuter5r5r6 link_gribsf           zTrackerTask.link_gribc Cst|d}|dW5QRX|jD]l}|sR|d|jtdq*t|d0}tt | d}t ||W5QRXW5QRXq&t t|d}t|dd S) ab!Concats all input GRIB1/2 files into a single file, waiting for each one to become available first. Produces the grbindex output for that file at the end. Only works in regional grid mode, and will raise TrackerModeError if the mode is unknown or moving grid. @note This is routine is untested because it is a bad idea. It results in duplication of an enormous amount of data. However, historically, this is how the tracker used to be run. @param filename the input GRIB1 file name @param ixfilename the output index file namerrz#%s: not yet available. Sleeping...rLabrr})filename ixfilenameN)r*truncateZ_gribsrOrr.rrrPrrrrrrrr)rrrZr[r2r&r1r}r5r5r6 concat_gribs     "zTrackerTask.concat_gribc Cst|j}|j}|j}|j}|j}|ddt|jd|ddt|jd|ddt|j|ddt|j |ddt|j |ddd |dd d |dd d |dd|j rdnd|ddd|dddtt |j d}tt |j dd|}|dd|d||ddd|ddd|ddd|dd d |dd!d"|dd#|jrdd$nd%|dd&d'|dd(d)|d*d+|jrd$nd%|d*d,d-|d*d.d/|d0d1|jrd$nd%|d0d2|jrd$nd%t|jD].} | |jkrt|j| j} nd } q q|d3d4| |d5d6d7|d8d9|rHd$nd%|d8d:d;|d8d|d8d?d@|jr|d8dAd$|d8dBdCn |d8dAd%dddd*d0d3d5d8g} ddddddDdd d dg } dddEdg} dFdGdHdIdddd d!d#g }d+d,d.g}d1d2g}dJdKd4g}d9d:d?rMBDEz %s.genvitalsCz %s.cps_parmsGz%s.ikeJz %s.structureHz %s.fractwindIz %s.pdfwindLzLink: fort.%d = %sTrzStarting gettrk.z ./input.nmlz tracker.logz%Successful return status from gettrk.zGETTRK FAILED: rNr)8rrrrr rrrworkdirrjrpathexistsrrmtreerr.rXr*rtracker_delivery_scriptformatrrZrrrrrr r' as_tcvitalsr\rqrrrrrsortedrNrrrrredirectrrrrcriticalrjoinoutdirrcall_completed_callbacks)rrr0rurrr(ZwdrZvitfrFvitalemptypreZlinkmeZfortirrtgtr5r5r6rGs             zTrackerTask.runcCs~|dkr|}|D]`}||jrf|sH|jd|jfn|jd|jf|q| d|jfqdS)zd!Calls callbacks for all completed products. @param logger a logging.Logger for log messagesNz'%s: rejoice: completed!! (no callbacks)z(%s: rejoice: completed!! (has callbacks)z$%s: tracker product is not complete.) rr)updaterrrr.rrr)rrr0r$r5r5r6rs   z$TrackerTask.call_completed_callbacks)TTFFTN)N)N)NNrgN)N)N) rrrrrHrpr%r&r)r0r1r3propertyrr4rr5rr6rr7rrArGrIrJrXr]rqrrrr5r5rsr6rsJ&   * ! 6_\)N)F)N)>r__all__r?rrrr.r,sys hwrf.regribrQ hwrf.hwrftask hwrf.numericshwrf.exceptions produtil.runr produtil.cdprodutil.fileopprodutil.datastoreprodutil.ecflowr r r r r rrrrrrrrrrrrrrrrrrrCrrGrHrrerrr datastore FileProductrrTaskrrhwrftaskHWRFTaskrr5r5r5r6sx8      5  3 hw