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 19 **`i`**: Integer value to convert to binary representation. 20 21 **`nbits`**: Number of bits to return. Valid values are 8 [DEFAULT], 16, 22 32, and 64. 23 24 **`output`**: Return data as `str` [DEFAULT] or `list` (list of ints). 25 26 Returns 27 ------- 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 47 **`f`**: Float value. 48 49 Returns 50 ------- 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) 56 57 58def ieee_int_to_float(i): 59 """ 60 Convert a 32-bit integer to an IEEE 32-bit float. 61 62 Parameters 63 ---------- 64 65 **`i`**: Integer value. 66 67 Returns 68 ------- 69 70 Numpy float32 71 """ 72 f = struct.unpack('>f',struct.pack('>i',np.int32(i)))[0] 73 return np.float32(f) 74 75 76def get_leadtime(idsec,pdtn,pdt): 77 """ 78 Computes lead time as a datetime.timedelta object using information from 79 GRIB2 Identification Section (Section 1), Product Definition Template 80 Number, and Product Definition Template (Section 4). 81 82 Parameters 83 ---------- 84 85 **`idsec`**: seqeunce containing GRIB2 Identification Section (Section 1). 86 87 **`pdtn`**: GRIB2 Product Definition Template Number 88 89 **`idsec`**: seqeunce containing GRIB2 Product Definition Template (Section 4). 90 91 Returns 92 ------- 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'))) 105 106 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 115 **`pdtn`**: GRIB2 Product Definition Template Number 116 117 **`pdt`**: sequence containing GRIB2 Product Definition Template (Section 4). 118 119 Returns 120 ------- 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 129 130 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 139 **`lus`**: GRIB2 Local Use Section containing NDFD weather strings. 140 141 Returns 142 ------- 143 144 **`dict`**: Dictionary of NDFD/MDL weather strings. Keys are an integer 145 value that represent the sequential order of the key in the packed loca 146 use section and the value is the weather key. 147 """ 148 assert lus[0] == 1 149 # Unpack information related to the simple packing method 150 # the packed weather string data. 151 ngroups = struct.unpack('>H',lus[1:3])[0] 152 nvalues = struct.unpack('>i',lus[3:7])[0] 153 refvalue = struct.unpack('>i',lus[7:11])[0] 154 dsf = struct.unpack('>h',lus[11:13])[0] 155 nbits = lus[13] 156 datatype = lus[14] 157 if datatype == 0: # Floating point 158 refvalue = np.float32(ieee_int_to_float(refvalue)*10**-dsf) 159 elif datatype == 1: # Integer 160 refvalue = np.int32(ieee_int_to_float(refvalue)*10**-dsf) 161 # Upack each byte starting at byte 15 to end of the local use 162 # section, create a binary string and append to the full 163 # binary string. 164 b = '' 165 for i in range(15,len(lus)): 166 iword = struct.unpack('>B',lus[i:i+1])[0] 167 b += bin(iword).split('b')[1].zfill(8) 168 # Iterate over the binary string (b). For each nbits 169 # chunk, convert to an integer, including the refvalue, 170 # and then convert the int to an ASCII character, then 171 # concatenate to wxstring. 172 wxstring = '' 173 for i in range(0,len(b),nbits): 174 wxstring += chr(int(b[i:i+nbits],2)+refvalue) 175 # Return string as list, split by null character. 176 #return list(filter(None,wxstring.split('\0'))) 177 return {n:k for n,k in enumerate(list(filter(None,wxstring.split('\0'))))} 178 179 180def get_wgrib2_prob_string(probtype,sfacl,svall,sfacu,svalu): 181 """ 182 Return a wgrib2-formatted string explaining probabilistic 183 threshold informaiton. Logic from wgrib2 source, [Prob.c](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c), 184 is replicated here. 185 186 Parameters 187 ---------- 188 189 **`probtype`**: `int` type of probability (Code Table 4.9). 190 191 **`sfacl`**: `int` scale factor of lower limit. 192 193 **`svall`**: `int` scaled value of lower limit. 194 195 **`sfacu`**: `int` scale factor of upper limit. 196 197 **`svalu`**: `int` scaled value of upper limit. 198 199 Returns 200 ------- 201 202 **`str`**: wgrib2-formatted string of probability threshold. 203 """ 204 probstr = '' 205 if sfacl == -127: sfacl = 0 206 if sfacu == -127: sfacu = 0 207 lower = svall/(10**sfacl) 208 upper = svalu/(10**sfacu) 209 if probtype == 0: 210 probstr = 'prob <%g' % (lower) 211 elif probtype == 1: 212 probstr = 'prob >%g' % (upper) 213 elif probtype == 2: 214 if lower == upper: 215 probstr = 'prob =%g' % (lower) 216 else: 217 probstr = 'prob >=%g <%g' % (lower,upper) 218 elif probtype == 3: 219 probstr = 'prob >%g' % (lower) 220 elif probtype == 4: 221 probstr = 'prob <%g' % (upper) 222 else: 223 probstr = '' 224 return probstr
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]
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.
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)
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.
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)
Convert a 32-bit integer to an IEEE 32-bit float.
Parameters
i
: Integer value.
Returns
Numpy float32
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')))
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.
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
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.
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'))))}
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.
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
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.