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 ieee_float_to_int(f):
     42    """
     43    Convert an IEEE 32-bit float to a 32-bit integer.
     44
     45    Parameters
     46    ----------
     47
     48    **`f`**: Float value.
     49
     50    Returns
     51    -------
     52
     53    Numpy Int32 representation of an IEEE 32-bit float.
     54    """
     55    i = struct.unpack('>i',struct.pack('>f',np.float32(f)))[0]
     56    return np.int32(i)
     57
     58
     59def ieee_int_to_float(i):
     60    """
     61    Convert a 32-bit integer to an IEEE 32-bit float.
     62
     63    Parameters
     64    ----------
     65
     66    **`i`**: Integer value.
     67
     68    Returns
     69    -------
     70
     71    Numpy float32
     72    """
     73    f = struct.unpack('>f',struct.pack('>i',np.int32(i)))[0]
     74    return np.float32(f)
     75
     76
     77def get_leadtime(idsec,pdtn,pdt):
     78    """
     79    Computes lead time as a datetime.timedelta object using information from
     80    GRIB2 Identification Section (Section 1), Product Definition Template
     81    Number, and Product Definition Template (Section 4).
     82
     83    Parameters
     84    ----------
     85
     86    **`idsec`**: seqeunce containing GRIB2 Identification Section (Section 1).
     87
     88    **`pdtn`**: GRIB2 Product Definition Template Number
     89
     90    **`idsec`**: seqeunce containing GRIB2 Product Definition Template (Section 4).
     91
     92    Returns
     93    -------
     94
     95    **`datetime.timedelta`** object representing the lead time of the GRIB2 message.
     96    """
     97    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
     98    refdate = datetime.datetime(*idsec[5:11])
     99    try:
    100        return datetime.datetime(*pdt[_key[pdtn]])-refdate
    101    except(KeyError):
    102        if pdtn == 48:
    103            return datetime.timedelta(hours=pdt[19]*(tables.get_value_from_table(pdt[18],'scale_time_hours')))
    104        else:
    105            return datetime.timedelta(hours=pdt[8]*(tables.get_value_from_table(pdt[7],'scale_time_hours')))
    106
    107
    108def get_duration(pdtn,pdt):
    109    """
    110    Computes a time duration as a datetime.timedelta using information from
    111    Product Definition Template Number, and Product Definition Template (Section 4).
    112
    113    Parameters
    114    ----------
    115
    116    **`pdtn`**: GRIB2 Product Definition Template Number
    117
    118    **`pdt`**: sequence containing GRIB2 Product Definition Template (Section 4).
    119
    120    Returns
    121    -------
    122
    123    **`datetime.timedelta`** object representing the time duration of the GRIB2 message.
    124    """
    125    _key = {8:25, 9:32, 10:26, 11:28, 12:27}
    126    try:
    127        return datetime.timedelta(hours=pdt[_key[pdtn]+1]*tables.get_value_from_table(pdt[_key[pdtn]],'scale_time_hours'))
    128    except(KeyError):
    129        return None
    130
    131
    132def decode_wx_strings(lus):
    133    """
    134    Decode GRIB2 Local Use Section to obtain NDFD/MDL Weather Strings.  The
    135    decode procedure is defined [here](https://vlab.noaa.gov/web/mdl/nbm-gmos-grib2-wx-info).
    136
    137    Parameters
    138    ----------
    139
    140    **`lus`**: GRIB2 Local Use Section containing NDFD weather strings.
    141
    142    Returns
    143    -------
    144
    145    **`dict`**: Dictionary of NDFD/MDL weather strings. Keys are an integer
    146    value that represent the sequential order of the key in the packed loca
    147    use section and the value is the weather key.
    148    """
    149    assert lus[0] == 1
    150    # Unpack information related to the simple packing method
    151    # the packed weather string data.
    152    ngroups = struct.unpack('>H',lus[1:3])[0]
    153    nvalues = struct.unpack('>i',lus[3:7])[0]
    154    refvalue = struct.unpack('>i',lus[7:11])[0]
    155    dsf = struct.unpack('>h',lus[11:13])[0]
    156    nbits = lus[13]
    157    datatype = lus[14]
    158    if datatype == 0: # Floating point
    159        refvalue = np.float32(ieee_int_to_float(refvalue)*10**-dsf)
    160    elif datatype == 1: # Integer
    161        refvalue = np.int32(ieee_int_to_float(refvalue)*10**-dsf)
    162    # Upack each byte starting at byte 15 to end of the local use
    163    # section, create a binary string and append to the full
    164    # binary string.
    165    b = ''
    166    for i in range(15,len(lus)):
    167        iword = struct.unpack('>B',lus[i:i+1])[0]
    168        b += bin(iword).split('b')[1].zfill(8)
    169    # Iterate over the binary string (b). For each nbits
    170    # chunk, convert to an integer, including the refvalue,
    171    # and then convert the int to an ASCII character, then
    172    # concatenate to wxstring.
    173    wxstring = ''
    174    for i in range(0,len(b),nbits):
    175        wxstring += chr(int(b[i:i+nbits],2)+refvalue)
    176    # Return string as list, split by null character.
    177    #return list(filter(None,wxstring.split('\0')))
    178    return {n:k for n,k in enumerate(list(filter(None,wxstring.split('\0'))))}
    179
    180
    181def get_wgrib2_prob_string(probtype,sfacl,svall,sfacu,svalu):
    182    """
    183    Return a wgrib2-formatted string explaining probabilistic
    184    threshold informaiton.  Logic from wgrib2 source, [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c),
    185    is replicated here.
    186
    187    Parameters
    188    ----------
    189
    190    **`probtype`**: `int` type of probability (Code Table 4.9).
    191
    192    **`sfacl`**: `int` scale factor of lower limit.
    193
    194    **`svall`**: `int` scaled value of lower limit.
    195
    196    **`sfacu`**: `int` scale factor of upper limit.
    197
    198    **`svalu`**: `int` scaled value of upper limit.
    199
    200    Returns
    201    -------
    202
    203    **`str`**: wgrib2-formatted string of probability threshold.
    204    """
    205    probstr = ''
    206    if sfacl == -127: sfacl = 0
    207    if sfacu == -127: sfacu = 0
    208    lower = svall/(10**sfacl)
    209    upper = svalu/(10**sfacu)
    210    if probtype == 0:
    211        probstr = 'prob <%g' % (lower)
    212    elif probtype == 1:
    213        probstr = 'prob >%g' % (upper)
    214    elif probtype == 2:
    215        if lower == upper:
    216            probstr = 'prob =%g' % (lower)
    217        else:
    218            probstr = 'prob >=%g <%g' % (lower,upper)
    219    elif probtype == 3:
    220        probstr = 'prob >%g' % (lower)
    221    elif probtype == 4:
    222        probstr = 'prob <%g' % (upper)
    223    else:
    224        probstr = ''
    225    return probstr

