U

����� g	����������������������@���s���d�Z�ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z
ddlZ
ddlZ
ddlmZmZmZmZmZmZmZmZmZmZmZmZmZ�ddlmZmZmZmZ�ddl	mZm Z �dddd	d
ddd
ddddddgZ!dZ"dZ#dZ$G�dd��de%�Z&G�dd��de&�Z'G�dd��de&�Z(dZ)dd��Z*dd ��Z+d!d"��Z,d#d$��Z-d%d&��Z.dSd'd(�Z/d)d*��Z0d+d,��Z1d-d.��Z2d/d0��Z3G�d1d2��d2e%�Z4G�d3d4��d4e4�Z5G�d5d	��d	e5�Z6e6d6d7d�Z7G�d8d9��d9e5�Z8G�d:d;��d;e5�Z9G�d<d=��d=e4�Z:dTd?d@�Z;G�dAd
��d
e4�Z<G�dBdC��dCe<�Z=G�dDd��de4�Z>G�dEd��de>�Z?G�dFd��de>�Z@G�dGdH��dHe@�ZAG�dId��de@�ZBG�dJd��de?�ZCG�dKd��dee@�ZDG�dLdM��dMe@�ZEdNdO��ZFG�dPd��de eC�ZGG�dQdR��dRe eB�ZHdS�)UaO��!Describes regribbing operations using an algebraic structure.

This module provides an object-oriented interface to the low-level
GRIB manipulation routines in produtil.gribop.  It also sits on top of
the produtil.datastore module, providing a means to grab GRIB files
from Task and Product objects, processing them upon availability.�����N)
�RegribError�GRIBInputError�
Subsetless�InvalidRegribResult�RegribProductError�NoProductError�ProductAmbiguityError�RegribManyError�RegribKeyError�RegribGridError�
GridlessError�GridMismatchError�NoIndexError)�exe�alias�run�runstr)�UpstreamFile�FileProduct�GRIBOp�GRIB2Op�GRIB1Op�GRIBGrid�
GRIBSubsetterZ
GRIB1Merge�Regrib�GRIB1�GRIB2�	GRIB1File�	GRIB2File�
UpstreamGRIB1�GRIB2Product�
quarterDegree������������c����������������
�������s����e�Zd�ZdZd!��fdd�	Zdd��Zdd��Zd	d
��Zdd��Zd
d��Z	dd��Z
dd��Zdd��Zdd��Z
edd���Zee
edd�Zeeddd�Zee
ddd�Zee	ddd�Zeeddd�Zeeddd�Zeeddd�Zeeddd �Z���ZS�)"�
RegribBasez�!This is the abstract base class of Regrib and RegribMany and
    should not be instantiated directly.  It exists only to reduce
    code duplication.Nc��������������������s^��t�t|������|dk	rh|j|�_|j|�_|j|�_|j	|�_
|j|�_|j
|�_|j|�_t|j�|�_t|j�|�_n�|dk	stt�|dkr�ttd��}|dkr�ttd��}|dkr�ttd�d��}|	dkr�ttd�d��}	|dkr�ttd�d��}|
dkr�ttd	��}
|
|�_||�_||�_|	|�_
||�_||�_|dk�r.g�|�_n
t|�|�_|dk�rJi�|�_n
t|�|�_||�_dS�)
a ��!Creates a RegribBase.  

        @param _base Do not use.  The _base should be another
            RegribBase to copy.  If this is specified, all other
            arguments are ignored, and the _base is copied.  This is
            the implementation of self.copy()

        @param logger the logging.Logger that should be used when regribbing
        @param prodargs a list of additional arguments to send to "products"
            iterators.
        @param prodkwargs a dict of additional keyword arguments to send to
            "products" iterators.

        @param regridmerge The hwrf_regrid_merge program, which performs
           multiple GRIB1 regridding operations and a final merge operation
           without creating intermediate files.
        @param cnvgrib_g12 The "cnvgrib -p32 -g12" program (a
           produtil.prog.ImmutableRunner) to convert from GRIB1 to GRIB2.
           (Other compression types besides -p32 are okay.)
        @param satgrib2 The "satgrib2 -p32" program (a
           produtil.prog.ImmutableRunner) to convert UPP "brightness
           temperatures on hybrid levels" to GRIB2 table 4.32
           ("synthetic satellite").  (Other compression types besides
           -p32 are okay.)
        @param cnvgrib_g21 The "cnvgrib -g21" program (a
           produtil.prog.ImmutableRunner) to convert from GRIB2 to GRIB1
        @param wgrib the wgrib program, with no arguments,
           a produtil.prog.ImmutableRunner
        @param copygb the copygb program, with no arguments,
           a produtil.prog.ImmutableRunnerN�copygb�wgrib�cnvgrib)z-g12�-p32�satgrib2r)���z-g21�regridmerge)�superr%����__init__r&����_copygbr'����_wgrib�cnvgrib_g12�_cnvgrib_g12r*����	_satgrib2�cnvgrib_g21�_cnvgrib_g21�logger�_loggerr+����_regridmerge�list�	_prodargs�dict�_prodkwargs�AssertionErrorr���r���)�selfr5����prodargs�
prodkwargs�_baser0���r3���r'���r&���r*���r+�����	__class__���8/lfs/h1/ops/prod/packages/hmon.v3.2.7/ush/hwrf/regrib.pyr-���2���sJ����!������



zRegribBase.__init__c�����������������C���s���|�j�S�)z#!Returns the copygb ImmutableRunner)r.����r=���rC���rC���rD����	getcopygbx���s����zRegribBase.getcopygbc�����������������C���s���|�j�S�)zR!Returns the cnvgrib -p32 -g12 command, which should be an
        ImmutableRunner)r1���rE���rC���rC���rD����getcnvgrib_g12{���s����zRegribBase.getcnvgrib_g12c�����������������C���s���|�j�S�)zS!Returns the hwrf_satgrib2 -p32 command, which should be an
        ImmutableRunner)r2���rE���rC���rC���rD����getsatgrib2���s����zRegribBase.getsatgrib2c�����������������C���s���|�j�S�)zN!Returns the cnvgrib -g21 command, which should be an
        ImmutableRunner.)r4���rE���rC���rC���rD����getcnvgrib_g21����s����zRegribBase.getcnvgrib_g21c�����������������C���s���|�j�S�)zG!Returns the wgrib command, which should be an
        ImmutableRunner.)r/���rE���rC���rC���rD����getwgrib����s����zRegribBase.getwgribc�����������������C���s���|�j�S�)z�!Returns the logger.Logging object to use for logging
        messages, or None if no logger was provided to the
        constructor.�r6���rE���rC���rC���rD����getlog����s����zRegribBase.getlogc�����������������C���s���||�_�|�j�S�)zf!Sets the logger.Logging object to use for logging
        messages.
        @param val the new loggerrK����r=����valrC���rC���rD����setlog����s����zRegribBase.setlogc�����������������C���s���|�j�S�)zJ!Returns the array of arguments to send to the products
        iterators.)r9���rE���rC���rC���rD����getprodargs����s����zRegribBase.getprodargsc�����������������C���s���|�j�S�)zO!Returns a dict of keyword arguments to send to the products
        iterators.)r;���rE���rC���rC���rD����
getprodkwargs����s����zRegribBase.getprodkwargsc�����������������C���s���|�j�S�)zC!Returns an ImmutableRunner that runs the hwrf_regrid_merge program)r7���rE���rC���rC���rD���r+�������s����zRegribBase.regridmergez9Either None or the logging.Logger object for this Regrib.zCA list of additional positional arguments to send to Task.products.z@A dict of additional keyword arguments to send to Task.products.z<Returns None or a wgrib object suitable for produtil.run.runz=Returns None or a copygb object suitable for produtil.run.runzCReturns None or a cnvgrib -g21 object suitable for produtil.run.runzCReturns None or a cnvgrib -g12 object suitable for produtil.run.runzQReturns None or an object suitable for running hwrf_satgrib2 via produtil.run.run)
NNNNNNNNNN)�__name__�
__module__�__qualname__�__doc__r-���rF���rG���rH���rI���rJ���rL���rO���rP���rQ����propertyr+���r5���r>���r?���r'���r&���r3���r0���r*����
__classcell__rC���rC���rA���rD���r%���.���sX���������������F
��������r%���c�����������������������s����e�Zd�ZdZd��fdd�	Zddd�Zddd�Zd	d
��Zeeddd�Z	dd
��Z
dd��Zdd��Zdd��Z
ddd�Zddd�Z���ZS�)r���z�!This is a helper class intended to be used internally by
    RegribMany.  It performs a small number of GRIB manipulations
    intended to produce the result of a single GRIB expression.Nc��������������������s<���t�t|��jf�|��||ddf\|�_|�_|�_|�_|��|��dS�)a'��!Creates a Regrib object whose result has the given name (in
        "result") and produces the output of the specified operation
        "op", prepending the given prefix "workprefix" to temporary
        and output filenames.
        @param result the name of this operation result, for 
          referencing it again in a RegribMany object after the
          operation is complete.
        @param op the operation to perform
        @param workprefix
        @param kwargs Additional keyword arguments are sent to 
          RegribBase.__init__()r���N)r,���r���r-����_result�_op�_step�_workprefix�set_workprefix)r=����result�op�
workprefix�kwargsrA���rC���rD���r-�������s����zRegrib.__init__c�����������������C���s0���|dkr&t�j�dt�j�t�d��|�_n||�_dS�)a`��!Sets the work directory and filename prefix to the given
        value, or sets it to a reasonable default if workprefix is
        None or missing.  The work prefix is not necessarily a
        directory: it can include additional text to prepend to the
        filename.

        @param workprefix The new work directory and filename
        prefix.N�./�.step)�os�path�join�basenamer]���r[���)r=���r_���rC���rC���rD���r\�������s����	zRegrib.set_workprefixc�����������������C���s ���|���|��||�_||�_d|�_dS�)a���!Discards all temporary data, and re-initializes this object
        for the specified result name, operator and workprefix.  This
        is used by RegribMany to re-use a single Regrib object over
        and over.

        @param result the new result object to return, if queried
        @param op the new operation to return if queried
        @param workprefix the new work directory and filename prefixr���N)r\���rX���rY���rZ���)r=���r]���r^���r_���rC���rC���rD����reset����s����	
zRegrib.resetc�����������������C���s���|�j�S�)z>!Returns the GRIBBase object that performs this Regrib's work.)rY���rE���rC���rC���rD����getop���s����zRegrib.getopz<Returns the GRIBBase object that performs this Regrib's workc�����������������K���s���|�j�j|�f|�S�)a"��!Returns True if this Regrib object's operator is "ready"
        (according to is_ready) and False otherwise.
        
        @param kwargs Additional keyword arguments passed to GRIBBase.is_ready(), called on self.op.
        @returns The result of GRIBBase.is_ready(), called on self.op)r^����is_ready�r=���r`���rC���rC���rD���ri�����s����zRegrib.is_readyc�����������������K���s���|�j�j|�f|�S�)a��!Returns True if the specified kwargs are valid for this
        Regrib object's operator and False otherwise.

        @param kwargs Additional keyword arguments passed to GRIBBase.input_valid() called on self.op
        @returns the result of GRIBBase.is_ready(), called on self.op)r^����input_validrj���rC���rC���rD���rk�����s����zRegrib.input_validc�����������������K���s^���|�j�j|�f|�}|dk	st�t|t�sZt|t�sZt�dt|�j	t
|�t
|�j��t
|�f���|S�)a��!Runs this Regrib object's operator's make function with the
        given keyword arguments, returning the results.

        @param kwargs Additional keyword arguments passed to GRIBBase.make() called on self.op
        @returns the result of GRIBBase.is_ready(), called on self.opNzkInvalid result for type=%s repr=%s which came from running self.op.make(**kwargs) on an op=%s and kwargs=%s)r^����maker<����
isinstance�GRIBBaser����logging�critical�typerR����repr)r=���r`���r]���rC���rC���rD���rl�����s�������zRegrib.makec�����������������C���s`���t�|t�stdt|�j���|�|�j�r0|d�S�|��jd7��_d|�j|�jtj	�
|�f�}|S�dS�)z�!Generates a temporary filename to use for the specified
        GRIB1/2 file's index file.

        @param grib the grib filename
        @returns the suggested filename for the wgrib -s outputz3Regrib.indextemp requires a string argument, not %s�.wgrib_sr"����	%s%02d.%sN)rm����str�	TypeErrorrq���rR����
startswithr[���rZ���rc���rd���rf���)r=����grib�outrC���rC���rD����	indextemp%��s����
�

�zRegrib.indextempc�����������������C���s<���|��j�d7��_�|dkrd}d|�j|�j�t|�f�}||d�fS�)z�!Returns a tuple (grib,index) containing a suggested GRIB1/2
        filename and index filename.  

        @param what The optional argument "what" must contain no shell
        metacharacters and is incorporated into the file name.r"���N�tmprt���rs����rZ���r[���ru����r=����whatry���rC���rC���rD����gribtemp5��s
����zRegrib.gribtempc�����������������C���s4���|��j�d7��_�|dkrd}d|�j|�j�t|�f�}|S�)z�!Creates a name of a temporary file.  

        @param what The "what" argument is a terse explanation of the
        purpose of the file (such as "merge" or "to-grib2") to include
        in the filename.
        @returns The suggested filename.r"���Nr{���rt���r|���r}���rC���rC���rD����tempfile@��s
����zRegrib.tempfile)N)N)N)N)N)rR���rS���rT���rU���r-���r\���rg���rh���rV���r^���ri���rk���rl���rz���r���r����rW���rC���rC���rA���rD���r�������s���


�
c�������������������@���s����e�Zd�ZdZd0dd�Zdd��Zdd��Zd	d
��Zdd��Zd
d��Z	dd��Z
dd��Zdd��Zdd��Z
dd��Zdd��Zdd��Zd1dd�Zd2d d!�Zd3d"d#�Zd$d%��Zd&d'��Zd(d)��Zd*d+��Zd,d-��Zd.d/��ZdS�)4�
RegribManya[��!Runs regrib operations on many input times, sending output to
    an hwrf.gribtask.GRIBTask.

    This class keeps track of a set of named regribbing operations
    and target grids.  Each operation may connect to another by name,
    allowing the output of one operation to be the input to one or
    more other operations.  The RegribMany.make can then produce the
    output of an operation, on the condition that its inputs from
    earlier operations are ready.  

    The RegribMany is not intended to be used alone.  Instead, the
    GRIBTask class in hwrf.gribtask should be used to execute
    RegribMany tasks.  You can run multiple GRIBTasks at the same
    time, on the same RegribMany outputs, and the GRIBTasks will
    automatically work together via file locking and a database to
    produce the outputs in parallel, as fast as possible.

    Here is a simple example of the use of a RegribMany object:

    @code
    # This code assumes a PostManyWRF object is available as "mypost",
    # and HWRFConfig as "conf", and two WRFDomain are available as
    # "d01" and "d02".  We also assume the post has already been run.

    r = RegribMany()
    getd01 = igrb1(mypost,domain=d01)
    getd02 = igrb1(mypost,domain=d02)
    r.add('cgrid',clatlon(getd02,res=[0.05,0.05],size=[30.,30.],
          scan=136,n=[600,600]))
    r.add('cGRIB1',getd01*r.grid('cgrid')+getd02*r.grid('cgrid'))
    r.add('cGRIB2',r.GRIB('cGRIB1') * GRIB2)
    r.to_intercom('output_f{fahr:03d}.grib2','cGRIB2')
    gribber = GribTask(conf.datastore,conf,'mygrib',r,conf.cycle,
                       126*3600, 6*3600)
    gribber.run()
    @endcode 

    Now lets step through that and explain what it does.  

    @code
    r = RegribMany() - creates a RegribMany.
    @endcode

    First, we create the RegribMany object.  We're actually doing this
    in a sloppy way: it will search the $PATH for cnvgrib, wgrib, and
    other programs.  It is better to specify the exact location.  That
    can be done by passing arguments to the RegribMany constructor.
    See the RegribBase instructor for a list.

    @code
    getd01 = igrb1(mypost,domain=d01)
    getd02 = igrb1(mypost,domain=d02)
    @endcode

    This creates a pair of GRIB1Selectors, operations recognized by
    RegribMany.  A GRIB1Selector takes a Task, in this case mypost,
    and calls its "products" function to get a Product as input to the
    next step in a regribbing operation.  The domain=d01 is passed
    into products, as is the time=X for each time X the RegribMany
    processes.

    @code
    r.add('cgrid',clatlon(getd02,res=[0.05,0.05],size=[30.,30.],
          scan=136,n=[600,600]))
    @endcode

    This instructs the RegribMany to add an operation to its
    dictionary.  The operation is called "cgrid", and consists of a
    GRIBGridCompute created by the clatlon function, defined later in
    this module.  The clatlon takes our getd02, and creates a 30x30
    degree, 600x600 gridpoint, 0.05 degree grid, centered on that
    domain at each time.  If domain d02 moves, this clatlon output
    will be a moving domain.


    @code
    r.add('cGRIB1',getd01*r.grid('cgrid')+getd02*r.grid('cgrid'))
    @endcode

    This adds another operation to the RegribMany's dictionary, this
    time a grib output operation called cGRIB1.  The r.grid('cgrid')
    looks up the cgrid operation we just inserted, connecting that to
    the cGRIB1.  Recall that getd01 and getd02 are also operations,
    and produce a GRIB1 file.  When we multiply that by a grid, it
    creates a new operation that will use copygb to output a new GRIB1
    file on that grid.  Hence, we have created two temporary files:

    @code
    getd01*r.grid('cgrid') = domain 1's post output on the cgrid
    getd02*r.grid('cgrid') = domain 2's post output on the cgrid
    @endcode

    When we add those two together, it pastes the second one on top of
    the first via a copygb merge operation.  That result is then
    stored as cGRIB1.

    @code
    r.add('cGRIB2',r.GRIB('cGRIB1') * GRIB2)
    @endcode

    This adds a third operation to the RegribMany, called cGRIB2.  The
    r.GRIB('cGRIB1') looks up the operation that creates cGRIB1,
    connecting that to the new cGRIB2.  When we multiply by the
    special constant GRIB2, it creates a new operation to convert that
    file to GRIB2.
    
    @code
    r.to_com('output_0p05_degree_f{fahr:03d}.grib2','cGRIB2')
    @endcode
  
    This sets the delivery location for the cGRIB2 outputs.  It will 
    create files with names like:

    @code
    output_0p05_degree_048.grib2   # 48hr output file
    @endcode

    Without that command, the output will go to automatically-generated
    locations somewhere in intercom, which is likely not what you want.

    @code
    gribber = GRIBTask(conf.datastore,conf,'mygrib',r,conf.cycle,
                       126*3600, 6*3600)
    @endcode

    This creates a GRIBTask that will execute the regribber we just made.

    The GRIBTask is configured to be able to run our RegribMany for
    all forecast times starting at the analysis time (conf.cycle) and
    running to 126 hours afterwards (126*3600), every six hours
    (6*3600).  The GRIBTask will set the time= keyword argument to
    mypost.products, allowing each RegribMany operation to run on the
    correct input time.

    @code
    gribber.run()
    @endcode

    This tells the gribber to run to completion, generating our output
    files.Nc�����������������K���s����d|kst��t�t�|�_|dk	r�tj|�|d��|j|�_t|j	�|�_	t|j
�|�_
t|j�|�_t�|j
�|�_
|�j
D�]}||�j|d�<�qnnXd|ks�|d�dkr�t��tj|�f|��|dkr�d}||�_t��|�_
t��|�_	t��|�_t��|�_
d|�_t���|�_dS�)a5��!Creats a new RegribMany.  

        @param workprefix The workprefix, if specified,
        sets the location in which to run.  The _copy is used by the
        self.copy() for copying.  

        @param _copy,kwargs All other arguments are passed to the
        superclass RegribBase.__init__  constructor .�timeN)r@���r#���r&���ra���)r<����collections�defaultdictr8����
_name_deliverr%���r-���r[���r:����_gens�_order�_kwargs�copy�	_delivery�_data�	threading�RLock�_lock)r=����_copyr_���r`����frC���rC���rD���r-������s,����	
zRegribMany.__init__c�����������������C���s���dS�)aO��!Has no effect.  This is for forward compatibility to a
        later thread-safe implementation.
        @note This used to be implemented but it turns out that
          Python locks are VERY slow, so the locking had to be
          removed.  Multiple simultaneous regrib operrations are now
          done through multiple processesNrC���rE���rC���rC���rD����	__enter__���s����zRegribMany.__enter__c�����������������C���s���dS�)a���!Has no effect.  This is for forward compatibility to a
        later thread-safe implementation.
        @param etype,evalue,traceback Exception information.
        @note This used to be implemented but it turns out that
          Python locks are VERY slow, so the locking had to be
          removed.  Multiple simultaneous regrib operations are now
          done through multiple processes.NrC���)r=����etype�evalue�	tracebackrC���rC���rD����__exit__��s����zRegribMany.__exit__c��������������
���C���s&���|���||�j�kW��5�Q�R���S�Q�R�X�dS�)zg!Returns True if an operation by the given name exists.
        @param name the operation name to queryN)r�����r=����namerC���rC���rD����has_name
��s����zRegribMany.has_namec��������������	���C���s���|���d|�_�W�5�Q�R�X�dS�)z!Erases all cached results.N)r����rE���rC���rC���rD���rg�����s����zRegribMany.resetc��������������
���C���s&���|���t�|�d�W��5�Q�R���S�Q�R�X�dS�)z/!Returns a copy of self with no cached results.)r����N)r����rE���rC���rC���rD���r������s����zRegribMany.copyc�����������������C���s���|�j�|��t|�S�)z�!Returns a GRIB1Fetcher object that will grab the GRIB1 data
        with the given name.
        @param name the operation name to query)r�����GRIB1Fetcherr����rC���rC���rD����GRIB��s����
zRegribMany.GRIBc�����������������c���s,���|�j����D�]\}}t|t�s
||fV��q
dS�)zc!Iterates over all non-GRIBOp operations yielding tuples
        containing the name and operation.N�r�����itemsrm���r����r=����k�vrC���rC���rD����
nonGRIBOps ��s����
zRegribMany.nonGRIBOpsc�����������������c���s,���|�j����D�]\}}t|t�r
||fV��q
dS�)z_!Iterates over all GRIBOp operations yielding tuples
        containing the name and operation.Nr����r����rC���rC���rD����GRIBOps&��s����
zRegribMany.GRIBOpsc�����������������C���s���t�|�j�|d�t�S�)z_!Returns True if the name corresponds to a grid
        @param name the operation name to queryN)rm���r�����get�GRIBGridBaser����rC���rC���rD����is_grid,��s����zRegribMany.is_gridc�����������������C���s���|�j�|��t|�S�)z�!Returns a GRIBGridFetcher object that will grab the grid
        structure with the given name.
        @param name the operation name to query)r�����GRIBGridFetcherr����rC���rC���rD����grid0��s����
zRegribMany.gridc�����������������C���s���|�j�|��t|�S�)z�!Returns a GRIBSubsetterFetcher object that will grab the
        GRIB subsetter with the given name.
        @param name the operation name to query)r�����GRIBSubsetterFetcherr����rC���rC���rD����subset6��s����
zRegribMany.subsetc��������������	���K���sT���|��F�||�j�kr"tj�d|f���||�j�|<�|�j�|��t|�|�j|<�W�5�Q�R�X�dS�)a��!Adds the given generator "arg" under the specified name (in
        "name") to this object.
        @param name the operation name to query
        @param arg A object of a subclass of GRIBBase 
        @param kwargs Stored for later passing to function calls to argz/%s: tried to add duplicate product to regribberN)r�����hwrf�
exceptionsr���r�����appendr:���r����)r=���r�����argr`���rC���rC���rD����add<��s����
�
zRegribMany.addTc��������������	���C���s����t�|t�st�t�|t�st�|dks2t�|t�s2t�|dksHt�|t�sHt�t�|t�sVt�|��J�||�jkrttd|f���d|||||g}|�j�|��|�j|��|��W�5�Q�R�X�dS�)a���!Requests delivery to the com directory in file "location"
        of operation "name".  

        @param category,prodname The category and prodname are used to
        create the FileProduct object.
        @param keep Sent to the final deliver_file operation.  It
        should be left as True.
        @param name the operation's name
        @param location the destination, which will be sent through
        hwrf.config.HWRFConfig.conftimestrinterp() by the 
        hwrf.gribtask.GRIBTaskN�%s: no such key�com�	rm���ru���r<����boolr����r
