grib2io.tables API documentation

# grib2io.tables

Functions for retrieving data from NCEP GRIB2 Tables.

View Source

      1"""Functions for retrieving data from NCEP GRIB2 Tables."""
      2
      3from functools import lru_cache
      4from typing import Optional, Union, List
      5from numpy.typing import ArrayLike
      6import itertools
      7import importlib
      8
      9from .section0 import *
     10from .section1 import *
     11from .section3 import *
     12from .section4 import *
     13from .section5 import *
     14from .section6 import *
     15from .originating_centers import *
     16from .ndfd_additionals import *
     17
     18_varinfo_tables_datastore = {}
     19
     20# Note 209 is MRMS
     21GRIB2_DISCIPLINES = [0, 1, 2, 3, 4, 10, 20, 209]
     22
     23AEROSOL_PDTNS = [46, 48]  # 47, 49, 80, 81, 82, 83, 84, 85] <- these don't seem to be working
     24AEROSOL_PARAMS = list(itertools.chain(range(0,19),range(50,82),range(100,113),range(192,197)))
     25
     26def _load_varinfo_tables(modname: str):
     27    """
     28    Load variable information tables from sub modules into the local
     29    varinfo table datastore (_varinfo_tables_datastore).
     30
     31    Parameters
     32    ----------
     33    modname
     34        Module name to extract variable info tables from.
     35    """
     36    module = importlib.import_module(modname, package=__name__)
     37    names = getattr(module, '__all__', [name for name in dir(module) if name.startswith('table_')])
     38    _varinfo_tables_datastore.update({name: getattr(module, name) for name in names})
     39
     40
     41def get_table(table: str, expand: bool=False) -> dict:
     42    """
     43    Return GRIB2 code table as a dictionary.
     44
     45    Parameters
     46    ----------
     47    table
     48        Code table number (e.g. '1.0').
     49
     50        NOTE: Code table '4.1' requires a 3rd value representing the product
     51        discipline (e.g. '4.1.0').
     52    expand
     53        If `True`, expand output dictionary wherever keys are a range.
     54
     55    Returns
     56    -------
     57    get_table
     58        GRIB2 code table as a dictionary.
     59    """
     60    if len(table) == 3 and table == '4.1':
     61        raise Exception('GRIB2 Code Table 4.1 requires a 3rd value representing the discipline.')
     62    if len(table) == 3 and table.startswith('4.2'):
     63        raise Exception('Use function get_varinfo_from_table() for GRIB2 Code Table 4.2')
     64    try:
     65        tbl = globals()['table_'+table.replace('.','_')]
     66        if expand:
     67            _tbl = {}
     68            for k,v in tbl.items():
     69                if '-' in k:
     70                    irng = [int(i) for i in k.split('-')]
     71                    for i in range(irng[0],irng[1]+1):
     72                        _tbl[str(i)] = v
     73                else:
     74                    _tbl[k] = v
     75            tbl = _tbl
     76        return tbl
     77    except(KeyError):
     78        return {}
     79
     80
     81def get_value_from_table(
     82    value: Union[int, str],
     83    table: str,
     84    expand: bool = False,
     85) -> Optional[Union[float, int]]:
     86    """
     87    Return the definition given a GRIB2 code table.
     88
     89    Parameters
     90    ----------
     91    value
     92        Code table value.
     93    table
     94        Code table number.
     95    expand
     96        If `True`, expand output dictionary where keys are a range.
     97
     98    Returns
     99    -------
    100    get_value_from_table
    101        Table value or `None` if not found.
    102    """
    103    try:
    104        tbl = get_table(table,expand=expand)
    105        value = str(value)
    106        return tbl[value]
    107    except(KeyError):
    108        for k in tbl.keys():
    109            if '-' in k:
    110                bounds = k.split('-')
    111                if value >= bounds[0] and value <= bounds[1]:
    112                    return tbl[k]
    113        return None
    114
    115
    116def get_varinfo_from_table(
    117    discipline: Union[int, str],
    118    parmcat: Union[int, str],
    119    parmnum: Union[int, str],
    120    isNDFD: bool = False,
    121):
    122    """
    123    Return the GRIB2 variable information.
    124
    125    NOTE: This functions allows for all arguments to be converted to a string
    126    type if arguments are integer.
    127
    128    Parameters
    129    ----------
    130    discipline
    131        Discipline code value of a GRIB2 message.
    132    parmcat
    133        Parameter Category value of a GRIB2 message.
    134    parmnum
    135        Parameter Number value of a GRIB2 message.
    136    isNDFD: optional
    137        If `True`, then attempt to get variable information from the
    138        supplemental NDFD tables, otherwise fallback to default tables.
    139
    140    Returns
    141    -------
    142    full_name
    143        Full name of the GRIB2 variable. "Unknown" if variable is not found.
    144    units
    145        Units of the GRIB2 variable. "Unknown" if variable is not found.
    146    shortName
    147        Abbreviated name of the GRIB2 variable. "Unknown" if variable is not
    148        found.
    149    """
    150    template = f'table_4_2_{discipline}_{parmcat}'
    151    tbls = []
    152    if isNDFD:
    153        tbls.append(template+'_ndfd')
    154    tbls.append(template)
    155    for tbl in tbls:
    156        vartbl = None
    157        modname = f'.section4_discipline{discipline}'
    158        if tbl not in _varinfo_tables_datastore.keys():
    159            _load_varinfo_tables(modname)
    160        try:
    161            vartbl = _varinfo_tables_datastore[tbl][str(parmnum)]
    162        except(KeyError):
    163            vartbl = ['Unknown','Unknown','Unknown']
    164        if vartbl is not None:
    165            break
    166    return vartbl
    167
    168
    169@lru_cache(maxsize=None)
    170def get_shortnames(
    171    discipline: Optional[Union[int, str]] = None,
    172    parmcat: Optional[Union[int, str]] = None,
    173    parmnum: Optional[Union[int, str]] = None,
    174    isNDFD: bool = False,
    175) -> List[str]:
    176    """
    177    Return a list of variable shortNames.
    178
    179    If all 3 args are None, then shortNames from all disciplines, parameter
    180    categories, and numbers will be returned.
    181
    182    Parameters
    183    ----------
    184    discipline
    185        GRIB2 discipline code value.
    186    parmcat
    187        GRIB2 parameter category value.
    188    parmnum
    189        Parameter Number value of a GRIB2 message.
    190    isNDFD: optional
    191        If `True`, signals function to try to get variable information from the
    192        supplemental NDFD tables.
    193
    194    Returns
    195    -------
    196    get_shortnames
    197        list of GRIB2 shortNames.
    198    """
    199    shortnames = list()
    200    if discipline is None:
    201        discipline = GRIB2_DISCIPLINES
    202    else:
    203        discipline = [discipline]
    204    if parmcat is None:
    205        parmcat = list()
    206        for d in discipline:
    207            parmcat += list(get_table(f'4.1.{d}').keys())
    208    else:
    209        parmcat = [parmcat]
    210    if parmnum is None:
    211        parmnum = list(range(256))
    212    else:
    213        parmnum = [parmnum]
    214    for d in discipline:
    215
    216        for pc in parmcat:
    217            for pn in parmnum:
    218                shortnames.append(get_varinfo_from_table(d,pc,pn,isNDFD)[2])
    219
    220    shortnames = sorted(set(shortnames))
    221    try:
    222        shortnames.remove('unknown')
    223        shortnames.remove('Unknown')
    224    except(ValueError):
    225        pass
    226    return shortnames
    227
    228
    229@lru_cache(maxsize=None)
    230def get_metadata_from_shortname(shortname: str):
    231    """
    232    Provide GRIB2 variable metadata attributes given a GRIB2 shortName.
    233
    234    Parameters
    235    ----------
    236    shortname
    237        GRIB2 variable shortName.
    238
    239    Returns
    240    -------
    241    get_metadata_from_shortname
    242        list of dictionary items where each dictionary item contains the
    243        variable metadata key:value pairs.
    244
    245        NOTE: Some variable shortNames will exist in multiple parameter
    246        category/number tables according to the GRIB2 discipline.
    247    """
    248    metadata = []
    249    for d in GRIB2_DISCIPLINES:
    250        parmcat = list(get_table(f'4.1.{d}').keys())
    251        for pc in parmcat:
    252            for pn in range(256):
    253                varinfo = get_varinfo_from_table(d,pc,pn,False)
    254                if shortname == varinfo[2]:
    255                    metadata.append(dict(discipline=d,parameterCategory=pc,parameterNumber=pn,
    256                                         fullName=varinfo[0],units=varinfo[1]))
    257    return metadata
    258
    259
    260def get_wgrib2_level_string(pdtn: int, pdt: ArrayLike) -> str:
    261    """
    262    Return a string that describes the level or layer of the GRIB2 message.
    263
    264    The format and language of the string is an exact replica of how wgrib2
    265    produces the level/layer string in its inventory output.
    266
    267    Contents of wgrib2 source,
    268    [Level.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c),
    269    were converted into a Python dictionary and stored in grib2io as table
    270    'wgrib2_level_string'.
    271
    272    Parameters
    273    ----------
    274    pdtn
    275        GRIB2 Product Definition Template Number
    276    pdt
    277        Sequence containing GRIB2 Product Definition Template (Section 4).
    278
    279    Returns
    280    -------
    281    get_wgrib2_level_string
    282        wgrib2-formatted level/layer string.
    283    """
    284    lvlstr = ''
    285    if pdtn == 32:
    286        return 'no_level'
    287    elif pdtn == 48:
    288        idxs = slice(20,26)
    289    else:
    290        idxs = slice(9,15)
    291    type1, sfac1, sval1, type2, sfac2, sval2 = map(int,pdt[idxs])
    292    val1 = sval1/10**sfac1
    293    if type1 in [100,108]: val1 *= 0.01
    294    if type2 != 255:
    295        # Layer
    296        #assert type2 == type1, "Surface types are not equal: %g - %g" % (type1,type2)
    297        val2 = sval2/10**sfac2
    298        if type2 in [100,108]: val2 *= 0.01
    299        lvlstr = get_value_from_table(type1,table='wgrib2_level_string')[1]
    300        vals = (val1,val2)
    301    else:
    302        # Level
    303        lvlstr = get_value_from_table(type1,table='wgrib2_level_string')[0]
    304        vals = (val1)
    305    if '%g' in lvlstr: lvlstr %= vals
    306    return lvlstr
    307
    308
    309def _build_aerosol_shortname(obj) -> str:
    310    """
    311    """
    312    _OPTICAL_WAVELENGTH_MAPPING = get_table('aerosol_optical_wavelength')
    313    _LEVEL_MAPPING = get_table('aerosol_level')
    314    _PARAMETER_MAPPING = get_table('aerosol_parameter')
    315    _AERO_TYPE_MAPPING = get_table('aerosol_type')
    316
    317    # Build shortname from aerosol components
    318    parts = []
    319
    320    # Get aerosol type
    321    aero_type = str(obj.typeOfAerosol.value) if obj.typeOfAerosol is not None else ""
    322
    323    # Add size information if applicable
    324    aero_size = ""
    325    if hasattr(obj, 'scaledValueOfFirstSize'):
    326        if float(obj.scaledValueOfFirstSize) > 0:
    327            first_size = float(obj.scaledValueOfFirstSize)
    328
    329            # Map common PM sizes
    330            size_map = {1: 'pm1', 25: 'pm25', 10: 'pm10', 20: 'pm20'}
    331            aero_size = size_map.get(first_size, f"pm{int(first_size)}")
    332
    333            # Check for size intervals
    334            if (hasattr(obj, 'scaledValueOfSecondSize') and
    335                obj.scaledValueOfSecondSize is not None and
    336                hasattr(obj, 'typeOfIntervalForAerosolSize') and
    337                obj.typeOfIntervalForAerosolSize.value == 6):
    338
    339                second_size = float(obj.scaledValueOfSecondSize)
    340                if second_size > 0:
    341                    if (first_size == 2.5 and second_size == 10):
    342                        aero_size = 'PM25to10'
    343                    elif (first_size == 10 and second_size == 20):
    344                        aero_size = 'PM10to20'
    345                    else:
    346                        aero_size = f"PM{int(first_size)}to{int(second_size)}"
    347
    348    # Add optical and wavelength information
    349    var_wavelength = ''
    350    if (hasattr(obj, 'parameterNumber') and
    351        hasattr(obj, 'scaledValueOfFirstWavelength') and
    352        hasattr(obj, 'scaledValueOfSecondWavelength')):
    353
    354        optical_type = str(obj.parameterNumber)
    355        if obj.scaledValueOfFirstWavelength > 0:
    356            first_wl = obj.scaledValueOfFirstWavelength
    357            second_wl = obj.scaledValueOfSecondWavelength
    358
    359            # Special case for AE between 440-870nm
    360            if optical_type == '111' and first_wl == 440 and second_wl == 870:
    361                key = (optical_type, '440TO870')
    362            else:
    363                # Find matching wavelength band
    364                for wl_key, wl_info in _OPTICAL_WAVELENGTH_MAPPING.items():
    365                    if (wl_key[0] == optical_type and  # Check optical_type first
    366                        int(wl_key[1]) == first_wl and
    367                        (second_wl is None or int(wl_key[2]) == second_wl)):
    368                        key = wl_key
    369                        break
    370                else:
    371                    # If no match found, use raw values
    372                    key = (optical_type, str(first_wl),
    373                          str(second_wl) if second_wl is not None else '')
    374
    375            # FIX THIS...
    376            if key in _OPTICAL_WAVELENGTH_MAPPING.keys():
    377                var_wavelength = _OPTICAL_WAVELENGTH_MAPPING[key]
    378
    379    # Add level information
    380    level_str = ''
    381    if hasattr(obj, 'typeOfFirstFixedSurface'):
    382        first_level = str(obj.typeOfFirstFixedSurface.value)
    383        first_value = str(obj.scaledValueOfFirstFixedSurface) if obj.scaledValueOfFirstFixedSurface > 0 else ''
    384        if first_level in _LEVEL_MAPPING:
    385            level_str = f"{_LEVEL_MAPPING[first_level]}{first_value}"
    386
    387    # Get parameter type
    388    param = ''
    389    if hasattr(obj, 'parameterNumber'):
    390        param_num = str(obj.parameterNumber)
    391        if param_num in _PARAMETER_MAPPING:
    392            param = _PARAMETER_MAPPING[param_num]
    393
    394    # Build the final shortname
    395    if var_wavelength and aero_type in _AERO_TYPE_MAPPING:
    396        shortname = f"{_AERO_TYPE_MAPPING[aero_type]}{var_wavelength}"
    397    elif aero_type in _AERO_TYPE_MAPPING:
    398        parts = []
    399        if level_str:
    400            parts.append(level_str)
    401        parts.append(_AERO_TYPE_MAPPING[aero_type])
    402        if aero_size:
    403            parts.append(aero_size)
    404        if param:
    405            parts.append(param)
    406        shortname = '_'.join(parts) if len(parts) > 1 else parts[0]
    407    else:
    408        return get_varinfo_from_table(obj.section0[2], *obj.section4[2:4], isNDFD=obj._isNDFD)[2]
    409
    410    return shortname
    411
    412
    413@lru_cache(maxsize=None)
    414def get_table_names(var_tables: bool=False) -> tuple:
    415    """
    416    Return the names of available GRIB2 tables.
    417
    418    The table dictionaries as they exist in grib2io are prefixed
    419    with "table_". When accessing a table through the available
    420    functions, the prefix is not necessary.
    421
    422    Parameters
    423    ----------
    424    var_tables : bool, optional
    425        If True, include names of variable tables.
    426        If False (default), include only non-variable tables.
    427
    428    Returns
    429    -------
    430    tuple of str
    431        A tuple sorted names of available tables.
    432    """
    433    tables = [
    434        name.replace("table_","") for name, val in globals().items()
    435        if isinstance(val, dict) and name.startswith("table_")
    436    ]
    437
    438    tables = [
    439        t.replace("_",".") if t.startswith(tuple("0123456789")) else t for t in tables
    440    ]
    441
    442    if var_tables:
    443        for d in GRIB2_DISCIPLINES:
    444            modname = f'.section4_discipline{d}'
    445            _load_varinfo_tables(modname)
    446        vt = [t.replace("table_","").replace("_",".") for t in _varinfo_tables_datastore.keys()]
    447        tables.extend(vt)
    448
    449    return tuple(sorted(tables))

