grib2io.utils API documentation

# grib2io.utils

Collection of utility functions to assist in the encoding and decoding of GRIB2 Messages.

View Source

      1"""
      2Collection of utility functions to assist in the encoding and decoding
      3of GRIB2 Messages.
      4"""
      5
      6import g2clib
      7import datetime
      8import numpy as np
      9import struct
     10
     11from .. import tables
     12
     13def int2bin(i,nbits=8,output=str):
     14    """
     15    Convert integer to binary string or list
     16
     17    Parameters
     18    ----------
     19
     20    **`i`**: Integer value to convert to binary representation.
     21
     22    **`nbits`**: Number of bits to return.  Valid values are 8 [DEFAULT], 16,
     23    32, and 64.
     24
     25    **`output`**: Return data as `str` [DEFAULT] or `list` (list of ints).
     26
     27    Returns
     28    -------
     29
     30    `str` or `list` (list of ints) of binary representation of the integer value.
     31    """
     32    i = int(i) if not isinstance(i,int) else i
     33    assert nbits in [8,16,32,64]
     34    bitstr = "{0:b}".format(i).zfill(nbits)
     35    if output is str:
     36        return bitstr
     37    elif output is list:
     38        return [int(b) for b in bitstr]
     39
     40
     41def putieeeint(r):
     42    """
     43    Convert an IEEE 32-bit float to a 32-bit integer.
     44
     45    Parameters
     46    ----------
     47
     48    **`r`**: Float value.
     49
     50    Returns
     51    -------
     52
     53    Integer representation of an IEEE 32-bit float.
     54    """
     55    ra = np.array([r],'f')
     56    ia = np.empty(1,'i')
     57    g2clib.rtoi_ieee(ra,ia)
     58    return ia[0]
     59
     60
     61def getieeeint(i):
     62    """
     63    Convert a 32-bit integer to an IEEE 32-bit float.
     64
     65    Parameters
     66    ----------
     67
     68    **`i`**: Integer value.
     69
     70    Returns
     71    -------
     72
     73    IEEE 32-bit float.
     74    """
     75    ia = np.array([i],'i')
     76    ra = np.empty(1,'f')
     77    g2clib.itor_ieee(ia,ra)
     78    return ra[0]
     79
     80
     81def getmd5str(a):
     82    """
     83    Generate a MD5 hash string from input list
     84    """
     85    import hashlib
     86    assert isinstance(a,list) or isinstance(a,bytes)
     87    return hashlib.md5(''.join([str(i) for i in a]).encode()).hexdigest()
     88
     89
     90def getdate(year,month,day,hour,minute=None,second=None):
     91    """
     92    Build an integer date from component input.
     93
     94    **`year`**: Year in 4-digit format.
     95
     96    **`month`**: Month in 2-digit format.
     97
     98    **`day`**: Day in 2-digit format.
     99
    100    **`hour`**: Hour in 2-digit format.
    101
    102    **`minute`**: Minute in 2-digit format. This argument is required if second is provided, otherwise
    103    it is optional.
    104
    105    **`second`**: Second in 2-digit format [OPTIONAL].
    106    """
    107    year_exp = 6
    108    month_exp = 4
    109    day_exp = 2
    110    hour_exp = 0
    111    #if second is not None and minute is None:
    112    #    raise ValueError("Must provide minute argument if second argument is provided.")
    113    #year_exp = 6
    114    #month_exp = 4
    115    #day_exp = 2
    116    #hour_exp = 0
    117    #minute_exp = -2
    118    #second_exp = -4
    119    #if minute is not None:
    120    #    assert minute >= 0 and minute <= 60
    121    #    year_exp += 2
    122    #    month_exp += 2
    123    #    day_exp += 2
    124    #    hour_exp += 2
    125    #    minute_exp += 2
    126    #    second_exp += 2
    127    #if second is not None:
    128    #    assert second >= 0 and second <= 60
    129    #    year_exp += 2
    130    #    month_exp += 2
    131    #    day_exp += 2
    132    #    hour_exp += 2
    133    #    minute_exp += 2
    134    #    second_exp += 2
    135    idate = (year*pow(10,year_exp))+(month*pow(10,month_exp))+\
    136            (day*pow(10,day_exp))+(hour*pow(10,hour_exp))
    137    #if minute is not None:
    138    #    idate += minute*pow(10,minute_exp)
    139    #if second is not None:
    140    #    idate += second*pow(10,second_exp)
    141    return idate
    142
    143
    144def getleadtime(idsec,pdtn,pdt):
    145    """
    146    Computes the lead time (in units of hours) from using information from
    147    GRIB2 Identification Section (Section 1), Product Definition Template
    148    Number, and Product Definition Template (Section 4).
    149
    150    Parameters
    151    ----------
    152
    153    **`idsec`**: seqeunce containing GRIB2 Identification Section (Section 1).
    154
    155    **`pdtn`**: GRIB2 Product Definition Template Number
    156
    157    **`idsec`**: seqeunce containing GRIB2 Product Definition Template (Section 4).
    158
    159    Returns
    160    -------
    161
    162    **`lt`**: Lead time in units of hours
    163    """
    164    refdate = datetime.datetime(*idsec[5:11])
    165    if pdtn == 8:
    166        enddate = datetime.datetime(*pdt[15:21])
    167        td = enddate - refdate
    168        lt = (td).total_seconds()/3600.0
    169    elif pdtn == 9:
    170        enddate = datetime.datetime(*pdt[22:28])
    171        td = enddate - refdate
    172        lt = (td).total_seconds()/3600.0
    173    elif pdtn == 10:
    174        enddate = datetime.datetime(*pdt[16:22])
    175        td = enddate - refdate
    176        lt = (td).total_seconds()/3600.0
    177    elif pdtn == 11:
    178        enddate = datetime.datetime(*pdt[18:24])
    179        td = enddate - refdate
    180        lt = (td).total_seconds()/3600.0
    181    elif pdtn == 12:
    182        enddate = datetime.datetime(*pdt[17:23])
    183        td = enddate - refdate
    184        lt = (td).total_seconds()/3600.0
    185    else:
    186        lt = pdt[8]*(tables.get_value_from_table(pdt[7],'scale_time_hours'))
    187    return int(lt)
    188
    189
    190def getduration(pdtn,pdt):
    191    """
    192    Computes the duration time (in units of hours) from using information from
    193    Product Definition Template Number, and Product Definition Template (Section 4).
    194
    195    Parameters
    196    ----------
    197
    198    **`pdtn`**: GRIB2 Product Definition Template Number
    199
    200    **`pdt`**: sequence containing GRIB2 Product Definition Template (Section 4).
    201
    202    Returns
    203    -------
    204
    205    **`dur`**: Duration time in units of hours
    206    """
    207    if pdtn == 8:
    208        dur = pdt[26]*(tables.get_value_from_table(pdt[25],'scale_time_hours'))
    209    elif pdtn == 9:
    210        dur = pdt[33]*(tables.get_value_from_table(pdt[32],'scale_time_hours'))
    211    elif pdtn == 10:
    212        dur = pdt[27]*(tables.get_value_from_table(pdt[26],'scale_time_hours'))
    213    elif pdtn == 11:
    214        dur = pdt[29]*(tables.get_value_from_table(pdt[28],'scale_time_hours'))
    215    elif pdtn == 12:
    216        dur = pdt[28]*(tables.get_value_from_table(pdt[27],'scale_time_hours'))
    217    else:
    218        dur = 0
    219    return int(dur)
    220
    221
    222def decode_mdl_wx_strings(lus):
    223    """
    224    Decode GRIB2 Local Use Section to obtain MDL Weather Strings.  The
    225    decode procedure is defined here:
    226
    227    https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml
    228
    229    Parameters
    230    ----------
    231
    232    **`lus`**: GRIB2 Local Use Section containing MDL weather strings.
    233
    234    Returns
    235    -------
    236
    237    **`list`**: List of weather strings.
    238    """
    239    assert lus[0] == 1
    240    # Unpack information related to the simple packing method
    241    # the packed weather string data.
    242    ngroups = struct.unpack('>h',lus[1:3])[0]
    243    nvalues = struct.unpack('>i',lus[3:7])[0]
    244    refvalue = struct.unpack('>i',lus[7:11])[0]
    245    dsf = struct.unpack('>h',lus[11:13])[0]
    246    nbits = lus[13]
    247    datatype = lus[14]
    248    if datatype == 0: # Floating point
    249        refvalue = np.float32(getieeeint(refvalue)*10**-dsf)
    250    elif datatype == 1: # Integer
    251        refvalue = np.int32(getieeeint(refvalue)*10**-dsf)
    252    #print("TEST:",ngroups,nvalues,refvalue,dsf,nbits,datatype)
    253    # Store the "data" part of the packed weather strings as
    254    # a binary string.
    255    b = bin(int.from_bytes(lus[15:],byteorder='big'))
    256    # Generated begin and end values. Note the offset begins at 2
    257    # due to the format nature of b (binary string).
    258    idxb = list(range(2,len(b),nbits))[0:nvalues-1]
    259    idxe = list(range(2+nbits,len(b)+nbits,nbits))[0:nvalues-1]
    260    # Iterate over the packed data, converting the nbits space to
    261    # and integer, then convert integer to an ASCII character.
    262    wxstring = ''
    263    for ib,ie in zip(idxb,idxe):
    264        wxstring += chr(int(b[ib:ie],2)+refvalue)
    265    # Return string as list, split by null character.
    266    return wxstring.split('\0')
    267
    268
    269def decode_ndfd_wx_strings(lus):
    270    """
    271    Decode GRIB2 Local Use Section to obtain NDFD Weather Strings.  The
    272    decode procedure is defined here:
    273
    274    https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml
    275
    276    NOTE: From testing, it seems how the process for packing Section 2 for NDFD
    277          Weather grids is different than GMOS and thus the need for a different
    278          method for decoding NDFD Wx vs. GMOS Wx.
    279
    280    Parameters
    281    ----------
    282
    283    **`lus`**: GRIB2 Local Use Section containing NDFD weather strings.
    284
    285    Returns
    286    -------
    287
    288    **`list`**: List of NDFD weather strings.
    289    """
    290    assert lus[0] == 1
    291    # Unpack information related to the simple packing method
    292    # the packed weather string data.
    293    ngroups = struct.unpack('>h',lus[1:3])[0]
    294    nvalues = struct.unpack('>i',lus[3:7])[0]
    295    refvalue = struct.unpack('>i',lus[7:11])[0]
    296    dsf = struct.unpack('>h',lus[11:13])[0]
    297    nbits = lus[13]
    298    datatype = lus[14]
    299    if datatype == 0: # Floating point
    300        refvalue = np.float32(getieeeint(refvalue)*10**-dsf)
    301    elif datatype == 1: # Integer
    302        refvalue = np.int32(getieeeint(refvalue)*10**-dsf)
    303    # Iterate over the data of section 2 in 4-byte (32-bit)
    304    # words OR 2-byte word at the end. Each word is unpacked
    305    # as an unsigned integer. Then convert the integer word
    306    # to a binary string and fill to the appropriate bit
    307    # size (16 or 32) and concatenate to b (binary string).
    308    b = ''
    309    for i in range(15,len(lus),4):
    310        if len(lus)-i < 4:
    311            iword = struct.unpack('>H',lus[i:i+2])[0]
    312            b += bin(iword).split('b')[1].zfill(16)
    313        else:
    314            iword = struct.unpack('>I',lus[i:i+4])[0]
    315            b += bin(iword).split('b')[1].zfill(32)
    316    # Iterate over the binary string (b). For each nbits
    317    # chunk, convert to an integer, including the refvalue,
    318    # and then convert the int to an ASCII character, then
    319    # concatenate to wxstring.
    320    wxstring = ''
    321    for i in range(0,len(b),nbits):
    322        wxstring += chr(int(b[i:i+nbits],2)+refvalue)
    323    # Return string as list, split by null character.
    324    return list(filter(None,wxstring.split('\0')))
    325
    326
    327def get_wgrib2_prob_string(probtype,sfacl,svall,sfacu,svalu):
    328    """
    329    Return a wgrib2-formatted string explaining probabilistic
    330    threshold informaiton.  Logic from wgrib2 source, [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c),
    331    is replicated here.
    332
    333    Parameters
    334    ----------
    335
    336    **`probtype`**: `int` type of probability (Code Table 4.9).
    337
    338    **`sfacl`**: `int` scale factor of lower limit.
    339
    340    **`svall`**: `int` scaled value of lower limit.
    341
    342    **`sfacu`**: `int` scale factor of upper limit.
    343
    344    **`svalu`**: `int` scaled value of upper limit.
    345
    346    Returns
    347    -------
    348
    349    **`str`**: wgrib2-formatted string of probability threshold.
    350    """
    351    probstr = ''
    352    lower = svall/(10**sfacl)
    353    upper = svalu/(10**sfacu)
    354    if probtype == 0:
    355        probstr = 'prob <%g' % (lower)
    356    elif probtype == 1:
    357        probstr = 'prob >%g' % (upper)
    358    elif probtype == 2:
    359        if lower == upper:
    360            probstr = 'prob =%g' % (lower)
    361        else:
    362            probstr = 'prob >=%g <%g' % (lower,upper)
    363    elif probtype == 3:
    364        probstr = 'prob >%g' % (lower)
    365    elif probtype == 4:
    366        probstr = 'prob <%g' % (upper)
    367    return probstr