���r����r����r�����r=����locationr�����category�prodname�keepZdeldatrC���rC���rD����to_comI��s����
zRegribMany.to_comc��������������	���C���s����t�|t�st�t�|t�st�|dks2t�|t�s2t�|dksHt�|t�sHt�t�|t�sVt�|��J�||�jkrttd|f���d|||||g}|�j�|��|�j|��|��W�5�Q�R�X�dS�)a���!Requests delivery to the intercom directory in file
        "location" of operation "name".  
        @param category,prodname The category and prodname are used to
        create the FileProduct object.
        @param keep Sent to the final deliver_file operation.  It
        should be left as True.
        @param name the operation's name
        @param location the destination, which will be sent through
        hwrf.config.HWRFConfig.conftimestrinterp() by the 
        hwrf.gribtask.GRIBTaskNr�����intercomr����r����rC���rC���rD����to_intercom`��s����
zRegribMany.to_intercomc�����������������c���s>���|�j�D�]2\}}}}}}|dks&||kr||||||fV��qdS�)a���!Iterates over all deliveries yielding a six element tuple

        @param name The name of the operation of interest.
        The tuple contents:
          1. "com" or "intercom"
          2. operation name
          3. location within target directory
          4. requested category or None
          5. requested prodname or None
          6. keep flag from the to_com or to_intercomN)r����)r=���r�����whereZiname�loc�cat�prodr����rC���rC���rD����
deliveriesv��s����zRegribMany.deliveriesc��������������
���C���s*���|���t�|�j�dkW��5�Q�R���S�Q�R�X�dS�)z�!Returns True if there are any requested deliveries and
        False otherwise.

        @returns True if to_com() or to_intercom() were called for a known name.r���N)�lenr����rE���rC���rC���rD����has_deliveries���s����zRegribMany.has_deliveriesc�����������������K���s����|�j�dkr|�j|f|�S�t|�j|��}|�|��|�|d<�|��@�|�j��.�|�j�j|f|�dk	W��5�Q�R���W��5�Q�R���S�Q�R�X�W�5�Q�R�X�dS�)a��!Returns True if there is a cached result for the specified
        operation.  

        @param kwargs The keyword arguments are passed on to the
        get_data routine for the caching object (usually an
        hwrf.gribtask.GRIBTask).
        @param name The operation name.N�
regribmany)r����ri���r:���r�����update�get_data)r=���r����r`����argsrC���rC���rD����has_data���s����

zRegribMany.has_datac��������������	���K���sN���|���|�j�|�}W�5�Q�R�X�d|kr.|jf�|�S�t|�}|�|d<�|jf�|�S�dS�)a	��!Determines if the specified operation is ready.  

        @param name Obtains the operation by the specified name.
        @param kwargs The is_ready funciton is called on the named
        operation's generator, passing the given keyword arguments to
        it.r����N)r����ri���r:����r=���r����r`���r^���r����rC���rC���rD���ri������s����zRegribMany.is_readyc��������������	���K���sN���|���|�j�|�}W�5�Q�R�X�d|kr.|jf�|�S�t|�}|�|d<�|jf�|�S�dS�)a>��!Determines if it is possible to run the specified operation
        with the given keyword arguments.  

        @param name Obtains the operation by the specified name.
        @param kwargs The input_valid function is called on the
        generator for the named operation, passing these keyword
        arguments.r����N)r����rk���r:���r����rC���rC���rD���rk������s����zRegribMany.input_validc�����������������K���s(��t�|�j|��}|�|��|�|d<�|��`�|�jdk	rv|�j�:�|�jj|f|�}|dk	rl|W��5�Q�R���W��5�Q�R���S�W�5�Q�R�X�|�j|�}W�5�Q�R�X�t||tj�	|�j
|d��|�d�}|jf�|�}t|t
�s�t|t�s�tdt|�t|�jt|�t|�t|�f���|��$�|�jdk	�r|�jj||f|��W�5�Q�R�X�|S�)a~��!Executes the operation previously stored in
        self.add(), passing it the given keyword arguments,
        returning the result.  If a cache is available (usually a
        GRIBTask), stores the result in that cache.

        @param name the name of the operation of interest
        @param kwargs Passed to the make function in the generator
          for the named operationr����Nrb���)r_���r@���zdInvalid result for %s: type=%s repr=%s which came from running r.make(**args) on an r=%s and args=%s)r:���r����r����r����r����r����r���rc���rd���re���r[���rl���rm���rn���r���r���ru���rq���rR���rr����set_data)r=���r����r`���r�����gotr^����rr]���rC���rC���rD���rl������s:����	

�&������zRegribMany.makec�����������������c���s���|�j�D�]
}|V��qdS�)z]!Iterates over the names provided to self.add(name,...) in
        the order they were added.N)r����r����rC���rC���rD����names���s����
zRegribMany.names)NN)NNT)NNT)N)rR���rS���rT���rU���r-���r����r����r����rg���r����r����r����r����r����r����r����r����r����r����r����r����r����ri���rk���rl���r����rC���rC���rC���rD���r����O��s0����
 	


r��������c��������������
���C���sR��|dkr"|�j�dk	r|�j��d��dS�z�t�|�}|jtk}|sf|�j�dk	r`|�j��dt|�|jf���W�dS�t�|j�}|s�|�j�dk	r�|�j��dt|�|jf���W�dS�W�n��t	k
�rL�}�z�|j
t
jkr�|�j�dk	r�|�j��dt|�t�|j
�f���W�Y��NdS�|j
t
j
k�r:|�j�dk	�r0|�j��dt|�t�|j
�f���W�Y��
dS���W�5�d}~X�Y�nX�dS�)	a���!Internal function for validating GRIB files.

    This is a low-level implementation function.  It should not be
    called directly.  This checks a file to make sure it exists, is a
    regular file (or symlink to a regular file) and is large enough to
    plausibly contain some GRIB1 or GRIB2 data.  Returns True for such
    plausible files and False otherwise.  Does not open the file, and
    performs only a single stat.  Uses errno ENOENT (no such file or
    directory) and ELOOP (too many symbolic links) to detect
    non-existence.  Other exceptions will be passed to the caller.
    @param regrib a regrib for logging information
    @param filename the name of the file of interestNz/checkgrib: filename=None.  Probable code error.Fz%s: size=%d < 8 bytesz%s: not a regular filez)%s: input GRIB1/2 file does not exist: %szZ%s: input GRIB1/2 file path results in too many symlinks (likely a symbolic link loop): %sT)r5����warningrc����stat�st_size�GRIB_FILE_MIN_SIZEru����S_ISREG�st_mode�EnvironmentError�errno�ENOENT�strerrorZELOOP)�regrib�filename�sZsizeokZtypeok�erC���rC���rD����	checkgrib���sB����

�


�
�

 
 
r����c�����������	������O���s����|��d�\}}tj�|j�s,td|jf���|j|j|f�}|jdk	rV|j�t	|���t
|�}|dkrttd|f���tj�|�s�td|f���t|dd�S�)����!Converts GRIB1 file to GRIB2

    This is a low-level implementation function.  It should not be
    called directly.  This function is sent as a parameter to GRIB1Op
    to produce a GRIB2 version of a GRIB1 file.  It uses
    regrib.cnvgrib_g12 to perform the conversion.

    @param op The GRIBBase operation running this funciton.
    @param regrib a Regrib for data information
    @param infile The input filename.
    @param args,kwargs Ignored
    @returns a new GRIB2File for the output file�grb2�%s: input file is emptyNr���z<ERROR: regrib.cnvgrib_g12 command failed with exit status %d�%s: output file is empty)r����produtil�fileop�
isnonempty�	grib1filer���r0���r5����inforr���r���r����	r^���r�����infiler����r`����outfile�outindex�cmd�exrC���rC���rD����action_grib1to2"��s����

�r����c�����������	������O���s����|��d�\}}tj�|j�s,td|jf���|j|j|f�}|jdk	rV|j�t	|���t
|�}|dkrttd|f���tj�|�s�td|f���t|dd�S�)r����r����r����Nr���z9ERROR: regrib.satgrib2 command failed with exit status %dr����)r���r����r����r����r����r���r*���r5���r����rr���r���r���r����rC���rC���rD����action_satgrib2=��s����

�r����c�����������	������O���sb���|��d�\}}|j|j|f�}|jdk	r8|j�t|���t|�}|dkrVtd|f���t|dd�S�)aX��!Converts GRIB2 files to GRIB1

    This is a low-level implementation function.  It should not be
    called directly.  This function is sent as a parameter to GRIB2Op
    to produce a GRIB1 version of a GRIB2 file.  It uses
    regrib.cnvgrib_g21 to do the conversion.
    
    @param op The GRIBBase operation running this funciton.
    @param regrib a Regrib for data information
    @param infile The input filename.
    @param args,kwargs Ignored
    @returns a new GRIB1File for the output file
    @warning This is not used by any HWRF configuration and 
      has not been tested in a while.Zgrb1Nr���z<ERROR: regrib.cnvgrib_g21 command failed with exit status %d)	r���r3����	grib2filer5���r����rr���r���r���r���r����rC���rC���rD����action_grib2to1X��s����
�r����c�����������������O���s����|j�}|dkrtd��t��}t��}|D�](}|j}|�|��t||�r&|�|��q&d�|�}	|sjt|	d���|�d�\}
}|j	|�|�|
�}|j
dk	r�|j
�t|���t
|�}
|
dkr�d|	|
f�}|j
dk	r�|j
�|��t|��t|
d|�S�)a���!Performs regridding and merges two or more files in a single
    operation, producing no intermediate files.

    This is a low-level implementation function.  It should not be
    called directly.  This function is sent as a parameter to GRIB1Op
    to do multiple regrid operations AND merge to a target grid, in a
    single operation.  This is done using the hwrf_regrid_merge
    program.

    @param op The GRIBBase operation running this funciton.
    @param regrib a Regrib for data information
    @param grid The GRIBGrid that provides grid information.
    @param args All other positional arguments are GRIB1 files to merge
    @param kwargs Ignored
    @returns a GRIB1File for the output file, which may be in1 or in2, or a new GRIB1File

    Nz<No GRIB1 grid in input grid object (grid.grib1grid is None).z, z7: all inputs to GRIB1 regribmerge are empty or missing.zregridmerge.grb1r���z&%s: GRIB1 merge failed: exit status %d)�	grib1gridr���r8���r����r����r����re���r���r���r+���r5���r����rr���r����errorr���r���)r^���r����r����r����r`���ZifilesZsfilesr����ZgfileZlfilesr����r����r����r�����messagerC���rC���rD����action_grib1regridmergeq��s4����


�

r����c�����������	������K���s����|dk	st��|dk	st��|j}|j}|j}|dkr�|dk	rJ|�d|f���|d�}tt|�d���}tj	j
|||f�|d��||_n|dk	r�|�d||f���|S�)a���!Runs the grbindex program on a GRIB1 file.

    This is a low-level implementation function.  It should not be
    called directly.  This function adds a grbindex output to the
    specified input file's product, unless one is already available.
    Unlike most action_* functions, this one does not create a new
    GRIBFile or GRIBProduct, instead it modifies the existing one to
    add the location of the grbindex output.

    @param op The GRIBBase operation running this funciton.
    @param regrib a Regrib for data information
    @param ingrib The input GRIBBase that represents the input file.
    @param task An hwrf.hwrftask.HWRFTask to provide the path to
      grbindex
    @param kwargs Ignored
    @returns ingribNz%s: make the grbindexz	.grbindex�grbindex�r5���z%s: already has grbindex %s)r<���r�����
grib1grbindexr5���r����r���r����getexer����r����checkrun)	r^���r����Zingrib�taskr`���r����Zinindexr5���r����rC���rC���rD����action_grbindex���s����r����c�����������������K���s���|j�}|j�}|dkr,|dkr,td|f���n:|dkr:|}n,|dkrH|}n||krbtd||f���n|}|j}	|j}
t||	�}t||
�}|�r|�r|�d�\}}
|jd|�d|	|
|f�}|jdk	r�|j�t	|���t
|�}|dk�rd|	|
|f�}|jdk	�r
|j�|��t|��t
|d|�S�|�rNt
td	�d
���t
td���t|
d��|S�|�r~t
td	�d
���t
td���t|	d��|S�td
|	|
f���dS�)a0��!Merges two GRIB1 files that must already have the same grid.

    This is a low-level implementation function.  It should not be
    called directly.  This function is sent as a parameter to GRIB1Op
    to do a copygb merge (-xM) of two GRIB1 files to produce a single
    GRIB1 file.  It requires that at least one of the files have a
    known grid, and if both have a known grid then their grids must
    mach.
    @param op The GRIBBase operation running this funciton.
    @param regrib a Regrib for data information
    @param in1,in2 The input GRIBGrid objects that provide filenames
    @param kwargs Ignored
    @returns The resulting GRIB1File, which may be in1, in2 or a new
       GRIB1File
    @bug This function calls pwd and ls -l if things go wrong.  It
       needs to use produtil.listing instead.Nz0%s: unable to guess the grid for this GRIB mergez4input grids to not match in GRIB merge: (%s) != (%s)z
merge.grb1�-gz-xMr���z+%s + %s: GRIB1 merge failed: exit status %d�lsz-l�pwdz: not ok (empty or missing)z8%s, %s: both inputs to GRIB1 merge are empty or missing.)r����r���r
���r����r����r���r&���r5���r����rr���r���r����r���r���r���r���)r^���r����Zin1Zin2r`���Zgrid1Zgrid2r����r�����file1�file2Zok1Zok2r����r����r����r����rC���rC���rD����action_grib1merge���sd��������



���

r����c�����������������O���s����|��d|j��\}}|j}|dkr*td��|jd|j�d|j|f�}	|jdk	r^|j�t|	���t	|	�}
|
dkr|t
d|
f���t||��t|d|j�S�)a@��!Regrids a GRIB1 file.

    This is a low-level implementation function.  It should not be
    called directly.  This is sent as a parameter to GRIB1Op to
    convert a GRIB1 file from one grid to another.  The output has a
    known grid, so it can be sent into an action_grib1merge.
    @param op The GRIBBase operation running this funciton.
    @param regrib a Regrib for data information
    @param infile The input filename.
    @param ingrid Input GRIB1Grid that specifies the target grid.
    @param args,kwargs Ignored
    @returns a new GRIB1File for the output fileZto_NzSTried to regrid a GRIB1 file, but the GRIBGrid did not have GRIB1 grid information.r����z-xr���z7ERROR: copygb regrid command failed with exit status %d)
r����gridnamer����r���r&���r����r5���r����rr���r���r���r����r���)r^���r����r����Zingridr����r`���r����r����r����r����r����rC���rC���rD����action_grib1regrid��s ����
�
�
r���c�����������������O���s����|��d|j��\}}|jdkr.td|tf���|�|�}dd��|�|�D��}	|jdd|jd|f�d	�|	�>�}
|j	dk	r�|j	�
t|
���t|
|j	d
�}|dkr�t
d|f���t|d|j|j|j�S�)
aX��!Subsets a GRIB1 file.

    This is a low-level implementation function.  It should not be
    called directly. It subsets a GRIB1 file infile using the given
    subsetter.  The subsetter should have a list of strings accessible
    via subsetter.grib1sub.  It should also have a name accessible
    through subsetter.subsetname.  The wgrib -s output of infile is
    scanned.  Any line in wgrib -s's output that contains the entirety
    of any line in the subsetter.grib1sub is retained. The subsetting
    is done via wgrib -i -grib (infile) -o (outfile).

    @param op The GRIBBase operation running this funciton.
    @param regrib a Regrib for data information
    @param infile The input filename.
    @param subsetter A GRIBSubsetter that chooses the fields to keep.
    @param args,kwargs Ignored
    @returns a new GRIB1File for the output fileZsub_Nz3%s: cannot create: no GRIB1 subsetter for subset %sc�����������������S���s���g�|�]}|�qS�rC���rC���)�.0�linerC���rC���rD����
<listcomp>=��s�����z&action_grib1subset.<locals>.<listcomp>z-iz-gribz-o�
r����r���z6ERROR: wgrib subset command failed with exit status %d)r����
subsetname�grib1subZSubsetlessErrorZsubname�wgrib_sr'���r����re���r5���r����rr���r���r���r���r�����nscenter�ewcenter)r^���r����r�����	subsetterr����r`���r����r�����indexZsubindexr����r����rC���rC���rD����action_grib1subset%��s*����
�
�
�
��r��c�����������������K���s���|j�dk	st�|j��d��t|j�}t|j�}
|j�dk	rp|j��dt|�t|�t|�t|�t|�t|	�||
f���t|d��}t|d��}t|
�}t|�}t|	�}t|d�d|�d���}t|d�d|�d���}t|
d�d|�d���}t|
d�d|�d���}dt|
�d@�k�r>|j�dk	�r4|j��dt|
�f���||�}}dt|
�d	@�k�r||j�dk	�rr|j��d
t|
�f���||�}}dt|
�d@�k�r�|j�dk	�r�|j��dt|
�f���||	�}	}|dk�s�t�|dk�s�t�d
|||||||||f	�}t||d�S�)ae��!Generates a latitude-longitude grid centered on a GRIB file or
    specified point.

    This is an internal implementation function that should not be
    called directly.  It queries the center object's nscenter and
    ewcenter properties to get the objects location.  It then adds a
    border around that, creating a GRIB1 grid 255 grid specification
    centered on the @c center object.
    @param op The GRIBBase operation running this funciton.
    @param center The GRIBBase operation on which to center the grid
    @param regrib a Regrib for data information
    @param name the name of the resulting grid, for storage in
       a RegribMany
    @param nsres,ewres GRIB1 grid 255 resolution information
    @param nssize,ewsize GRIB1 grid 255 size information, but in degrees.
       It will be converted to millidegrees for passing to underlying
       GRIB manipulation programs.
    @param nscount,ewcount Number of gridpoints in each direction,
       for the GRIB1 grid 255 information.
    @param scan GRIB1 grid 255 scanning mode byte
    @param kwargs Ignored
    @returns a new GRIBGrid for the new gridNz
IN CLATLONzVCLATLON: nsres=%s ewres=%s nssize=%s ewsize=%s nscount=%s ewcount=%s nscen=%f ewcen=%fi���r#���r�������zCLATLON scan=%d, swap EW�@���zCLATLON scan=%d, swap NS� ���z!CLATLON scan=%d, swap NS-EW sizesz"255 0 %d %d %d %d %d %d %d %d %d 0)	r5���r<���r�����floatr��r	��rr����intr���)r^���r����r�����centerZnsresZewresZnssizeZewsizeZnscountZewcount�scanr`���ZnscenZewcenZiewresZinsresZiscanZinscountZiewcountZinlatZislatZielonZiwlonr����rC���rC���rD����action_clatlonI��s`����


������

�
����r��c�������������������@���s(���e�Zd�ZdZdd��Zdd��Zdd��ZdS�)	rn���a��!Base class for the regridding object tree.

    This is the abstract base class for all GRIB files, operators,
    subsetters and grids.  Everything that is representable as an
    Regrib operation is a subclass of GRIBBase.  This class should
    never be instantiated directly.c�����������������O���s���dS�)z�!Returns True if this object and its subobjects are all
        ready for a call to make, and False otherwise.
        @param args,kwargs Ignored, but used by subclasses.TrC����r=���r����r`���rC���rC���rD���ri������s����zGRIBBase.is_readyc�����������������K���s���dS�)z�!Returns True if the specified kwargs are valid and False
        otherwise.
        @param kwargs Ignored, but used by subclassesTrC���rj���rC���rC���rD���rk������s����zGRIBBase.input_validc�����������������K���s���|�S�)z�!Runs the action this object should perform and returns
        another GRIBBase object.
        @param regrib a Regrib for data information
        @param kwargs Ignored, but used by subclasses.rC���)r=���r����r`���rC���rC���rD���rl������s����z
GRIBBase.makeN)rR���rS���rT���rU���ri���rk���rl���rC���rC���rC���rD���rn������s���rn���c�������������������@���s���e�Zd�ZdZdS�)r����zs!This abstract base class represents something that is able to
    produce a GRIBGrid object when make() is called.N)rR���rS���rT���rU���rC���rC���rC���rD���r�������s���r����c�����������������������s|���e�Zd�ZdZd��fdd�	Zdd��Zdd��Zd	d
��Zdd��Zd
d��Z	dd��Z
eeddd�Zee	ddd�Z
ee
ddd�Z���ZS�)r���z;!This class represents a GRIB1 or GRIB2 grid specification.Nc��������������������s$���t�t|������||�_||�_||�_dS�)a���!Creates a GRIBGrid with a given name, a copygb -g style
        GRIB1 grid specification and a GRIB2 grid specification that
        is currently unused.  
        @param gridname The gridname is mandatory and will be used to
        generate temporary filenames.
        @param grib1grid The GRIB1 grid information, a string
        @param grib2grid The GRIB2 grid information (unsupported)N)r,���r���r-����	_gridname�
_grib1grid�
_grib2grid)r=���r����r�����	grib2gridrA���rC���rD���r-������s����zGRIBGrid.__init__c�����������������O���s���dS�)zq!Returns True.  The grid information is always ready.
        @param args,kwargs Ignored, but used by subclasses.TrC���r��rC���rC���rD���ri������s����zGRIBGrid.is_readyc�����������������K���s���dS�)z�!Returns True.  The grid information is always available,
        regardless of the kwargs.
        @param kwargs Ignored, but used by subclasses.TrC���rj���rC���rC���rD���rk������s����zGRIBGrid.input_validc�����������������O���s���|�S�)zv!Returns self.  This grid is the output grid of this grid.
        @param args,kwargs Ignored, but used by subclasses.rC���r��rC���rC���rD���rl������s����z
GRIBGrid.makec�����������������C���s���|�j�S�)zG!Returns the name of this grid, as provided to the
        constructor.)r��rE���rC���rC���rD����getgridname���s����zGRIBGrid.getgridnamec�����������������C���s���|�j�S�)zk!Returns the GRIB1 (wgrib) style grid information, as sent
        to the constructor's grib1grid argument.�r��rE���rC���rC���rD����getgrib1grid���s����zGRIBGrid.getgrib1gridc�����������������C���s���|�j�S�)z�!This is a placeholder to return the GRIB2-style grid
        information.  At present, it returns whatever was sent to the
        constructor's grib2grid argument�r��rE���rC���rC���rD����getgrib2grid���s����zGRIBGrid.getgrib2gridzRThe name of this grid.  This is used to generate output filenames when regridding.zIA string to send to copygb's -g parameter for interpolating to this grid.z/GRIB2 regridding information, currently unused.)NN)rR���rS���rT���rU���r-���ri���rk���rl���r��r��r��rV���r����r����r��rW���rC���rC���rA���rD���r������s"������ZQuarter_Degree_Grid_193Z193c�������������������@���s0���e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zd
S�)r����z�!This class represents a GRIBGrid that is stored in a RegribMany
    object.  It is able to check for readiness via RegribMany.is_ready
    and produce a result via RegribMany.make.c�����������������C���s
���||�_�dS�)z�!GRIBGridFetcher constructor
        @param name The name of the grid that is fetched.  This is used
        to generate temporary filenames and is used in RegribMany for
        the generator name.N��_namer����rC���rC���rD���r-������s����zGRIBGridFetcher.__init__c�����������������O���s$���|d�}|st��|j|�jf|�|�S�)a*��!Calls kwargs['regribmany'].has_data to see if the specified
        operation has produced its grid.
        @param args,kwargs Passed to source.has_data.  The meaning
        is implementation-specific, but generally the kwargs are
        used for string replacement in an hwrf.config.HWRFConfigr�����r<���r����r ���r=���r����r`����sourcerC���rC���rD���ri������s����zGRIBGridFetcher.is_readyc�����������������K���s ���|d�}|st��|j|�jf|�S�)a6��!Calls kwargs['regribmany'].input_valid to see if the
        specified kwargs make a valid input to the operation.
        @param kwargs Passed to source.input_valid.  The meaning
        is implementation-specific, but generally the kwargs are
        used for string replacement in an hwrf.config.HWRFConfigr�����r<���rk���r ���r=���r`���r#��rC���rC���rD���rk������s����zGRIBGridFetcher.input_validc�����������������O���s ���|d�}|st��|j|�jf|�S�)z�!Calls kwargs['regribmany'].make to produce the grid.
        @param args,kwargs Passed to source.make.  The meaning
        is implementation-specific, but generally the kwargs are
        used for string replacement in an hwrf.config.HWRFConfigr�����r<���rl���r ��r"��rC���rC���rD���rl������s����zGRIBGridFetcher.makeN�rR���rS���rT���rU���r-���ri���rk���rl���rC���rC���rC���rD���r�������s