GRIB2_DISCIPLINES = [0, 1, 2, 3, 4, 10, 20, 209]
AEROSOL_PDTNS = [46, 48]
AEROSOL_PARAMS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 192, 193, 194, 195, 196]
def get_table(table: str, expand: bool = False) -> dict: View Source

    42def get_table(table: str, expand: bool=False) -> dict:
    43    """
    44    Return GRIB2 code table as a dictionary.
    45
    46    Parameters
    47    ----------
    48    table
    49        Code table number (e.g. '1.0').
    50
    51        NOTE: Code table '4.1' requires a 3rd value representing the product
    52        discipline (e.g. '4.1.0').
    53    expand
    54        If `True`, expand output dictionary wherever keys are a range.
    55
    56    Returns
    57    -------
    58    get_table
    59        GRIB2 code table as a dictionary.
    60    """
    61    if len(table) == 3 and table == '4.1':
    62        raise Exception('GRIB2 Code Table 4.1 requires a 3rd value representing the discipline.')
    63    if len(table) == 3 and table.startswith('4.2'):
    64        raise Exception('Use function get_varinfo_from_table() for GRIB2 Code Table 4.2')
    65    try:
    66        tbl = globals()['table_'+table.replace('.','_')]
    67        if expand:
    68            _tbl = {}
    69            for k,v in tbl.items():
    70                if '-' in k:
    71                    irng = [int(i) for i in k.split('-')]
    72                    for i in range(irng[0],irng[1]+1):
    73                        _tbl[str(i)] = v
    74                else:
    75                    _tbl[k] = v
    76            tbl = _tbl
    77        return tbl
    78    except(KeyError):
    79        return {}