def int2bin(i, nbits=8, output=) View Source

    14def int2bin(i,nbits=8,output=str):
    15    """
    16    Convert integer to binary string or list
    17
    18    Parameters
    19    ----------
    20
    21    **`i`**: Integer value to convert to binary representation.
    22
    23    **`nbits`**: Number of bits to return.  Valid values are 8 [DEFAULT], 16,
    24    32, and 64.
    25
    26    **`output`**: Return data as `str` [DEFAULT] or `list` (list of ints).
    27
    28    Returns
    29    -------
    30
    31    `str` or `list` (list of ints) of binary representation of the integer value.
    32    """
    33    i = int(i) if not isinstance(i,int) else i
    34    assert nbits in [8,16,32,64]
    35    bitstr = "{0:b}".format(i).zfill(nbits)
    36    if output is str:
    37        return bitstr
    38    elif output is list:
    39        return [int(b) for b in bitstr]

Convert integer to binary string or list

## Parameters

`i`: Integer value to convert to binary representation.

`nbits`: Number of bits to return. Valid values are 8 [DEFAULT], 16, 32, and 64.

`output`: Return data as `str` [DEFAULT] or `list` (list of ints).

## Returns

`str` or `list` (list of ints) of binary representation of the integer value.

def putieeeint(r) View Source

    42def putieeeint(r):
    43    """
    44    Convert an IEEE 32-bit float to a 32-bit integer.
    45
    46    Parameters
    47    ----------
    48
    49    **`r`**: Float value.
    50
    51    Returns
    52    -------
    53
    54    Integer representation of an IEEE 32-bit float.
    55    """
    56    ra = np.array([r],'f')
    57    ia = np.empty(1,'i')
    58    g2clib.rtoi_ieee(ra,ia)
    59    return ia[0]

