Module pywgrib2_s
Expand source code
# pywgrib2 5/2020 public domain Wesley Ebisuzaki
#
# provides a simple python interface for reading/writing grib for python based
# on the fortran wgrib2api
#
# requirements: python 3.6, numpy (common but not standard),
# ctypes and os.path from the standard library
from ctypes import *
import os
import numpy
# load gomp (gnu openmp), gfortran (gnu: IPOLATES, ftp_api), mvec (debian) and
# wgrib2 libraries, based on your system, run lld wgrib2/wgrib2
# gomp = CDLL("/usr/lib/x86_64-linux-gnu/libgomp.so.1", mode=RTLD_GLOBAL)
# print("loaded gomp library")
# gfortran = CDLL("/lib/x86_64-linux-gnu/libgfortran.so.5", mode=RTLD_GLOBAL)
# print("loaded gfortran library")
# libmvec is needed for ubuntu
# mvec = CDLL("/lib/x86_64-linux-gnu/libmvec.so.1", mode=RTLD_GLOBAL)
# print("loaded mvec library")
# libwgrib2.so must be in same dir as this file, can be link to file
dir=os.path.dirname(__file__)
lib=os.path.join(dir,'libwgrib2.so')
try:
my_wgrib2=CDLL(lib)
except Exception as e:
print("*** Problem ",e)
print("*** Will load wgrib2 library in RTLD_LAZY mode")
my_wgrib2=CDLL(lib, mode=os.RTLD_LAZY)
print("finished loading libraries")
# default global variables
nx = 0
ny = 0
ndata = 0
nmatch = 0
msgno = 0
submsgno = 0
data = None
lat = None
lon = None
matched = []
grid_defn = []
use_numpy_nan = True
# UNDEFINED values from wgrib2.h
UNDEFINED = 9.999e20
UNDEFINED_LOW = 9.9989e20
UNDEFINED_HIGH = 9.9991e20
debug = False
__version__='0.0.7'
print("pywgrib2_s v"+__version__+" 7-30-2020 w. ebisuzaki")
def wgrib2(arg):
#
# call wgrib2
# ex. pywgrib2.wgrib2(["in.grb","-inv","@mem.0"])
#
# uses C calling convention: 1st arg is name of program
#
global debug
arg_length = len(arg) + 1
select_type = (c_char_p * arg_length)
select = select_type()
item = "pywgrib2"
select[0] = item.encode('utf-8')
for key, item in enumerate(arg):
select[key + 1] = item.encode('utf-8')
if debug: print("wgrib2 args: ", arg)
ierr = my_wgrib2.wgrib2(arg_length, select)
if debug: print("wgrib2 err=", ierr)
return ierr
def mk_inv(grb_file, inv_file, Use_ncep_table=False, Short=False):
#
# make inventory by -Match_inv or -S
#
global debug
cmds = [grb_file, "-rewind_init", grb_file, "-inv", inv_file]
if Use_ncep_table:
cmds.append('-set')
cmds.append('center')
cmds.append('7')
if Short == False:
cmds.append('-Match_inv')
else:
cmds.append('-S')
ierr = wgrib2(cmds)
if debug: print("mk_inv: ierr=", ierr)
return ierr
def close(file):
#
# close file, does a flush and frees resources
#
global debug
# create byte object
a = file.encode('utf-8')
ierr = my_wgrib2.wgrib2_free_file(a)
if debug: print("close error=", ierr)
return ierr
# inq
#
# data access options
# 1) select != '' .. N(.m):byte_location only N is not used
# a field is selected
# 2) inv, optional match terms
# 3) inv == FALSE, optional match terms
#
# register and memory files used by inq()
#
# @mem:10 - used by ftp_api_fn0
# @mem:11 - used by matched inv
# @mem:12 - used by grid metadata
# reg_13 - data (data point values)
# reg_14 - lon
# reg_15 - lat
def inq(gfile,
*matches,
inv='',
select='',
Data=False,
Latlon=False,
Regex=False,
grib='',
Append_grib=False,
bin='',
Append_bin=False,
Matched=False,
Grid_defn=False,
sequential=-1,
var='',
time0=None,
ftime='',
level=''):
# based on grb2_inq() from ftn wgrib2api
global nx, ny, ndata, nmatch, msgno, submsgno, matched
global data, lat, lon, grid_defn
global use_numpy_nan, UNDEFINED_LOW, UNDEFINED_HIGH, debug
data = None
lat = None
lon = None
grid_defn = []
matched = []
# how to match
if inv == '': # no inventory
if Regex == False:
match_option = '-match_fs'
else:
match_option = '-match'
else: # use inventory
if Regex == False:
match_option = '-fgrep'
else:
match_option = '-egrep'
if select != '': # selected field, use -d, sequential not valid
if Matched != False:
cmds = [
gfile, "-d", select, "-last", "@mem:11", "-print_out", ":",
"@mem:11", "-S", "-last", "@mem:11", "-nl_out", "@mem:11",
"-ftn_api_fn0", "-last0", "@mem:10", "-inv", "/dev/null"
]
else:
cmds = [
gfile, "-d", select, "-ftn_api_fn0", "-last0", "@mem:10",
"-inv", "/dev/null"
]
elif inv != '': # use inventory
if Matched != False:
cmds = [
gfile, "-i_file", inv, "-last", "@mem:11", "-ftn_api_fn0",
"-last0", "@mem:10", "-inv", "/dev/null", "-print_out", ":",
"@mem:11", "-S", "-last", "@mem:11", "-nl_out", "@mem:11"
]
else:
cmds = [
gfile, "-i_file", inv, "-ftn_api_fn0", "-last0", "@mem:10",
"-inv", "/dev/null"
]
if sequential <= 0:
cmds.append('-rewind_init')
cmds.append(inv)
if sequential >= 0:
cmds.append('-end')
for m in matches:
cmds.append(match_option)
cmds.append(m)
else: # no inventory
if Matched != False:
cmds = [
gfile, "-last", "@mem:11", "-ftn_api_fn0", "-last0", "@mem:10",
"-inv", "/dev/null", "-print_out", ":",
"@mem:11", "-S", "-last", "@mem:11", "-nl_out", "@mem:11"
]
else:
cmds = [
gfile, "-ftn_api_fn0", "-last0", "@mem:10", "-inv", "/dev/null"
]
if sequential <= 0:
cmds.append('-rewind_init')
cmds.append(gfile)
if sequential >= 0:
cmds.append('-end')
for m in matches:
cmds.append(match_option)
cmds.append(m)
if var != '':
cmds.append(match_option)
cmds.append(':' + var + ':')
if time0 is not None:
if time0 < 0:
return -1
cmds.append(match_option)
if time0 <= 9999999999:
cmds.append(':d=' + str(time0) + ':')
else:
cmds.append(':D=' + str(time0) + ':')
if ftime != '':
cmds.append(match_option)
cmds.append(':' + ftime + ':')
if level != '':
cmds.append(match_option)
cmds.append(':' + level + ':')
if grib != '':
if Append_grib != False:
cmds.append("-append")
cmds.append("-grib")
cmds.append(grib)
if Append_grib != False:
cmds.append("-no_append")
if bin != '':
if Append_bin != False:
cmds.append("-append")
cmds.append("-no_header")
cmds.append("-bin")
cmds.append(bin)
if Append_bin != False:
cmds.append("-no_append")
if Data != False:
cmds.append("-rpn")
cmds.append("sto_13")
if Latlon != False:
cmds.append("-rpn")
cmds.append("rcl_lon:sto_14:rcl_lat:sto_15")
if Grid_defn != False:
cmds.append("-one_line")
cmds.append("-grid")
cmds.append("-last")
cmds.append("@mem:12")
cmds.append("-nl_out")
cmds.append("@mem:12")
if debug: print('wgrib2 args=', cmds)
ierr = wgrib2(cmds)
if ierr > 0:
if debug: print("wgrib2 failed ierr=", ierr)
nmatch = -1
return -1
if mem_size(10) == 0:
if debug: print("no match")
nmatch = 0
return 0
string = get_str_mem(10)
x = string.split()
nmatch = int(x[0])
ndata = int(x[1])
nx = int(x[2])
ny = int(x[3])
msgno = int(x[4])
submsgno = int(x[5])
if (nmatch == 0):
if debug: print("inq found no matches, program error")
return 0
# for weird grids nx=-1/0 ny=-1/0
if (nx * ny != ndata):
nx = ndata
ny = 1
if Grid_defn != False:
size = my_wgrib2.wgrib2_get_mem_buffer_size(12)
string = create_string_buffer(size)
ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, 12)
if debug: print("get_str_mem 12 ierr=", ierr)
if (ierr == 0):
grid_defn = string.value.decode("utf-8").rstrip().split('\n')
# get data, lat/lon
if (Data != False or Latlon != False):
array_type = (c_float * ndata)
array = array_type()
if (Data != False):
ierr = my_wgrib2.wgrib2_get_reg_data(byref(array), ndata, 13)
if (ierr == 0):
data = numpy.reshape(numpy.array(array), (nx, ny), order='F')
if use_numpy_nan:
data[numpy.logical_and((data > UNDEFINED_LOW), (data < UNDEFINED_HIGH))] = numpy.nan
if (Latlon != False):
ierr = my_wgrib2.wgrib2_get_reg_data(byref(array), ndata, 14)
if (ierr == 0):
lon = numpy.reshape(numpy.array(array), (nx, ny), order='F')
if use_numpy_nan:
lon[numpy.logical_and((lon > UNDEFINED_LOW), (lon < UNDEFINED_HIGH))] = numpy.nan
ierr = my_wgrib2.wgrib2_get_reg_data(byref(array), ndata, 15)
if (ierr == 0):
lat = numpy.reshape(numpy.array(array), (nx, ny), order='F')
if use_numpy_nan:
lat[numpy.logical_and((lat > UNDEFINED_LOW), (lat < UNDEFINED_HIGH))] = numpy.nan
if Matched != False:
size = my_wgrib2.wgrib2_get_mem_buffer_size(11)
string = create_string_buffer(size)
ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, 11)
if debug: print("get_str_mem ierr=", ierr)
if (ierr == 0):
matched = string.value.decode("utf-8").rstrip().split('\n')
if debug:
print("inq nmatch=", nmatch)
print("ndata=", ndata, nx, ny)
print("msg=", msgno, submsgno)
print("has_data=", data is not None)
return nmatch
#
# write grib message
# returns string of metadata (-S)
# '' for error
#
def write(gfile,
template,
msgno,
new_data=None,
Append=False,
var='',
lev='',
time0=None,
ftime='',
packing='',
d_scale=None,
b_scale=None,
encode_bits=None,
metadata='',):
#
# write grib message (record)
#
global use_numpy_nan, UNDEFINED, debug
# if you only change metadata, no need to pack grid point data
pack = False
cmds = [
template, "-rewind_init", template, "-d",
str(msgno), "-inv", "@mem:11"
]
# metadata is first source, var, lev are applied afterwards
if metadata != '':
cmds.append("-set_metadata_str")
cmds.append(metadata)
if time0 is not None:
cmds.append("-set_date")
cmds.append(str(time0))
if var != '':
cmds.append("-set_var")
cmds.append(var)
if lev != '':
cmds.append("-set_lev")
cmds.append(lev)
if ftime != '':
cmds.append("-set_ftime")
cmds.append(ftime)
if packing != '':
cmds.append("-set_grib_type")
cmds.append(packing)
pack = True
# set grid point data
# -rpn will clear scaling parameters, so set grid point data first
if new_data is not None:
asize = new_data.size
a = new_data.astype(dtype=numpy.float32).reshape((asize),order='F')
if use_numpy_nan:
a[numpy.isnan(a)] = UNDEFINED
a_p = a.ctypes.data_as(c_void_p)
ierr = my_wgrib2.wgrib2_set_reg(a_p, asize, 10)
cmds.append("-rpn")
cmds.append("rcl_10")
pack = True
use_d_scale = d_scale is not None
use_b_scale = b_scale is not None
new_d_scale = 0 if use_d_scale else d_scale
new_b_scale = 0 if use_b_scale else b_scale
if use_d_scale or use_b_scale:
cmds.append("-set_grib_max_bits")
cmds.append("24")
cmds.append("-set_scaling")
cmds.append(str(d_scale))
cmds.append(str(b_scale))
pack = True
if encode_bits is not None:
cmds.append("-set_grib_max_bits")
cmds.append("24")
cmds.append("-set_bin_prec")
cmds.append(str(encode_bits))
pack = True
# Write out grib message
if Append != False:
cmds.append("-append")
if pack == False:
cmds.append("-grib")
else:
cmds.append("-grib_out")
cmds.append(gfile)
cmds.append("-S")
#
err = wgrib2(cmds)
if debug: print("write: ierr=", ierr)
if err != 0:
return None
size = my_wgrib2.wgrib2_get_mem_buffer_size(11)
string = create_string_buffer(size)
err = my_wgrib2.wgrib2_get_mem_buffer(string, size, 11)
if debug: print("get_str_mem ierr=", ierr)
if (err != 0):
return None
else:
return string.value.decode("utf-8").rstrip()
def read_inv(file):
#
# read inventory from memory or regular file
# returns the inventory as a list
#
global debug
if file[0:5] == '@mem:':
i = int(file[5:])
a = get_str_mem(i)
else:
close(file)
f = open(file, 'r')
a = f.read()
f.close()
if a == '':
return []
s = a.rstrip().split('\n')
return s
#
# get the version of wgrib2 and configuration functions
#
def wgrib2_version():
ierr = wgrib2(['-inv', '@mem:10','-version'])
size = my_wgrib2.wgrib2_get_mem_buffer_size(10)
string = create_string_buffer(size)
ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, 10)
s = string.value.decode("utf-8")
return s
def wgrib2_config():
ierr = wgrib2(['-inv', '@mem:10','-config'])
size = my_wgrib2.wgrib2_get_mem_buffer_size(10)
string = create_string_buffer(size)
ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, 10)
s = string.value.decode("utf-8")
s = s.rstrip().split('\n')
return s
#
# These are low level api functions
#
def mem_size(arg):
#
# return size of @mem:arg
#
global debug
i = c_int(arg)
size = my_wgrib2.wgrib2_get_mem_buffer_size(i)
if debug: print("mem_size=", size)
return size
def get_str_mem(arg):
#
# return a string of contents of @mem:arg
#
global debug
i = c_int(arg)
size = my_wgrib2.wgrib2_get_mem_buffer_size(i)
string = create_string_buffer(size)
ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, i)
if debug: print("get_str_mem ierr=", ierr)
s = string.value.decode("utf-8")
return s
def get_bytes_mem(arg):
#
# return bytes with contents of @mem:arg
#
global debug
i = c_int(arg)
size = my_wgrib2.wgrib2_get_mem_buffer_size(i)
if debug: print("get_bytes_mem: size=",size)
array = create_string_buffer(size)
ierr = my_wgrib2.wgrib2_get_mem_buffer(array, size, i)
if debug: print("get_byte_mem ierr=", ierr)
return array
def get_flt_mem(mem_no):
# return contents of mem file as numpy array (vector)
global debug
i = c_int(mem_no)
size = my_wgrib2.wgrib2_get_mem_buffer_size(i)
if (size % 4) != 0:
if debug:
print("*** ERROR: get_flt_mem, not float @mem",mem_no)
return None
size_flt = int(size / 4)
array_type = (c_float * size_flt)
array = array_type()
ierr = my_wgrib2.wgrib2_get_mem_buffer(byref(array), size, i)
if ierr != 0:
if debug:
print("*** ERROR: get_flt_mem, could not read @mem",mem_no)
return None
data = numpy.array(array)
if use_numpy_nan:
data[numpy.logical_and((data > UNDEFINED_LOW), (data < UNDEFINED_HIGH))] = numpy.nan
return data
def set_mem(mem_no,data):
global debug, use_numpy_nan
i = c_int(mem_no)
# data can be type bytes, str or something else in future
if isinstance(data,bytes):
size = c_int(len(data))
ierr = my_wgrib2.wgrib2_set_mem_buffer(data, size, i)
elif isinstance(data[0],bytes):
size = c_int(len(data))
ierr = my_wgrib2.wgrib2_set_mem_buffer(data, size, i)
elif isinstance(data, str):
size = c_int(len(data))
a = data.encode('utf-8')
ierr = my_wgrib2.wgrib2_set_mem_buffer(a, size, i)
elif isinstance(data, numpy.ndarray):
asize = data.size
size = c_int(4*asize)
a = data.astype(dtype=numpy.float32).reshape(asize)
if use_numpy_nan:
a[numpy.isnan(a)] = UNDEFINED
a_p = a.ctypes.data_as(c_void_p)
ierr = my_wgrib2.wgrib2_set_mem_buffer(a_p, size, i)
else:
print("set_mem does not support ",type(data))
quit()
if (debug):
print("set_mem: ierr=", ierr)
return ierr
#
# register routines
#
def reg_size(regno):
# return size of register-arg
global debug
i = c_int(regno)
size = my_wgrib2.wgrib2_get_reg_size(i)
if debug: print("reg_size=", size)
return size
def get_reg(regno):
# return register(arg) as numpy array (vector)
#
# get size of register
#
global use_numpy_nan, debug
i = c_int(regno)
size = my_wgrib2.wgrib2_get_reg_size(i)
array_type = (c_float * size)
array = array_type()
ierr = my_wgrib2.wgrib2_get_reg_data(byref(array), size, i)
if ierr != 0:
if debug: print("get_reg wgrib2 ierr=", ierr)
return None
# don't know dimensions of register
data = numpy.array(array)
if use_numpy_nan:
data[numpy.logical_and((data > UNDEFINED_LOW), (data < UNDEFINED_HIGH))] = numpy.nan
return data
def set_reg(regno, array):
#
# set register(regno) = array
#
global use_numpy_nan, debug
i = c_int(regno)
asize = array.size
# convert array to 32-bit float, linear
a = array.astype(dtype=numpy.float32).reshape((asize))
if use_numpy_nan:
a[numpy.isnan(a)] = UNDEFINED
a_p = a.ctypes.data_as(c_void_p)
ierr = my_wgrib2.wgrib2_set_reg(a_p, asize, i)
if debug: print("set_reg ierr=", ierr)
return ierr
Functions
def close(file)
-
Expand source code
def close(file): # # close file, does a flush and frees resources # global debug # create byte object a = file.encode('utf-8') ierr = my_wgrib2.wgrib2_free_file(a) if debug: print("close error=", ierr) return ierr
def get_bytes_mem(arg)
-
Expand source code
def get_bytes_mem(arg): # # return bytes with contents of @mem:arg # global debug i = c_int(arg) size = my_wgrib2.wgrib2_get_mem_buffer_size(i) if debug: print("get_bytes_mem: size=",size) array = create_string_buffer(size) ierr = my_wgrib2.wgrib2_get_mem_buffer(array, size, i) if debug: print("get_byte_mem ierr=", ierr) return array
def get_flt_mem(mem_no)
-
Expand source code
def get_flt_mem(mem_no): # return contents of mem file as numpy array (vector) global debug i = c_int(mem_no) size = my_wgrib2.wgrib2_get_mem_buffer_size(i) if (size % 4) != 0: if debug: print("*** ERROR: get_flt_mem, not float @mem",mem_no) return None size_flt = int(size / 4) array_type = (c_float * size_flt) array = array_type() ierr = my_wgrib2.wgrib2_get_mem_buffer(byref(array), size, i) if ierr != 0: if debug: print("*** ERROR: get_flt_mem, could not read @mem",mem_no) return None data = numpy.array(array) if use_numpy_nan: data[numpy.logical_and((data > UNDEFINED_LOW), (data < UNDEFINED_HIGH))] = numpy.nan return data
def get_reg(regno)
-
Expand source code
def get_reg(regno): # return register(arg) as numpy array (vector) # # get size of register # global use_numpy_nan, debug i = c_int(regno) size = my_wgrib2.wgrib2_get_reg_size(i) array_type = (c_float * size) array = array_type() ierr = my_wgrib2.wgrib2_get_reg_data(byref(array), size, i) if ierr != 0: if debug: print("get_reg wgrib2 ierr=", ierr) return None # don't know dimensions of register data = numpy.array(array) if use_numpy_nan: data[numpy.logical_and((data > UNDEFINED_LOW), (data < UNDEFINED_HIGH))] = numpy.nan return data
def get_str_mem(arg)
-
Expand source code
def get_str_mem(arg): # # return a string of contents of @mem:arg # global debug i = c_int(arg) size = my_wgrib2.wgrib2_get_mem_buffer_size(i) string = create_string_buffer(size) ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, i) if debug: print("get_str_mem ierr=", ierr) s = string.value.decode("utf-8") return s
def inq(gfile, *matches, inv='', select='', Data=False, Latlon=False, Regex=False, grib='', Append_grib=False, bin='', Append_bin=False, Matched=False, Grid_defn=False, sequential=-1, var='', time0=None, ftime='', level='')
-
Expand source code
def inq(gfile, *matches, inv='', select='', Data=False, Latlon=False, Regex=False, grib='', Append_grib=False, bin='', Append_bin=False, Matched=False, Grid_defn=False, sequential=-1, var='', time0=None, ftime='', level=''): # based on grb2_inq() from ftn wgrib2api global nx, ny, ndata, nmatch, msgno, submsgno, matched global data, lat, lon, grid_defn global use_numpy_nan, UNDEFINED_LOW, UNDEFINED_HIGH, debug data = None lat = None lon = None grid_defn = [] matched = [] # how to match if inv == '': # no inventory if Regex == False: match_option = '-match_fs' else: match_option = '-match' else: # use inventory if Regex == False: match_option = '-fgrep' else: match_option = '-egrep' if select != '': # selected field, use -d, sequential not valid if Matched != False: cmds = [ gfile, "-d", select, "-last", "@mem:11", "-print_out", ":", "@mem:11", "-S", "-last", "@mem:11", "-nl_out", "@mem:11", "-ftn_api_fn0", "-last0", "@mem:10", "-inv", "/dev/null" ] else: cmds = [ gfile, "-d", select, "-ftn_api_fn0", "-last0", "@mem:10", "-inv", "/dev/null" ] elif inv != '': # use inventory if Matched != False: cmds = [ gfile, "-i_file", inv, "-last", "@mem:11", "-ftn_api_fn0", "-last0", "@mem:10", "-inv", "/dev/null", "-print_out", ":", "@mem:11", "-S", "-last", "@mem:11", "-nl_out", "@mem:11" ] else: cmds = [ gfile, "-i_file", inv, "-ftn_api_fn0", "-last0", "@mem:10", "-inv", "/dev/null" ] if sequential <= 0: cmds.append('-rewind_init') cmds.append(inv) if sequential >= 0: cmds.append('-end') for m in matches: cmds.append(match_option) cmds.append(m) else: # no inventory if Matched != False: cmds = [ gfile, "-last", "@mem:11", "-ftn_api_fn0", "-last0", "@mem:10", "-inv", "/dev/null", "-print_out", ":", "@mem:11", "-S", "-last", "@mem:11", "-nl_out", "@mem:11" ] else: cmds = [ gfile, "-ftn_api_fn0", "-last0", "@mem:10", "-inv", "/dev/null" ] if sequential <= 0: cmds.append('-rewind_init') cmds.append(gfile) if sequential >= 0: cmds.append('-end') for m in matches: cmds.append(match_option) cmds.append(m) if var != '': cmds.append(match_option) cmds.append(':' + var + ':') if time0 is not None: if time0 < 0: return -1 cmds.append(match_option) if time0 <= 9999999999: cmds.append(':d=' + str(time0) + ':') else: cmds.append(':D=' + str(time0) + ':') if ftime != '': cmds.append(match_option) cmds.append(':' + ftime + ':') if level != '': cmds.append(match_option) cmds.append(':' + level + ':') if grib != '': if Append_grib != False: cmds.append("-append") cmds.append("-grib") cmds.append(grib) if Append_grib != False: cmds.append("-no_append") if bin != '': if Append_bin != False: cmds.append("-append") cmds.append("-no_header") cmds.append("-bin") cmds.append(bin) if Append_bin != False: cmds.append("-no_append") if Data != False: cmds.append("-rpn") cmds.append("sto_13") if Latlon != False: cmds.append("-rpn") cmds.append("rcl_lon:sto_14:rcl_lat:sto_15") if Grid_defn != False: cmds.append("-one_line") cmds.append("-grid") cmds.append("-last") cmds.append("@mem:12") cmds.append("-nl_out") cmds.append("@mem:12") if debug: print('wgrib2 args=', cmds) ierr = wgrib2(cmds) if ierr > 0: if debug: print("wgrib2 failed ierr=", ierr) nmatch = -1 return -1 if mem_size(10) == 0: if debug: print("no match") nmatch = 0 return 0 string = get_str_mem(10) x = string.split() nmatch = int(x[0]) ndata = int(x[1]) nx = int(x[2]) ny = int(x[3]) msgno = int(x[4]) submsgno = int(x[5]) if (nmatch == 0): if debug: print("inq found no matches, program error") return 0 # for weird grids nx=-1/0 ny=-1/0 if (nx * ny != ndata): nx = ndata ny = 1 if Grid_defn != False: size = my_wgrib2.wgrib2_get_mem_buffer_size(12) string = create_string_buffer(size) ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, 12) if debug: print("get_str_mem 12 ierr=", ierr) if (ierr == 0): grid_defn = string.value.decode("utf-8").rstrip().split('\n') # get data, lat/lon if (Data != False or Latlon != False): array_type = (c_float * ndata) array = array_type() if (Data != False): ierr = my_wgrib2.wgrib2_get_reg_data(byref(array), ndata, 13) if (ierr == 0): data = numpy.reshape(numpy.array(array), (nx, ny), order='F') if use_numpy_nan: data[numpy.logical_and((data > UNDEFINED_LOW), (data < UNDEFINED_HIGH))] = numpy.nan if (Latlon != False): ierr = my_wgrib2.wgrib2_get_reg_data(byref(array), ndata, 14) if (ierr == 0): lon = numpy.reshape(numpy.array(array), (nx, ny), order='F') if use_numpy_nan: lon[numpy.logical_and((lon > UNDEFINED_LOW), (lon < UNDEFINED_HIGH))] = numpy.nan ierr = my_wgrib2.wgrib2_get_reg_data(byref(array), ndata, 15) if (ierr == 0): lat = numpy.reshape(numpy.array(array), (nx, ny), order='F') if use_numpy_nan: lat[numpy.logical_and((lat > UNDEFINED_LOW), (lat < UNDEFINED_HIGH))] = numpy.nan if Matched != False: size = my_wgrib2.wgrib2_get_mem_buffer_size(11) string = create_string_buffer(size) ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, 11) if debug: print("get_str_mem ierr=", ierr) if (ierr == 0): matched = string.value.decode("utf-8").rstrip().split('\n') if debug: print("inq nmatch=", nmatch) print("ndata=", ndata, nx, ny) print("msg=", msgno, submsgno) print("has_data=", data is not None) return nmatch
def mem_size(arg)
-
Expand source code
def mem_size(arg): # # return size of @mem:arg # global debug i = c_int(arg) size = my_wgrib2.wgrib2_get_mem_buffer_size(i) if debug: print("mem_size=", size) return size
def mk_inv(grb_file, inv_file, Use_ncep_table=False, Short=False)
-
Expand source code
def mk_inv(grb_file, inv_file, Use_ncep_table=False, Short=False): # # make inventory by -Match_inv or -S # global debug cmds = [grb_file, "-rewind_init", grb_file, "-inv", inv_file] if Use_ncep_table: cmds.append('-set') cmds.append('center') cmds.append('7') if Short == False: cmds.append('-Match_inv') else: cmds.append('-S') ierr = wgrib2(cmds) if debug: print("mk_inv: ierr=", ierr) return ierr
def read_inv(file)
-
Expand source code
def read_inv(file): # # read inventory from memory or regular file # returns the inventory as a list # global debug if file[0:5] == '@mem:': i = int(file[5:]) a = get_str_mem(i) else: close(file) f = open(file, 'r') a = f.read() f.close() if a == '': return [] s = a.rstrip().split('\n') return s
def reg_size(regno)
-
Expand source code
def reg_size(regno): # return size of register-arg global debug i = c_int(regno) size = my_wgrib2.wgrib2_get_reg_size(i) if debug: print("reg_size=", size) return size
def set_mem(mem_no, data)
-
Expand source code
def set_mem(mem_no,data): global debug, use_numpy_nan i = c_int(mem_no) # data can be type bytes, str or something else in future if isinstance(data,bytes): size = c_int(len(data)) ierr = my_wgrib2.wgrib2_set_mem_buffer(data, size, i) elif isinstance(data[0],bytes): size = c_int(len(data)) ierr = my_wgrib2.wgrib2_set_mem_buffer(data, size, i) elif isinstance(data, str): size = c_int(len(data)) a = data.encode('utf-8') ierr = my_wgrib2.wgrib2_set_mem_buffer(a, size, i) elif isinstance(data, numpy.ndarray): asize = data.size size = c_int(4*asize) a = data.astype(dtype=numpy.float32).reshape(asize) if use_numpy_nan: a[numpy.isnan(a)] = UNDEFINED a_p = a.ctypes.data_as(c_void_p) ierr = my_wgrib2.wgrib2_set_mem_buffer(a_p, size, i) else: print("set_mem does not support ",type(data)) quit() if (debug): print("set_mem: ierr=", ierr) return ierr
def set_reg(regno, array)
-
Expand source code
def set_reg(regno, array): # # set register(regno) = array # global use_numpy_nan, debug i = c_int(regno) asize = array.size # convert array to 32-bit float, linear a = array.astype(dtype=numpy.float32).reshape((asize)) if use_numpy_nan: a[numpy.isnan(a)] = UNDEFINED a_p = a.ctypes.data_as(c_void_p) ierr = my_wgrib2.wgrib2_set_reg(a_p, asize, i) if debug: print("set_reg ierr=", ierr) return ierr
def wgrib2(arg)
-
Expand source code
def wgrib2(arg): # # call wgrib2 # ex. pywgrib2.wgrib2(["in.grb","-inv","@mem.0"]) # # uses C calling convention: 1st arg is name of program # global debug arg_length = len(arg) + 1 select_type = (c_char_p * arg_length) select = select_type() item = "pywgrib2" select[0] = item.encode('utf-8') for key, item in enumerate(arg): select[key + 1] = item.encode('utf-8') if debug: print("wgrib2 args: ", arg) ierr = my_wgrib2.wgrib2(arg_length, select) if debug: print("wgrib2 err=", ierr) return ierr
def wgrib2_config()
-
Expand source code
def wgrib2_config(): ierr = wgrib2(['-inv', '@mem:10','-config']) size = my_wgrib2.wgrib2_get_mem_buffer_size(10) string = create_string_buffer(size) ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, 10) s = string.value.decode("utf-8") s = s.rstrip().split('\n') return s
def wgrib2_version()
-
Expand source code
def wgrib2_version(): ierr = wgrib2(['-inv', '@mem:10','-version']) size = my_wgrib2.wgrib2_get_mem_buffer_size(10) string = create_string_buffer(size) ierr = my_wgrib2.wgrib2_get_mem_buffer(string, size, 10) s = string.value.decode("utf-8") return s
def write(gfile, template, msgno, new_data=None, Append=False, var='', lev='', time0=None, ftime='', packing='', d_scale=None, b_scale=None, encode_bits=None, metadata='')
-
Expand source code
def write(gfile, template, msgno, new_data=None, Append=False, var='', lev='', time0=None, ftime='', packing='', d_scale=None, b_scale=None, encode_bits=None, metadata='',): # # write grib message (record) # global use_numpy_nan, UNDEFINED, debug # if you only change metadata, no need to pack grid point data pack = False cmds = [ template, "-rewind_init", template, "-d", str(msgno), "-inv", "@mem:11" ] # metadata is first source, var, lev are applied afterwards if metadata != '': cmds.append("-set_metadata_str") cmds.append(metadata) if time0 is not None: cmds.append("-set_date") cmds.append(str(time0)) if var != '': cmds.append("-set_var") cmds.append(var) if lev != '': cmds.append("-set_lev") cmds.append(lev) if ftime != '': cmds.append("-set_ftime") cmds.append(ftime) if packing != '': cmds.append("-set_grib_type") cmds.append(packing) pack = True # set grid point data # -rpn will clear scaling parameters, so set grid point data first if new_data is not None: asize = new_data.size a = new_data.astype(dtype=numpy.float32).reshape((asize),order='F') if use_numpy_nan: a[numpy.isnan(a)] = UNDEFINED a_p = a.ctypes.data_as(c_void_p) ierr = my_wgrib2.wgrib2_set_reg(a_p, asize, 10) cmds.append("-rpn") cmds.append("rcl_10") pack = True use_d_scale = d_scale is not None use_b_scale = b_scale is not None new_d_scale = 0 if use_d_scale else d_scale new_b_scale = 0 if use_b_scale else b_scale if use_d_scale or use_b_scale: cmds.append("-set_grib_max_bits") cmds.append("24") cmds.append("-set_scaling") cmds.append(str(d_scale)) cmds.append(str(b_scale)) pack = True if encode_bits is not None: cmds.append("-set_grib_max_bits") cmds.append("24") cmds.append("-set_bin_prec") cmds.append(str(encode_bits)) pack = True # Write out grib message if Append != False: cmds.append("-append") if pack == False: cmds.append("-grib") else: cmds.append("-grib_out") cmds.append(gfile) cmds.append("-S") # err = wgrib2(cmds) if debug: print("write: ierr=", ierr) if err != 0: return None size = my_wgrib2.wgrib2_get_mem_buffer_size(11) string = create_string_buffer(size) err = my_wgrib2.wgrib2_get_mem_buffer(string, size, 11) if debug: print("get_str_mem ierr=", ierr) if (err != 0): return None else: return string.value.decode("utf-8").rstrip()