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 decimal import Decimal, localcontext
      9from typing import Dict, List, Optional, Tuple, Type, Union
     10
     11import numpy as np
     12from numpy.typing import ArrayLike
     13
     14from .. import iplib
     15from .. import tables
     16from .. import templates
     17
     18
     19def decimal_to_scaled_int(
     20    value: Union[float, str, int],
     21    scale_factor: Optional[int] = None,
     22) -> Tuple[int, int]:
     23    """
     24    Convert a float-like value to a scaled integer using the minimal decimal scaling factor.
     25
     26    The input value is internally converted to a `Decimal` to ensure precise scaling.
     27
     28    Parameters
     29    ----------
     30    value : float, str, or int
     31        The numeric value to scale.
     32    scaled_value : int
     33        The integer result of scaling the original value by `10**scale_factor`.
     34
     35    Returns
     36    -------
     37    scale_factor : int
     38        The smallest power of 10 such that `value * 10**scale_factor` is an exact integer.
     39    scaled_value : int
     40        The integer result of scaling the original value by `10**scale_factor`.
     41    """
     42    dec_value = Decimal(str(value))  # Preserve exact decimal representation
     43
     44    with localcontext() as ctx:
     45        ctx.prec = 28
     46
     47        if scale_factor is not None:
     48            scaled = dec_value * (10 ** scale_factor)
     49            if scaled != scaled.to_integral_value():
     50                raise ValueError(
     51                    f"Value {value} cannot be exactly scaled by 10^{scale_factor}"
     52                )
     53            return scale_factor, int(scaled)
     54        else:
     55            scale_factor = 0
     56            while dec_value != dec_value.to_integral_value():
     57                dec_value *= 10
     58                scale_factor += 1
     59                if scale_factor > 20:
     60                    raise ValueError(
     61                        f"Could not find exact scale factor for value {value} within bounds."
     62                    )
     63            return scale_factor, int(dec_value)
     64
     65
     66def int2bin(i: int, nbits: int=8, output: Union[Type[str], Type[List]]=str):
     67    """
     68    Convert integer to binary string or list
     69
     70    The struct module unpack using ">i" will unpack a 32-bit integer from a
     71    binary string.
     72
     73    Parameters
     74    ----------
     75    i
     76        Integer value to convert to binary representation.
     77    nbits : default=8
     78        Number of bits to return.  Valid values are 8 [DEFAULT], 16, 32, and
     79        64.
     80    output : default=str
     81        Return data as `str` [DEFAULT] or `list` (list of ints).
     82
     83    Returns
     84    -------
     85    int2bin
     86        `str` or `list` (list of ints) of binary representation of the integer
     87        value.
     88    """
     89    i = int(i) if not isinstance(i,int) else i
     90    assert nbits in [8,16,32,64]
     91    bitstr = "{0:b}".format(i).zfill(nbits)
     92    if output is str:
     93        return bitstr
     94    elif output is list:
     95        return [int(b) for b in bitstr]
     96
     97
     98def ieee_float_to_int(f):
     99    """
    100    Convert an IEEE 754 32-bit float to a 32-bit integer.
    101
    102    Parameters
    103    ----------
    104    f : float
    105        Floating-point value.
    106
    107    Returns
    108    -------
    109    ieee_float_to_int
    110        `numpy.int32` representation of an IEEE 32-bit float.
    111    """
    112    i = struct.unpack('>i',struct.pack('>f',np.float32(f)))[0]
    113    return np.int32(i)
    114
    115
    116def ieee_int_to_float(i):
    117    """
    118    Convert a 32-bit integer to an IEEE 32-bit float.
    119
    120    Parameters
    121    ----------
    122    i : int
    123        Integer value.
    124
    125    Returns
    126    -------
    127    ieee_int_to_float
    128        `numpy.float32` representation of a 32-bit int.
    129    """
    130    f = struct.unpack('>f',struct.pack('>i',np.int32(i)))[0]
    131    return np.float32(f)
    132
    133
    134def get_leadtime(pdtn: int, pdt: ArrayLike) -> datetime.timedelta:
    135    """
    136    Compute lead time as a datetime.timedelta object.
    137
    138    Using information from GRIB2 Product Definition Template
    139    Number, and Product Definition Template (Section 4).
    140
    141    Parameters
    142    ----------
    143    pdtn
    144        GRIB2 Product Definition Template Number
    145    pdt
    146        Sequence containing GRIB2 Product Definition Template (Section 4).
    147
    148    Returns
    149    -------
    150    leadTime
    151        datetime.timedelta object representing the lead time of the GRIB2 message.
    152    """
    153    lt = tables.get_value_from_table(pdt[templates.UnitOfForecastTime._key[pdtn]], 'scale_time_seconds')
    154    lt *= pdt[templates.ValueOfForecastTime._key[pdtn]]
    155    return datetime.timedelta(seconds=int(lt))
    156
    157
    158def get_duration(pdtn: int, pdt: ArrayLike) -> datetime.timedelta:
    159    """
    160    Compute a time duration as a datetime.timedelta.
    161
    162    Uses information from Product Definition Template Number, and Product
    163    Definition Template (Section 4).
    164
    165    Parameters
    166    ----------
    167    pdtn
    168        GRIB2 Product Definition Template Number
    169    pdt
    170        Sequence containing GRIB2 Product Definition Template (Section 4).
    171
    172    Returns
    173    -------
    174    get_duration
    175        datetime.timedelta object representing the time duration of the GRIB2
    176        message.
    177    """
    178    if pdtn in templates._timeinterval_pdtns:
    179        ntime = pdt[templates.NumberOfTimeRanges._key[pdtn]]
    180        duration_unit = tables.get_value_from_table(
    181            pdt[templates.UnitOfTimeRangeOfStatisticalProcess._key[pdtn]],
    182            'scale_time_seconds')
    183        d = ntime * duration_unit * pdt[
    184            templates.TimeRangeOfStatisticalProcess._key[pdtn]]
    185    else:
    186        d = 0
    187    return datetime.timedelta(seconds=int(d))
    188
    189
    190def decode_wx_strings(lus: bytes) -> Dict[int, str]:
    191    """
    192    Decode GRIB2 Local Use Section to obtain NDFD/MDL Weather Strings.
    193
    194    The decode procedure is defined
    195    [here](https://vlab.noaa.gov/web/mdl/nbm-gmos-grib2-wx-info).
    196
    197    Parameters
    198    ----------
    199    lus
    200        GRIB2 Local Use Section containing NDFD weather strings.
    201
    202    Returns
    203    -------
    204    decode_wx_strings
    205        Dict of NDFD/MDL weather strings. Keys are an integer value that
    206        represent the sequential order of the key in the packed local use
    207        section and the value is the weather key.
    208    """
    209    assert lus[0] == 1
    210    # Unpack information related to the simple packing method
    211    # the packed weather string data.
    212    ngroups = struct.unpack('>H',lus[1:3])[0]
    213    nvalues = struct.unpack('>i',lus[3:7])[0]
    214    refvalue = struct.unpack('>i',lus[7:11])[0]
    215    dsf = struct.unpack('>h',lus[11:13])[0]
    216    nbits = lus[13]
    217    datatype = lus[14]
    218    if datatype == 0: # Floating point
    219        refvalue = np.float32(ieee_int_to_float(refvalue)*10**-dsf)
    220    elif datatype == 1: # Integer
    221        refvalue = np.int32(ieee_int_to_float(refvalue)*10**-dsf)
    222    # Upack each byte starting at byte 15 to end of the local use
    223    # section, create a binary string and append to the full
    224    # binary string.
    225    b = ''
    226    for i in range(15,len(lus)):
    227        iword = struct.unpack('>B',lus[i:i+1])[0]
    228        b += bin(iword).split('b')[1].zfill(8)
    229    # Iterate over the binary string (b). For each nbits
    230    # chunk, convert to an integer, including the refvalue,
    231    # and then convert the int to an ASCII character, then
    232    # concatenate to wxstring.
    233    wxstring = ''
    234    for i in range(0,len(b),nbits):
    235        wxstring += chr(int(b[i:i+nbits],2)+refvalue)
    236    # Return string as list, split by null character.
    237    #return list(filter(None,wxstring.split('\0')))
    238    return {n:k for n,k in enumerate(list(filter(None,wxstring.split('\0'))))}
    239
    240
    241def get_wgrib2_prob_string(
    242    probtype: int,
    243    sfacl: int,
    244    svall: int,
    245    sfacu: int,
    246    svalu: int,
    247) -> str:
    248    """
    249    Return a wgrib2-styled string of probabilistic threshold information.
    250
    251    Logic from wgrib2 source,
    252    [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c),
    253    is replicated here.
    254
    255    Parameters
    256    ----------
    257    probtype
    258        Type of probability (Code Table 4.9).
    259    sfacl
    260        Scale factor of lower limit.
    261    svall
    262        Scaled value of lower limit.
    263    sfacu
    264        Scale factor of upper limit.
    265    svalu
    266        Scaled value of upper limit.
    267
    268    Returns
    269    -------
    270    get_wgrib2_prob_string
    271        wgrib2-formatted string of probability threshold.
    272    """
    273    probstr = ''
    274    if sfacl < 0: sfacl = 0
    275    if sfacu < 0: sfacu = 0
    276    lower = svall/(10**sfacl)
    277    upper = svalu/(10**sfacu)
    278    if probtype == 0:
    279        probstr = 'prob <%g' % (lower)
    280    elif probtype == 1:
    281        probstr = 'prob >%g' % (upper)
    282    elif probtype == 2:
    283        if lower == upper:
    284            probstr = 'prob =%g' % (lower)
    285        else:
    286            probstr = 'prob >=%g <%g' % (lower,upper)
    287    elif probtype == 3:
    288        probstr = 'prob >%g' % (lower)
    289    elif probtype == 4:
    290        probstr = 'prob <%g' % (upper)
    291    else:
    292        probstr = ''
    293    return probstr
    294
    295
    296def latlon_to_ij(
    297    gdtn,
    298    gdt,
    299    lats,
    300    lons,
    301    missing_value = np.nan,
    302):
    303    """
    304    Convert latitude/longitude coordinates to grid (i, j) indices using the
    305    GRIB2 Grid Definition Section (GDS).
    306
    307    This function calls the grib2io iplib Cython extension module function,
    308    `grib2io.iplib.latlon_to_ij`.
    309
    310    Parameters
    311    ----------
    312    gdtn : int
    313        GRIB2 grid definition template number.
    314    gdt : ndarray of int32
    315        GRIB2 grid definition template values.
    316    lats : numpy.ndarray or list
    317        Latitude coordinates in degrees.
    318    lons : numpy.ndarray or list
    319        Longitude coordinates in degrees.
    320    missing_value : float, optional
    321        Missing value to represent when latitude/longitude coordinate is
    322        outside the grid domain.
    323
    324    Returns
    325    -------
    326    xpts : ndarray of float32
    327        Grid x-coordinates (i-indices) corresponding to the input
    328        latitude/longitude points.
    329    ypts : ndarray of float32
    330        Grid y-coordinates (j-indices) corresponding to the input
    331        latitude/longitude points.
    332    """
    333    # Check lats and lons
    334    if isinstance(lats,list):
    335        nlats = len(lats)
    336    elif isinstance(lats,np.ndarray) and len(lats.shape) == 1:
    337        nlats = lats.shape[0]
    338    else:
    339        raise ValueError("Latitudes must be a list or 1-D NumPy array.")
    340    if isinstance(lons,list):
    341        nlons = len(lons)
    342    elif isinstance(lons,np.ndarray) and len(lons.shape) == 1:
    343        nlons = lons.shape[0]
    344    else:
    345        raise ValueError("Longitudes must be a list or 1-D NumPy array.")
    346    if nlats != nlons:
    347        raise ValueError("Latitudes and longitudes same length.")
    348    return iplib.latlon_to_ij(
    349        gdtn.astype(np.int32),
    350        gdt.astype(np.int32),
    351        np.array(lats, dtype=np.float32),
    352        np.array(lons, dtype=np.float32),
    353        missing_value,
    354    )