Return GRIB2 code table as a dictionary.

###### Parameters

- table: Code table number (e.g. '1.0').

NOTE: Code table '4.1' requires a 3rd value representing the product discipline (e.g. '4.1.0').

- expand: If `True`, expand output dictionary wherever keys are a range.

###### Returns

- get_table: GRIB2 code table as a dictionary.

def get_value_from_table( value: Union[int, str], table: str, expand: bool = False) -> Union[float, int, NoneType]: View Source

     82def get_value_from_table(
     83    value: Union[int, str],
     84    table: str,
     85    expand: bool = False,
     86) -> Optional[Union[float, int]]:
     87    """
     88    Return the definition given a GRIB2 code table.
     89
     90    Parameters
     91    ----------
     92    value
     93        Code table value.
     94    table
     95        Code table number.
     96    expand
     97        If `True`, expand output dictionary where keys are a range.
     98
     99    Returns
    100    -------
    101    get_value_from_table
    102        Table value or `None` if not found.
    103    """
    104    try:
    105        tbl = get_table(table,expand=expand)
    106        value = str(value)
    107        return tbl[value]
    108    except(KeyError):
    109        for k in tbl.keys():
    110            if '-' in k:
    111                bounds = k.split('-')
    112                if value >= bounds[0] and value <= bounds[1]:
    113                    return tbl[k]
    114        return None