Convert an IEEE 32-bit float to a 32-bit integer.

## Parameters

`r`: Float value.

## Returns

Integer representation of an IEEE 32-bit float.

def getieeeint(i) View Source

    62def getieeeint(i):
    63    """
    64    Convert a 32-bit integer to an IEEE 32-bit float.
    65
    66    Parameters
    67    ----------
    68
    69    **`i`**: Integer value.
    70
    71    Returns
    72    -------
    73
    74    IEEE 32-bit float.
    75    """
    76    ia = np.array([i],'i')
    77    ra = np.empty(1,'f')
    78    g2clib.itor_ieee(ia,ra)
    79    return ra[0]

Convert a 32-bit integer to an IEEE 32-bit float.

## Parameters

`i`: Integer value.

## Returns

IEEE 32-bit float.

def getmd5str(a) View Source

    82def getmd5str(a):
    83    """
    84    Generate a MD5 hash string from input list
    85    """
    86    import hashlib
    87    assert isinstance(a,list) or isinstance(a,bytes)
    88    return hashlib.md5(''.join([str(i) for i in a]).encode()).hexdigest()

Generate a MD5 hash string from input list

def getdate(year, month, day, hour, minute=None, second=None) View Source

     91def getdate(year,month,day,hour,minute=None,second=None):
     92    """
     93    Build an integer date from component input.
     94
     95    **`year`**: Year in 4-digit format.
     96
     97    **`month`**: Month in 2-digit format.
     98
     99    **`day`**: Day in 2-digit format.
    100
    101    **`hour`**: Hour in 2-digit format.
    102
    103    **`minute`**: Minute in 2-digit format. This argument is required if second is provided, otherwise
    104    it is optional.
    105
    106    **`second`**: Second in 2-digit format [OPTIONAL].
    107    """
    108    year_exp = 6
    109    month_exp = 4
    110    day_exp = 2
    111    hour_exp = 0
    112    #if second is not None and minute is None:
    113    #    raise ValueError("Must provide minute argument if second argument is provided.")
    114    #year_exp = 6
    115    #month_exp = 4
    116    #day_exp = 2
    117    #hour_exp = 0
    118    #minute_exp = -2
    119    #second_exp = -4
    120    #if minute is not None:
    121    #    assert minute >= 0 and minute <= 60
    122    #    year_exp += 2
    123    #    month_exp += 2
    124    #    day_exp += 2
    125    #    hour_exp += 2
    126    #    minute_exp += 2
    127    #    second_exp += 2
    128    #if second is not None:
    129    #    assert second >= 0 and second <= 60
    130    #    year_exp += 2
    131    #    month_exp += 2
    132    #    day_exp += 2
    133    #    hour_exp += 2
    134    #    minute_exp += 2
    135    #    second_exp += 2
    136    idate = (year*pow(10,year_exp))+(month*pow(10,month_exp))+\
    137            (day*pow(10,day_exp))+(hour*pow(10,hour_exp))
    138    #if minute is not None:
    139    #    idate += minute*pow(10,minute_exp)
    140    #if second is not None:
    141    #    idate += second*pow(10,second_exp)
    142    return idate