���		r����c�������������������@���s0���e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zd
S�)�GRIBGridComputez�!This class represents a GRIBGrid that must be computed from
    some other input, usually a GRIB file.  This is used to create
    storm-centered or E-grid GRIB-centered grids for the HWRF.c�����������������G���s���||�_�||�_t|�|�_dS�)a���!Creates a new GRIBGridCompute with the given name and
        action.  The action is a function or callable object that
        takes this object, the regrib, the name and the contents of
        args.  Also, any keyword arguments given to self.make are
        passed on as well.
        @param name The name of the computed grid.
        @param action The function that computes the grid.
        @param args Additional positional arguments are sent to the function.N)r ���_actionr8����_args)r=���r�����actionr����rC���rC���rD���r-�����s����	zGRIBGridCompute.__init__c�����������������O���s,���|�j�D�] }t|t�r|j||�s�dS�qdS�)a*��!Returns the logical "or" of is_ready(*args,**kwargs) called
        on all subobjects.  Subobjects that are not instances of
        GRIBBase are assumed to be ready.
        @param args,kwargs Passed to arg.is_ready, for all args sent to
           the constructor that are subclasses of GRIBBaseFT)r*��rm���rn���ri����r=���r����r`���r����rC���rC���rD���ri�����s����
zGRIBGridCompute.is_readyc�����������������O���s,���|�j�D�] }t|t�r|jf�|�s�dS�qdS�)a*��!Returns the logical "or" of input_valid(**kwargs) called on
        all subobjects.  Subobjects that are not instances of GRIBBase
        are assumed to be ready.
        @param args,kwargs Passed to arg.input_valid, for all args sent to
           the constructor that are subclasses of GRIBBaseFT)r*��rm���rn���rk���r,��rC���rC���rD���rk���"��s����
zGRIBGridCompute.input_validc�����������������K���sR���g�}|�j�D�].}t|t�r.|�|j|f|���q
|�|��q
|�j|�||�jf|�|�S�)ag��!Runs the action specified in the constructor, providing as
        arguments regrib, and the result of running make on all of the
        other arguments sent to the constructor.
        @param regrib The Regrib object for data storage.
        @param kwargs Passed to arg.make, for all args sent to
           the constructor that are subclasses of GRIBBase)r*��rm���rn���r����rl���r)��r ��)r=���r����r`���r����r����rC���rC���rD���rl���,��s����

zGRIBGridCompute.makeNr'��rC���rC���rC���rD���r(����s
���

r(��c�������������������@���sT���e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zd
d��Ze	eedd
�Z
e	eedd�ZdS�)�
FixedLocationz�!Represents a specific location on the earth as a latitude,
    longitude pair.  This is meant to be used with action_clatlon to
    generate fixed lat-lon grids.c�����������������C���s���t�|�|�_t�|�|�_dS�)z_!FixedLocation constructor
        @param lat,lon The fixed location in degrees North and East.N)r���_FixedLocation__lat�_FixedLocation__lon)r=����lat�lonrC���rC���rD���r-���?��s����
zFixedLocation.__init__c�����������������C���s���|�j�S�)z!Returns the point's latitude�r.��rE���rC���rC���rD����getlatD��s����zFixedLocation.getlatc�����������������C���s���|�j�S�)z!Returns the point's longitude.�r/��rE���rC���rC���rD����getlonG��s����zFixedLocation.getlonc�����������������C���s
���||�_�dS�)zP!Sets the point's latitude
        @param val The new latitude in degrees North.Nr2��rM���rC���rC���rD����setlatJ��s����zFixedLocation.setlatc�����������������C���s
���||�_�dS�)zQ!Sets the point's longitude.
        @param val The new longitude in degrees EastNr4��rM���rC���rC���rD����setlonN��s����zFixedLocation.setlonNz$The latitude of this fixed location.z%The longitude of this fixed location.)rR���rS���rT���rU���r-���r3��r5��r6��r7��rV���r��r	��rC���rC���rC���rD���r-��;��s�����r-������c�����������������C���s����t�|�dkr$|d�dkr$|d�dks(t�t�|�dkrL|d�dkrL|d�dksPt�|dkr`|dksdt�t�|�dkr�|d�dkr�|d�dks�t�|dkr�dt|d��t|d��f�}t|t|�|d�|d�|d�|d�|d�|d�|�
S�)a^��!Create a GRIBGridCompute that makes a lat-lon grid.

    Returns a GRIBGridCompute that will produce a lat-lon grid
    centered on the given object.  The provided object must have
    nscenter and ewcenter properties that produce real lats and lons
    that are positive North and positive East.  The res parameter is a
    two element array containing the resolution in degrees.  

    @param name the new grid's name
    @param center An object on which to center.  Must have nscenter and ewcenter
      properties.
    @param res The GRIB1 grid 255 resolution information in a two-element array.
    @param size The size parameter is a two-element array containing the
       extent in degrees.  
    @param n The n parameter contains the number of gridpoints.  
    @param scan The "scan" parameter is the scanning mode parameter: 128
       means E-W are reversed, 64 means N-S are reversed, and 32 means
       the data is transposed.

    @note All three, res, size and n, are two element arrays with the
    N-S value first and the E-W value second.  These are turned into
    a GRIB1 grid 255 specification.r#���r���r"��������Nz
clatlon%dx%dp)r����r<���r��r(��r��)r���res�size�nr��r����rC���rC���rD����clatlon]��s����(((����r=��c�����������������������s|���e�Zd�ZdZd��fdd�	Zdd��Zdd��Zd	d
��Zdd��Zd
d��Z	dd��Z
eeddd�Zee	ddd�Z
ee
ddd�Z���ZS�)r���zE!A GRIBBase that subsets GRIB files, keeping only certain parameters.Nc��������������������s$���t�t|������||�_||�_||�_dS�)aL��!GRIBSubsetter constructor.

        Creates a GRIBSubsetter with a given name, a callable
        object grib1sub that will be sent to
        produtil.gribop.grib1subset, and an unused grib2sub that will
        be used for GRIB2 subsetting one day.  
        @param grib1sub Callable object that iterates over
          wgrib -s output and yields only fields that should be kept,
          potentially in a new order.
        @param grib2sub Unsupported: GRIB2 subsetter.
        @param subsetname The subsetname is mandatory and will be used to
          generate temporary filenames.N)r,���r���r-����_subsetname�	_grib1sub�	_grib2sub)r=���r��r���grib2subrA���rC���rD���r-�����s����
zGRIBSubsetter.__init__c�����������������O���s���dS�)z�!Returns True.  The subsetter is its own product, so it is
        always "ready."
        @param args,kwargs Ignored, but used by subclasses. TrC���r��rC���rC���rD���ri������s����zGRIBSubsetter.is_readyc�����������������K���s���dS�)z�!Returns True.  The subsetter's product (itself) does not
        vary with the kwargs, so any input is valid.
        @param kwargs Ignored, but used by subclasses.TrC���rj���rC���rC���rD���rk������s����zGRIBSubsetter.input_validc�����������������O���s���|�S�)zm!Returns self.  The subsetter is its own product.
        @param args,kwargs Ignored, but used by subclasses.rC���r��rC���rC���rD���rl������s����zGRIBSubsetter.makec�����������������C���s���|�j�S�)z4!Returns a name of this subset for use in filenames.)r>��rE���rC���rC���rD����
getsubsetname���s����zGRIBSubsetter.getsubsetnamec�����������������C���s���|�j�S�)zb!Returns an iterator that takes as its only argument an
        array of lines of wgrib -s output.)r?��rE���rC���rC���rD����getgrib1sub���s����zGRIBSubsetter.getgrib1subc�����������������C���s���|�j�S�)zC!This is a placeholder for future GRIB2 subsetting
        support.)r@��rE���rC���rC���rD����getgrib2sub���s����zGRIBSubsetter.getgrib2subzTThe name of this GRIB1/2 subset.  This is used to generate 
       output filenames.zUA callable object to send to produtil.gribop.grib1subset's
       subsetter argument.z/GRIB2 subsetting information, currently unused.)NN)rR���rS���rT���rU���r-���ri���rk���rl���rB��rC��rD��rV���r��r��rA��rW���rC���rC���rA���rD���r���}��s"������c�������������������@���s0���e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zd
S�)r����z;!This class grabs a GRIBSubsetter from a RegribMany object.c�����������������C���s
���||�_�dS�)zL!GRIBSubsetterFetcher constructor
        @param name the name of the subsetNr��r����rC���rC���rD���r-������s����zGRIBSubsetterFetcher.__init__c�����������������K���s ���|d�}|st��|j|�jf|�S�)z�!Calls kwargs['regribmany'].input_valid to see if the kwargs
        make a valid input.
        @param kwargs Contains a regribmany key mapping to a RegribMany objectr����r$��r%��rC���rC���rD���rk������s����z GRIBSubsetterFetcher.input_validc�����������������O���s$���|d�}|st��|j|�jf|�|�S�)a ��!Calls kwargs['regribmany'].has_data to see if the operation
        has produced its subsetter yet.
        @param kwargs Contains a regribmany key mapping to a RegribMany object.
          Is also passed to has_data
        @param args Additional positional arguments passed to has_datar����r!��r"��rC���rC���rD���ri������s����zGRIBSubsetterFetcher.is_readyc�����������������O���s ���|d�}|st��|j|�jf|�S�)z�!Calls kwargs['regribmany'].make to produce the subsetter.
        @param args,kwargs Passed to source.make.  The meaning
        is implementation-specific, but generally the kwargs are
        used for string replacement in an hwrf.config.HWRFConfigr����r&��r"��rC���rC���rD���rl������s����zGRIBSubsetterFetcher.makeN�rR���rS���rT���rU���r-���rk���ri���rl���rC���rC���rC���rD���r�������s
���	r����c�������������������@���sV���e�Zd�ZdZdd��Zdd��Zdd��Zeeddd	�Zd
d��Z	dd
��Z
dd��Zdd��ZdS�)r���z|!This is the abstract base class for all GRIB1 and GRIB2 files
    and operators.  It should never be instantiated directly.c�����������������G���s���||�_�t|�|�_dS�)a���!Creates a GRIBOp that has a number of child GRIBBase
        objects, with a specified action to perform in the GRIBOp.make
        method.  The action should be a callable object that takes as
        input a Regrib, the contents of args and any keyword arguments
        sent to make.
        @param action the function that performs the operation
        @param args arguments to the actionN)r)��r8���r*���r=���r+��r����rC���rC���rD���r-������s����zGRIBOp.__init__c�����������������C���s���|�j�S�)z3!Returns the action, a function or callable object.)r)��rE���rC���rC���rD����	getaction���s����zGRIBOp.getactionc�����������������c���s���|�j�D�]
}|V��qdS�)z*!Iterates over all child GRIBBase objects.N)r*��)r=���r����rC���rC���rD���r�������s����
zGRIBOp.argsNz<Returns the callable object that performs this object's workc�����������������O���s$���|�����D�]}|j||�s�dS�qdS�)a��!Returns the logical "and" of is_ready(*args,**kwargs)
        called on all subobjects.
        @param args,kwargs Passed to arg.is_ready.  The meaning
        is implementation-specific, but generally the kwargs are
        used for string replacement in an hwrf.config.HWRFConfigFT)r����ri���r,��rC���rC���rD���ri������s����zGRIBOp.is_readyc�����������������K���s$���|�����D�]}|jf�|�s�dS�qdS�)a��!Returns the logical "and" of input_valid(**kwargs) called
        on all subobjects.
        @param kwargs Passed to source.has_data.  The meaning
        is implementation-specific, but generally the kwargs are
        used for string replacement in an hwrf.config.HWRFConfigFT)r����rk���)r=���r`���r����rC���rC���rD���rk������s����zGRIBOp.input_validc�����������������K���sX���g�}|�����D�]6}|j|f|�}|dk	s*t�t|t�s8t�|�|��q|�j|�|f|�|�S�)a���!Runs the action specified in the constructor, providing as
        arguments regrib, and the result of running make on all of the
        other arguments sent to the constructor.
        @param regrib a Regrib for data storage
        @param kwargs Passed to the action.  The meaning
        is implementation-specific, but generally the kwargs are
        used for string replacement in an hwrf.config.HWRFConfigN)r����rl���r<���rm���rn���r����r)��)r=���r����r`���r����r����r]���rC���rC���rD���rl���
��s����zGRIBOp.makec�����������������C���s.���dt�|��jt|�j�d�dd��|����D���f�S�)z0!A string representation of this GRIB operation.z
<%s %s %s>�,c�����������������S���s���g�|�]}t�|��qS�rC���)rr���)r���xrC���rC���rD���r����s�����z#GRIBOp.__repr__.<locals>.<listcomp>)rq���rR���rr���r)��re���r����rE���rC���rC���rD����__repr__��s�����zGRIBOp.__repr__)
rR���rS���rT���rU���r-���rG��r����rV���r+��ri���rk���rl���rJ��rC���rC���rC���rD���r������s���
�

c�����������������������s8���e�Zd�ZdZ��fdd�Zdd��Zdd��Zdd	��Z���ZS�)
r���z�!This subclass of GRIBOp produces GRIB2 files, and can be
    converted to GRIB1 via obj*GRIB1 or obj.to_grib1().  Calls to
    obj.to_grib2() or obj*GRIB2 simply return self.c��������������������s���t�t|��j|f|����dS�)zI!GRIB2Op constructor
        @param action,args Passed to GRIBOp.__init__N)r,���r���r-���rF��rA���rC���rD���r-���"��s����zGRIB2Op.__init__c�����������������C���s
���t�t|��S�)zA!Returns a GRIB2Op that converts this operation's output to GRIB1)r���r����rE���rC���rC���rD����to_grib1&��s����zGRIB2Op.to_grib1c�����������������C���s���|�S�)z4!Returns self (converting GRIB2 to GRIB2 is a no-op)rC���rE���rC���rC���rD����to_grib2)��s����zGRIB2Op.to_grib2c�����������������C���s,���|t�kr|����S�|tkr|�S�|tkr(|�S�tS�)a��!If grid is the special constant GRIB1, this is the same as to_grib1(),
        if GRIB2, then returns self.  Otherwise, returns NotImplemented to indicate
        that GRIB2 regridding is not implemented yet.
        @param grid The constant GRIB1, GRIB2, or a GRIBGrid)r���rK��r����SATGRIB2�NotImplemented�r=���r����rC���rC���rD����__mul__,��s����zGRIB2Op.__mul__)	rR���rS���rT���rU���r-���rK��rL��rP��rW���rC���rC���rA���rD���r�����s
���c�����������������������s`���e�Zd�ZdZ��fdd�Zdd��Zdd��Zdd	��Zd
d��Zdd
��Z	dd��Z
dd��Zdd��Z���Z
S�)r���a���!This subclass of GRIBOp produces GRIB1 files.  It introduces a
    number of convenience calls:

    * file1 + file2 + file3 = a copygb merge of the three files
    * file1*grid = copygb interpolate file1 to the specified GRIBGrid
    * file1*GRIB2 = convert to GRIB2
    * file1*GRIB1 = no-op (returns self)
    * file1/subsetter = subsets the GRIB1 file using the given GRIBSubsetter

    These can be combined, of course, and follow the usual Python
    order of precedence:

    * (file1*grid + file2*grid + file3/subsetter*grid)*GRIB1

    As with the GRIB2Op, there are also to_grib1() and to_grib2()
    methods which return self, and a GRIB2 conversion of self,
    respectively.c��������������������s���t�t|��j|f|����dS�)z�!Creates a new GRIB1Op, passing all arguments to the
        superclass constructor.
        @param action,args Passed to GRIBOp.__init__N)r,���r���r-���rF��rA���rC���rD���r-���K��s����zGRIB1Op.__init__c�����������������C���s���|�S�)z:!Returns self.  The GRIB1Op already produces a GRIB1 file.rC���rE���rC���rC���rD���rK��P��s����zGRIB1Op.to_grib1c�����������������C���s