Return the definition given a GRIB2 code table.

###### Parameters

- value: Code table value.
- table: Code table number.
- expand: If `True`, expand output dictionary where keys are a range.

###### Returns

- get_value_from_table: Table value or `None` if not found.

def get_varinfo_from_table( discipline: Union[int, str], parmcat: Union[int, str], parmnum: Union[int, str], isNDFD: bool = False): View Source

    117def get_varinfo_from_table(
    118    discipline: Union[int, str],
    119    parmcat: Union[int, str],
    120    parmnum: Union[int, str],
    121    isNDFD: bool = False,
    122):
    123    """
    124    Return the GRIB2 variable information.
    125
    126    NOTE: This functions allows for all arguments to be converted to a string
    127    type if arguments are integer.
    128
    129    Parameters
    130    ----------
    131    discipline
    132        Discipline code value of a GRIB2 message.
    133    parmcat
    134        Parameter Category value of a GRIB2 message.
    135    parmnum
    136        Parameter Number value of a GRIB2 message.
    137    isNDFD: optional
    138        If `True`, then attempt to get variable information from the
    139        supplemental NDFD tables, otherwise fallback to default tables.
    140
    141    Returns
    142    -------
    143    full_name
    144        Full name of the GRIB2 variable. "Unknown" if variable is not found.
    145    units
    146        Units of the GRIB2 variable. "Unknown" if variable is not found.
    147    shortName
    148        Abbreviated name of the GRIB2 variable. "Unknown" if variable is not
    149        found.
    150    """
    151    template = f'table_4_2_{discipline}_{parmcat}'
    152    tbls = []
    153    if isNDFD:
    154        tbls.append(template+'_ndfd')
    155    tbls.append(template)
    156    for tbl in tbls:
    157        vartbl = None
    158        modname = f'.section4_discipline{discipline}'
    159        if tbl not in _varinfo_tables_datastore.keys():
    160            _load_varinfo_tables(modname)
    161        try:
    162            vartbl = _varinfo_tables_datastore[tbl][str(parmnum)]
    163        except(KeyError):
    164            vartbl = ['Unknown','Unknown','Unknown']
    165        if vartbl is not None:
    166            break
    167    return vartbl