def int2bin(i, nbits=8, output=<class 'str'>): 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 ieee_float_to_int(f): View Source

    42def ieee_float_to_int(f):
    43    """
    44    Convert an IEEE 32-bit float to a 32-bit integer.
    45
    46    Parameters
    47    ----------
    48
    49    **`f`**: Float value.
    50
    51    Returns
    52    -------
    53
    54    Numpy Int32 representation of an IEEE 32-bit float.
    55    """
    56    i = struct.unpack('>i',struct.pack('>f',np.float32(f)))[0]
    57    return np.int32(i)

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

## Parameters

`f`: Float value.

## Returns

Numpy Int32 representation of an IEEE 32-bit float.

def ieee_int_to_float(i): View Source

    60def ieee_int_to_float(i):
    61    """
    62    Convert a 32-bit integer to an IEEE 32-bit float.
    63
    64    Parameters
    65    ----------
    66
    67    **`i`**: Integer value.
    68
    69    Returns
    70    -------
    71
    72    Numpy float32
    73    """
    74    f = struct.unpack('>f',struct.pack('>i',np.int32(i)))[0]
    75    return np.float32(f)

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

## Parameters

`i`: Integer value.

## Returns

Numpy float32

def get_leadtime(idsec, pdtn, pdt): View Source

     78def get_leadtime(idsec,pdtn,pdt):
     79    """
     80    Computes lead time as a datetime.timedelta object using information from
     81    GRIB2 Identification Section (Section 1), Product Definition Template
     82    Number, and Product Definition Template (Section 4).
     83
     84    Parameters
     85    ----------
     86
     87    **`idsec`**: seqeunce containing GRIB2 Identification Section (Section 1).
     88
     89    **`pdtn`**: GRIB2 Product Definition Template Number
     90
     91    **`idsec`**: seqeunce containing GRIB2 Product Definition Template (Section 4).
     92
     93    Returns
     94    -------
     95
     96    **`datetime.timedelta`** object representing the lead time of the GRIB2 message.
     97    """
     98    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
     99    refdate = datetime.datetime(*idsec[5:11])
    100    try:
    101        return datetime.datetime(*pdt[_key[pdtn]])-refdate
    102    except(KeyError):
    103        if pdtn == 48:
    104            return datetime.timedelta(hours=pdt[19]*(tables.get_value_from_table(pdt[18],'scale_time_hours')))
    105        else:
    106            return datetime.timedelta(hours=pdt[8]*(tables.get_value_from_table(pdt[7],'scale_time_hours')))

Computes lead time as a datetime.timedelta object 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

`datetime.timedelta` object representing the lead time of the GRIB2 message.