���t�t|��S�)zU!Returns a GRIB2Op that will make a GRIB2 version of this
        operation's output.)r���r����rE���rC���rC���rD���rL��S��s����zGRIB1Op.to_grib2c�����������������C���s
���t�t|��S�)zi!Returns a GRIB2Op that will make a GRIB2 version of this
        operation's output using hwrf_satgrib2.)r���r����rE���rC���rC���rD����to_satgrib2W��s����zGRIB1Op.to_satgrib2c�����������������G���s����t�|t�stdt|�jf���t��}|�|��|�|������|D�]:}|���}t�|t�sptdt|�jt	|�f���|�|��q@tt
f|���S�)aq��!Returns a GRIB1Op that will ask hwrf_regrid_merge to convert one
        or more files to a target grid and paste them on top of one
        another, without making intermediate files.

        @param grid The target grid (GRIBGrid) for both objects
        @param args All other positional arguments contain the other
        GRIB1 file producers to regrid.

        zPFirst argument to GRIB1Op.regridmerge must be a GRIBGridBase subclass, not a %s.zmSecond and later arguments to GRIB1Op.regridmerge must convertable to GRIB1Op objects.  You provided a %s %s.)rm���r����rv���rq���rR���r8���r����rK��r���rr���r����)r=���r����r�����largsr����Zarg1rC���rC���rD���r+���[��s&����


��

��zGRIB1Op.regridmergec�����������������C���s
���t�t|��S�)zj!Returns a GRIB1Op that will run grbindex and save the
        results, unless that has already been done.)r���r����rE���rC���rC���rD����
make_grbindexv��s����zGRIB1Op.make_grbindexc�����������������C���s���t�|t�rtt|�|�S�tS�)z�!Returns a GRIB1Op that will subset this one using the
        specified subsetter.
        @param subsetter a GRIBSubsetter to do the subsetting.)rm���r���r���r��rN��)r=���r
��rC���rC���rD����__div__z��s����
zGRIB1Op.__div__c�����������������C���sJ���t�|t�rtt|�|�S�|tkr&|����S�|tkr6|����S�|tkrF|��	��S�t
S�)a\��!If the grid is a GRIBGridBase, returns a GRIB1Op that will
        regrid this GRIB1Op's output to that grid.  If grid is the
        special constant GRIB2, returns self.to_grib2.  If it is the
        constant GRIB1, returns self.to_grib1.  Otherwise, returns
        NotImplemented.
        @param grid Constants GRIB1, GRIB2, or a GRIBGridBase)rm���r����r���r���r���rK��r���rL��rM��rQ��rN��rO��rC���rC���rD���rP�����s����
zGRIB1Op.__mul__c�����������������C���s���t�|t�rtt|�|����S�tS�)a3��!If the argument is a GRIBOp, returns a GRIB1Op that will
        paste a GRIB1 version of that operations output onto this
        operation's output.  For any other argument type, returns
        NotImplemented.
        @param other a GRIBOp whose output will be interpolated
          on top of this one.)rm���r���r���r����rK��rN��)r=����otherrC���rC���rD����__add__���s����
zGRIB1Op.__add__)rR���rS���rT���rU���r-���rK��rL��rQ��r+���rS��rT��rP��rV��rW���rC���rC���rA���rD���r���9��s���c�������������������@���s0���e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zd
S�)r����zX!The GRIB1Fetcher is a GRIB1Op subclass that fetches a GRIB1
    file from a RegribMany.c�����������������C���s
���||�_�dS�)z�!Creates a GRIB1Fetcher for the specified operation name.
        @param name the name of this operation for temporary filename
          generationNr��r����rC���rC���rD���r-������s����zGRIB1Fetcher.__init__c�����������������K���s ���|d�}|st��|j|�jf|�S�)a��!Calls kwargs['regribmany'].input_valid to determine if the
        specified keyword arguments make a valid input to the
        operation.
        @param kwargs Contains a regribmany key mapping to a RegribMany object.
          Is also passed to source.input_validr����r$��r%��rC���rC���rD���rk������s����zGRIB1Fetcher.input_validc�����������������O���s$���|d�}|st��|j|�jf|�|�S�)a!��!Calls kwargs['regribmany'].has_data to see if there is
        cached output from the operation.
        @param kwargs Contains a regribmany key mapping to a RegribMany object.
          Is also passed to source.has_data.
        @param args Positional arguments passed to source.has_datar����r!��r"��rC���rC���rD���ri������s����zGRIB1Fetcher.is_readyc�����������������O���s ���|d�}|st��|j|�jf|�S�)a��!Calls kwargs['regribmany'].make to produce the operation's
        output.
        @param kwargs Contains a regribmany key mapping to a RegribMany object.
          Is also passed to source.make.
        @param args Additional positional arguments are unused.r����r&��r"��rC���rC���rD���rl������s����zGRIB1Fetcher.makeNrE��rC���rC���rC���rD���r�������s
���		r����c�����������������������s����e�Zd�ZdZd"��fdd�	Zdd��Zdd��Zd	d
��Zdd��Zd
d��Z	dd��Z
dd��Zdd��Zdd��Z
dd��Zdd��Zee
ddd�Zee
ddd�Zeeddd�Zeee
dd�Zeeddd�Zeeddd �Zee	ddd!�Z���ZS�)#r���z�!This subclass of GRIB1Op represents a GRIB1 file on disk that
    is ALREADY PRESENT.  Its is_ready function is overridden to assume
    the file is always ready, and its "make" method simply returns
    self.Nc��������������������s����t�t|���d��||�_||�_||�_||�_|dksTt|�dk	sTtd|j	j
t|�f���|dks�t|�dk	s�td|j	j
t|�f���||�_||�_
d|�_dS�)aP��!GRIB1File constructor.
        @param grib1file The file path.
        @param grib1index Path to the wgrib -s output
        @param grib1grid Grid information.
        @param nscenter,ewcenter Latitude and longitude of the grid center point,
          in degrees North and East
        @param grib1grbindex Path to the grbindex output.NzAewcenter must be None, or an int or float, not a %s (ewcenter=%s)zAnscenter must be None, or an int or float, not a %s (nscenter=%s))r,���r���r-����
_grib1file�_grib1indexr���_grib1grbindexr��rv���rB���rR���rr����	_ewcenter�	_nscenter�
_indexdata)r=���r�����
grib1indexr����r��r	��r����rA���rC���rD���r-������s ����	��zGRIB1File.__init__c�����������������K���s���dS��zu!Returns True.  The file is already present, so any kwargs
        make a valid input.
        @param kwargs Ignored.TrC���rj���rC���rC���rD���rk������s����zGRIB1File.input_validc�����������������O���s���dS��z�!Returns True.  The operation is ready to run because it has
        nothing to do: the file is already present.
        @param args,kwargs Ignored.TrC���r��rC���rC���rD���ri������s����zGRIB1File.is_readyc�����������������O���s���|�S�)zx!Returns self.  This class represents a GRIB1 file, so it is
        its own output.
        @param args,kwargs Ignored.rC���r��rC���rC���rD���rl������s����zGRIB1File.makec�����������������C���s���|�j�S�)z$!Returns the domain center latitude.)r[��rE���rC���rC���rD����getnscenter���s����zGRIB1File.getnscenterc�����������������C���s���|�j�S�)z%!Returns the domain center longitude.)rZ��rE���rC���rC���rD����getewcenter���s����zGRIB1File.getewcenterc�����������������C���s���|�j�S�)z#!Returns the GRIB1 file's location.)rW��rE���rC���rC���rD����getgrib1file���s����zGRIB1File.getgrib1filec�����������������C���s���|�j�S�)zM!Returns the location of the file that stores the output of
        wgrib -s.)rX��rE���rC���rC���rD����
getgrib1index���s����zGRIB1File.getgrib1indexc�����������������C���s���|�j�S�)zo!Returns the location of the file that stores the output of
        the grbindex program run on the GRIB1 file.�rY��rE���rC���rC���rD����getgrib1grbindex���s����zGRIB1File.getgrib1grbindexc�����������������C���s