Return the GRIB2 variable information.

NOTE: This functions allows for all arguments to be converted to a string type if arguments are integer.

###### Parameters

- discipline: Discipline code value of a GRIB2 message.
- parmcat: Parameter Category value of a GRIB2 message.
- parmnum: Parameter Number value of a GRIB2 message.
- isNDFD (optional): If `True`, then attempt to get variable information from the supplemental NDFD tables, otherwise fallback to default tables.

###### Returns

- full_name: Full name of the GRIB2 variable. "Unknown" if variable is not found.
- units: Units of the GRIB2 variable. "Unknown" if variable is not found.
- shortName: Abbreviated name of the GRIB2 variable. "Unknown" if variable is not found.

@lru_cache(maxsize=None)
def get_shortnames( discipline: Union[int, str, NoneType] = None, parmcat: Union[int, str, NoneType] = None, parmnum: Union[int, str, NoneType] = None, isNDFD: bool = False) -> List[str]: View Source

    170@lru_cache(maxsize=None)
    171def get_shortnames(
    172    discipline: Optional[Union[int, str]] = None,
    173    parmcat: Optional[Union[int, str]] = None,
    174    parmnum: Optional[Union[int, str]] = None,
    175    isNDFD: bool = False,
    176) -> List[str]:
    177    """
    178    Return a list of variable shortNames.
    179
    180    If all 3 args are None, then shortNames from all disciplines, parameter
    181    categories, and numbers will be returned.
    182
    183    Parameters
    184    ----------
    185    discipline
    186        GRIB2 discipline code value.
    187    parmcat
    188        GRIB2 parameter category value.
    189    parmnum
    190        Parameter Number value of a GRIB2 message.
    191    isNDFD: optional
    192        If `True`, signals function to try to get variable information from the
    193        supplemental NDFD tables.
    194
    195    Returns
    196    -------
    197    get_shortnames
    198        list of GRIB2 shortNames.
    199    """
    200    shortnames = list()
    201    if discipline is None:
    202        discipline = GRIB2_DISCIPLINES
    203    else:
    204        discipline = [discipline]
    205    if parmcat is None:
    206        parmcat = list()
    207        for d in discipline:
    208            parmcat += list(get_table(f'4.1.{d}').keys())
    209    else:
    210        parmcat = [parmcat]
    211    if parmnum is None:
    212        parmnum = list(range(256))
    213    else:
    214        parmnum = [parmnum]
    215    for d in discipline:
    216
    217        for pc in parmcat:
    218            for pn in parmnum:
    219                shortnames.append(get_varinfo_from_table(d,pc,pn,isNDFD)[2])
    220
    221    shortnames = sorted(set(shortnames))
    222    try:
    223        shortnames.remove('unknown')
    224        shortnames.remove('Unknown')
    225    except(ValueError):
    226        pass
    227    return shortnames

