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