���||�_�dS�)zl!Sets the location of the file that stores the output of
        the grbindex program run on the GRIB1 file.Nrd��)r=����hererC���rC���rD����setgrib1grbindex���s����zGRIB1File.setgrib1grbindexc�����������������C���s���|�j�S�)z0!Returns the GRIB1 grid information as a string.r��rE���rC���rC���rD���r����s����zGRIB1File.getgrib1gridc��������������	���C���s����|�j�dk	r|�j�S�|�j}|dks*tj�|�sl|�|�j�}t|jd|�jf��}t	|d��}|�
|��W�5�Q�R�X�nt	|d��}|���}W�5�Q�R�X�|���|�_�|�j�S�)z�!Returns the output of wgrib -s run on this file, which may
        be from cached data.
        @param regrib a Regrib for data storageNz-s�wt�rt)
r\��r]��rc���rd����existsrz���r����r���r'����open�write�readall�
splitlines)r=���r����Z	indexfiler��r����rC���rC���rD���r����s����

zGRIB1File.wgrib_sz9The path to the result file, in this case the GRIB1 file.z=The path to the GRIB1 file which is assumed to already exist.z:Either None or the wgrib -s index file for the GRIB1 file.zAEither None or the grbindex binary index file for the GRIB1 file.zDEither None or the copygb -g argument data for the GRIB1 file's gridz7Returns None or the center latitude of this GRIB1 file.z8Returns None or the center longitude of this GRIB1 file.)NNN)rR���rS���rT���rU���r-���rk���ri���rl���r`��ra��rb��rc��re��rg��r��r��rV����
resultfiler����r]��r����r����r��r	��rW���rC���rC���rA���rD���r������sJ����������������c�����������������������s����e�Zd�ZdZ��fdd�Zdd��Zdd��Zdd	��Zd
d��Zdd
��Z	dd��Z
eeddd�Zeeddd�Z
ee	ddd�Zee
ddd�Z���ZS�)r���z�!This subclass of GRIB2Op represents a GRIB2 file on disk that
    is ALREADY PRESENT.  Its is_ready function is overridden to assume
    the file is always ready, and its "make" method simply returns
    self.c��������������������s&���t�t|���d��||�_||�_||�_dS�)z�!GRIB2File constructor
        @param grib2file The grib2 file path.
        @param grib2index The grib 2 index file path.
        @param grib2grid GRIB2 grid information.N)r,���r���r-����
_grib2file�_grib2indexr��)r=���r�����
grib2indexr��rA���rC���rD���r-���?��s����zGRIB2File.__init__c�����������������O���s���dS�r_��rC���r��rC���rC���rD���ri���H��s����zGRIB2File.is_readyc�����������������K���s���dS�r^��rC���rj���rC���rC���rD���rk���M��s����zGRIB2File.input_validc�����������������O���s���|�S�)zx!Returns self.  This class represents a GRIB2 file, so it is
        its own output.
        @param args,kwargs Ignored.rC���r��rC���rC���rD���rl���R��s����zGRIB2File.makec�����������������C���s���|�j�S�)z#!Returns the GRIB2 file's location.)rp��rE���rC���rC���rD����getgrib2fileW��s����zGRIB2File.getgrib2filec�����������������C���s���|�j�S�)zp!This is a placeholder for future development.  It returns
        the grib2index argument from the constructor.)rq��rE���rC���rC���rD����
getgrib2indexZ��s����zGRIB2File.getgrib2indexc�����������������C���s���|�j�S�)zo!This is a placeholder for future development.  It returns
        the grib2grid argument from the constructor.r��rE���rC���rC���rD���r��^��s����zGRIB2File.getgrib2gridNz9The path to the result file, in this case the GRIB2 file.z=The path to the GRIB2 file which is assumed to already exist.z9This is a placeholder for future GRIB2 subsetting supportz9This is a placeholder for future GRIB2 regridding support)rR���rS���rT���rU���r-���ri���rk���rl���rs��rt��r��rV���ro��r����rr��r��rW���rC���rC���rA���rD���r���:��s(���	����c�������������������@���s@���e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zee	j
d
d
d�Zd
S�)r���a��!This subclass of GRIB1Op and UpstreamFile represents a GRIB1
    file that is produced by an upstream workflow.  The is_ready
    subroutine calls self.check to check the modification time and
    file size.  The make subroutine copies the file to a local
    location.c�����������������O���s$���t�j|�|f|�|��t�|�d��dS�)z�!UpstreamGRIB1 constructor
        @param dstore the produtil.datastore.Datastore for database info
        @param args,kwargs All other arguments passed to produtil.datastore.UpstreamFile.__init__N)r���r-���r����r=����dstorer����r`���rC���rC���rD���r-���}��s����zUpstreamGRIB1.__init__c�����������������O���s"���d|kr|���|d��S�|�����S�dS�)a@��!Runs the check function on the upstream product, and
        returns its results.  If the frominfo argument is in kwargs,
        it is passed as the first positional parameter to check.
        @param kwargs The frominfo argument to UpstreamFile.check()
        @param args Additional positional arguments are ignored.�frominfoN��checkr��rC���rC���rD���ri������s����zUpstreamGRIB1.is_readyc�����������������K���s���dS�)zC!Returns True.
        @param kwargs Keyword arguments are ignored.TrC���rj���rC���rC���rD���rk������s����zUpstreamGRIB1.input_validc�����������������O���s@���|�j�}|�dtj�|���\}}tjj|||jd��t	|dd�S�)z�!Calls deliver_file to copy the file to a temporary location
        decided by regrib.gribtemp.  Returns a GRIB1File for that
        file.
        @param regrib a Regrib for data storage
        @param args,kwargs All other arguments are ignored.z	upstream.r����N�
r����r���rc���rd���rf���r����r�����deliver_filer5���r����r=���r����r����r`���r����r����r��rC���rC���rD���rl������s����zUpstreamGRIB1.makeNz8The path to the result file, in this case self.location.)rR���rS���rT���rU���r-���ri���rk���rl���rV���r����getlocationro��rC���rC���rC���rD���r���w��s���

�c�������������������@���s@���e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zd
d��Zdd
��Z	dS�)�
GRIB1Selectorz�!This object produces a GRIB1Op from a call to a Task object's
    Task.product.  This is the class that underlies the implementation
    of igrb1.c�����������������K���s���||�_�t|�|�_dS�)z�!Creates a GRIB1Selector for the specified task.  

        @param task The task whose products function is called.
        @param kwargs All other arguments are sent to task.products.N)�_taskr:���r����)r=���r����r`���rC���rC���rD���r-������s����zGRIB1Selector.__init__c�����������������K���s���|���|�}|���S�)zr!Returns True if the task's product is available.
        @param kwargs All keyword arguments are sent to select())�select�is_available�r=���r`����productrC���rC���rD���ri������s����
zGRIB1Selector.is_readyc�����������������K���s,���z|���|�}W�dS��tk
r&���Y�dS�X�dS�)z�!Returns True if select() is able to find a product and
        False if NoProductError is raised.  
        @param kwargs Keyword arguments are passed to select()TFN)r���r���r���rC���rC���rD���rk������s
����
zGRIB1Selector.input_validc�����������������K���s*���|���|�}t|t�std��|j|f|�S�)z�!Calls self.select(kwargs) to get the product, and calls
        make on the result.
        @param regrib A Regrib for data storage
        @param kwargs Keyword arguments are passed to select()z'Selected product is not a GRIB product.)r���rm���r���r���rl���)r=���r����r`���r���rC���rC���rD���rl������s����

