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

def int2bin( i: int, nbits: int = 8, output: Union[Type[str], Type[List]] = <class 'str'>): View Source

    17def int2bin(i: int, nbits: int=8, output: Union[Type[str], Type[List]]=str):
    18    """
    19    Convert integer to binary string or list
    20
    21    The struct module unpack using ">i" will unpack a 32-bit integer from a
    22    binary string.
    23
    24    Parameters
    25    ----------
    26    i
    27        Integer value to convert to binary representation.
    28    nbits : default=8
    29        Number of bits to return.  Valid values are 8 [DEFAULT], 16, 32, and
    30        64.
    31    output : default=str
    32        Return data as `str` [DEFAULT] or `list` (list of ints).
    33
    34    Returns
    35    -------
    36    int2bin
    37        `str` or `list` (list of ints) of binary representation of the integer
    38        value.
    39    """
    40    i = int(i) if not isinstance(i,int) else i
    41    assert nbits in [8,16,32,64]
    42    bitstr = "{0:b}".format(i).zfill(nbits)
    43    if output is str:
    44        return bitstr
    45    elif output is list:
    46        return [int(b) for b in bitstr]

Convert integer to binary string or list

The struct module unpack using ">i" will unpack a 32-bit integer from a binary string.

###### Parameters

- i: Integer value to convert to binary representation.
- nbits (default=8): Number of bits to return. Valid values are 8 [DEFAULT], 16, 32, and 64.
- output (default=str): Return data as `str` [DEFAULT] or `list` (list of ints).

###### Returns

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

def ieee_float_to_int(f): View Source

    49def ieee_float_to_int(f):
    50    """
    51    Convert an IEEE 754 32-bit float to a 32-bit integer.
    52
    53    Parameters
    54    ----------
    55    f : float
    56        Floating-point value.
    57
    58    Returns
    59    -------
    60    ieee_float_to_int
    61        `numpy.int32` representation of an IEEE 32-bit float.
    62    """
    63    i = struct.unpack('>i',struct.pack('>f',np.float32(f)))[0]
    64    return np.int32(i)

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

###### Parameters

- f (float): Floating-point value.

###### Returns

- ieee_float_to_int: `numpy.int32` representation of an IEEE 32-bit float.

def ieee_int_to_float(i): View Source

    67def ieee_int_to_float(i):
    68    """
    69    Convert a 32-bit integer to an IEEE 32-bit float.
    70
    71    Parameters
    72    ----------
    73    i : int
    74        Integer value.
    75
    76    Returns
    77    -------
    78    ieee_int_to_float
    79        `numpy.float32` representation of a 32-bit int.
    80    """
    81    f = struct.unpack('>f',struct.pack('>i',np.int32(i)))[0]
    82    return np.float32(f)

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

###### Parameters

- i (int): Integer value.

###### Returns

- ieee_int_to_float: `numpy.float32` representation of a 32-bit int.

def get_leadtime( pdtn: int, pdt: Union[Buffer, numpy._typing._array_like._SupportsArray[numpy.dtype[Any]], numpy._typing._nested_sequence._NestedSequence[numpy._typing._array_like._SupportsArray[numpy.dtype[Any]]], bool, int, float, complex, str, bytes, numpy._typing._nested_sequence._NestedSequence[bool | int | float | complex | str | bytes]]) -> datetime.timedelta: View Source

     85def get_leadtime(pdtn: int, pdt: ArrayLike) -> datetime.timedelta:
     86    """
     87    Compute lead time as a datetime.timedelta object.
     88
     89    Using information from GRIB2 Product Definition Template
     90    Number, and Product Definition Template (Section 4).
     91
     92    Parameters
     93    ----------
     94    pdtn
     95        GRIB2 Product Definition Template Number
     96    pdt
     97        Sequence containing GRIB2 Product Definition Template (Section 4).
     98
     99    Returns
    100    -------
    101    leadTime
    102        datetime.timedelta object representing the lead time of the GRIB2 message.
    103    """
    104    lt = tables.get_value_from_table(pdt[templates.UnitOfForecastTime._key[pdtn]], 'scale_time_seconds')
    105    lt *= pdt[templates.ValueOfForecastTime._key[pdtn]]
    106    return datetime.timedelta(seconds=int(lt))

Compute lead time as a datetime.timedelta object.

Using information from GRIB2 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