Return a list of variable shortNames.

If all 3 args are None, then shortNames from all disciplines, parameter categories, and numbers will be returned.

###### Parameters

- discipline: GRIB2 discipline code value.
- parmcat: GRIB2 parameter category value.
- parmnum: Parameter Number value of a GRIB2 message.
- isNDFD (optional): If `True`, signals function to try to get variable information from the supplemental NDFD tables.

###### Returns

- get_shortnames: list of GRIB2 shortNames.

@lru_cache(maxsize=None)
def get_metadata_from_shortname(shortname: str): View Source

    230@lru_cache(maxsize=None)
    231def get_metadata_from_shortname(shortname: str):
    232    """
    233    Provide GRIB2 variable metadata attributes given a GRIB2 shortName.
    234
    235    Parameters
    236    ----------
    237    shortname
    238        GRIB2 variable shortName.
    239
    240    Returns
    241    -------
    242    get_metadata_from_shortname
    243        list of dictionary items where each dictionary item contains the
    244        variable metadata key:value pairs.
    245
    246        NOTE: Some variable shortNames will exist in multiple parameter
    247        category/number tables according to the GRIB2 discipline.
    248    """
    249    metadata = []
    250    for d in GRIB2_DISCIPLINES:
    251        parmcat = list(get_table(f'4.1.{d}').keys())
    252        for pc in parmcat:
    253            for pn in range(256):
    254                varinfo = get_varinfo_from_table(d,pc,pn,False)
    255                if shortname == varinfo[2]:
    256                    metadata.append(dict(discipline=d,parameterCategory=pc,parameterNumber=pn,
    257                                         fullName=varinfo[0],units=varinfo[1]))
    258    return metadata

