interface.py 8.63 KB
Newer Older
1
2
3
"""Python interface to handel API."""

from __future__ import absolute_import
Vincent Michel's avatar
Vincent Michel committed
4
5
6

import numpy

7
from .error import check_error
8
9
from ._cffi import handel, ffi

10
11
12
13
14
15
16
17
18
__all__ = ['init', 'init_handel', 'exit',
           'new_detector', 'get_num_detectors', 'get_detectors',
           'start_run', 'stop_run', 'get_run_data_length', 'get_run_data',
           'load_system', 'save_system', 'start_system',
           'enable_log_output', 'disable_log_output',
           'set_log_output', 'set_log_level', 'close_log',
           'set_acquisition_value', 'get_acquisition_value',
           'get_handel_version']

19
20
MAX_STRING_LENGTH = 80

21
22
23
24
25
26
27
28

# Helpers

def to_bytes(arg):
    if isinstance(arg, bytes):
        return arg
    return arg.encode()

29

30
31
32
33
34
35
36
37
def to_buffer_id(bid):
    bid = to_bytes(bid.lower())
    if bid in (b'a', b'b'):
        return bid
    msg = '{!r} is not a valid buffer id'
    raise ValueError(msg.format(bid))


Vincent Michel's avatar
Vincent Michel committed
38
39
# Initializing handel

40
def init(filename):
41
    filename = to_bytes(filename)
42
43
    code = handel.xiaInit(filename)
    check_error(code)
44
45
46


def init_handel():
47
48
    code = handel.xiaInitHandel()
    check_error(code)
49
50


Vincent Michel's avatar
Vincent Michel committed
51
def exit():
52
53
    code = handel.xiaExit()
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
54
55
56
57


# Detectors

58
def new_detector(alias):
59
    alias = to_bytes(alias)
60
61
    code = handel.xiaNewDetector(alias)
    check_error(code)
62
63


64
65
def get_num_detectors():
    num = ffi.new('unsigned int *')
66
67
    code = handel.xiaGetNumDetectors(num)
    check_error(code)
68
69
70
71
72
    return num[0]


def get_detectors():
    n = get_num_detectors()
73
    arg = [ffi.new('char []', MAX_STRING_LENGTH) for _ in range(n)]
74
75
    code = handel.xiaGetDetectors(arg)
    check_error(code)
76
    return tuple(ffi.string(x).decode() for x in arg)
77

Vincent Michel's avatar
Vincent Michel committed
78

79
80
81
82
83
84
85
86
87
def get_detector_from_channel(channel):
    alias = ffi.new('char []', MAX_STRING_LENGTH)
    code = handel.xiaDetectorFromDetChan(channel, alias)
    check_error(code)
    return ffi.string(alias).decode()


# Not exposed

Vincent Michel's avatar
Vincent Michel committed
88
89
90
# int xiaAddDetectorItem(char *alias, char *name, void *value);
# int xiaModifyDetectorItem(char *alias, char *name, void *value);
# int xiaGetDetectorItem(char *alias, char *name, void *value);
91
92
# int xiaGetDetectors_VB(unsigned int index, char *alias);
# int xiaRemoveDetector(char *alias);
Vincent Michel's avatar
Vincent Michel committed
93
94
95
96
97


# Run control

def start_run(channel, resume=False):
98
99
    code = handel.xiaStartRun(channel, resume)
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
100
101
102


def stop_run(channel):
103
104
    code = handel.xiaStopRun(channel)
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
105
106
107
108


def get_run_data_length(channel):
    length = ffi.new('unsigned long *')
Vincent Michel's avatar
Vincent Michel committed
109
    code = handel.xiaGetRunData(channel, b'mca_length', length)
110
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
111
112
113
114
115
116
117
    return length[0]


def get_run_data(channel):
    length = get_run_data_length(channel)
    array = numpy.zeros(length, dtype='uint')
    data = ffi.cast('unsigned long *', array.ctypes.data)
