grib2io.utils
Collection of utility functions to assist in the encoding and decoding of GRIB2 Messages.
1""" 2Collection of utility functions to assist in the encoding and decoding 3of GRIB2 Messages. 4""" 5 6import g2clib 7import datetime 8import numpy as np 9import struct 10 11from .. import tables 12 13def int2bin(i,nbits=8,output=str): 14 """ 15 Convert integer to binary string or list 16 17 Parameters 18 ---------- 19 20 **`i`**: Integer value to convert to binary representation. 21 22 **`nbits`**: Number of bits to return. Valid values are 8 [DEFAULT], 16, 23 32, and 64. 24 25 **`output`**: Return data as `str` [DEFAULT] or `list` (list of ints). 26 27 Returns 28 ------- 29 30 `str` or `list` (list of ints) of binary representation of the integer value. 31 """ 32 i = int(i) if not isinstance(i,int) else i 33 assert nbits in [8,16,32,64] 34 bitstr = "{0:b}".format(i).zfill(nbits) 35 if output is str: 36 return bitstr 37 elif output is list: 38 return [int(b) for b in bitstr] 39 40 41def putieeeint(r): 42 """ 43 Convert an IEEE 32-bit float to a 32-bit integer. 44 45 Parameters 46 ---------- 47 48 **`r`**: Float value. 49 50 Returns 51 ------- 52 53 Integer representation of an IEEE 32-bit float. 54 """ 55 ra = np.array([r],'f') 56 ia = np.empty(1,'i') 57 g2clib.rtoi_ieee(ra,ia) 58 return ia[0] 59 60 61def getieeeint(i): 62 """ 63 Convert a 32-bit integer to an IEEE 32-bit float. 64 65 Parameters 66 ---------- 67 68 **`i`**: Integer value. 69 70 Returns 71 ------- 72 73 IEEE 32-bit float. 74 """ 75 ia = np.array([i],'i') 76 ra = np.empty(1,'f') 77 g2clib.itor_ieee(ia,ra) 78 return ra[0] 79 80 81def getmd5str(a): 82 """ 83 Generate a MD5 hash string from input list 84 """ 85 import hashlib 86 assert isinstance(a,list) or isinstance(a,bytes) 87 return hashlib.md5(''.join([str(i) for i in a]).encode()).hexdigest() 88 89 90def getdate(year,month,day,hour,minute=None,second=None): 91 """ 92 Build an integer date from component input. 93 94 **`year`**: Year in 4-digit format. 95 96 **`month`**: Month in 2-digit format. 97 98 **`day`**: Day in 2-digit format. 99 100 **`hour`**: Hour in 2-digit format. 101 102 **`minute`**: Minute in 2-digit format. This argument is required if second is provided, otherwise 103 it is optional. 104 105 **`second`**: Second in 2-digit format [OPTIONAL]. 106 """ 107 year_exp = 6 108 month_exp = 4 109 day_exp = 2 110 hour_exp = 0 111 #if second is not None and minute is None: 112 # raise ValueError("Must provide minute argument if second argument is provided.") 113 #year_exp = 6 114 #month_exp = 4 115 #day_exp = 2 116 #hour_exp = 0 117 #minute_exp = -2 118 #second_exp = -4 119 #if minute is not None: 120 # assert minute >= 0 and minute <= 60 121 # year_exp += 2 122 # month_exp += 2 123 # day_exp += 2 124 # hour_exp += 2 125 # minute_exp += 2 126 # second_exp += 2 127 #if second is not None: 128 # assert second >= 0 and second <= 60 129 # year_exp += 2 130 # month_exp += 2 131 # day_exp += 2 132 # hour_exp += 2 133 # minute_exp += 2 134 # second_exp += 2 135 idate = (year*pow(10,year_exp))+(month*pow(10,month_exp))+\ 136 (day*pow(10,day_exp))+(hour*pow(10,hour_exp)) 137 #if minute is not None: 138 # idate += minute*pow(10,minute_exp) 139 #if second is not None: 140 # idate += second*pow(10,second_exp) 141 return idate 142 143 144def getleadtime(idsec,pdtn,pdt): 145 """ 146 Computes the lead time (in units of hours) from using information from 147 GRIB2 Identification Section (Section 1), Product Definition Template 148 Number, and Product Definition Template (Section 4). 149 150 Parameters 151 ---------- 152 153 **`idsec`**: seqeunce containing GRIB2 Identification Section (Section 1). 154 155 **`pdtn`**: GRIB2 Product Definition Template Number 156 157 **`idsec`**: seqeunce containing GRIB2 Product Definition Template (Section 4). 158 159 Returns 160 ------- 161 162 **`lt`**: Lead time in units of hours 163 """ 164 refdate = datetime.datetime(*idsec[5:11]) 165 if pdtn == 8: 166 enddate = datetime.datetime(*pdt[15:21]) 167 td = enddate - refdate 168 lt = (td).total_seconds()/3600.0 169 elif pdtn == 9: 170 enddate = datetime.datetime(*pdt[22:28]) 171 td = enddate - refdate 172 lt = (td).total_seconds()/3600.0 173 elif pdtn == 10: 174 enddate = datetime.datetime(*pdt[16:22]) 175 td = enddate - refdate 176 lt = (td).total_seconds()/3600.0 177 elif pdtn == 11: 178 enddate = datetime.datetime(*pdt[18:24]) 179 td = enddate - refdate 180 lt = (td).total_seconds()/3600.0 181 elif pdtn == 12: 182 enddate = datetime.datetime(*pdt[17:23]) 183 td = enddate - refdate 184 lt = (td).total_seconds()/3600.0 185 else: 186 lt = pdt[8]*(tables.get_value_from_table(pdt[7],'scale_time_hours')) 187 return int(lt) 188 189 190def getduration(pdtn,pdt): 191 """ 192 Computes the duration time (in units of hours) from using information from 193 Product Definition Template Number, and Product Definition Template (Section 4). 194 195 Parameters 196 ---------- 197 198 **`pdtn`**: GRIB2 Product Definition Template Number 199 200 **`pdt`**: sequence containing GRIB2 Product Definition Template (Section 4). 201 202 Returns 203 ------- 204 205 **`dur`**: Duration time in units of hours 206 """ 207 if pdtn == 8: 208 dur = pdt[26]*(tables.get_value_from_table(pdt[25],'scale_time_hours')) 209 elif pdtn == 9: 210 dur = pdt[33]*(tables.get_value_from_table(pdt[32],'scale_time_hours')) 211 elif pdtn == 10: 212 dur = pdt[27]*(tables.get_value_from_table(pdt[26],'scale_time_hours')) 213 elif pdtn == 11: 214 dur = pdt[29]*(tables.get_value_from_table(pdt[28],'scale_time_hours')) 215 elif pdtn == 12: 216 dur = pdt[28]*(tables.get_value_from_table(pdt[27],'scale_time_hours')) 217 else: 218 dur = 0 219 return int(dur) 220 221 222def decode_mdl_wx_strings(lus): 223 """ 224 Decode GRIB2 Local Use Section to obtain MDL Weather Strings. The 225 decode procedure is defined here: 226 227 https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml 228 229 Parameters 230 ---------- 231 232 **`lus`**: GRIB2 Local Use Section containing MDL weather strings. 233 234 Returns 235 ------- 236 237 **`list`**: List of weather strings. 238 """ 239 assert lus[0] == 1 240 # Unpack information related to the simple packing method 241 # the packed weather string data. 242 ngroups = struct.unpack('>h',lus[1:3])[0] 243 nvalues = struct.unpack('>i',lus[3:7])[0] 244 refvalue = struct.unpack('>i',lus[7:11])[0] 245 dsf = struct.unpack('>h',lus[11:13])[0] 246 nbits = lus[13] 247 datatype = lus[14] 248 if datatype == 0: # Floating point 249 refvalue = np.float32(getieeeint(refvalue)*10**-dsf) 250 elif datatype == 1: # Integer 251 refvalue = np.int32(getieeeint(refvalue)*10**-dsf) 252 #print("TEST:",ngroups,nvalues,refvalue,dsf,nbits,datatype) 253 # Store the "data" part of the packed weather strings as 254 # a binary string. 255 b = bin(int.from_bytes(lus[15:],byteorder='big')) 256 # Generated begin and end values. Note the offset begins at 2 257 # due to the format nature of b (binary string). 258 idxb = list(range(2,len(b),nbits))[0:nvalues-1] 259 idxe = list(range(2+nbits,len(b)+nbits,nbits))[0:nvalues-1] 260 # Iterate over the packed data, converting the nbits space to 261 # and integer, then convert integer to an ASCII character. 262 wxstring = '' 263 for ib,ie in zip(idxb,idxe): 264 wxstring += chr(int(b[ib:ie],2)+refvalue) 265 # Return string as list, split by null character. 266 return wxstring.split('\0') 267 268 269def decode_ndfd_wx_strings(lus): 270 """ 271 Decode GRIB2 Local Use Section to obtain NDFD Weather Strings. The 272 decode procedure is defined here: 273 274 https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml 275 276 NOTE: From testing, it seems how the process for packing Section 2 for NDFD 277 Weather grids is different than GMOS and thus the need for a different 278 method for decoding NDFD Wx vs. GMOS Wx. 279 280 Parameters 281 ---------- 282 283 **`lus`**: GRIB2 Local Use Section containing NDFD weather strings. 284 285 Returns 286 ------- 287 288 **`list`**: List of NDFD weather strings. 289 """ 290 assert lus[0] == 1 291 # Unpack information related to the simple packing method 292 # the packed weather string data. 293 ngroups = struct.unpack('>h',lus[1:3])[0] 294 nvalues = struct.unpack('>i',lus[3:7])[0] 295 refvalue = struct.unpack('>i',lus[7:11])[0] 296 dsf = struct.unpack('>h',lus[11:13])[0] 297 nbits = lus[13] 298 datatype = lus[14] 299 if datatype == 0: # Floating point 300 refvalue = np.float32(getieeeint(refvalue)*10**-dsf) 301 elif datatype == 1: # Integer 302 refvalue = np.int32(getieeeint(refvalue)*10**-dsf) 303 # Iterate over the data of section 2 in 4-byte (32-bit) 304 # words OR 2-byte word at the end. Each word is unpacked 305 # as an unsigned integer. Then convert the integer word 306 # to a binary string and fill to the appropriate bit 307 # size (16 or 32) and concatenate to b (binary string). 308 b = '' 309 for i in range(15,len(lus),4): 310 if len(lus)-i < 4: 311 iword = struct.unpack('>H',lus[i:i+2])[0] 312 b += bin(iword).split('b')[1].zfill(16) 313 else: 314 iword = struct.unpack('>I',lus[i:i+4])[0] 315 b += bin(iword).split('b')[1].zfill(32) 316 # Iterate over the binary string (b). For each nbits 317 # chunk, convert to an integer, including the refvalue, 318 # and then convert the int to an ASCII character, then 319 # concatenate to wxstring. 320 wxstring = '' 321 for i in range(0,len(b),nbits): 322 wxstring += chr(int(b[i:i+nbits],2)+refvalue) 323 # Return string as list, split by null character. 324 return list(filter(None,wxstring.split('\0'))) 325 326 327def get_wgrib2_prob_string(probtype,sfacl,svall,sfacu,svalu): 328 """ 329 Return a wgrib2-formatted string explaining probabilistic 330 threshold informaiton. Logic from wgrib2 source, [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c), 331 is replicated here. 332 333 Parameters 334 ---------- 335 336 **`probtype`**: `int` type of probability (Code Table 4.9). 337 338 **`sfacl`**: `int` scale factor of lower limit. 339 340 **`svall`**: `int` scaled value of lower limit. 341 342 **`sfacu`**: `int` scale factor of upper limit. 343 344 **`svalu`**: `int` scaled value of upper limit. 345 346 Returns 347 ------- 348 349 **`str`**: wgrib2-formatted string of probability threshold. 350 """ 351 probstr = '' 352 lower = svall/(10**sfacl) 353 upper = svalu/(10**sfacu) 354 if probtype == 0: 355 probstr = 'prob <%g' % (lower) 356 elif probtype == 1: 357 probstr = 'prob >%g' % (upper) 358 elif probtype == 2: 359 if lower == upper: 360 probstr = 'prob =%g' % (lower) 361 else: 362 probstr = 'prob >=%g <%g' % (lower,upper) 363 elif probtype == 3: 364 probstr = 'prob >%g' % (lower) 365 elif probtype == 4: 366 probstr = 'prob <%g' % (upper) 367 return probstr
14def int2bin(i,nbits=8,output=str): 15 """ 16 Convert integer to binary string or list 17 18 Parameters 19 ---------- 20 21 **`i`**: Integer value to convert to binary representation. 22 23 **`nbits`**: Number of bits to return. Valid values are 8 [DEFAULT], 16, 24 32, and 64. 25 26 **`output`**: Return data as `str` [DEFAULT] or `list` (list of ints). 27 28 Returns 29 ------- 30 31 `str` or `list` (list of ints) of binary representation of the integer value. 32 """ 33 i = int(i) if not isinstance(i,int) else i 34 assert nbits in [8,16,32,64] 35 bitstr = "{0:b}".format(i).zfill(nbits) 36 if output is str: 37 return bitstr 38 elif output is list: 39 return [int(b) for b in bitstr]
Convert integer to binary string or list
Parameters
i
: Integer value to convert to binary representation.
nbits
: Number of bits to return. Valid values are 8 [DEFAULT], 16,
32, and 64.
output
: Return data as str
[DEFAULT] or list
(list of ints).
Returns
str
or list
(list of ints) of binary representation of the integer value.
42def putieeeint(r): 43 """ 44 Convert an IEEE 32-bit float to a 32-bit integer. 45 46 Parameters 47 ---------- 48 49 **`r`**: Float value. 50 51 Returns 52 ------- 53 54 Integer representation of an IEEE 32-bit float. 55 """ 56 ra = np.array([r],'f') 57 ia = np.empty(1,'i') 58 g2clib.rtoi_ieee(ra,ia) 59 return ia[0]
Convert an IEEE 32-bit float to a 32-bit integer.
Parameters
r
: Float value.
Returns
Integer representation of an IEEE 32-bit float.
62def getieeeint(i): 63 """ 64 Convert a 32-bit integer to an IEEE 32-bit float. 65 66 Parameters 67 ---------- 68 69 **`i`**: Integer value. 70 71 Returns 72 ------- 73 74 IEEE 32-bit float. 75 """ 76 ia = np.array([i],'i') 77 ra = np.empty(1,'f') 78 g2clib.itor_ieee(ia,ra) 79 return ra[0]
Convert a 32-bit integer to an IEEE 32-bit float.
Parameters
i
: Integer value.
Returns
IEEE 32-bit float.
82def getmd5str(a): 83 """ 84 Generate a MD5 hash string from input list 85 """ 86 import hashlib 87 assert isinstance(a,list) or isinstance(a,bytes) 88 return hashlib.md5(''.join([str(i) for i in a]).encode()).hexdigest()
Generate a MD5 hash string from input list
91def getdate(year,month,day,hour,minute=None,second=None): 92 """ 93 Build an integer date from component input. 94 95 **`year`**: Year in 4-digit format. 96 97 **`month`**: Month in 2-digit format. 98 99 **`day`**: Day in 2-digit format. 100 101 **`hour`**: Hour in 2-digit format. 102 103 **`minute`**: Minute in 2-digit format. This argument is required if second is provided, otherwise 104 it is optional. 105 106 **`second`**: Second in 2-digit format [OPTIONAL]. 107 """ 108 year_exp = 6 109 month_exp = 4 110 day_exp = 2 111 hour_exp = 0 112 #if second is not None and minute is None: 113 # raise ValueError("Must provide minute argument if second argument is provided.") 114 #year_exp = 6 115 #month_exp = 4 116 #day_exp = 2 117 #hour_exp = 0 118 #minute_exp = -2 119 #second_exp = -4 120 #if minute is not None: 121 # assert minute >= 0 and minute <= 60 122 # year_exp += 2 123 # month_exp += 2 124 # day_exp += 2 125 # hour_exp += 2 126 # minute_exp += 2 127 # second_exp += 2 128 #if second is not None: 129 # assert second >= 0 and second <= 60 130 # year_exp += 2 131 # month_exp += 2 132 # day_exp += 2 133 # hour_exp += 2 134 # minute_exp += 2 135 # second_exp += 2 136 idate = (year*pow(10,year_exp))+(month*pow(10,month_exp))+\ 137 (day*pow(10,day_exp))+(hour*pow(10,hour_exp)) 138 #if minute is not None: 139 # idate += minute*pow(10,minute_exp) 140 #if second is not None: 141 # idate += second*pow(10,second_exp) 142 return idate
Build an integer date from component input.
year
: Year in 4-digit format.
month
: Month in 2-digit format.
day
: Day in 2-digit format.
hour
: Hour in 2-digit format.
minute
: Minute in 2-digit format. This argument is required if second is provided, otherwise
it is optional.
second
: Second in 2-digit format [OPTIONAL].
145def getleadtime(idsec,pdtn,pdt): 146 """ 147 Computes the lead time (in units of hours) from using information from 148 GRIB2 Identification Section (Section 1), Product Definition Template 149 Number, and Product Definition Template (Section 4). 150 151 Parameters 152 ---------- 153 154 **`idsec`**: seqeunce containing GRIB2 Identification Section (Section 1). 155 156 **`pdtn`**: GRIB2 Product Definition Template Number 157 158 **`idsec`**: seqeunce containing GRIB2 Product Definition Template (Section 4). 159 160 Returns 161 ------- 162 163 **`lt`**: Lead time in units of hours 164 """ 165 refdate = datetime.datetime(*idsec[5:11]) 166 if pdtn == 8: 167 enddate = datetime.datetime(*pdt[15:21]) 168 td = enddate - refdate 169 lt = (td).total_seconds()/3600.0 170 elif pdtn == 9: 171 enddate = datetime.datetime(*pdt[22:28]) 172 td = enddate - refdate 173 lt = (td).total_seconds()/3600.0 174 elif pdtn == 10: 175 enddate = datetime.datetime(*pdt[16:22]) 176 td = enddate - refdate 177 lt = (td).total_seconds()/3600.0 178 elif pdtn == 11: 179 enddate = datetime.datetime(*pdt[18:24]) 180 td = enddate - refdate 181 lt = (td).total_seconds()/3600.0 182 elif pdtn == 12: 183 enddate = datetime.datetime(*pdt[17:23]) 184 td = enddate - refdate 185 lt = (td).total_seconds()/3600.0 186 else: 187 lt = pdt[8]*(tables.get_value_from_table(pdt[7],'scale_time_hours')) 188 return int(lt)
Computes the lead time (in units of hours) from using information from GRIB2 Identification Section (Section 1), Product Definition Template Number, and Product Definition Template (Section 4).
Parameters
idsec
: seqeunce containing GRIB2 Identification Section (Section 1).
pdtn
: GRIB2 Product Definition Template Number
idsec
: seqeunce containing GRIB2 Product Definition Template (Section 4).
Returns
lt
: Lead time in units of hours
191def getduration(pdtn,pdt): 192 """ 193 Computes the duration time (in units of hours) from using information from 194 Product Definition Template Number, and Product Definition Template (Section 4). 195 196 Parameters 197 ---------- 198 199 **`pdtn`**: GRIB2 Product Definition Template Number 200 201 **`pdt`**: sequence containing GRIB2 Product Definition Template (Section 4). 202 203 Returns 204 ------- 205 206 **`dur`**: Duration time in units of hours 207 """ 208 if pdtn == 8: 209 dur = pdt[26]*(tables.get_value_from_table(pdt[25],'scale_time_hours')) 210 elif pdtn == 9: 211 dur = pdt[33]*(tables.get_value_from_table(pdt[32],'scale_time_hours')) 212 elif pdtn == 10: 213 dur = pdt[27]*(tables.get_value_from_table(pdt[26],'scale_time_hours')) 214 elif pdtn == 11: 215 dur = pdt[29]*(tables.get_value_from_table(pdt[28],'scale_time_hours')) 216 elif pdtn == 12: 217 dur = pdt[28]*(tables.get_value_from_table(pdt[27],'scale_time_hours')) 218 else: 219 dur = 0 220 return int(dur)
Computes the duration time (in units of hours) from using information from Product Definition Template Number, and Product Definition Template (Section 4).
Parameters
pdtn
: GRIB2 Product Definition Template Number
pdt
: sequence containing GRIB2 Product Definition Template (Section 4).
Returns
dur
: Duration time in units of hours
223def decode_mdl_wx_strings(lus): 224 """ 225 Decode GRIB2 Local Use Section to obtain MDL Weather Strings. The 226 decode procedure is defined here: 227 228 https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml 229 230 Parameters 231 ---------- 232 233 **`lus`**: GRIB2 Local Use Section containing MDL weather strings. 234 235 Returns 236 ------- 237 238 **`list`**: List of weather strings. 239 """ 240 assert lus[0] == 1 241 # Unpack information related to the simple packing method 242 # the packed weather string data. 243 ngroups = struct.unpack('>h',lus[1:3])[0] 244 nvalues = struct.unpack('>i',lus[3:7])[0] 245 refvalue = struct.unpack('>i',lus[7:11])[0] 246 dsf = struct.unpack('>h',lus[11:13])[0] 247 nbits = lus[13] 248 datatype = lus[14] 249 if datatype == 0: # Floating point 250 refvalue = np.float32(getieeeint(refvalue)*10**-dsf) 251 elif datatype == 1: # Integer 252 refvalue = np.int32(getieeeint(refvalue)*10**-dsf) 253 #print("TEST:",ngroups,nvalues,refvalue,dsf,nbits,datatype) 254 # Store the "data" part of the packed weather strings as 255 # a binary string. 256 b = bin(int.from_bytes(lus[15:],byteorder='big')) 257 # Generated begin and end values. Note the offset begins at 2 258 # due to the format nature of b (binary string). 259 idxb = list(range(2,len(b),nbits))[0:nvalues-1] 260 idxe = list(range(2+nbits,len(b)+nbits,nbits))[0:nvalues-1] 261 # Iterate over the packed data, converting the nbits space to 262 # and integer, then convert integer to an ASCII character. 263 wxstring = '' 264 for ib,ie in zip(idxb,idxe): 265 wxstring += chr(int(b[ib:ie],2)+refvalue) 266 # Return string as list, split by null character. 267 return wxstring.split('\0')
Decode GRIB2 Local Use Section to obtain MDL Weather Strings. The decode procedure is defined here:
https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml
Parameters
lus
: GRIB2 Local Use Section containing MDL weather strings.
Returns
list
: List of weather strings.
270def decode_ndfd_wx_strings(lus): 271 """ 272 Decode GRIB2 Local Use Section to obtain NDFD Weather Strings. The 273 decode procedure is defined here: 274 275 https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml 276 277 NOTE: From testing, it seems how the process for packing Section 2 for NDFD 278 Weather grids is different than GMOS and thus the need for a different 279 method for decoding NDFD Wx vs. GMOS Wx. 280 281 Parameters 282 ---------- 283 284 **`lus`**: GRIB2 Local Use Section containing NDFD weather strings. 285 286 Returns 287 ------- 288 289 **`list`**: List of NDFD weather strings. 290 """ 291 assert lus[0] == 1 292 # Unpack information related to the simple packing method 293 # the packed weather string data. 294 ngroups = struct.unpack('>h',lus[1:3])[0] 295 nvalues = struct.unpack('>i',lus[3:7])[0] 296 refvalue = struct.unpack('>i',lus[7:11])[0] 297 dsf = struct.unpack('>h',lus[11:13])[0] 298 nbits = lus[13] 299 datatype = lus[14] 300 if datatype == 0: # Floating point 301 refvalue = np.float32(getieeeint(refvalue)*10**-dsf) 302 elif datatype == 1: # Integer 303 refvalue = np.int32(getieeeint(refvalue)*10**-dsf) 304 # Iterate over the data of section 2 in 4-byte (32-bit) 305 # words OR 2-byte word at the end. Each word is unpacked 306 # as an unsigned integer. Then convert the integer word 307 # to a binary string and fill to the appropriate bit 308 # size (16 or 32) and concatenate to b (binary string). 309 b = '' 310 for i in range(15,len(lus),4): 311 if len(lus)-i < 4: 312 iword = struct.unpack('>H',lus[i:i+2])[0] 313 b += bin(iword).split('b')[1].zfill(16) 314 else: 315 iword = struct.unpack('>I',lus[i:i+4])[0] 316 b += bin(iword).split('b')[1].zfill(32) 317 # Iterate over the binary string (b). For each nbits 318 # chunk, convert to an integer, including the refvalue, 319 # and then convert the int to an ASCII character, then 320 # concatenate to wxstring. 321 wxstring = '' 322 for i in range(0,len(b),nbits): 323 wxstring += chr(int(b[i:i+nbits],2)+refvalue) 324 # Return string as list, split by null character. 325 return list(filter(None,wxstring.split('\0')))
Decode GRIB2 Local Use Section to obtain NDFD Weather Strings. The decode procedure is defined here:
https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_mdl_temp2-1.shtml
NOTE: From testing, it seems how the process for packing Section 2 for NDFD Weather grids is different than GMOS and thus the need for a different method for decoding NDFD Wx vs. GMOS Wx.
Parameters
lus
: GRIB2 Local Use Section containing NDFD weather strings.
Returns
list
: List of NDFD weather strings.
328def get_wgrib2_prob_string(probtype,sfacl,svall,sfacu,svalu): 329 """ 330 Return a wgrib2-formatted string explaining probabilistic 331 threshold informaiton. Logic from wgrib2 source, [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c), 332 is replicated here. 333 334 Parameters 335 ---------- 336 337 **`probtype`**: `int` type of probability (Code Table 4.9). 338 339 **`sfacl`**: `int` scale factor of lower limit. 340 341 **`svall`**: `int` scaled value of lower limit. 342 343 **`sfacu`**: `int` scale factor of upper limit. 344 345 **`svalu`**: `int` scaled value of upper limit. 346 347 Returns 348 ------- 349 350 **`str`**: wgrib2-formatted string of probability threshold. 351 """ 352 probstr = '' 353 lower = svall/(10**sfacl) 354 upper = svalu/(10**sfacu) 355 if probtype == 0: 356 probstr = 'prob <%g' % (lower) 357 elif probtype == 1: 358 probstr = 'prob >%g' % (upper) 359 elif probtype == 2: 360 if lower == upper: 361 probstr = 'prob =%g' % (lower) 362 else: 363 probstr = 'prob >=%g <%g' % (lower,upper) 364 elif probtype == 3: 365 probstr = 'prob >%g' % (lower) 366 elif probtype == 4: 367 probstr = 'prob <%g' % (upper) 368 return probstr
Return a wgrib2-formatted string explaining probabilistic threshold informaiton. Logic from wgrib2 source, Prob.c, is replicated here.
Parameters
probtype
: int
type of probability (Code Table 4.9).
sfacl
: int
scale factor of lower limit.
svall
: int
scaled value of lower limit.
sfacu
: int
scale factor of upper limit.
svalu
: int
scaled value of upper limit.
Returns
str
: wgrib2-formatted string of probability threshold.