Build an integer date from component input.

`year`: Year in 4-digit format.

`month`: Month in 2-digit format.

`day`: Day in 2-digit format.

`hour`: Hour in 2-digit format.

`minute`: Minute in 2-digit format. This argument is required if second is provided, otherwise it is optional.

`second`: Second in 2-digit format [OPTIONAL].

def getleadtime(idsec, pdtn, pdt) View Source

    145def getleadtime(idsec,pdtn,pdt):
    146    """
    147    Computes the lead time (in units of hours) from using information from
    148    GRIB2 Identification Section (Section 1), Product Definition Template
    149    Number, and Product Definition Template (Section 4).
    150
    151    Parameters
    152    ----------
    153
    154    **`idsec`**: seqeunce containing GRIB2 Identification Section (Section 1).
    155
    156    **`pdtn`**: GRIB2 Product Definition Template Number
    157
    158    **`idsec`**: seqeunce containing GRIB2 Product Definition Template (Section 4).
    159
    160    Returns
    161    -------
    162
    163    **`lt`**: Lead time in units of hours
    164    """
    165    refdate = datetime.datetime(*idsec[5:11])
    166    if pdtn == 8:
    167        enddate = datetime.datetime(*pdt[15:21])
    168        td = enddate - refdate
    169        lt = (td).total_seconds()/3600.0
    170    elif pdtn == 9:
    171        enddate = datetime.datetime(*pdt[22:28])
    172        td = enddate - refdate
    173        lt = (td).total_seconds()/3600.0
    174    elif pdtn == 10:
    175        enddate = datetime.datetime(*pdt[16:22])
    176        td = enddate - refdate
    177        lt = (td).total_seconds()/3600.0
    178    elif pdtn == 11:
    179        enddate = datetime.datetime(*pdt[18:24])
    180        td = enddate - refdate
    181        lt = (td).total_seconds()/3600.0
    182    elif pdtn == 12:
    183        enddate = datetime.datetime(*pdt[17:23])
    184        td = enddate - refdate
    185        lt = (td).total_seconds()/3600.0
    186    else:
    187        lt = pdt[8]*(tables.get_value_from_table(pdt[7],'scale_time_hours'))
    188    return int(lt)

