FrelonTacoCcd.py 15.3 KB
Newer Older
1
from TacoCcd import *
2
from FrelonAcq import FrelonAcq
3
import gc
4
5
6

class FrelonTacoAcq(TacoCcdAcq):

7
8
9
    DEB_CLASS(DebModApplication, "FrelonTacoAcq")

    @DEB_MEMBER_FUNCT
10
11
12
13
14
15
    def __init__(self, dev_name, dev_class=None, cmd_list=None):
        TacoCcdAcq.__init__(self, dev_name, dev_class, cmd_list)
        
        espia_dev_nb = 0
        self.m_acq = FrelonAcq(espia_dev_nb)

16
    @DEB_MEMBER_FUNCT
17
    def __del__(self):
18
        pass
19

20
    @DEB_MEMBER_FUNCT
21
    def reset(self):
22
23
24
        deb.Trace("Reseting the device!")
        ct = self.m_acq.getGlobalControl()
        ct.reset()
25
        
26
    @DEB_MEMBER_FUNCT
27
    def getState(self):
28
        deb.Trace('Query device state ...')
29
30
31
32
33
34
35
36
        ct = self.m_acq.getGlobalControl()
        ct_status = ct.getStatus()
        acq_status = ct_status.AcquisitionStatus
        if acq_status == AcqRunning:
            self.state = DevCcdAcquiring
        else:
            self.state = DevCcdReady
        deb.Return('Device state: 0x%08x (%d)' % (self.state, self.state))
37
38
        return self.state

39
    @DEB_MEMBER_FUNCT
40
41
42
43
44
    def getStatus(self):
        state_desc = { DevCcdReady:     'CCD is Ready',
                       DevCcdAcquiring: 'CCD is Acquiring' }
        state = self.getState()
        status = state_desc[state]
45
        deb.Return('Device status: %s (0x%08x)' % (status, state))
46
47
        return status

48
    @DEB_MEMBER_FUNCT
49
50
51
52
53
54
55
    def getFrameDim(self, max_dim=False):
        ct_image = self.m_acq.getImageControl()
        if max_dim:
            max_size = ct_image.getMaxImageSize()
            fdim = FrameDim(max_size, ct_image.getImageType())
        else:
            fdim = ct_image.getImageDim()
56
        deb.Return('Frame dim: %s' % fdim)
57
58
        return fdim
    
59
    @DEB_MEMBER_FUNCT
60
    def getType(self):
61
62
        cam = self.m_acq.getFrelonCamera()
        type_nb = (cam.isFrelon2k16() and 2016) or 2014
63
        deb.Return('Getting type: %s' % type_nb)
64
65
        return type_nb

66
    @DEB_MEMBER_FUNCT
67
68
    def getLstErrMsg(self):
        err_msg = ''
69
        deb.Return('Getting last err. msg: %s' % err_msg)
70
71
        return err_msg
    
72
    @DEB_MEMBER_FUNCT
73
    def setTrigger(self, ext_trig):
74
        deb.Param('Setting trigger: %s' % ext_trig)
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
        ct_acq = self.m_acq.getAcqControl()
        exp_time = prev_exp_time = ct_acq.getAcqExpoTime()
        if ext_trig == 0:
            trig_mode = IntTrig
            if exp_time == 0:
                exp_time = 1
        elif ext_trig == 1:
            trig_mode = ((exp_time == 0) and ExtGate) or ExtTrigSingle
        elif ext_trig == 2:
            trig_mode = ExtTrigMult
        else:
            raise 'Invalid ext. trig: %s' % ext_trig
        ct_acq.setTriggerMode(trig_mode)
        if exp_time != prev_exp_time:
            ct_acq.setAcqExpoTime(exp_time)
90
    
91
    @DEB_MEMBER_FUNCT
92
    def getTrigger(self):
93
94
95
96
97
98
99
100
101
102
        ct_acq = self.m_acq.getAcqControl()
        trig_mode = ct_acq.getTriggerMode()
        if trig_mode == IntTrig:
            ext_trig = 0
        elif trig_mode in [ExtTrigSingle, ExtGate]:
            ext_trig = 1
        elif trig_mode == ExtTrigMult:
            ext_trig = 2
        else:
            raise 'Invalid trigger mode: %s' % trig_mode