Provide GRIB2 variable metadata attributes given a GRIB2 shortName.

###### Parameters

- shortname: GRIB2 variable shortName.

###### Returns

- get_metadata_from_shortname: list of dictionary items where each dictionary item contains the variable metadata key:value pairs.

NOTE: Some variable shortNames will exist in multiple parameter category/number tables according to the GRIB2 discipline.

def get_wgrib2_level_string( 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]]) -> str: View Source

    261def get_wgrib2_level_string(pdtn: int, pdt: ArrayLike) -> str:
    262    """
    263    Return a string that describes the level or layer of the GRIB2 message.
    264
    265    The format and language of the string is an exact replica of how wgrib2
    266    produces the level/layer string in its inventory output.
    267
    268    Contents of wgrib2 source,
    269    [Level.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c),
    270    were converted into a Python dictionary and stored in grib2io as table
    271    'wgrib2_level_string'.
    272
    273    Parameters
    274    ----------
    275    pdtn
    276        GRIB2 Product Definition Template Number
    277    pdt
    278        Sequence containing GRIB2 Product Definition Template (Section 4).
    279
    280    Returns
    281    -------
    282    get_wgrib2_level_string
    283        wgrib2-formatted level/layer string.
    284    """
    285    lvlstr = ''
    286    if pdtn == 32:
    287        return 'no_level'
    288    elif pdtn == 48:
    289        idxs = slice(20,26)
    290    else:
    291        idxs = slice(9,15)
    292    type1, sfac1, sval1, type2, sfac2, sval2 = map(int,pdt[idxs])
    293    val1 = sval1/10**sfac1
    294    if type1 in [100,108]: val1 *= 0.01
    295    if type2 != 255:
    296        # Layer
    297        #assert type2 == type1, "Surface types are not equal: %g - %g" % (type1,type2)
    298        val2 = sval2/10**sfac2
    299        if type2 in [100,108]: val2 *= 0.01
    300        lvlstr = get_value_from_table(type1,table='wgrib2_level_string')[1]
    301        vals = (val1,val2)
    302    else:
    303        # Level
    304        lvlstr = get_value_from_table(type1,table='wgrib2_level_string')[0]
    305        vals = (val1)
    306    if '%g' in lvlstr: lvlstr %= vals
    307    return lvlstr