Computes the lead time (in units of hours) from using information from GRIB2 Identification Section (Section 1), Product Definition Template Number, and Product Definition Template (Section 4).

## Parameters

`idsec`: seqeunce containing GRIB2 Identification Section (Section 1).

`pdtn`: GRIB2 Product Definition Template Number

`idsec`: seqeunce containing GRIB2 Product Definition Template (Section 4).

## Returns

`lt`: Lead time in units of hours

def getduration(pdtn, pdt) View Source

    191def getduration(pdtn,pdt):
    192    """
    193    Computes the duration time (in units of hours) from using information from
    194    Product Definition Template Number, and Product Definition Template (Section 4).
    195
    196    Parameters
    197    ----------
    198
    199    **`pdtn`**: GRIB2 Product Definition Template Number
    200
    201    **`pdt`**: sequence containing GRIB2 Product Definition Template (Section 4).
    202
    203    Returns
    204    -------
    205
    206    **`dur`**: Duration time in units of hours
    207    """
    208    if pdtn == 8:
    209        dur = pdt[26]*(tables.get_value_from_table(pdt[25],'scale_time_hours'))
    210    elif pdtn == 9:
    211        dur = pdt[33]*(tables.get_value_from_table(pdt[32],'scale_time_hours'))
    212    elif pdtn == 10:
    213        dur = pdt[27]*(tables.get_value_from_table(pdt[26],'scale_time_hours'))
    214    elif pdtn == 11:
    215        dur = pdt[29]*(tables.get_value_from_table(pdt[28],'scale_time_hours'))
    216    elif pdtn == 12:
    217        dur = pdt[28]*(tables.get_value_from_table(pdt[27],'scale_time_hours'))
    218    else:
    219        dur = 0
    220    return int(dur)