103
        deb.Return('Getting trigger: %s' % ext_trig)
104
105
        return ext_trig
    
106
    @DEB_MEMBER_FUNCT
107
    def setNbFrames(self, nb_frames):
108
        deb.Param('Setting nb. frames: %s' % nb_frames)
109
110
        ct_acq = self.m_acq.getAcqControl()
        ct_acq.setAcqNbFrames(nb_frames)
111
    
112
    @DEB_MEMBER_FUNCT
113
    def getNbFrames(self):
114
115
        ct_acq = self.m_acq.getAcqControl()
        nb_frames = ct_acq.getAcqNbFrames()
116
        deb.Return('Getting nb. frames: %s' % nb_frames)
117
118
        return nb_frames
    
119
    @DEB_MEMBER_FUNCT
120
    def setExpTime(self, exp_time):
121
        deb.Param('Setting exp. time: %s' % exp_time)
122
        ct_acq = self.m_acq.getAcqControl()
123
124
125
126
127
        trig_mode = ct_acq.getTriggerMode()
        if exp_time == 0 and trig_mode == ExtTrigSingle:
            ct_acq.setTriggerMode(ExtGate)
        elif exp_time > 0 and trig_mode == ExtGate:
            ct_acq.setTriggerMode(ExtTrigSingle)
128
        ct_acq.setAcqExpoTime(exp_time)
129
    
130
    @DEB_MEMBER_FUNCT
131
    def getExpTime(self):
132
133
        ct_acq = self.m_acq.getAcqControl()
        exp_time = ct_acq.getAcqExpoTime()
134
        deb.Return('Getting exp. time: %s' % exp_time)
135
136
        return exp_time

137
    @DEB_MEMBER_FUNCT
138
139
140
    def setBin(self, bin):
        # SPEC format Y,X -> incompat. with getBin ...
        bin = Bin(bin[1], bin[0])
141
        deb.Param('Setting binning: %s' % bin)
142
143
        ct_image = self.m_acq.getImageControl()
        ct_image.setBin(bin)
144

145
    @DEB_MEMBER_FUNCT
146
    def getBin(self):
147
148
        ct_image = self.m_acq.getImageControl()
        bin = ct_image.getBin()
149
        deb.Return('Getting binning: %s' % bin)
150
151
        return [bin.getX(), bin.getY()]

152
153
154
155
156
157
158
159
160
    @DEB_MEMBER_FUNCT
    def getMaxRoi(self):
        ct_image = self.m_acq.getImageControl()
        max_roi_size = ct_image.getMaxImageSize()
        max_roi_size /= Point(ct_image.getBin())
        max_roi = Roi(Point(0, 0), max_roi_size)
        deb.Return('Max roi: %s' % max_roi)
        return max_roi
        
161
    @DEB_MEMBER_FUNCT
162
163
    def setRoi(self, roi):
        roi = Roi(Point(roi[0], roi[1]), Point(roi[2], roi[3]))
164
        deb.Param('Setting roi: %s' % roi)
165
166
167
168
        if roi == self.getMaxRoi():
            roi = Roi()
        ct_image = self.m_acq.getImageControl()
        ct_image.setRoi(roi)
169

170
    @DEB_MEMBER_FUNCT
171
    def getRoi(self):
172
173
174
175
        ct_image = self.m_acq.getImageControl()
        roi = ct_image.getRoi()
        if roi.isEmpty():
            roi = self.getMaxRoi()
176
        deb.Return('Getting roi: %s' % roi)
177
178
        tl = roi.getTopLeft()
        br = roi.getBottomRight()
179
        return [tl.x, tl.y, br.x, br.y]
180
            
181
    @DEB_MEMBER_FUNCT
182
    def setFilePar(self, par_arr):
183
        deb.Param('Setting file pars: %s' % par_arr)
184
185
        ct_saving = self.m_acq.getSavingControl()
        pars = ct_saving.getParameters()