- leadTime: datetime.timedelta object representing the lead time of the GRIB2 message.

def get_duration( pdtn: int, pdt: Union[Buffer, numpy._typing._array_like._SupportsArray[numpy.dtype[Any]], numpy._typing._nested_sequence._NestedSequence[numpy._typing._array_like._SupportsArray[numpy.dtype[Any]]], bool, int, float, complex, str, bytes, numpy._typing._nested_sequence._NestedSequence[bool | int | float | complex | str | bytes]]) -> datetime.timedelta: View Source

    109def get_duration(pdtn: int, pdt: ArrayLike) -> datetime.timedelta:
    110    """
    111    Compute a time duration as a datetime.timedelta.
    112
    113    Uses information from Product Definition Template Number, and Product
    114    Definition Template (Section 4).
    115
    116    Parameters
    117    ----------
    118    pdtn
    119        GRIB2 Product Definition Template Number
    120    pdt
    121        Sequence containing GRIB2 Product Definition Template (Section 4).
    122
    123    Returns
    124    -------
    125    get_duration
    126        datetime.timedelta object representing the time duration of the GRIB2
    127        message.
    128    """
    129    if pdtn in templates._timeinterval_pdtns:
    130        ntime = pdt[templates.NumberOfTimeRanges._key[pdtn]]
    131        duration_unit = tables.get_value_from_table(
    132            pdt[templates.UnitOfTimeRangeOfStatisticalProcess._key[pdtn]],
    133            'scale_time_seconds')
    134        d = ntime * duration_unit * pdt[
    135            templates.TimeRangeOfStatisticalProcess._key[pdtn]]
    136    else:
    137        d = 0
    138    return datetime.timedelta(seconds=int(d))

Compute a time duration as a datetime.timedelta.

Uses 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

- get_duration: datetime.timedelta object representing the time duration of the GRIB2 message.

def decode_wx_strings(lus: bytes) -> Dict[int, str]: View Source

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

- decode_wx_strings: Dict of NDFD/MDL weather strings. Keys are an integer value that represent the sequential order of the key in the packed local use section and the value is the weather key.

def get_wgrib2_prob_string(probtype: int, sfacl: int, svall: int, sfacu: int, svalu: int) -> str: View Source

    192def get_wgrib2_prob_string(
    193    probtype: int,
    194    sfacl: int,
    195    svall: int,
    196    sfacu: int,
    197    svalu: int,
    198) -> str:
    199    """
    200    Return a wgrib2-styled string of probabilistic threshold information.
    201
    202    Logic from wgrib2 source,
    203    [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c),
    204    is replicated here.
    205
    206    Parameters
    207    ----------
    208    probtype
    209        Type of probability (Code Table 4.9).
    210    sfacl
    211        Scale factor of lower limit.
    212    svall
    213        Scaled value of lower limit.
    214    sfacu
    215        Scale factor of upper limit.
    216    svalu
    217        Scaled value of upper limit.
    218
    219    Returns
    220    -------
    221    get_wgrib2_prob_string
    222        wgrib2-formatted string of probability threshold.
    223    """
    224    probstr = ''
    225    if sfacl == -127: sfacl = 0
    226    if sfacu == -127: sfacu = 0
    227    lower = svall/(10**sfacl)
    228    upper = svalu/(10**sfacu)
    229    if probtype == 0:
    230        probstr = 'prob <%g' % (lower)
    231    elif probtype == 1:
    232        probstr = 'prob >%g' % (upper)
    233    elif probtype == 2:
    234        if lower == upper:
    235            probstr = 'prob =%g' % (lower)
    236        else:
    237            probstr = 'prob >=%g <%g' % (lower,upper)
    238    elif probtype == 3:
    239        probstr = 'prob >%g' % (lower)
    240    elif probtype == 4:
    241        probstr = 'prob <%g' % (upper)
    242    else:
    243        probstr = ''
    244    return probstr

Return a wgrib2-styled string of probabilistic threshold information.

Logic from wgrib2 source, Prob.c, is replicated here.

###### Parameters

- probtype: Type of probability (Code Table 4.9).
- sfacl: Scale factor of lower limit.
- svall: Scaled value of lower limit.
- sfacu: Scale factor of upper limit.
- svalu: Scaled value of upper limit.

###### Returns

- get_wgrib2_prob_string: wgrib2-formatted string of probability threshold.