def decimal_to_scaled_int( value: Union[float, str, int], scale_factor: Optional[int] = None) -> Tuple[int, int]: View Source

    20def decimal_to_scaled_int(
    21    value: Union[float, str, int],
    22    scale_factor: Optional[int] = None,
    23) -> Tuple[int, int]:
    24    """
    25    Convert a float-like value to a scaled integer using the minimal decimal scaling factor.
    26
    27    The input value is internally converted to a `Decimal` to ensure precise scaling.
    28
    29    Parameters
    30    ----------
    31    value : float, str, or int
    32        The numeric value to scale.
    33    scaled_value : int
    34        The integer result of scaling the original value by `10**scale_factor`.
    35
    36    Returns
    37    -------
    38    scale_factor : int
    39        The smallest power of 10 such that `value * 10**scale_factor` is an exact integer.
    40    scaled_value : int
    41        The integer result of scaling the original value by `10**scale_factor`.
    42    """
    43    dec_value = Decimal(str(value))  # Preserve exact decimal representation
    44
    45    with localcontext() as ctx:
    46        ctx.prec = 28
    47
    48        if scale_factor is not None:
    49            scaled = dec_value * (10 ** scale_factor)
    50            if scaled != scaled.to_integral_value():
    51                raise ValueError(
    52                    f"Value {value} cannot be exactly scaled by 10^{scale_factor}"
    53                )
    54            return scale_factor, int(scaled)
    55        else:
    56            scale_factor = 0
    57            while dec_value != dec_value.to_integral_value():
    58                dec_value *= 10
    59                scale_factor += 1
    60                if scale_factor > 20:
    61                    raise ValueError(
    62                        f"Could not find exact scale factor for value {value} within bounds."
    63                    )
    64            return scale_factor, int(dec_value)