Vincent Michel's avatar
Vincent Michel committed
118
    code = handel.xiaGetRunData(channel, b'mca', data)
119
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
120
121
122
    return array


123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# Buffer

def get_buffer_length(channel):
    length = ffi.new('unsigned long *')
    code = handel.xiaGetRunData(channel, b'buffer_len', length)
    check_error(code)
    return length[0]


def get_buffer_full(channel, buffer_id):
    bid = to_buffer_id(buffer_id)
    command = b'buffer_full_%c' % bid
    result = ffi.new('unsigned short *')
    code = handel.xiaGetRunData(channel, command, result)
    check_error(code)
    return bool(result[0])


def get_buffer(channel, buffer_id):
    bid = to_buffer_id(buffer_id)
    command = b'buffer_%c' % bid
    length = get_buffer_length(channel)
    array = numpy.zeros(length, dtype='uint')
    data = ffi.cast('unsigned long *', array.ctypes.data)
    code = handel.xiaGetRunData(channel, command, data)
    check_error(code)
    return array


def buffer_done(channel, buffer_id):
    bid = to_buffer_id(buffer_id)
    code = handel.xiaBoardOperation(channel, b'buffer_done', bid)
    check_error(code)


# Not exposed

Vincent Michel's avatar
Vincent Michel committed
160
161
162
163
164
165
166
# int xiaDoSpecialRun(int detChan, char *name, void *info);
# int xiaGetSpecialRunData(int detChan, char *name, void *value);


# System

def load_system(filename):
167
    filename = to_bytes(filename)
168
169
    code = handel.xiaLoadSystem(b'handel_ini', filename)
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
170
171
172


def save_system(filename):
173
    filename = to_bytes(filename)
174
175
    code = handel.xiaSaveSystem(b'handel_ini', filename)
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
176
177
178


def start_system():
179
180
    code = handel.xiaStartSystem()
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
181
182
183
184
185


# Logging

def enable_log_output():
186
187
    code = handel.xiaEnableLogOutput()
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
188
189
190


def disable_log_output():
191
192
    code = handel.xiaSuppressLogOutput()
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
193
194
195


def set_log_level(level):
196
197
    code = handel.xiaSetLogLevel(level)
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
198
199
200


def set_log_output(filename):
201
    filename = to_bytes(filename)
202
203
    code = handel.xiaSetLogOutput(filename)
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
204
205
206


def close_log():
207
208
    code = handel.xiaCloseLog()
    check_error(code)
Vincent Michel's avatar
Vincent Michel committed
209
210
211

# Firmware

212
213
# Not exposed

214
215
216
217
218
219
220
221
222
# int xiaNewFirmware(char *alias);
# int xiaAddFirmwareItem(char *alias, char *name, void *value);
# int xiaModifyFirmwareItem(char *alias, unsigned short decimation, char *name, void *value);
# int xiaGetFirmwareItem(char *alias, unsigned short decimation, char *name, void *value);
# int xiaGetNumFirmwareSets(unsigned int *numFirmware);
# int xiaGetFirmwareSets(char *firmware[]);
# int xiaGetFirmwareSets_VB(unsigned int index, char *alias);
# int xiaGetNumPTRRs(char *alias, unsigned int *numPTRR);
# int xiaRemoveFirmware(char *alias);
Vincent Michel's avatar
Vincent Michel committed
223
224
225
226
227
# int xiaDownloadFirmware(int detChan, char *type);


# Module

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
def get_num_modules():
    num_modules = ffi.new('unsigned int *')
    code = handel.xiaGetNumModules(num_modules)
    check_error(code)
    return num_modules[0]


def get_modules():
    n = get_num_modules()
    arg = [ffi.new('char []', MAX_STRING_LENGTH) for _ in range(n)]
    code = handel.xiaGetModules(arg)
    check_error(code)
    return tuple(ffi.string(x).decode() for x in arg)


def get_module_from_channel(channel):
    alias = ffi.new('char []', MAX_STRING_LENGTH)
    code = handel.xiaModuleFromDetChan(channel, alias)
    check_error(code)
    return ffi.string(alias).decode()


