from dynamico.libs import libxios import dynamico.wrap as wrap import numpy as np 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 import getargs log_master, log_world = getargs.getLogger(__name__) INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error INFO_ALL, DEBUG_ALL = log_world.info, log_world.debug # ------------- Direct cython interfaces ----------------- # cdef extern from "functions.h": cdef void cxios_context_close_definition() cdef void cxios_context_finalize() cdef void cxios_finalize() cdef void cxios_write_data_k81(char*, int, double*, int) cdef void cxios_write_data_k82(char*, int, double*, int,int) cdef void cxios_write_data_k83(char*, int, double*, int,int,int) def context_close_definition(): cxios_context_close_definition() def context_finalize(): cxios_context_finalize() def finalize(): cxios_finalize() cdef send_field1(char* id, int idlen, double[:] data): cxios_write_data_k81(id, idlen, &data[0], data.shape[0]) cdef send_field2(char* id, int idlen, double[:,:] data): cxios_write_data_k82(id, idlen, &data[0,0], data.shape[0],data.shape[1]) cdef send_field3(char* id, int idlen, double[:,:,:] data): cxios_write_data_k83(id, idlen, &data[0,0,0], data.shape[0],data.shape[1],data.shape[2]) def send_field(bytes id, data): cdef char* idptr = id cdef int idlen = len(id) # print 'cxios.write_data', id, data.shape ndim=data.ndim if ndim==1: send_field1(idptr,idlen,data) if ndim==2: send_field2(idptr,idlen,data) if ndim==3: send_field3(idptr,idlen,data) # -------------------------------------------------------- # lib=wrap.Struct() cxios = wrap.SharedLib(vars(lib), libxios, 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') ] 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,np.int64,np.int32): 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) DEBUG('%s.%s %s %s' % (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([ [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','nj_glo','ibegin','jbegin','ni','nvertex','data_dim'], [str,'type'], [np.ndarray, 'i_index','j_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']) import_cxios_functions()