def get_duration(pdtn, pdt): View Source

    109def get_duration(pdtn,pdt):
    110    """
    111    Computes a time duration as a datetime.timedelta using information from
    112    Product Definition Template Number, and Product Definition Template (Section 4).
    113
    114    Parameters
    115    ----------
    116
    117    **`pdtn`**: GRIB2 Product Definition Template Number
    118
    119    **`pdt`**: sequence containing GRIB2 Product Definition Template (Section 4).
    120
    121    Returns
    122    -------
    123
    124    **`datetime.timedelta`** object representing the time duration of the GRIB2 message.
    125    """
    126    _key = {8:25, 9:32, 10:26, 11:28, 12:27}
    127    try:
    128        return datetime.timedelta(hours=pdt[_key[pdtn]+1]*tables.get_value_from_table(pdt[_key[pdtn]],'scale_time_hours'))
    129    except(KeyError):
    130        return None

Computes a time duration as a datetime.timedelta 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

`datetime.timedelta` object representing the time duration of the GRIB2 message.

def decode_wx_strings(lus): View Source

    133def decode_wx_strings(lus):
    134    """
    135    Decode GRIB2 Local Use Section to obtain NDFD/MDL Weather Strings.  The
    136    decode procedure is defined [here](https://vlab.noaa.gov/web/mdl/nbm-gmos-grib2-wx-info).
    137
    138    Parameters
    139    ----------
    140
    141    **`lus`**: GRIB2 Local Use Section containing NDFD weather strings.
    142
    143    Returns
    144    -------
    145
    146    **`dict`**: Dictionary of NDFD/MDL weather strings. Keys are an integer
    147    value that represent the sequential order of the key in the packed loca
    148    use section and the value is the weather key.
    149    """
    150    assert lus[0] == 1
    151    # Unpack information related to the simple packing method
    152    # the packed weather string data.
    153    ngroups = struct.unpack('>H',lus[1:3])[0]
    154    nvalues = struct.unpack('>i',lus[3:7])[0]
    155    refvalue = struct.unpack('>i',lus[7:11])[0]
    156    dsf = struct.unpack('>h',lus[11:13])[0]
    157    nbits = lus[13]
    158    datatype = lus[14]
    159    if datatype == 0: # Floating point
    160        refvalue = np.float32(ieee_int_to_float(refvalue)*10**-dsf)
    161    elif datatype == 1: # Integer
    162        refvalue = np.int32(ieee_int_to_float(refvalue)*10**-dsf)
    163    # Upack each byte starting at byte 15 to end of the local use
    164    # section, create a binary string and append to the full
    165    # binary string.
    166    b = ''
    167    for i in range(15,len(lus)):
    168        iword = struct.unpack('>B',lus[i:i+1])[0]
    169        b += bin(iword).split('b')[1].zfill(8)
    170    # Iterate over the binary string (b). For each nbits
    171    # chunk, convert to an integer, including the refvalue,
    172    # and then convert the int to an ASCII character, then
    173    # concatenate to wxstring.
    174    wxstring = ''
    175    for i in range(0,len(b),nbits):
    176        wxstring += chr(int(b[i:i+nbits],2)+refvalue)
    177    # Return string as list, split by null character.
    178    #return list(filter(None,wxstring.split('\0')))
    179    return {n:k for n,k in enumerate(list(filter(None,wxstring.split('\0'))))}

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

## Parameters

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

## Returns

`dict`: Dictionary of NDFD/MDL weather strings. Keys are an integer value that represent the sequential order of the key in the packed loca use section and the value is the weather key.

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

    182def get_wgrib2_prob_string(probtype,sfacl,svall,sfacu,svalu):
    183    """
    184    Return a wgrib2-formatted string explaining probabilistic
    185    threshold informaiton.  Logic from wgrib2 source, [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c),
    186    is replicated here.
    187
    188    Parameters
    189    ----------
    190
    191    **`probtype`**: `int` type of probability (Code Table 4.9).
    192
    193    **`sfacl`**: `int` scale factor of lower limit.
    194
    195    **`svall`**: `int` scaled value of lower limit.
    196
    197    **`sfacu`**: `int` scale factor of upper limit.
    198
    199    **`svalu`**: `int` scaled value of upper limit.
    200
    201    Returns
    202    -------
    203
    204    **`str`**: wgrib2-formatted string of probability threshold.
    205    """
    206    probstr = ''
    207    if sfacl == -127: sfacl = 0
    208    if sfacu == -127: sfacu = 0
    209    lower = svall/(10**sfacl)
    210    upper = svalu/(10**sfacu)
    211    if probtype == 0:
    212        probstr = 'prob <%g' % (lower)
    213    elif probtype == 1:
    214        probstr = 'prob >%g' % (upper)
    215    elif probtype == 2:
    216        if lower == upper:
    217            probstr = 'prob =%g' % (lower)
    218        else:
    219            probstr = 'prob >=%g <%g' % (lower,upper)
    220    elif probtype == 3:
    221        probstr = 'prob >%g' % (lower)
    222    elif probtype == 4:
    223        probstr = 'prob <%g' % (upper)
    224    else:
    225        probstr = ''
    226    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.