zGRIB1Selector.makec�����������������C���s����t�|�j�}|�|��dd��|�jjf�|�D��}t|�dkrBtd��nFt|�dkrXtd��n0|d�}t|t	�s�t
dt|�jt
|�f���|S�dS�)	a|��!Attempts to attain a Product from the supplied Task.  

        @protected
        Calls a Task's products function to get the Product of
        interest.  The kwargs is a dict of keyword arguments to pass
        to task.products.  Those will override any keyword arguments
        that were sent to the constructor.  If more than one Product
        is yielded, then ProductAmbiguityError is raised.  If no
        Product is yielded, NoProductError is raised.  If the returned
        Product is not a GRIBBase, TypeError is raised.  Otherwise,
        the result is returned.

        @param kwargs a dict to pass to task.productsc�����������������S���s���g�|�]}|�qS�rC���rC���)r���prC���rC���rD���r�����s�����z(GRIB1Selector.select.<locals>.<listcomp>r"���z3Specified arguments produced more than one product.r���z(Specified arguments produced no product.zvERROR: in GRIB1Selector, a Task.products call returned something that was not a GRIBBase object.  It returned a %s %s.N)r:���r����r����r���productsr����r���r���rm���rn���rv���rq���rR���rr���)r=���r`���r����r���r���rC���rC���rD���r������s����




��zGRIB1Selector.selectc�����������������C���s���d|�j�j|�jj�jf�S�)z*!Returns a Pythonic representation of selfz%s(%s))rB���rR���r��rE���rC���rC���rD���rJ�����s����zGRIB1Selector.__repr__N)
rR���rS���rT���rU���r-���ri���rk���rl���r���rJ��rC���rC���rC���rD���r~�����s���		r~��c�����������������K���s���t�|�f|�S�)zx!This is a convenient alias for the GRIB1Selector constructor.
    @param task,kwargs Passed to GRIB1Selector.__init__())r~��)r����r`���rC���rC���rD����igrb1���s����r���c�������������������@���s����e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zd
d��Zdd
��Z	dd��Z
ee	ee
d�Zdd��Z
dd��Zdd��Zeee
ed�Zdd��Zdd��Zeeedd�Zeeedd�Zd#dd �Zd!d"��ZdS�)$r ���z�!This class represents a GRIB2 file that is produced by this
    workflow.  It is a direct subclass of both GRIB2File and
    FileProduct.c�����������������O���s^���d|kr|d�dkst��tj|�|f|�|��t�|�ddd��d|�_|�jdk	rV|�jdksZt��dS�)aP��!Creates a new GRIB2Product.  

        @param dstore The dstore is the produtil.datastore.Datastore
        for database storage.  
        @param args,kwargs All other arguments are passed on to
        FileProduct's constructor.  
        @note The GRIB2File constructor is initialized with None for
        the file, index and grid.r������N)r<���r���r-���r���r\��r����ru��rC���rC���rD���r-������s
����	zGRIB2Product.__init__c�����������������K���s���dS�)z!Returns True.  Since this object is already its product,
        any kwargs make a valid input.
        @param kwargs Ignored.TrC���rj���rC���rC���rD���rk������s����zGRIB2Product.input_validc�����������������O���s"���d|kr|���td��S�|�����S�dS�)a��!Calls self.check to see if the product is available.  

        @param args Additional positional arguments are ignored.
        @param kwargs Additional keyword arguments.  If frominfo is in
        the kwargs, it is passed as the first positional argument to
        check.rw��N)ry��Zkwrargsr��rC���rC���rD���ri�����s����zGRIB2Product.is_readyc�����������������O���s@���|�j�}|�dtj�|���\}}tjj|||jd��t	|dd�S�)a���!Calls deliver_file to copy the file to a new temporary
        location from regrib.gribtemp.  Returns a GRIB2File for that
        temporary file.
        @param regrib A Regrib for data storage
        @param args,kwargs All other arguments are ignored.�prod.r����N)
r����r���rc���rd���rf���r����r����r{��r5���r���r|��rC���rC���rD���rl�����s����zGRIB2Product.makec�����������������C���s(���|dks|dks|dkrdS�||�d<�dS�)zM!Sets the grib2 grid information.
        @param grid GRIB2 grid information.Nr����Noner��rC���rO��rC���rC���rD����setgrib2grid��s�����zGRIB2Product.setgrib2gridc�����������������C���s���|���dd�S�)z$!Returns the grib2 grid information.r��N�r����rE���rC���rC���rD���r����s����zGRIB2Product.getgrib2gridc�����������������C���s
���|�d=�dS�)z#!Clears the grib2 grid information.r��NrC���rE���rC���rC���rD����delgrib2grid��s����zGRIB2Product.delgrib2gridz$The GRIB2 grid information if known.c�����������������C���s(���|dks|dks|dkrdS�||�d<�dS�)z"!Sets the grib2 index information.Nr���r���rr��rC����r=���r��rC���rC���rD����
setgrib2index'��s�����zGRIB2Product.setgrib2indexc�����������������C���s���|���dd�S�)z>!Gets the grib2 index information, or returns None if unknown.rr��Nr���rE���rC���rC���rD���rt��+��s����zGRIB2Product.getgrib2indexc�����������������C���s
���|�d=�dS�)�a!Cleares the stored information about the index location.
        Does NOT delete the index file.rr��NrC���rE���rC���rC���rD����
delgrib2index.��s����zGRIB2Product.delgrib2indexz*The disk location of the GRIB2 index file.c�����������������C���s���|�j�S�)z;!Returns the location of the GRIB2 file from self.location.�r����rE���rC���rC���rD���rs��8��s����zGRIB2Product.getgrib2filec�����������������C���s
���||�_�dS�)z>!Sets the location of the GRIB2 file by setting self.location.Nr���rM���rC���rC���rD����setgrib2file;��s����zGRIB2Product.setgrib2fileN�Synonym for self.locationTc�����������
������C���s���t�|t�r tj|�|||d��dS�t�|t�s2td��|�j������|dk	rJ|n|�j}|dkrjt	j
�d|�j���d\}}	z
|j
}W�n"�tk
r��}
�zW�5�d}
~
X�Y�nX�z
|j}W�n(�tk
r��}
�z
|j}W�5�d}
~
X�Y�nX�W�5�Q�R�X�|dk	r�t|�nd|f�}	|dk	�r|dk�st�|dk	�r$|dk�s(t�t	jj|||d��d	}|dk	�rv|	dk	�rvt	j�|��rvt	jj||	|d��d
}|�j����P�||�_|�r�|	|�_
z|j|�_W�n$�tk
�r��}
�zW�5�d}
~
X�Y�nX�d
|�_W�5�Q�R�X�|�j|d��dS�)a���!Delivers a GRIB2 file to its destination.  May also deliver
        other files associated with that GRIB2 file.

        @param location Delivery location.
        @param index Index file delivery location
        @param grbindex Ignored.
        @param frominfo Either a source filename, or a GRIB2Op.
        @param keep If True, the source file will be copied instead of moved.
        @param logger A logging.Logger for log information.�r����rw��r����NzWGRIB2Product.deliver requires a frominfo that is either a string filename or a GRIB2Op.�P%s: no location known when delivering product.  Specify a location to deliver().�NN�
%s.wgrib_sr���)r����FTr����)rm���ru���r����deliverr���rv���rv���transactionr����r�����	datastore�UnknownLocation�didrr���AttributeErrorr����ro��r<���r����r{��r����r���	available�call_callbacks)
r=���r����r��r����rw��r����r5���r�����	fromindex�toindex�KeyError�fromloc�	haveindexrC���rC���rD���r���I��s\����

�
���
�
"
���zGRIB2Product.deliverc��������������	���C���sP���|�j�}|dk	r"|dkr"tj�|��|�j}|�j�����|�`|�`d|�_W�5�Q�R�X�dS�)zV!Deletes the delivered GRIB2 file and discards the index and
        grid information.Nr���F)	r����r����r�����remove_filerr��rv��r���r��r���)r=���r����r��rC���rC���rD����	undeliver���s����zGRIB2Product.undeliver)NNNNTN)rR���rS���rT���rU���r-���rk���ri���rl���r���r��r���rV���r��r���rt��r���rr��rs��r���r����ro��r���r���rC���rC���rC���rD���r ������s<���
���������
<c�������������������@���s����e�Zd�ZdZdd��Zdd��Zdd��Zdd	��Zd
d��Zdd
��Z	dd��Z
ee	ee
d�Zdd��Z
dd��Zdd��Zeee
ed�Zdd��Zdd��Zdd��Zeeeed�Zdd ��Zd!d"��Zeeed#d$�Zeeed#d$�Zd*d&d'�Zd(d)��Zd#S�)+�GRIB1Productz�!This class represents a GRIB1 file produced by this workflow.
    It stores grid information, if available, and will also deliver an
    index file if one exists.  It is a direct subclass of both
    FileProduct and GRIB1File.c�����������������O���s^���d|kr|d�dkst��tj|�|f|�|��t�|�ddd��d|�_|�jdk	rV|�jdksZt��dS�)a���!Creates a new GRIB1Product.  

        @param dstore The dstore is the produtil.datastore.Datastore.
        @param args Positional arguments, passed to the FileProduct
          constructor.  
        @param kwargs Keyword arguments.  The kwargs must specify the
          file location as a non-empty string.  
 
        @note The GRIB1File is initialized with the various indexes
        and grid missing (None).r����r���N)r<���r���r-���r���r\��r����ru��rC���rC���rD���r-������s
����zGRIB1Product.__init__c�����������������K���s���dS�)z�!Returns True.  This object is its own product, so any
        kwargs are valid.
        @param kwargs Keyword arguments are ignored.TrC���rj���rC���rC���rD���rk������s����zGRIB1Product.input_validc�����������������O���s"���d|kr|���|d��S�|�����S�dS�)z�!Runs self.check and returns the result.  
        @param args Positional arguments are ignored.
        @param kwargs Keyword arguments.  If frominfo is in kwargs, it
        is sent as the first positional argument to check.rw��Nrx��r��rC���rC���rD���ri������s����zGRIB1Product.is_readyc�����������������O���s@���|�j�}|�dtj�|���\}}tjj|||jd��t	|dd�S�)z�!Gets a temporary filename from gribtemp, and copies the
        GRIB1 file there.  Returns a new GRIB1File object for that
        file.
        @param regrib A Regrib for data storage
        @param args,kwargs All other arguments are ignored.r���r����Nrz��r|��rC���rC���rD���rl������s����zGRIB1Product.makec�����������������C���s���||�d<�dS�)z�!Sets the GRIB1 grid information; modifies the grib1grid
        metadata in the datastore.
        @param grid the new grid informationr����NrC���rO��rC���rC���rD����setgrib1grid���s����zGRIB1Product.setgrib1gridc�����������������C���s���|���dd�S�)zY!Returns the GRIB1 grid information from the grib1grid
        metadata in the datastore.r����Nr���rE���rC���rC���rD���r�����s����zGRIB1Product.getgrib1gridc�����������������C���s
���|�d=�dS�)z_!Discards GRIB1 grid information by removing the grib1grid
        metadata from the datastore.r����NrC���rE���rC���rC���rD����delgrib1grid���s����zGRIB1Product.delgrib1gridz*The GRIB1 grid (GDS) information if known.c�����������������C���s���||�d<�dS�)z�!Sets the output location of grbindex to the given location,
        and sets the grib1grbindex metadata value.
        @param index Location of the grbindex output.r����NrC���r���rC���rC���rD���rg�����s����zGRIB1Product.setgrib1grbindexc�����������������C���s���|���dd�S�)zW!Returns the output location of grbindex from the
        grib1grbindex metadata value.r����Nr���rE���rC���rC���rD���re�����s����zGRIB1Product.getgrib1grbindexc�����������������C���s
���|�d=�dS�)z�!Cleares the stored information about the grbindex binary
        index file location for this GRIB1 product by deleting the
        grib1grbindex metadata value.  Does NOT delete the grbindex
        file.r����NrC���rE���rC���rC���rD����delgrib1grbindex���s����zGRIB1Product.delgrib1grbindexz:The disk location of the GRIB1 grbindex binary index file.c�����������������C���s���||�d<�dS�)z�!Sets the output location of wgrib -s and sets the
        grib1index metadata value.
        @param index Location of the wgrib -s output.r]��NrC���r���rC���rC���rD����
setgrib1index���s����zGRIB1Product.setgrib1indexc�����������������C���s���|���dd�S�)zT!Returns the output location of wgrib -s from the grib1index
        metadata value.r]��Nr���rE���rC���rC���rD���rc�����s����zGRIB1Product.getgrib1indexc�����������������C���s
���|�d=�dS�)r���r]��NrC���rE���rC���rC���rD����
delgrib1index���s����zGRIB1Product.delgrib1indexz9The disk location of the GRIB1 index file, from wgrib -s.c�����������������C���s���|�j�S�)z4!Returns the GRIB1 file location from self.location.r���rE���rC���rC���rD���rb�����s����zGRIB1Product.getgrib1filec�����������������C���s
���||�_�dS�)zd!Sets the GRIB1 file location.  Same as setting self.location.
        @param val New file location.Nr���rM���rC���rC���rD����setgrib1file���s����zGRIB1Product.setgrib1fileNr���Tc�����������������C���s���t�|t�r tj|�|||d��dS�t�|t�s2td��|�j������|dk	rL|n|�j}|dkrlt	j
�d|�j���d\}}	z
|j
}W�n"�tk
r��}
�zW�5�d}
~
X�Y�nX�z
|j}W�n(�tk
r��}
�z
|j}W�5�d}
~
X�Y�nX�z
|j}W�n<�tk
�r�}
�z|�d�dk�rtd��W�5�d}
~
X�Y�nX�|dk�r@|�d�dk�r@td	��W�5�Q�R�X�|dk	�r\t|�nd
|f�}	|dk	�rxt|�nd|f�}
|dk	�r�|dk�s�t�|dk	�r�|dk�s�t�t	jj||||d
��d}|dk	�r|	dk	�rt	j�|��rt	jj||	||d
��d}d}|dk	�rB|
dk	�rBt	j�|��rBt	jj||
||d
��d}|�d�dk�r\|�s\t�|�j����\�||�_|�rz|	|�_
|�r�|
|�_z|j|�_W�n$�tk
�r��}
�zW�5�d}
~
X�Y�nX�d|�_W�5�Q�R�X�|�j|d��dS�)a%��!Delivers the GRIB1 data, and possibly the various index
        files as well.  

        If frominfo is supplied, then that file is
        delivered, and no other action is performed.  Otherwise, the
        file is delivered from self.location to the supplied location,
        the grib1index is delivered to the same location with an added
        ".wgrib_s" extension and the grib1grbindex is delivered with a
        ".grbindex" extension.

        @param location GRIB file delivery location
        @param index Delivery wgrib -s output location
        @param grbindex Where to deliver the output of grbindex
        @param frominfo Source information; see above.
        @param keep If False, source files can be moved instead of copied.
        @param logger a logging.Logger for log messages.r���NzWGRIB1Product.deliver requires a frominfo that is either a string filename or a GRIB1Op.r���r���Zhwrftrkr���z%hwrf track input has no grib1grbindexz)hwrf track input has a grib1grbindex=Noner���z%s.grbindexr���)r����r5���FTr����)rm���ru���r���r���r���rv���rv��r���r����r����r���r���r���r]��r���r����ro��r�����findr���r<���r����r{��r����r����r���r���)r=���r����r��r����rw��r����r5���r����r���r���r���r���ZfromgrbindexZ
togrbindexr���ZhavegrbindexrC���rC���rD���r���	��s�����
����
��
�

�
�����
�����
���zGRIB1Product.deliverc��������������	���C���sz���|�j�}|dk	r"|dkr"tj�|��|�j}|r8tj�|��|�j}|rNtj�|��|�j�����|�`|�`|�`d|�_	W�5�Q�R�X�dS�)z^!Undoes the effect of deliver(), removing the destination
          index files and GRIB file.Nr���F)
r����r����r����r���r]��r����rv��r���r����r���)r=���r����r��r����rC���rC���rD���r���j	��s������zGRIB1Product.undeliver)NNNNTN)rR���rS���rT���rU���r-���rk���ri���rl���r���r��r���rV���r����rg��re��r���r����r���rc��r���r]��rb��r���r����ro��r���r���rC���rC���rC���rD���r������sJ���	�	�����������
\r���)N)r8��N)IrU���rc���r����r�����os.pathr����r����r����ro����produtil.datastorer�����produtil.run�hwrf.exceptionsr����r���r���r���r���r���r���r���r	���r
���r���r���r
���r���r���r���r���r���r���r����__all__r���r���rM���objectr%���r���r����r����r����r����r����r����r����r����r����r���r��r��rn���r����r���r!���r����r(��r-��r=��r���r����r���r���r���r����r���r���r���r~��r���r ���r���rC���rC���rC���rD����<module>���sx���@<
���������%}���#-2
#B$A;%3"
 ?!Ae$x=)C�*