186
187
188
        pars.directory  = par_arr[0]
        pars.prefix     = par_arr[1]
        pars.suffix     = par_arr[2]
189
190
        pars.nextNumber = int(par_arr[3])
        index_format    = par_arr[4]
191
        if par_arr[5] in ['y', 'yes']:
192
            pars.overwritePolicy = CtSaving.Overwrite
193
        else:
194
            pars.overwritePolicy = CtSaving.Abort
195
        if pars.suffix.lower()[-4:] == '.edf':
196
197
198
            pars.fileFormat = CtSaving.EDF
        else:
            pars.fileFormat = CtSaving.RAW
199
        ct_saving.setParameters(pars)
200

201
    @DEB_MEMBER_FUNCT
202
    def getFilePar(self):
203
204
205
206
        ct_saving = self.m_acq.getSavingControl()
        pars = ct_saving.getParameters()
        overwrite = (pars.overwritePolicy == CtSaving.Overwrite)
        over_str = (overwrite and 'yes') or 'no'
207
        index_format = '%04d'
208
        arr = [pars.directory, pars.prefix, pars.suffix, pars.nextNumber,
209
210
               index_format, over_str]
        par_arr = map(str, arr)
211
212
        deb.Return('File pars: %s' % par_arr)
        return par_arr
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
    @DEB_MEMBER_FUNCT
    def setFileHeader(self, header_str):
        deb.Param('Setting file header: %s' % header_str)
        header_map = {}
        for line in header_str.split('\n'):
            token = line.split('=')
            key = token[0].strip()
            if not key:
                continue
            val = string.join(token[1:], '=').strip()
            if val[-1] == ';':
                val = val[:-1].strip()
            header_map[key] = val
        ct_saving = self.m_acq.getSavingControl()
        ct_saving.setCommonHeader(header_map)
        
    @DEB_MEMBER_FUNCT
    def writeFile(self, frame_nb):
        deb.Param('Writing frame %s to file' % frame_nb)
        
234
    @DEB_MEMBER_FUNCT
235
    def setChannel(self, input_chan):
236
        deb.Param('Setting input channel: %s' % input_chan)
237
        cam = self.m_acq.getFrelonCamera()
238
        cam.setInputChan(int(input_chan))
239
    
240
    @DEB_MEMBER_FUNCT
241
    def getChannel(self):
242
243
        cam = self.m_acq.getFrelonCamera()
        input_chan = cam.getInputChan()
244
        deb.Return('Getting input channel: %s' % input_chan)
245
246
        return input_chan
        
247
    @DEB_MEMBER_FUNCT
248
    def setMode(self, mode):
249
        deb.Param('Setting mode: %s (0x%x)' % (mode, mode))
ahoms's avatar
ahoms committed
250
251
        live_display = (mode & self.LiveDisplay) != 0
        self.setLiveDisplay(live_display)
252
        auto_save = (mode & self.AutoSave) != 0
253
        self.setAutosave(auto_save)
254
        
255
    @DEB_MEMBER_FUNCT
256
    def getMode(self):
ahoms's avatar
ahoms committed
257
258
259
260
261
        mode = 0
        if self.getLiveDisplay():
            mode |= self.LiveDisplay
        if self.getAutosave():
            mode |= self.AutoSave
262
        deb.Return('Getting mode: %s (0x%x)' % (mode, mode))
263
264
        return mode

265
    @DEB_MEMBER_FUNCT
266
267
    def setHwPar(self, hw_par_str):
        hw_par = map(int, string.split(hw_par_str))
268
        deb.Param('Setting hw par: %s' % hw_par)
269
270
271
272
        flip_mode, kin_line_beg, kin_stripes, d0, roi_mode = hw_par
        cam = self.m_acq.getFrelonCamera()
        flip = Flip(flip_mode >> 1, flip_mode & 1)
        cam.setFlip(flip)
273
274
275
        roi_modes = [Frelon.None, Frelon.Slow, Frelon.Fast, Frelon.Kinetic]
        roi_modes_int = map(int, roi_modes)
        roi_mode = roi_modes[roi_modes_int.index(roi_mode)]
