import numpy as np import dynamico.wrap as wrap from ctypes import c_int, c_double, c_bool, c_void_p, c_char_p, byref, POINTER, Structure c_void_pp=POINTER(c_void_p) # used in prototype c_void_p_byref=type(byref(c_void_p())) # used in py2c because byref creates an object of this type, not c_void_pp # ------------- Direct cython interfaces ----------------- # cdef extern from "functions.h": cpdef void context_close_definition "cxios_context_close_definition"() cpdef void context_finalize "cxios_context_finalize"() cpdef void finalize "cxios_finalize"() # -------------------------------------------------------- # lib=wrap.Struct() cxios = wrap.SharedLib(vars(lib), "libxios.so", prefix_so='cxios_') class Duration(Structure): _fields_ = [(name, c_double) for name in ('year', 'month', 'day', 'hour', 'minute', 'second', 'timestep') ] class Date(Structure): _fields_ = [(name, c_int) for name in ('year', 'month', 'day', 'hour', 'minute', 'second') ] print Duration.from_param for x in c_void_p_byref, Duration, Date : wrap.py2c[x]=wrap.noop # accept arguments of type (void*)&, Duration, ... def SHAPE(data): return np.asarray(list(reversed(data.shape)),c_int) # reverse shape to follow Fortran convention class Handle: def __init__(self, cat, id=None): self.handle = c_void_p() if id is None: id='default' create_fun = cxios.vardict['get_current_'+cat] create_fun(byref(self.handle)) else: create_fun = cxios.vardict[cat+'_handle_create'] create_fun(byref(self.handle), id, c_int(len(id))) self.cat, self.prefix_set, self.id = cat, 'set_'+cat+'_', id print 'Handle', cat, self.id, self.handle def set_attr(self, **kwargs): prefix, handle = self.prefix_set, self.handle for key, value in kwargs.iteritems(): fun = cxios.vardict[prefix+key] extra=value if type(value) in (int,c_int): fun(handle,c_int(value)) elif type(value) is np.ndarray: extra=SHAPE(value) fun(handle,value,extra) elif type(value) is str: fun(handle,value,c_int(len(value))) elif type(value) in (Duration, Date): fun(handle,value) else: raise(TypeError) print self.id+'.'+prefix+key, type(value), extra def update_timestep(self): lib.update_calendar_timestep(self.handle) def import_set_attr(cats, *args): #attr_int, attr_array, attr_str): for arg in args: argtype = arg.pop(0) if argtype is str: argtype = [c_void_p, c_char_p, c_int] #char *str, int strlen elif argtype is np.ndarray: argtype = [c_void_p, c_void_p, c_void_p] # void *handle, double *data, int* SHAPE(data) else: argtype = [c_void_p, argtype] #void *handle, argtype data for cat in cats: cxios.import_funs( [arg + argtype], prefix='set_'+cat+'_') def import_cxios_functions(): cats=['axis','domain','domaingroup','field','fieldgroup'] # XIOS categories cxios.import_funs([ # ['finalize','context_finalize','context_close_definition', None], [cat+'_handle_create' for cat in cats]+[c_void_pp,c_char_p,c_int], ['get_current_'+'calendar_wrapper',c_void_pp], ['update_calendar_timestep',c_void_p], ['update_calendar',c_int] ]) import_set_attr(['domain','domaingroup'], [c_int,'ni_glo','ibegin','ni','nvertex','data_dim'], [str,'type'], [np.ndarray, 'i_index','lonvalue_1d','latvalue_1d','bounds_lat_1d','bounds_lon_1d']) import_set_attr(['field','fieldgroup'], [Duration,'freq_op','freq_offset']) import_set_attr(['axis'], [c_int,'n_glo'], [np.ndarray,'value']) import_set_attr(['calendar_wrapper'], [Duration,'timestep']) cxios.import_funs([['write_data_k80', c_char_p, c_int, c_void_p], ['write_data_k81', c_char_p, c_int, c_void_p, c_int], ['write_data_k82', c_char_p, c_int, c_void_p, c_int, c_int], ['write_data_k83', c_char_p, c_int, c_void_p, c_int, c_int, c_int]]) def send_field(id, data): if type(data) is np.ndarray: shp=data.shape print 'cxios.write_data', id, shp ndim=len(shp) if ndim==1: lib.write_data_k81(id, c_int(len(id)), data, shp[0]) if ndim==2: lib.write_data_k82(id, c_int(len(id)), data, shp[0], shp[1]) # reverse order of dimensions ?? if ndim==3: lib.write_data_k83(id, c_int(len(id)), data, shp[0], shp[1], shp[2]) else: print id, type(data) raise(TypeError) import_cxios_functions()