1 | import numpy as np |
---|
2 | import dynamico.wrap as wrap |
---|
3 | from ctypes import c_int, c_double, c_bool, c_void_p, c_char_p, byref, POINTER, Structure |
---|
4 | c_void_pp=POINTER(c_void_p) # used in prototype |
---|
5 | c_void_p_byref=type(byref(c_void_p())) # used in py2c because byref creates an object of this type, not c_void_pp |
---|
6 | |
---|
7 | # ------------- Direct cython interfaces ----------------- # |
---|
8 | |
---|
9 | cdef extern from "functions.h": |
---|
10 | cpdef void context_close_definition "cxios_context_close_definition"() |
---|
11 | cpdef void context_finalize "cxios_context_finalize"() |
---|
12 | cpdef void finalize "cxios_finalize"() |
---|
13 | |
---|
14 | # -------------------------------------------------------- # |
---|
15 | |
---|
16 | lib=wrap.Struct() |
---|
17 | cxios = wrap.SharedLib(vars(lib), "libxios.so", prefix_so='cxios_') |
---|
18 | |
---|
19 | class Duration(Structure): |
---|
20 | _fields_ = [(name, c_double) for name in ('year', 'month', 'day', 'hour', 'minute', 'second', 'timestep') ] |
---|
21 | class Date(Structure): |
---|
22 | _fields_ = [(name, c_int) for name in ('year', 'month', 'day', 'hour', 'minute', 'second') ] |
---|
23 | |
---|
24 | print Duration.from_param |
---|
25 | |
---|
26 | for x in c_void_p_byref, Duration, Date : wrap.py2c[x]=wrap.noop # accept arguments of type (void*)&, Duration, ... |
---|
27 | |
---|
28 | def SHAPE(data): return np.asarray(list(reversed(data.shape)),c_int) # reverse shape to follow Fortran convention |
---|
29 | |
---|
30 | class Handle: |
---|
31 | def __init__(self, cat, id=None): |
---|
32 | self.handle = c_void_p() |
---|
33 | if id is None: |
---|
34 | id='default' |
---|
35 | create_fun = cxios.vardict['get_current_'+cat] |
---|
36 | create_fun(byref(self.handle)) |
---|
37 | else: |
---|
38 | create_fun = cxios.vardict[cat+'_handle_create'] |
---|
39 | create_fun(byref(self.handle), id, c_int(len(id))) |
---|
40 | self.cat, self.prefix_set, self.id = cat, 'set_'+cat+'_', id |
---|
41 | print 'Handle', cat, self.id, self.handle |
---|
42 | def set_attr(self, **kwargs): |
---|
43 | prefix, handle = self.prefix_set, self.handle |
---|
44 | for key, value in kwargs.iteritems(): |
---|
45 | fun = cxios.vardict[prefix+key] |
---|
46 | extra=value |
---|
47 | if type(value) in (int,c_int): |
---|
48 | fun(handle,c_int(value)) |
---|
49 | elif type(value) is np.ndarray: |
---|
50 | extra=SHAPE(value) |
---|
51 | fun(handle,value,extra) |
---|
52 | elif type(value) is str: |
---|
53 | fun(handle,value,c_int(len(value))) |
---|
54 | elif type(value) in (Duration, Date): |
---|
55 | fun(handle,value) |
---|
56 | else: |
---|
57 | raise(TypeError) |
---|
58 | print self.id+'.'+prefix+key, type(value), extra |
---|
59 | def update_timestep(self): |
---|
60 | lib.update_calendar_timestep(self.handle) |
---|
61 | |
---|
62 | def import_set_attr(cats, *args): #attr_int, attr_array, attr_str): |
---|
63 | for arg in args: |
---|
64 | argtype = arg.pop(0) |
---|
65 | if argtype is str: |
---|
66 | argtype = [c_void_p, c_char_p, c_int] #char *str, int strlen |
---|
67 | elif argtype is np.ndarray: |
---|
68 | argtype = [c_void_p, c_void_p, c_void_p] # void *handle, double *data, int* SHAPE(data) |
---|
69 | else: |
---|
70 | argtype = [c_void_p, argtype] #void *handle, argtype data |
---|
71 | for cat in cats: |
---|
72 | cxios.import_funs( [arg + argtype], prefix='set_'+cat+'_') |
---|
73 | |
---|
74 | def import_cxios_functions(): |
---|
75 | cats=['axis','domain','domaingroup','field','fieldgroup'] # XIOS categories |
---|
76 | cxios.import_funs([ |
---|
77 | # ['finalize','context_finalize','context_close_definition', None], |
---|
78 | [cat+'_handle_create' for cat in cats]+[c_void_pp,c_char_p,c_int], |
---|
79 | ['get_current_'+'calendar_wrapper',c_void_pp], |
---|
80 | ['update_calendar_timestep',c_void_p], |
---|
81 | ['update_calendar',c_int] ]) |
---|
82 | |
---|
83 | import_set_attr(['domain','domaingroup'], [c_int,'ni_glo','ibegin','ni','nvertex','data_dim'], [str,'type'], |
---|
84 | [np.ndarray, 'i_index','lonvalue_1d','latvalue_1d','bounds_lat_1d','bounds_lon_1d']) |
---|
85 | import_set_attr(['field','fieldgroup'], [Duration,'freq_op','freq_offset']) |
---|
86 | import_set_attr(['axis'], [c_int,'n_glo'], [np.ndarray,'value']) |
---|
87 | import_set_attr(['calendar_wrapper'], [Duration,'timestep']) |
---|
88 | |
---|
89 | cxios.import_funs([['write_data_k80', c_char_p, c_int, c_void_p], |
---|
90 | ['write_data_k81', c_char_p, c_int, c_void_p, c_int], |
---|
91 | ['write_data_k82', c_char_p, c_int, c_void_p, c_int, c_int], |
---|
92 | ['write_data_k83', c_char_p, c_int, c_void_p, c_int, c_int, c_int]]) |
---|
93 | |
---|
94 | def send_field(id, data): |
---|
95 | if type(data) is np.ndarray: |
---|
96 | shp=data.shape |
---|
97 | print 'cxios.write_data', id, shp |
---|
98 | ndim=len(shp) |
---|
99 | if ndim==1: |
---|
100 | lib.write_data_k81(id, c_int(len(id)), data, shp[0]) |
---|
101 | if ndim==2: |
---|
102 | lib.write_data_k82(id, c_int(len(id)), data, shp[0], shp[1]) # reverse order of dimensions ?? |
---|
103 | if ndim==3: |
---|
104 | lib.write_data_k83(id, c_int(len(id)), data, shp[0], shp[1], shp[2]) |
---|
105 | else: |
---|
106 | print id, type(data) |
---|
107 | raise(TypeError) |
---|
108 | |
---|
109 | import_cxios_functions() |
---|