276
277
278
279
280
        cam.setRoiMode(roi_mode)
        if roi_mode == Frelon.Kinetic:
            self.setKinPars(kin_line_beg, kin_stripes)
        else:
            deb.Warning("Ingoring Kinetic parameters")
281
        
282
    @DEB_MEMBER_FUNCT
283
    def getHwPar(self):
284
285
286
287
288
289
        cam = self.m_acq.getFrelonCamera()
        flip = cam.getFlip()
        flip_mode = flip.x << 1 | flip.y
        roi_mode = cam.getRoiMode()
        kin_line_beg, kin_stripes = self.getKinPars()
        hw_par = [flip_mode, kin_line_beg, kin_stripes, 0, roi_mode]
290
        deb.Return('Getting hw par: %s' % hw_par)
291
292
        hw_par_str = string.join(map(str, hw_par))
        return hw_par_str
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

    @DEB_MEMBER_FUNCT
    def setKinPars(self, kin_line_beg, kin_stripes):
        deb.Param('Setting kin pars: kin_line_beg=%s, kin_stripes=%s' % \
                  (kin_line_beg, kin_stripes))
        if kin_stripes > 1:
            deb.Warning('Ignoring kin_stripes=%d' % kin_stripes)
            
        ct_image = self.m_acq.getImageControl()
        bin = ct_image.getBin()
        roi = ct_image.getRoi()
        if roi.isEmpty():
            roi = self.getMaxRoi()
        roi = roi.getUnbinned(bin)
        roi_bin_offset  = Point(roi.getTopLeft().x, kin_line_beg)
        roi_bin_offset -= roi.getTopLeft()
        cam = self.m_acq.getFrelonCamera()
        cam.setRoiBinOffset(roi_bin_offset)
311
        
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    @DEB_MEMBER_FUNCT
    def getKinPars(self):
        ct_image = self.m_acq.getImageControl()
        bin = ct_image.getBin()
        roi = ct_image.getRoi()
        if roi.isEmpty():
            roi = self.getMaxRoi()
        roi = roi.getUnbinned(bin)
        cam = self.m_acq.getFrelonCamera()
        tl  = roi.getTopLeft()
        tl += cam.getRoiBinOffset()
        kin_line_beg = tl.y
        kin_stripes = 1
        deb.Return('Getting kin pars: kin_line_beg=%s, kin_stripes=%s' % \
                   (kin_line_beg, kin_stripes))
        return kin_line_beg, kin_stripes

    
330
    @DEB_MEMBER_FUNCT
331
    def setKinetics(self, kinetics):
332
        deb.Param('Setting the profile: %s' % kinetics)
333
        if kinetics == 0:
334
            ftm = Frelon.FFM
335
        elif kinetics == 3:
336
            ftm = Frelon.FTM
337
338
339
340
341
        else:
            raise 'Invalid kinetics value: %s' % kinetics
        cam = self.m_acq.getFrelonCamera()
        cam.setFrameTransferMode(ftm)
        
342
    @DEB_MEMBER_FUNCT
343
    def getKinetics(self):
344
345
        cam = self.m_acq.getFrelonCamera()
        ftm = cam.getFrameTransferMode()
346
        if ftm == Frelon.FTM:
347
348
349
            kinetics = 3
        else:
            kinetics = 0
350
        deb.Return('Getting the profile: %s' % kinetics)
351
352
        return kinetics
    
353
    @DEB_MEMBER_FUNCT
354
    def startAcq(self):
355
        deb.Trace('Starting the device')
356
357
358
359
        ct = self.m_acq.getGlobalControl()
        ct.prepareAcq()
        ct.startAcq()
        
360
    @DEB_MEMBER_FUNCT
361
    def stopAcq(self):
362
        deb.Trace('Stopping the device')
363
364
        ct = self.m_acq.getGlobalControl()
        ct.stopAcq()
365
    
366
    @DEB_MEMBER_FUNCT
367
368
    def readFrame(self, frame_data):
        frame_nb, frame_size = frame_data