# Not exposed

252
253
254
255
256
257
# int xiaNewModule(char *alias);
# int xiaAddModuleItem(char *alias, char *name, void *value);
# int xiaModifyModuleItem(char *alias, char *name, void *value);
# int xiaGetModuleItem(char *alias, char *name, void *value);
# int xiaGetModules_VB(unsigned int index, char *alias);
# int xiaRemoveModule(char *alias);
Vincent Michel's avatar
Vincent Michel committed
258
259
260
261


# Channel set

262
263
# Not exposed

264
265
266
# int xiaAddChannelSetElem(unsigned int detChanSet, unsigned int newChan);
# int xiaRemoveChannelSetElem(unsigned int detChan, unsigned int chan);
# int xiaRemoveChannelSet(unsigned int detChan);
Vincent Michel's avatar
Vincent Michel committed
267
268


269
270
271
# Parameters

def set_acquisition_value(channel, name, value):
272
    name = to_bytes(name)
273
    pointer = ffi.new('double *', value)
274
275
    code = handel.xiaSetAcquisitionValues(channel, name, pointer)
    check_error(code)
276
277
278


def get_acquisition_value(channel, name):
279
    name = to_bytes(name)
280
    pointer = ffi.new('double *')
281
282
    code = handel.xiaGetAcquisitionValues(channel, name, pointer)
    check_error(code)
283
284
    return pointer[0]

Vincent Michel's avatar
Vincent Michel committed
285

286
287
288
289
290
291
292
293
294
295
296
297
298
299
def remove_acquisition_value(channel, name):
    name = to_bytes(name)
    code = handel.xiaRemoveAcquisitionValues(channel, name)
    check_error(code)


def apply_acquisition_value(channel):
    dummy = ffi.new('int *')
    code = handel.xiaBoardOperation(channel, b'apply', dummy)
    check_error(code)


# Not exposed

300
301
302
303
304
305
306
307
# int xiaUpdateUserParams(int detChan);
# int xiaGainOperation(int detChan, char *name, void *value);
# int xiaGainCalibrate(int detChan, double deltaGain);
# int xiaGetParameter(int detChan, const char *name, unsigned short *value);
# int xiaSetParameter(int detChan, const char *name, unsigned short value);
# int xiaGetNumParams(int detChan, unsigned short *numParams);
# int xiaGetParamData(int detChan, char *name, void *value);
# int xiaGetParamName(int detChan, unsigned short index, char *name);
Vincent Michel's avatar
Vincent Michel committed
308
309
310
311


# Operation

312
313
314
# Not exposed

# int xiaBoardOperation(int detChan, char *name, void *value) with mapping_pixel_next (int 0);
315
316
# int xiaMemoryOperation(int detChan, char *name, void *value);
# int xiaCommandOperation(int detChan, byte_t cmd, unsigned int lenS, byte_t *send, unsigned int lenR, byte_t *recv);
Vincent Michel's avatar
Vincent Michel committed
317
318
319
320


# Analysis

321
322
# Not exposed

323
324
# int xiaFitGauss(long data[], int lower, int upper, float *pos, float *fwhm);
# int xiaFindPeak(long *data, int numBins, float thresh, int *lower, int *upper);
Vincent Michel's avatar
Vincent Michel committed
325
326
327
328
329


# Debugging


330
def get_handel_version():
Vincent Michel's avatar
Vincent Michel committed
331
332
333
334
335
336
337
338
    rel = ffi.new('int *')
    min = ffi.new('int *')
    maj = ffi.new('int *')
    pretty = ffi.new('char *')
    handel.xiaGetVersionInfo(rel, min, maj, pretty)
    return maj[0], min[0], rel[0]


339
340
# Not exposed

341
342
343
344
# int xiaSetIOPriority(int pri);
# int xiaMemStatistics(unsigned long *total, unsigned long *current, unsigned long *peak);
# void xiaMemSetCheckpoint(void);
# void xiaMemLeaks(char *);