grib2io.tables
Functions for retreiving data from NCEP GRIB2 Tables.
1""" 2Functions for retreiving data from NCEP GRIB2 Tables. 3""" 4#from functools import cache # USE WHEN Python 3.9+ only 5from functools import lru_cache 6 7from .section0 import * 8from .section1 import * 9from .section3 import * 10from .section4 import * 11from .section5 import * 12from .section6 import * 13from .originating_centers import * 14 15GRIB2_DISCIPLINES = [0, 1, 2, 3, 4, 10, 20] 16 17def get_table(table, expand=False): 18 """ 19 Return GRIB2 code table as a dictionary. 20 21 Parameters 22 ---------- 23 **`table : str`** 24 Code table number (e.g. '1.0'). NOTE: Code table '4.1' requires a 3rd value 25 representing the product discipline (e.g. '4.1.0'). 26 27 **`expand : bool, optional`** 28 If `True`, expand output dictionary where keys are a range. 29 30 Returns 31 ------- 32 Table as a **`dict`**. 33 """ 34 if len(table) == 3 and table == '4.1': 35 raise Exception('GRIB2 Code Table 4.1 requires a 3rd value representing the discipline.') 36 if len(table) == 3 and table.startswith('4.2'): 37 raise Exception('Use function get_varinfo_from_table() for GRIB2 Code Table 4.2') 38 try: 39 tbl = globals()['table_'+table.replace('.','_')] 40 if expand: 41 _tbl = {} 42 for k,v in tbl.items(): 43 if '-' in k: 44 irng = [int(i) for i in k.split('-')] 45 for i in range(irng[0],irng[1]+1): 46 _tbl[str(i)] = v 47 else: 48 _tbl[k] = v 49 tbl = _tbl 50 return tbl 51 except(KeyError): 52 return {} 53 54 55def get_value_from_table(value, table, expand=False): 56 """ 57 Return the definition given a GRIB2 code table. 58 59 Parameters 60 ---------- 61 **`value : int or str`** 62 Code table value. 63 64 **`table : str`** 65 Code table number. 66 67 **`expand : bool, optional`** 68 If `True`, expand output dictionary where keys are a range. 69 70 Returns 71 ------- 72 Table value or `None` if not found. 73 """ 74 try: 75 tbl = get_table(table,expand=expand) 76 value = str(value) 77 return tbl[value] 78 except(KeyError): 79 for k in tbl.keys(): 80 if '-' in k: 81 bounds = k.split('-') 82 if value >= bounds[0] and value <= bounds[1]: 83 return tbl[k] 84 return None 85 86 87def get_varinfo_from_table(discipline,parmcat,parmnum,isNDFD=False): 88 """ 89 Return the GRIB2 variable information given values of `discipline`, 90 `parmcat`, and `parmnum`. NOTE: This functions allows for all arguments 91 to be converted to a string type if arguments are integer. 92 93 Parameters 94 ---------- 95 **`discipline : int or str`** 96 Discipline code value of a GRIB2 message. 97 98 **`parmcat : int or str`** 99 Parameter Category value of a GRIB2 message. 100 101 **`parmnum : int or str`** 102 Parameter Number value of a GRIB2 message. 103 104 **`isNDFD : bool, optional`** 105 If `True`, signals function to try to get variable information from 106 the supplemental NDFD tables. 107 108 Returns 109 ------- 110 **`list`** containing variable information. "Unknown" is given for item of 111 information if variable is not found. 112 - list[0] = full name 113 - list[1] = units 114 - list[2] = short name (abbreviated name) 115 """ 116 if isNDFD: 117 try: 118 tblname = f'table_4_2_{discipline}_{parmcat}_ndfd' 119 modname = f'.section4_discipline{discipline}' 120 exec('from '+modname+' import *') 121 return locals()[tblname][str(parmnum)] 122 except(ImportError,KeyError): 123 pass 124 #return ['Unknown','Unknown','Unknown'] 125 try: 126 tblname = f'table_4_2_{discipline}_{parmcat}' 127 modname = f'.section4_discipline{discipline}' 128 exec('from '+modname+' import *') 129 return locals()[tblname][str(parmnum)] 130 except(ImportError,KeyError): 131 return ['Unknown','Unknown','Unknown'] 132 133 134#@cache# USE WHEN Python 3.9+ only 135@lru_cache(maxsize=None) 136def get_shortnames(discipline=None, parmcat=None, parmnum=None, isNDFD=False): 137 """ 138 Returns a list of variable shortNames given GRIB2 discipline, parameter 139 category, and parameter number. If all 3 args are None, then shortNames 140 from all disciplines, parameter categories, and numbers will be returned. 141 142 Parameters 143 ---------- 144 **`discipline : int`** 145 GRIB2 discipline code value. 146 147 **`parmcat : int`** 148 GRIB2 parameter category value. 149 150 **`parmnum : int or str`** 151 Parameter Number value of a GRIB2 message. 152 153 Returns 154 ------- 155 **`list`** of GRIB2 shortNames. 156 """ 157 shortnames = list() 158 if discipline is None: 159 discipline = GRIB2_DISCIPLINES 160 else: 161 discipline = [discipline] 162 if parmcat is None: 163 parmcat = list() 164 for d in discipline: 165 parmcat += list(get_table(f'4.1.{d}').keys()) 166 else: 167 parmcat = [parmcat] 168 if parmnum is None: 169 parmnum = list(range(256)) 170 else: 171 parmnum = [parmnum] 172 for d in discipline: 173 174 for pc in parmcat: 175 for pn in parmnum: 176 shortnames.append(get_varinfo_from_table(d,pc,pn,isNDFD)[2]) 177 178 shortnames = sorted(set(shortnames)) 179 try: 180 shortnames.remove('unknown') 181 shortnames.remove('Unknown') 182 except(ValueError): 183 pass 184 return shortnames 185 186 187#@cache# USE WHEN Python 3.9+ only 188@lru_cache(maxsize=None) 189def get_metadata_from_shortname(shortname): 190 """ 191 Provide GRIB2 variable metadata attributes given a GRIB2 shortName. 192 193 Parameters 194 ---------- 195 **`shortname : str`** 196 GRIB2 variable shortName. 197 198 Returns 199 ------- 200 **`list`** of dictionary items where each dictionary items contains the variable 201 metadata key:value pairs. **NOTE:** Some variable shortNames will exist in multiple 202 parameter category/number tables according to the GRIB2 discipline. 203 """ 204 metadata = [] 205 for d in GRIB2_DISCIPLINES: 206 parmcat = list(get_table(f'4.1.{d}').keys()) 207 for pc in parmcat: 208 for pn in range(256): 209 varinfo = get_varinfo_from_table(d,pc,pn,False) 210 if shortname == varinfo[2]: 211 metadata.append(dict(discipline=d,parameterCategory=pc,parameterNumber=pn, 212 fullName=varinfo[0],units=varinfo[1])) 213 return metadata 214 215 216def get_wgrib2_level_string(pdtn, pdt): 217 """ 218 Return a string that describes the level or layer of the GRIB2 message. The 219 format and language of the string is an exact replica of how wgrib2 produces 220 the level/layer string in its inventory output. 221 222 Contents of wgrib2 source, [Level.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c), 223 were converted into a Python dictionary and stored in grib2io as table 224 'wgrib2_level_string'. 225 226 Parameters 227 ---------- 228 **`pdtn : int`** 229 GRIB2 Product Definition Template Number 230 231 **`pdt : list or array_like`** 232 Sequence containing GRIB2 Product Definition Template (Section 4). 233 234 Returns 235 ------- 236 wgrib2-formatted level/layer string. 237 """ 238 if pdtn == 48: 239 idxs = slice(20,26) 240 else: 241 idxs = slice(9,15) 242 type1, sfac1, sval1, type2, sfac2, sval2 = map(int,pdt[idxs]) 243 lvlstr = '' 244 val1 = sval1/10**sfac1 245 if type1 in [100,108]: val1 *= 0.01 246 if type2 != 255: 247 # Layer 248 #assert type2 == type1, "Surface types are not equal: %g - %g" % (type1,type2) 249 val2 = sval2/10**sfac2 250 if type2 in [100,108]: val2 *= 0.01 251 lvlstr = get_value_from_table(type1,table='wgrib2_level_string')[1] 252 vals = (val1,val2) 253 else: 254 # Level 255 lvlstr = get_value_from_table(type1,table='wgrib2_level_string')[0] 256 vals = (val1) 257 if '%g' in lvlstr: lvlstr %= vals 258 return lvlstr
18def get_table(table, expand=False): 19 """ 20 Return GRIB2 code table as a dictionary. 21 22 Parameters 23 ---------- 24 **`table : str`** 25 Code table number (e.g. '1.0'). NOTE: Code table '4.1' requires a 3rd value 26 representing the product discipline (e.g. '4.1.0'). 27 28 **`expand : bool, optional`** 29 If `True`, expand output dictionary where keys are a range. 30 31 Returns 32 ------- 33 Table as a **`dict`**. 34 """ 35 if len(table) == 3 and table == '4.1': 36 raise Exception('GRIB2 Code Table 4.1 requires a 3rd value representing the discipline.') 37 if len(table) == 3 and table.startswith('4.2'): 38 raise Exception('Use function get_varinfo_from_table() for GRIB2 Code Table 4.2') 39 try: 40 tbl = globals()['table_'+table.replace('.','_')] 41 if expand: 42 _tbl = {} 43 for k,v in tbl.items(): 44 if '-' in k: 45 irng = [int(i) for i in k.split('-')] 46 for i in range(irng[0],irng[1]+1): 47 _tbl[str(i)] = v 48 else: 49 _tbl[k] = v 50 tbl = _tbl 51 return tbl 52 except(KeyError): 53 return {}
Return GRIB2 code table as a dictionary.
Parameters
table : str
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 : bool, optional
If True
, expand output dictionary where keys are a range.
Returns
Table as a dict
.
56def get_value_from_table(value, table, expand=False): 57 """ 58 Return the definition given a GRIB2 code table. 59 60 Parameters 61 ---------- 62 **`value : int or str`** 63 Code table value. 64 65 **`table : str`** 66 Code table number. 67 68 **`expand : bool, optional`** 69 If `True`, expand output dictionary where keys are a range. 70 71 Returns 72 ------- 73 Table value or `None` if not found. 74 """ 75 try: 76 tbl = get_table(table,expand=expand) 77 value = str(value) 78 return tbl[value] 79 except(KeyError): 80 for k in tbl.keys(): 81 if '-' in k: 82 bounds = k.split('-') 83 if value >= bounds[0] and value <= bounds[1]: 84 return tbl[k] 85 return None
Return the definition given a GRIB2 code table.
Parameters
value : int or str
Code table value.
table : str
Code table number.
expand : bool, optional
If True
, expand output dictionary where keys are a range.
Returns
Table value or None
if not found.
88def get_varinfo_from_table(discipline,parmcat,parmnum,isNDFD=False): 89 """ 90 Return the GRIB2 variable information given values of `discipline`, 91 `parmcat`, and `parmnum`. NOTE: This functions allows for all arguments 92 to be converted to a string type if arguments are integer. 93 94 Parameters 95 ---------- 96 **`discipline : int or str`** 97 Discipline code value of a GRIB2 message. 98 99 **`parmcat : int or str`** 100 Parameter Category value of a GRIB2 message. 101 102 **`parmnum : int or str`** 103 Parameter Number value of a GRIB2 message. 104 105 **`isNDFD : bool, optional`** 106 If `True`, signals function to try to get variable information from 107 the supplemental NDFD tables. 108 109 Returns 110 ------- 111 **`list`** containing variable information. "Unknown" is given for item of 112 information if variable is not found. 113 - list[0] = full name 114 - list[1] = units 115 - list[2] = short name (abbreviated name) 116 """ 117 if isNDFD: 118 try: 119 tblname = f'table_4_2_{discipline}_{parmcat}_ndfd' 120 modname = f'.section4_discipline{discipline}' 121 exec('from '+modname+' import *') 122 return locals()[tblname][str(parmnum)] 123 except(ImportError,KeyError): 124 pass 125 #return ['Unknown','Unknown','Unknown'] 126 try: 127 tblname = f'table_4_2_{discipline}_{parmcat}' 128 modname = f'.section4_discipline{discipline}' 129 exec('from '+modname+' import *') 130 return locals()[tblname][str(parmnum)] 131 except(ImportError,KeyError): 132 return ['Unknown','Unknown','Unknown']
Return the GRIB2 variable information given values of discipline
,
parmcat
, and parmnum
. NOTE: This functions allows for all arguments
to be converted to a string type if arguments are integer.
Parameters
discipline : int or str
Discipline code value of a GRIB2 message.
parmcat : int or str
Parameter Category value of a GRIB2 message.
parmnum : int or str
Parameter Number value of a GRIB2 message.
isNDFD : bool, optional
If True
, signals function to try to get variable information from
the supplemental NDFD tables.
Returns
list
containing variable information. "Unknown" is given for item of
information if variable is not found.
- list[0] = full name
- list[1] = units
- list[2] = short name (abbreviated name)
136@lru_cache(maxsize=None) 137def get_shortnames(discipline=None, parmcat=None, parmnum=None, isNDFD=False): 138 """ 139 Returns a list of variable shortNames given GRIB2 discipline, parameter 140 category, and parameter number. If all 3 args are None, then shortNames 141 from all disciplines, parameter categories, and numbers will be returned. 142 143 Parameters 144 ---------- 145 **`discipline : int`** 146 GRIB2 discipline code value. 147 148 **`parmcat : int`** 149 GRIB2 parameter category value. 150 151 **`parmnum : int or str`** 152 Parameter Number value of a GRIB2 message. 153 154 Returns 155 ------- 156 **`list`** of GRIB2 shortNames. 157 """ 158 shortnames = list() 159 if discipline is None: 160 discipline = GRIB2_DISCIPLINES 161 else: 162 discipline = [discipline] 163 if parmcat is None: 164 parmcat = list() 165 for d in discipline: 166 parmcat += list(get_table(f'4.1.{d}').keys()) 167 else: 168 parmcat = [parmcat] 169 if parmnum is None: 170 parmnum = list(range(256)) 171 else: 172 parmnum = [parmnum] 173 for d in discipline: 174 175 for pc in parmcat: 176 for pn in parmnum: 177 shortnames.append(get_varinfo_from_table(d,pc,pn,isNDFD)[2]) 178 179 shortnames = sorted(set(shortnames)) 180 try: 181 shortnames.remove('unknown') 182 shortnames.remove('Unknown') 183 except(ValueError): 184 pass 185 return shortnames
Returns a list of variable shortNames given GRIB2 discipline, parameter category, and parameter number. If all 3 args are None, then shortNames from all disciplines, parameter categories, and numbers will be returned.
Parameters
discipline : int
GRIB2 discipline code value.
parmcat : int
GRIB2 parameter category value.
parmnum : int or str
Parameter Number value of a GRIB2 message.
Returns
list
of GRIB2 shortNames.
189@lru_cache(maxsize=None) 190def get_metadata_from_shortname(shortname): 191 """ 192 Provide GRIB2 variable metadata attributes given a GRIB2 shortName. 193 194 Parameters 195 ---------- 196 **`shortname : str`** 197 GRIB2 variable shortName. 198 199 Returns 200 ------- 201 **`list`** of dictionary items where each dictionary items contains the variable 202 metadata key:value pairs. **NOTE:** Some variable shortNames will exist in multiple 203 parameter category/number tables according to the GRIB2 discipline. 204 """ 205 metadata = [] 206 for d in GRIB2_DISCIPLINES: 207 parmcat = list(get_table(f'4.1.{d}').keys()) 208 for pc in parmcat: 209 for pn in range(256): 210 varinfo = get_varinfo_from_table(d,pc,pn,False) 211 if shortname == varinfo[2]: 212 metadata.append(dict(discipline=d,parameterCategory=pc,parameterNumber=pn, 213 fullName=varinfo[0],units=varinfo[1])) 214 return metadata
Provide GRIB2 variable metadata attributes given a GRIB2 shortName.
Parameters
shortname : str
GRIB2 variable shortName.
Returns
list
of dictionary items where each dictionary items contains the variable
metadata key:value pairs. NOTE: Some variable shortNames will exist in multiple
parameter category/number tables according to the GRIB2 discipline.
217def get_wgrib2_level_string(pdtn, pdt): 218 """ 219 Return a string that describes the level or layer of the GRIB2 message. The 220 format and language of the string is an exact replica of how wgrib2 produces 221 the level/layer string in its inventory output. 222 223 Contents of wgrib2 source, [Level.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c), 224 were converted into a Python dictionary and stored in grib2io as table 225 'wgrib2_level_string'. 226 227 Parameters 228 ---------- 229 **`pdtn : int`** 230 GRIB2 Product Definition Template Number 231 232 **`pdt : list or array_like`** 233 Sequence containing GRIB2 Product Definition Template (Section 4). 234 235 Returns 236 ------- 237 wgrib2-formatted level/layer string. 238 """ 239 if pdtn == 48: 240 idxs = slice(20,26) 241 else: 242 idxs = slice(9,15) 243 type1, sfac1, sval1, type2, sfac2, sval2 = map(int,pdt[idxs]) 244 lvlstr = '' 245 val1 = sval1/10**sfac1 246 if type1 in [100,108]: val1 *= 0.01 247 if type2 != 255: 248 # Layer 249 #assert type2 == type1, "Surface types are not equal: %g - %g" % (type1,type2) 250 val2 = sval2/10**sfac2 251 if type2 in [100,108]: val2 *= 0.01 252 lvlstr = get_value_from_table(type1,table='wgrib2_level_string')[1] 253 vals = (val1,val2) 254 else: 255 # Level 256 lvlstr = get_value_from_table(type1,table='wgrib2_level_string')[0] 257 vals = (val1) 258 if '%g' in lvlstr: lvlstr %= vals 259 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 : int
GRIB2 Product Definition Template Number
pdt : list or array_like
Sequence containing GRIB2 Product Definition Template (Section 4).
Returns
wgrib2-formatted level/layer string.