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