Convert a float-like value to a scaled integer using the minimal decimal scaling factor.

The input value is internally converted to a `Decimal` to ensure precise scaling.

###### Parameters

- value (float, str, or int): The numeric value to scale.
- scaled_value (int): The integer result of scaling the original value by `10**scale_factor`.

###### Returns

- scale_factor (int): The smallest power of 10 such that `value * 10**scale_factor` is an exact integer.
- scaled_value (int): The integer result of scaling the original value by `10**scale_factor`.

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

    67def int2bin(i: int, nbits: int=8, output: Union[Type[str], Type[List]]=str):
    68    """
    69    Convert integer to binary string or list
    70
    71    The struct module unpack using ">i" will unpack a 32-bit integer from a
    72    binary string.
    73
    74    Parameters
    75    ----------
    76    i
    77        Integer value to convert to binary representation.
    78    nbits : default=8
    79        Number of bits to return.  Valid values are 8 [DEFAULT], 16, 32, and
    80        64.
    81    output : default=str
    82        Return data as `str` [DEFAULT] or `list` (list of ints).
    83
    84    Returns
    85    -------
    86    int2bin
    87        `str` or `list` (list of ints) of binary representation of the integer
    88        value.
    89    """
    90    i = int(i) if not isinstance(i,int) else i
    91    assert nbits in [8,16,32,64]
    92    bitstr = "{0:b}".format(i).zfill(nbits)
    93    if output is str:
    94        return bitstr
    95    elif output is list:
    96        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

     99def ieee_float_to_int(f):
    100    """
    101    Convert an IEEE 754 32-bit float to a 32-bit integer.
    102
    103    Parameters
    104    ----------
    105    f : float
    106        Floating-point value.
    107
    108    Returns
    109    -------
    110    ieee_float_to_int
    111        `numpy.int32` representation of an IEEE 32-bit float.
    112    """
    113    i = struct.unpack('>i',struct.pack('>f',np.float32(f)))[0]
    114    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

    117def ieee_int_to_float(i):
    118    """
    119    Convert a 32-bit integer to an IEEE 32-bit float.
    120
    121    Parameters
    122    ----------
    123    i : int
    124        Integer value.
    125
    126    Returns
    127    -------
    128    ieee_int_to_float
    129        `numpy.float32` representation of a 32-bit int.
    130    """
    131    f = struct.unpack('>f',struct.pack('>i',np.int32(i)))[0]
    132    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]]], complex, bytes, str, numpy._typing._nested_sequence._NestedSequence[complex | bytes | str]]) -> datetime.timedelta: View Source

    135def get_leadtime(pdtn: int, pdt: ArrayLike) -> datetime.timedelta:
    136    """
    137    Compute lead time as a datetime.timedelta object.
    138
    139    Using information from GRIB2 Product Definition Template
    140    Number, and Product Definition Template (Section 4).
    141
    142    Parameters
    143    ----------
    144    pdtn
    145        GRIB2 Product Definition Template Number
    146    pdt
    147        Sequence containing GRIB2 Product Definition Template (Section 4).
    148
    149    Returns
    150    -------
    151    leadTime
    152        datetime.timedelta object representing the lead time of the GRIB2 message.
    153    """
    154    lt = tables.get_value_from_table(pdt[templates.UnitOfForecastTime._key[pdtn]], 'scale_time_seconds')
    155    lt *= pdt[templates.ValueOfForecastTime._key[pdtn]]
    156    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]]], complex, bytes, str, numpy._typing._nested_sequence._NestedSequence[complex | bytes | str]]) -> datetime.timedelta: View Source

    159def get_duration(pdtn: int, pdt: ArrayLike) -> datetime.timedelta:
    160    """
    161    Compute a time duration as a datetime.timedelta.
    162
    163    Uses information from Product Definition Template Number, and Product
    164    Definition Template (Section 4).
    165
    166    Parameters
    167    ----------
    168    pdtn
    169        GRIB2 Product Definition Template Number
    170    pdt
    171        Sequence containing GRIB2 Product Definition Template (Section 4).
    172
    173    Returns
    174    -------
    175    get_duration
    176        datetime.timedelta object representing the time duration of the GRIB2
    177        message.
    178    """
    179    if pdtn in templates._timeinterval_pdtns:
    180        ntime = pdt[templates.NumberOfTimeRanges._key[pdtn]]
    181        duration_unit = tables.get_value_from_table(
    182            pdt[templates.UnitOfTimeRangeOfStatisticalProcess._key[pdtn]],
    183            'scale_time_seconds')
    184        d = ntime * duration_unit * pdt[
    185            templates.TimeRangeOfStatisticalProcess._key[pdtn]]
    186    else:
    187        d = 0
    188    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

    191def decode_wx_strings(lus: bytes) -> Dict[int, str]:
    192    """
    193    Decode GRIB2 Local Use Section to obtain NDFD/MDL Weather Strings.
    194
    195    The decode procedure is defined
    196    [here](https://vlab.noaa.gov/web/mdl/nbm-gmos-grib2-wx-info).
    197
    198    Parameters
    199    ----------
    200    lus
    201        GRIB2 Local Use Section containing NDFD weather strings.
    202
    203    Returns
    204    -------
    205    decode_wx_strings
    206        Dict of NDFD/MDL weather strings. Keys are an integer value that
    207        represent the sequential order of the key in the packed local use
    208        section and the value is the weather key.
    209    """
    210    assert lus[0] == 1
    211    # Unpack information related to the simple packing method
    212    # the packed weather string data.
    213    ngroups = struct.unpack('>H',lus[1:3])[0]
    214    nvalues = struct.unpack('>i',lus[3:7])[0]
    215    refvalue = struct.unpack('>i',lus[7:11])[0]
    216    dsf = struct.unpack('>h',lus[11:13])[0]
    217    nbits = lus[13]
    218    datatype = lus[14]
    219    if datatype == 0: # Floating point
    220        refvalue = np.float32(ieee_int_to_float(refvalue)*10**-dsf)
    221    elif datatype == 1: # Integer
    222        refvalue = np.int32(ieee_int_to_float(refvalue)*10**-dsf)
    223    # Upack each byte starting at byte 15 to end of the local use
    224    # section, create a binary string and append to the full
    225    # binary string.
    226    b = ''
    227    for i in range(15,len(lus)):
    228        iword = struct.unpack('>B',lus[i:i+1])[0]
    229        b += bin(iword).split('b')[1].zfill(8)
    230    # Iterate over the binary string (b). For each nbits
    231    # chunk, convert to an integer, including the refvalue,
    232    # and then convert the int to an ASCII character, then
    233    # concatenate to wxstring.
    234    wxstring = ''
    235    for i in range(0,len(b),nbits):
    236        wxstring += chr(int(b[i:i+nbits],2)+refvalue)
    237    # Return string as list, split by null character.
    238    #return list(filter(None,wxstring.split('\0')))
    239    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

    242def get_wgrib2_prob_string(
    243    probtype: int,
    244    sfacl: int,
    245    svall: int,
    246    sfacu: int,
    247    svalu: int,
    248) -> str:
    249    """
    250    Return a wgrib2-styled string of probabilistic threshold information.
    251
    252    Logic from wgrib2 source,
    253    [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c),
    254    is replicated here.
    255
    256    Parameters
    257    ----------
    258    probtype
    259        Type of probability (Code Table 4.9).
    260    sfacl
    261        Scale factor of lower limit.
    262    svall
    263        Scaled value of lower limit.
    264    sfacu
    265        Scale factor of upper limit.
    266    svalu
    267        Scaled value of upper limit.
    268
    269    Returns
    270    -------
    271    get_wgrib2_prob_string
    272        wgrib2-formatted string of probability threshold.
    273    """
    274    probstr = ''
    275    if sfacl < 0: sfacl = 0
    276    if sfacu < 0: sfacu = 0
    277    lower = svall/(10**sfacl)
    278    upper = svalu/(10**sfacu)
    279    if probtype == 0:
    280        probstr = 'prob <%g' % (lower)
    281    elif probtype == 1:
    282        probstr = 'prob >%g' % (upper)
    283    elif probtype == 2:
    284        if lower == upper:
    285            probstr = 'prob =%g' % (lower)
    286        else:
    287            probstr = 'prob >=%g <%g' % (lower,upper)
    288    elif probtype == 3:
    289        probstr = 'prob >%g' % (lower)
    290    elif probtype == 4:
    291        probstr = 'prob <%g' % (upper)
    292    else:
    293        probstr = ''
    294    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.

