U Ó go-ã@sNdZdddddgZddlZddlZddlZddlZddlZddlZddl Zddl Zddl Z ddl Z ddlZ ddlZ ddlZ ddlmZdd lmZdd l mZmZdd l mZdd lmZmZdd lmZddlmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#ddd„Z$ddd„Z%ddd„Z&dd„Z'dd„Z(dd„Z)ddd„Z*Gdd„deƒZ+dS) aÙ!Creates the initial HWRF directory structure, loads information into each job. This module is used to create the initial HWRF conf file in the first HWRF job via the hwrf.launcher.launch(). The hwrf.launcher.load() then reloads that configuration. The launch() function does more than just create the conf file though. It parses the tcvitals, creates several initial files and directories and runs a sanity check on the whole setup. The HWRFLauncher class is used in place of an hwrf.config.HWRFConfig throughout the HWRF system. It can be used as a drop-in replacement for an hwrf.config.HWRFConfig, but has additional features needed to support sanity checks, initial creation of the HWRF system and tcvitals generation.ÚloadÚlaunchÚ HWRFLauncherÚparse_launch_argsÚmultistorm_parse_argséN)ÚRandom)Ú isnonempty)ÚrunÚexe)Újlogger)Úto_datetime_relÚ to_datetime)Ú HWRFConfig) Ú HWRFDirInsaneÚHWRFStormInsaneÚHWRFCycleInsaneÚHWRFVariableInsaneÚHWRFInputInsaneÚHWRFScriptInsaneÚHWRFExecutableInsaneÚ HWRFFixInsaneÚHWRFArchiveInsaneÚHWRFConfigInsaneFcsŒ‡fdd„ˆDƒ}t|ƒdkr2| d¡t d¡d}|dk sBt‚||dkrX|d}nttƒdkrn|d}n|d}||krˆ| |¡t|ƒ} |  |¡ˆ d |¡ˆ d |¡ˆ d d   |¡¡|  d |¡|  d|¡|  d|¡g} g} g} ˆd} t | ƒD]†\}}|  ˆdd…¡|| |d<|r| | ||dkrtˆ|d  | |¡| ||d<n ˆ|dt |ƒ| ||d<qt | ƒD]Ø\}}t||||ƒ\}}}}}|  |¡|  |¡dD]œ}tj  ||¡}tj |¡s| |d¡t d¡nDtj |¡s:| |d¡t d¡ntj |¡sV| |d¡|  dt|ƒ¡| |¡qØq |||| ||| fS)a¹This is the multistorm argument parser. It is really just a wrapper around parse_launch_args(). The last Element of the returned list is the launch args for the Fake storm. From the original arguments, returns a new list of launch args for all the storms in a multistorm run. The SID and optional config.startfile from the original sys.argv[1:] list are replaced with a storm id and a config.startfile (if present) from the MULTISTORM_SIDS. The following multistorm conf options are also added to each storm. config.fakestormid=, config.multistorm_sids=,config.multistorm_priority_sid=, config.multistorm_sids=, General structure of the returned list. [[storm1, arg1, ..argN], ..[stormN, arg1, ..argN], [storm00, arg1, ..argN]] INPUT: args -- a copy of the initial command line args, excluding sys.argv[0] RETURNS: case_root,parm,infiles,stids,fake_stid,multistorm_priority_sid,moreopts[] csg|]}d|krˆ |¡‘qS)zconfig.startfile)Úindex)Ú.0Úarg©Úargs©ú:/lfs/h1/ops/prod/packages/hmon.v3.2.7/ush/hwrf/launcher.pyÚ <sz)multistorm_parse_args..ézFExiting, More than 1 config.startfile= parameter in the argument list.éZ00LNrzconfig.fakestormid=zconfig.multistorm_priority_sid=zconfig.multistorm_sids=ú z5Setting up hwrf to run as a multi storm with sids: %sz(HWRF multistorm: The priority sid is: %sz4HWRF multistorm: The multistorm fake storm id is: %s)z hwrf_3km.confzhwrf_multistorm.confú: conf file does not exist.ú": conf file is not a regular file.ú,: conf file is empty. Will continue anyway.ú Conf input: )ÚlenÚerrorÚsysÚexitÚAssertionErrorÚmultistorm_sidsÚremoveÚlistÚappendÚjoinÚinfoÚ enumerateÚreplaceÚstrrÚosÚpathÚexistsÚisfileÚprodutilÚfileoprÚwarningÚrepr)ZmsidsrÚloggerÚusageÚPARMhwrfÚwrapperZ startfile_idxÚ fake_stidZmultistorm_priority_sidZmultistorm_all_sidsZ multistormsÚstidsÚmoreoptsZ sid_passedinÚiÚstormidZ storm_argsÚ case_rootÚparmÚinfilesÚstidÚmoreoptZconfbnZconfyrrrr#sj           ÿ$ ÿ     ÿc sttƒ}|d}tj |¡}| d¡‰t|dd…|||ƒ\} } } } } t| || | | d|dd}| d¡}| dd d ¡}t j   || |¡¡}|  dd d¡}tj j|d }|j|dd | ¡| ¡| ‡fdd„¡| ‡fdd„¡|rø| dd„¡| ¡| |j¡|D] }| ¡ ¡d}| |¡qt|ƒdkrp| d| d¡¡tj t j   | d¡d¡¡|S)Nrú%Y%m%d%Hr!FT)Ú init_dirsÚ prelaunchÚ fakestormÚsyndatÚconfigÚ vitpatternúsyndat_tcvitals.%YÚrun_multistorm©r>©Z raise_allcs |jˆkS©N©ÚYMDH©ÚvrXrrÚœóz%multistorm_priority..cs |jˆkSrW)Úbasin1rZ)Úbasinsrrr\r]cSs|jdkp|jdko|jdkS)NÚEitÿÿÿ)r^ZlonrZrrrr\Ÿr]zNo storms for cycle: Úcomz no_storms.txt)r/ÚhwrfÚnumericsr ÚstrftimerrÚgetdirÚgetstrr6r7r1ÚgetboolÚrevitalÚRevitalÚ readfilesZdelete_invest_duplicatesÚclean_up_vitalsÚdiscard_exceptZsort_by_functionZhrd_multistorm_sorterÚ as_tcvitalsÚsplitr0r(r2r:r;Útouch)rr_r>r?r@rNZstormsÚstrcycleÚcycrGrHrIrJrKÚconfZ syndatdirrRÚvitfileZ multistormÚrvr[Zsidr)rYr_rÚmultistorm_priority‰sD  ÿ  þ  ÿruc CsHt|ƒdks |dkr4t|ƒdkr4||dt d¡|d ¡}t d|¡sf| d|f¡t d¡| dt|ƒ¡|d  ¡}|d kr’d }n(|d kr d }n| d|f¡t d¡| dt|ƒ¡|dkrP|d}t j   |¡s| |d¡t d¡n&t j   |¡s,| |d¡t d¡| dt|ƒd¡|dd…}n&|}| dt|ƒd ¡|dd…}t j   |¡}t j  |d¡t j  |d¡t j  |d¡t j  |d¡t j  |d¡g}d } t t¡} tt|ƒƒD]Â} | || ¡t d|| ¡} | rN| d|  d¡|  d¡t|  d¡ƒf¡|  d¡| |  d¡|  d¡<nNt j   || ¡r„| d|| f¡| || ¡nd } | d|| f¡qÜ| r°t d¡|D]„} t j   | ¡sà| | d¡t d¡nDt j  | ¡s| | d ¡t d¡ntj | ¡s$| | d!¡| d"t| ƒ¡q´||||| fS)#af!Parsed arguments to scripts that launch the HWRF system. This is the argument parser for the exhwrf_launch.py and hwrf_driver.py scripts. It parses the storm ID and later arguments (in args). Earlier arguments are parsed by the scripts themselves. If something goes wrong, this function calls sys.exit(1) or sys.exit(2). The arguments depend on if PARMhwrf=None or not. @code{.py} If PARMhwrf is None: StormID CASE_ROOT /path/to/parm [options] Otherwise: StormID CASE_ROOT [options] @endcode * StormID --- three character storm identifier (ie.: 12L for Katrina) * CASE_ROOT -- HISTORY or FORECAST * /path/to/parm - path to the parm directory, which contains the default conf files. Options: * section.variable=value --- set this value in this section, no matter what * /path/to/file.conf --- read this conf file after the default conf files. Later conf files override earlier ones. The conf files read in are: * parm/hwrf_input.conf * parm/hwrf.conf * parm/hwrf_holdvars.conf * parm/hwrf_basic.conf * parm/system.conf @param args the script arguments, after script-specific ones are removed @param logger a logging.Logger for log messages @param usage a function called to provide a usage message @param PARMhwrf the directory with *.conf filesr"NérUrz^[0-9][0-9][ABCELPQSW]$zL%s: invalid storm id. Must be a three character storm ID such as 90L or 13WzRunning Storm ID is r!ÚHISTORYFÚFORECASTTz^%s: invalid case root. Must be HISTORY for retrospective runs or FORECAST for real-time runs.z Case root is z: parm directory does not existz#: parm directory is not a directoryzScan %d optional arguments.zhmon_input.confz hmon_2.confzhmon_holdvars.confzhmon_basic.confz system.confzk(?x) (?P
[a-zA-Z][a-zA-Z0-9_]*) \.(?P