Computes the duration time (in units of hours) from using information from Product Definition Template Number, and Product Definition Template (Section 4).

## Parameters

`pdtn`: GRIB2 Product Definition Template Number

`pdt`: sequence containing GRIB2 Product Definition Template (Section 4).

## Returns

`dur`: Duration time in units of hours

def decode_mdl_wx_strings(lus) View Source

    223def decode_mdl_wx_strings(lus):
    224    """
    225    Decode GRIB2 Local Use Section to obtain MDL Weather Strings.  The
    226    decode procedure is defined here:
    227
    228    https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml
    229
    230    Parameters
    231    ----------
    232
    233    **`lus`**: GRIB2 Local Use Section containing MDL weather strings.
    234
    235    Returns
    236    -------
    237
    238    **`list`**: List of weather strings.
    239    """
    240    assert lus[0] == 1
    241    # Unpack information related to the simple packing method
    242    # the packed weather string data.
    243    ngroups = struct.unpack('>h',lus[1:3])[0]
    244    nvalues = struct.unpack('>i',lus[3:7])[0]
    245    refvalue = struct.unpack('>i',lus[7:11])[0]
    246    dsf = struct.unpack('>h',lus[11:13])[0]
    247    nbits = lus[13]
    248    datatype = lus[14]
    249    if datatype == 0: # Floating point
    250        refvalue = np.float32(getieeeint(refvalue)*10**-dsf)
    251    elif datatype == 1: # Integer
    252        refvalue = np.int32(getieeeint(refvalue)*10**-dsf)
    253    #print("TEST:",ngroups,nvalues,refvalue,dsf,nbits,datatype)
    254    # Store the "data" part of the packed weather strings as
    255    # a binary string.
    256    b = bin(int.from_bytes(lus[15:],byteorder='big'))
    257    # Generated begin and end values. Note the offset begins at 2
    258    # due to the format nature of b (binary string).
    259    idxb = list(range(2,len(b),nbits))[0:nvalues-1]
    260    idxe = list(range(2+nbits,len(b)+nbits,nbits))[0:nvalues-1]
    261    # Iterate over the packed data, converting the nbits space to
    262    # and integer, then convert integer to an ASCII character.
    263    wxstring = ''
    264    for ib,ie in zip(idxb,idxe):
    265        wxstring += chr(int(b[ib:ie],2)+refvalue)
    266    # Return string as list, split by null character.
    267    return wxstring.split('\0')

Decode GRIB2 Local Use Section to obtain MDL Weather Strings. The decode procedure is defined here:

https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml

## Parameters

`lus`: GRIB2 Local Use Section containing MDL weather strings.

## Returns

`list`: List of weather strings.