Return a string that describes the level or layer of the GRIB2 message.

The format and language of the string is an exact replica of how wgrib2 produces the level/layer string in its inventory output.

Contents of wgrib2 source, Level.c, were converted into a Python dictionary and stored in grib2io as table 'wgrib2_level_string'.

###### Parameters

- pdtn: GRIB2 Product Definition Template Number
- pdt: Sequence containing GRIB2 Product Definition Template (Section 4).

###### Returns

- get_wgrib2_level_string: wgrib2-formatted level/layer string.

@lru_cache(maxsize=None)
def get_table_names(var_tables: bool = False) -> tuple: View Source

    414@lru_cache(maxsize=None)
    415def get_table_names(var_tables: bool=False) -> tuple:
    416    """
    417    Return the names of available GRIB2 tables.
    418
    419    The table dictionaries as they exist in grib2io are prefixed
    420    with "table_". When accessing a table through the available
    421    functions, the prefix is not necessary.
    422
    423    Parameters
    424    ----------
    425    var_tables : bool, optional
    426        If True, include names of variable tables.
    427        If False (default), include only non-variable tables.
    428
    429    Returns
    430    -------
    431    tuple of str
    432        A tuple sorted names of available tables.
    433    """
    434    tables = [
    435        name.replace("table_","") for name, val in globals().items()
    436        if isinstance(val, dict) and name.startswith("table_")
    437    ]
    438
    439    tables = [
    440        t.replace("_",".") if t.startswith(tuple("0123456789")) else t for t in tables
    441    ]
    442
    443    if var_tables:
    444        for d in GRIB2_DISCIPLINES:
    445            modname = f'.section4_discipline{d}'
    446            _load_varinfo_tables(modname)
    447        vt = [t.replace("table_","").replace("_",".") for t in _varinfo_tables_datastore.keys()]
    448        tables.extend(vt)
    449
    450    return tuple(sorted(tables))

Return the names of available GRIB2 tables.

The table dictionaries as they exist in grib2io are prefixed with "table_". When accessing a table through the available functions, the prefix is not necessary.

###### Parameters

- var_tables (bool, optional): If True, include names of variable tables. If False (default), include only non-variable tables.

###### Returns

- tuple of str: A tuple sorted names of available tables.