def latlon_to_ij(gdtn, gdt, lats, lons, missing_value=nan): View Source

    297def latlon_to_ij(
    298    gdtn,
    299    gdt,
    300    lats,
    301    lons,
    302    missing_value = np.nan,
    303):
    304    """
    305    Convert latitude/longitude coordinates to grid (i, j) indices using the
    306    GRIB2 Grid Definition Section (GDS).
    307
    308    This function calls the grib2io iplib Cython extension module function,
    309    `grib2io.iplib.latlon_to_ij`.
    310
    311    Parameters
    312    ----------
    313    gdtn : int
    314        GRIB2 grid definition template number.
    315    gdt : ndarray of int32
    316        GRIB2 grid definition template values.
    317    lats : numpy.ndarray or list
    318        Latitude coordinates in degrees.
    319    lons : numpy.ndarray or list
    320        Longitude coordinates in degrees.
    321    missing_value : float, optional
    322        Missing value to represent when latitude/longitude coordinate is
    323        outside the grid domain.
    324
    325    Returns
    326    -------
    327    xpts : ndarray of float32
    328        Grid x-coordinates (i-indices) corresponding to the input
    329        latitude/longitude points.
    330    ypts : ndarray of float32
    331        Grid y-coordinates (j-indices) corresponding to the input
    332        latitude/longitude points.
    333    """
    334    # Check lats and lons
    335    if isinstance(lats,list):
    336        nlats = len(lats)
    337    elif isinstance(lats,np.ndarray) and len(lats.shape) == 1:
    338        nlats = lats.shape[0]
    339    else:
    340        raise ValueError("Latitudes must be a list or 1-D NumPy array.")
    341    if isinstance(lons,list):
    342        nlons = len(lons)
    343    elif isinstance(lons,np.ndarray) and len(lons.shape) == 1:
    344        nlons = lons.shape[0]
    345    else:
    346        raise ValueError("Longitudes must be a list or 1-D NumPy array.")
    347    if nlats != nlons:
    348        raise ValueError("Latitudes and longitudes same length.")
    349    return iplib.latlon_to_ij(
    350        gdtn.astype(np.int32),
    351        gdt.astype(np.int32),
    352        np.array(lats, dtype=np.float32),
    353        np.array(lons, dtype=np.float32),
    354        missing_value,
    355    )

Convert latitude/longitude coordinates to grid (i, j) indices using the GRIB2 Grid Definition Section (GDS).

This function calls the grib2io iplib Cython extension module function, `grib2io.iplib.latlon_to_ij`.

###### Parameters

- gdtn (int): GRIB2 grid definition template number.
- gdt (ndarray of int32): GRIB2 grid definition template values.
- lats (numpy.ndarray or list): Latitude coordinates in degrees.
- lons (numpy.ndarray or list): Longitude coordinates in degrees.
- missing_value (float, optional): Missing value to represent when latitude/longitude coordinate is outside the grid domain.

###### Returns

- xpts (ndarray of float32): Grid x-coordinates (i-indices) corresponding to the input latitude/longitude points.
- ypts (ndarray of float32): Grid y-coordinates (j-indices) corresponding to the input latitude/longitude points.