def decode_ndfd_wx_strings(lus) View Source

    270def decode_ndfd_wx_strings(lus):
    271    """
    272    Decode GRIB2 Local Use Section to obtain NDFD Weather Strings.  The
    273    decode procedure is defined here:
    274
    275    https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml
    276
    277    NOTE: From testing, it seems how the process for packing Section 2 for NDFD
    278          Weather grids is different than GMOS and thus the need for a different
    279          method for decoding NDFD Wx vs. GMOS Wx.
    280
    281    Parameters
    282    ----------
    283
    284    **`lus`**: GRIB2 Local Use Section containing NDFD weather strings.
    285
    286    Returns
    287    -------
    288
    289    **`list`**: List of NDFD weather strings.
    290    """
    291    assert lus[0] == 1
    292    # Unpack information related to the simple packing method
    293    # the packed weather string data.
    294    ngroups = struct.unpack('>h',lus[1:3])[0]
    295    nvalues = struct.unpack('>i',lus[3:7])[0]
    296    refvalue = struct.unpack('>i',lus[7:11])[0]
    297    dsf = struct.unpack('>h',lus[11:13])[0]
    298    nbits = lus[13]
    299    datatype = lus[14]
    300    if datatype == 0: # Floating point
    301        refvalue = np.float32(getieeeint(refvalue)*10**-dsf)
    302    elif datatype == 1: # Integer
    303        refvalue = np.int32(getieeeint(refvalue)*10**-dsf)
    304    # Iterate over the data of section 2 in 4-byte (32-bit)
    305    # words OR 2-byte word at the end. Each word is unpacked
    306    # as an unsigned integer. Then convert the integer word
    307    # to a binary string and fill to the appropriate bit
    308    # size (16 or 32) and concatenate to b (binary string).
    309    b = ''
    310    for i in range(15,len(lus),4):
    311        if len(lus)-i < 4:
    312            iword = struct.unpack('>H',lus[i:i+2])[0]
    313            b += bin(iword).split('b')[1].zfill(16)
    314        else:
    315            iword = struct.unpack('>I',lus[i:i+4])[0]
    316            b += bin(iword).split('b')[1].zfill(32)
    317    # Iterate over the binary string (b). For each nbits
    318    # chunk, convert to an integer, including the refvalue,
    319    # and then convert the int to an ASCII character, then
    320    # concatenate to wxstring.
    321    wxstring = ''
    322    for i in range(0,len(b),nbits):
    323        wxstring += chr(int(b[i:i+nbits],2)+refvalue)
    324    # Return string as list, split by null character.
    325    return list(filter(None,wxstring.split('\0')))

Decode GRIB2 Local Use Section to obtain NDFD Weather Strings. The decode procedure is defined here:

https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml

NOTE: From testing, it seems how the process for packing Section 2 for NDFD Weather grids is different than GMOS and thus the need for a different method for decoding NDFD Wx vs. GMOS Wx.

## Parameters

`lus`: GRIB2 Local Use Section containing NDFD weather strings.

## Returns

`list`: List of NDFD weather strings.

def get_wgrib2_prob_string(probtype, sfacl, svall, sfacu, svalu) View Source

    328def get_wgrib2_prob_string(probtype,sfacl,svall,sfacu,svalu):
    329    """
    330    Return a wgrib2-formatted string explaining probabilistic
    331    threshold informaiton.  Logic from wgrib2 source, [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c),
    332    is replicated here.
    333
    334    Parameters
    335    ----------
    336
    337    **`probtype`**: `int` type of probability (Code Table 4.9).
    338
    339    **`sfacl`**: `int` scale factor of lower limit.
    340
    341    **`svall`**: `int` scaled value of lower limit.
    342
    343    **`sfacu`**: `int` scale factor of upper limit.
    344
    345    **`svalu`**: `int` scaled value of upper limit.
    346
    347    Returns
    348    -------
    349
    350    **`str`**: wgrib2-formatted string of probability threshold.
    351    """
    352    probstr = ''
    353    lower = svall/(10**sfacl)
    354    upper = svalu/(10**sfacu)
    355    if probtype == 0:
    356        probstr = 'prob <%g' % (lower)
    357    elif probtype == 1:
    358        probstr = 'prob >%g' % (upper)
    359    elif probtype == 2:
    360        if lower == upper:
    361            probstr = 'prob =%g' % (lower)
    362        else:
    363            probstr = 'prob >=%g <%g' % (lower,upper)
    364    elif probtype == 3:
    365        probstr = 'prob >%g' % (lower)
    366    elif probtype == 4:
    367        probstr = 'prob <%g' % (upper)
    368    return probstr

Return a wgrib2-formatted string explaining probabilistic threshold informaiton. Logic from wgrib2 source, Prob.c, is replicated here.

## Parameters

`probtype`: `int` type of probability (Code Table 4.9).

`sfacl`: `int` scale factor of lower limit.

`svall`: `int` scaled value of lower limit.

`sfacu`: `int` scale factor of upper limit.

`svalu`: `int` scaled value of upper limit.

## Returns

`str`: wgrib2-formatted string of probability threshold.