369
        deb.Param('frame_nb=%s, frame_size=%s' % (frame_nb, frame_size))
370
371
372
373
        frame_dim = self.getFrameDim()
        if frame_size != frame_dim.getMemSize():
            raise ValueError, ('Client expects %d bytes, frame has %d' % \
                               (frame_size, frame_dim.getMemSize()))
374
375
376
        ct = self.m_acq.getGlobalControl()
        img_data = ct.ReadImage(frame_nb)
        data = img_data.buffer
377
378
379
380
381
382
        s = data.tostring()
        if len(s) != frame_size:
            raise ValueError, ('Client expects %d bytes, data str has %d' % \
                               (frame_size, len(s)))
        return s

383
    @DEB_MEMBER_FUNCT
384
    def startLive(self):
385
386
387
388
389
390
391
        deb.Trace('Starting live mode')
        self.setNbFrames(0)
        self.startAcq()
        
    @DEB_MEMBER_FUNCT
    def setAutosave(self, autosave_act):
        deb.Param('Setting autosave active: %s' % autosave_act)
392
393
394
395
        if autosave_act:
            saving_mode = CtSaving.AutoFrame
        else:
            saving_mode = CtSaving.Manual
396
397
398
399
400
401
402
403
404
        ct_saving = self.m_acq.getSavingControl()
        ct_saving.setSavingMode(saving_mode)
    
    @DEB_MEMBER_FUNCT
    def getAutosave(self):
        ct_saving = self.m_acq.getSavingControl()
        autosave_act = (ct_saving.getSavingMode() == CtSaving.AutoFrame)
        deb.Return('Getting autosave active: %s' % autosave_act)
        return autosave_act
ahoms's avatar
ahoms committed
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

    @DEB_MEMBER_FUNCT
    def setLiveDisplay(self, livedisplay_act):
        deb.Param('Setting live display active: %s' % livedisplay_act)
        ct_display = self.m_acq.getDisplayControl()
        ct_display.setNames('_ccd_ds_', 'frelon_live')
        ct_display.setActive(livedisplay_act)
        
    @DEB_MEMBER_FUNCT
    def getLiveDisplay(self):
        ct_display = self.m_acq.getDisplayControl()
        livedisplay_act = ct_display.isActive()
        deb.Return('Getting live display active: %s' % livedisplay_act)
        return livedisplay_act

420
    @DEB_MEMBER_FUNCT
421
    def getCurrent(self):
422
423
424
425
426
427
428
429
430
        ct = self.m_acq.getGlobalControl()
        ct_status = ct.getStatus()
        img_counters = ct_status.ImageCounters
        if self.getAutosave():
            last_frame_nb = img_counters.LastImageSaved
        else:
            last_frame_nb = img_counters.LastImageAcquired
        last_frame_nb += 1
        deb.Return('Last frame nb: %s' % last_frame_nb)
431
432
        return last_frame_nb

433
    @DEB_MEMBER_FUNCT
434
    def execCommand(self, cmd):
435
436
437
438
439
440
441
442
        deb.Param('Sending cmd: %s' % cmd)
        cam = self.m_acq.getFrelonCamera()
        ser_line = cam.getSerialLine()
        ser_line.write(cmd)
        resp = ser_line.readLine()
        deb.Return('Received response:')
        for line in resp.split('\r\n'):
            deb.Return(line)
443
444
        return resp

445
    @DEB_MEMBER_FUNCT
446
447
    def getChanges(self):
        changes = 0
448
        deb.Trace('Getting changes: %s' % changes)
449
450
451
452
453
        return changes

    
class FrelonServer(CcdServer):

454
    DEB_CLASS(DebModApplication, "FrelonServer")
455
    
456
    @DEB_MEMBER_FUNCT
457
458
459
460
461
462
463
464
465
466
467
    def __init__(self, bin_name, pers_name):
        CcdServer.__init__(self, bin_name, pers_name)

        dev_name_list = self.getDevNameList()

        for dev_name in dev_name_list:
            dev = FrelonTacoAcq(dev_name)
            self.addDev(dev)

        self.startup()