Commit 3ee6bbab authored by Alejandro Homs Puron's avatar Alejandro Homs Puron Committed by operator for beamline
Browse files

Tango: split SlsDetector into specific Eiger & Jungfrau classes

parent 93b46661
...@@ -35,4 +35,4 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) ...@@ -35,4 +35,4 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
include(LimaTools) include(LimaTools)
endif() endif()
limatools_install_camera_tango("SlsDetector.py") limatools_install_camera_tango("SlsDetector.py SlsDetectorEiger.py SlsDetectorJungfrau.py")
\ No newline at end of file
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
# #
# file : SlsDetector.py # file : SlsDetector.py
# #
# description : Python source for the PSI/SlsDetector and its commands. # description : Python common source for the PSI/SlsDetector and its commands.
# The class is derived from Device. It represents the # The class is derived from Device. It represents the
# CORBA servant object which will be accessed from the # CORBA servant object which will be accessed from the
# network. All commands which can be executed on the # network. All commands which can be executed on the
...@@ -71,40 +71,37 @@ def ConstListAttr(nl, vl=None, namespc=SlsDetectorHw.Defs): ...@@ -71,40 +71,37 @@ def ConstListAttr(nl, vl=None, namespc=SlsDetectorHw.Defs):
return OrderedDict([(g(n), v) for n, v in zip(nl, vl)]) return OrderedDict([(g(n), v) for n, v in zip(nl, vl)])
def to_bool(x, default_val=False):
if x is None:
return default_val
elif type(x) is str:
x = x.lower()
if x == 'true':
return True
elif x == 'false':
return False
else:
return bool(int(x))
else:
return bool(x)
#------------------------------------------------------------------
# SlsDetector base device class
#------------------------------------------------------------------
class SlsDetector(PyTango.Device_4Impl): class SlsDetector(PyTango.Device_4Impl):
Core.DEB_CLASS(Core.DebModApplication, 'LimaSlsDetector') Core.DEB_CLASS(Core.DebModApplication, 'LimaSlsDetector')
AttrNameRe = re.compile('_(?P<klass>[^_]+)__(?P<member>.+)')
#------------------------------------------------------------------ #------------------------------------------------------------------
# Device constructor # Device constructor
#------------------------------------------------------------------ #------------------------------------------------------------------
MilliVoltSuffix = '_mv' MilliVoltSuffix = '_mv'
ModelAttrs = ['parallel_mode',
'high_voltage',
'clock_div',
'fixed_clock_div',
'threshold_energy',
'tx_frame_delay',
'fpga_frame_ptr_diff',
'img_proc_config',
]
GainPedAttrs = ['map_type',
]
GainPedCalibAttrRe = re.compile('((?P<action>read|write)_)?'
'(?P<select>gain|ped)_'
'(?P<gain>[0-2])_calib_map')
GainPedProcAttrRe = re.compile('((?P<action>read|write)_)?'
'gain_ped_proc_map(?P<map_type>16|32)')
GainPedAttrRe = re.compile('((?P<action>read|write)_)?'
'gain_ped_(?P<attr>.+)')
def __init__(self,*args) : def __init__(self,*args) :
PyTango.Device_4Impl.__init__(self,*args) PyTango.Device_4Impl.__init__(self,*args)
self.init_device() self.init_device()
...@@ -135,13 +132,6 @@ class SlsDetector(PyTango.Device_4Impl): ...@@ -135,13 +132,6 @@ class SlsDetector(PyTango.Device_4Impl):
self.proc_finished = self.cam.getProcessingFinishedEvent() self.proc_finished = self.cam.getProcessingFinishedEvent()
self.proc_finished.registerStatusCallback(_SlsDetectorControl) self.proc_finished.registerStatusCallback(_SlsDetectorControl)
if self.high_voltage > 0:
self.model.setHighVoltage(self.high_voltage)
if self.fixed_clock_div > 0:
self.model.setFixedClockDiv(self.fixed_clock_div)
if self.threshold_energy > 0:
self.model.setThresholdEnergy(self.threshold_energy)
self.cam.setTolerateLostPackets(self.tolerate_lost_packets) self.cam.setTolerateLostPackets(self.tolerate_lost_packets)
aff_arr = self.pixel_depth_cpu_affinity_map aff_arr = self.pixel_depth_cpu_affinity_map
if aff_arr: if aff_arr:
...@@ -150,24 +140,11 @@ class SlsDetector(PyTango.Device_4Impl): ...@@ -150,24 +140,11 @@ class SlsDetector(PyTango.Device_4Impl):
self.printPixelDepthCPUAffinityMap(aff_map) self.printPixelDepthCPUAffinityMap(aff_map)
self.cam.setPixelDepthCPUAffinityMap(aff_map) self.cam.setPixelDepthCPUAffinityMap(aff_map)
self.gain_ped_bckgnd = None
def init_list_attr(self): def init_list_attr(self):
nl = ['FullSpeed', 'HalfSpeed', 'QuarterSpeed']
self.__ClockDiv = ConstListAttr(nl)
nl = ['NonParallel', 'Parallel']
self.__ParallelMode = ConstListAttr(nl, namespc=SlsDetectorHw.Eiger)
nl = ['PixelDepth4', 'PixelDepth8', 'PixelDepth16', 'PixelDepth32'] nl = ['PixelDepth4', 'PixelDepth8', 'PixelDepth16', 'PixelDepth32']
bdl = map(lambda x: getattr(SlsDetectorHw, x), nl) bdl = map(lambda x: getattr(SlsDetectorHw, x), nl)
self.__PixelDepth = OrderedDict([(str(bd), int(bd)) for bd in bdl]) self.__PixelDepth = OrderedDict([(str(bd), int(bd)) for bd in bdl])
nl = ['Map16', 'Map32']
klass = SlsDetectorHw.Jungfrau.GainPed
self.__GainPedMapType = ConstListAttr(nl, namespc=klass)
self.__MapType = self.__GainPedMapType
@Core.DEB_MEMBER_FUNCT @Core.DEB_MEMBER_FUNCT
def init_dac_adc_attr(self): def init_dac_adc_attr(self):
nb_modules = self.cam.getNbDetModules() nb_modules = self.cam.getNbDetModules()
...@@ -227,30 +204,19 @@ class SlsDetector(PyTango.Device_4Impl): ...@@ -227,30 +204,19 @@ class SlsDetector(PyTango.Device_4Impl):
def getAttrStringValueList(self, attr_name): def getAttrStringValueList(self, attr_name):
return get_attr_string_value_list(self, attr_name) return get_attr_string_value_list(self, attr_name)
def __getattr__(self, name): @Core.DEB_MEMBER_FUNCT
def getDevAttr(self, name, obj=None):
if '_stats_' in name: if '_stats_' in name:
stats_tok = name.split('_stats_') stats_tok = name.split('_stats_')
if stats_tok[1] in ['do_hist']: if stats_tok[1] in ['do_hist']:
stats_name = '_'.join(stats_tok) stats_name = '_'.join(stats_tok)
return get_attr_4u(self, stats_name, SlsDetectorHw.SimpleStat) return get_attr_4u(self, stats_name, SlsDetectorHw.SimpleStat)
obj = self.cam m = self.AttrNameRe.match(name)
m = self.GainPedCalibAttrRe.match(name) if m and (m.group('klass') != 'SlsDetector'):
if m: member = m.group('member')
name = f'{m.group("action")}_gain_ped_calib_map' if member in ['PixelDepth']:
return partial(getattr(self, name), map_select=m.group("select"), return getattr(self, '_SlsDetector__' + member)
gain=int(m.group("gain"))) obj = obj or self.cam
m = self.GainPedProcAttrRe.match(name)
if m:
name = f'{m.group("action")}_gain_ped_proc_map'
return partial(getattr(self, name), map_type=m.group("map_type"))
for attr in self.GainPedAttrs:
m = self.GainPedAttrRe.match(name)
if m:
name = f'{m.group("action")}_{m.group("attr")}'
obj = _SlsDetectorJungfrau.getGainPed()
for attr in self.ModelAttrs:
if attr in name:
obj = self.model
return get_attr_4u(self, name, obj) return get_attr_4u(self, name, obj)
@Core.DEB_MEMBER_FUNCT @Core.DEB_MEMBER_FUNCT
...@@ -258,11 +224,6 @@ class SlsDetector(PyTango.Device_4Impl): ...@@ -258,11 +224,6 @@ class SlsDetector(PyTango.Device_4Impl):
deb.Return("config_fname=%s" % self.config_fname) deb.Return("config_fname=%s" % self.config_fname)
attr.set_value(self.config_fname) attr.set_value(self.config_fname)
@Core.DEB_MEMBER_FUNCT
def read_apply_corrections(self, attr):
deb.Return("apply_corrections=%s" % self.apply_corrections)
attr.set_value(self.apply_corrections)
@Core.DEB_MEMBER_FUNCT @Core.DEB_MEMBER_FUNCT
def putCmd(self, cmd): def putCmd(self, cmd):
deb.Param("cmd=%s" % cmd) deb.Param("cmd=%s" % cmd)
...@@ -313,17 +274,6 @@ class SlsDetector(PyTango.Device_4Impl): ...@@ -313,17 +274,6 @@ class SlsDetector(PyTango.Device_4Impl):
for i, val in self.get_write_mod_idx_val_list(attr): for i, val in self.get_write_mod_idx_val_list(attr):
self.cam.setDAC(i, idx, val, milli_volt) self.cam.setDAC(i, idx, val, milli_volt)
@Core.DEB_MEMBER_FUNCT
def read_all_trim_bits(self, attr):
val_list = self.model.getAllTrimBitsList()
deb.Return("val_list=%s" % val_list)
attr.set_value(val_list)
@Core.DEB_MEMBER_FUNCT
def write_all_trim_bits(self, attr):
for i, val in self.get_write_mod_idx_val_list(attr):
self.model.setAllTrimBits(i, val)
@Core.DEB_MEMBER_FUNCT @Core.DEB_MEMBER_FUNCT
def get_write_mod_idx_val_list(self, attr): def get_write_mod_idx_val_list(self, attr):
attr_name = attr.get_name() attr_name = attr.get_name()
...@@ -543,63 +493,15 @@ class SlsDetector(PyTango.Device_4Impl): ...@@ -543,63 +493,15 @@ class SlsDetector(PyTango.Device_4Impl):
self.printPixelDepthCPUAffinityMap(aff_map) self.printPixelDepthCPUAffinityMap(aff_map)
self.cam.setPixelDepthCPUAffinityMap(aff_map) self.cam.setPixelDepthCPUAffinityMap(aff_map)
@Core.DEB_MEMBER_FUNCT
def read_det_map(self, attr):
det_map = self.model.getDetMap();
attr.set_value(det_map.buffer)
@Core.DEB_MEMBER_FUNCT
def read_gain_map(self, attr):
jungfrau = _SlsDetectorJungfrau
gain_data, adc_data, frame = jungfrau.readGainADCMaps(-1)
deb.Return("frame=%s, gain_data=%s" % (frame, gain_data))
attr.set_value(gain_data.buffer)
@Core.DEB_MEMBER_FUNCT
def read_adc_map(self, attr):
jungfrau = _SlsDetectorJungfrau
gain_data, adc_data, frame = jungfrau.readGainADCMaps(-1)
deb.Return("frame=%s, adc_data=%s" % (frame, adc_data))
attr.set_value(adc_data.buffer)
@Core.DEB_MEMBER_FUNCT
def getGainPedProcMap(self, map_type):
jungfrau = _SlsDetectorJungfrau
map_type_nb = self.__GainPedMapType[f'MAP{map_type}']
if jungfrau.getGainPed().getMapType() != map_type_nb:
raise ValueError('Invalid map_type %s' % map_type);
return jungfrau.readGainPedProcMap(-1)
@Core.DEB_MEMBER_FUNCT
def read_gain_ped_proc_map(self, attr, map_type):
proc_data, frame = self.getGainPedProcMap(map_type)
data = proc_data.buffer
if self.gain_ped_bckgnd is not None:
data = data - self.gain_ped_bckgnd
deb.Return("frame=%s, data=%s" % (frame, data))
attr.set_value(data)
@Core.DEB_MEMBER_FUNCT
def setGainPedBackground(self, level=0):
proc_data, frame = self.getGainPedProcMap('32')
self.gain_ped_bckgnd = proc_data.buffer.copy() - level
@Core.DEB_MEMBER_FUNCT
def clearGainPedBackground(self):
self.gain_ped_bckgnd = None
@Core.DEB_MEMBER_FUNCT
def read_gain_ped_calib_map(self, attr, map_select, gain):
gain_ped = _SlsDetectorJungfrau.getGainPed()
c = gain_ped.getCalib()
d = c.gain_map[gain] if map_select == 'gain' else c.ped_map[gain]
deb.Return("%s_%d=%s" % (map_select, gain, d))
attr.set_value(d.buffer)
@Core.DEB_MEMBER_FUNCT @Core.DEB_MEMBER_FUNCT
def clearAllBuffers(self): def clearAllBuffers(self):
self.cam.clearAllBuffers() self.cam.clearAllBuffers()
#------------------------------------------------------------------
# SlsDetector base class
#------------------------------------------------------------------
class SlsDetectorClass(PyTango.DeviceClass): class SlsDetectorClass(PyTango.DeviceClass):
class_property_list = {} class_property_list = {}
...@@ -615,22 +517,9 @@ class SlsDetectorClass(PyTango.DeviceClass): ...@@ -615,22 +517,9 @@ class SlsDetectorClass(PyTango.DeviceClass):
[PyTango.DevString, [PyTango.DevString,
"Initial acquisition parameters: " "Initial acquisition parameters: "
"acq_expo_time=0.01,acq_nb_frames=10,...", ""], "acq_expo_time=0.01,acq_nb_frames=10,...", ""],
'high_voltage':
[PyTango.DevShort,
"Initial detector high voltage (V) "
"(set to 150 if already tested)", 0],
'fixed_clock_div':
[PyTango.DevShort,
"Initial detector fixed-clock-div (0, 1)", 0],
'threshold_energy':
[PyTango.DevLong,
"Initial detector threshold energy (eV)", 0],
'tolerate_lost_packets': 'tolerate_lost_packets':
[PyTango.DevBoolean, [PyTango.DevBoolean,
"Initial tolerance to lost packets", True], "Initial tolerance to lost packets", True],
'apply_corrections':
[PyTango.DevBoolean,
"Apply frame corrections", True],
'pixel_depth_cpu_affinity_map': 'pixel_depth_cpu_affinity_map':
[PyTango.DevVarStringArray, [PyTango.DevVarStringArray,
"Default PixelDepthCPUAffinityMap as Python string(s) defining a dict: " "Default PixelDepthCPUAffinityMap as Python string(s) defining a dict: "
...@@ -668,12 +557,6 @@ class SlsDetectorClass(PyTango.DeviceClass): ...@@ -668,12 +557,6 @@ class SlsDetectorClass(PyTango.DeviceClass):
[[PyTango.DevString, "recv_idx(-1=all):stats_name"], [[PyTango.DevString, "recv_idx(-1=all):stats_name"],
[PyTango.DevVarDoubleArray, "[[bin, count], ...]"]], [PyTango.DevVarDoubleArray, "[[bin, count], ...]"]],
'clearAllBuffers': 'clearAllBuffers':
[[PyTango.DevVoid, ""],
[PyTango.DevVoid, ""]],
'setGainPedBackground':
[[PyTango.DevULong, "level"],
[PyTango.DevVoid, ""]],
'clearGainPedBackground':
[[PyTango.DevVoid, ""], [[PyTango.DevVoid, ""],
[PyTango.DevVoid, ""]], [PyTango.DevVoid, ""]],
} }
...@@ -687,14 +570,6 @@ class SlsDetectorClass(PyTango.DeviceClass): ...@@ -687,14 +570,6 @@ class SlsDetectorClass(PyTango.DeviceClass):
[[PyTango.DevString, [[PyTango.DevString,
PyTango.SPECTRUM, PyTango.SPECTRUM,
PyTango.READ, 64]], PyTango.READ, 64]],
'apply_corrections':
[[PyTango.DevBoolean,
PyTango.SCALAR,
PyTango.READ]],
'img_proc_config':
[[PyTango.DevString,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'dac_name_list': 'dac_name_list':
[[PyTango.DevString, [[PyTango.DevString,
PyTango.SPECTRUM, PyTango.SPECTRUM,
...@@ -715,30 +590,6 @@ class SlsDetectorClass(PyTango.DeviceClass): ...@@ -715,30 +590,6 @@ class SlsDetectorClass(PyTango.DeviceClass):
[[PyTango.DevBoolean, [[PyTango.DevBoolean,
PyTango.SCALAR, PyTango.SCALAR,
PyTango.READ_WRITE]], PyTango.READ_WRITE]],
'threshold_energy':
[[PyTango.DevLong,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'all_trim_bits':
[[PyTango.DevLong,
PyTango.SPECTRUM,
PyTango.READ_WRITE, 64]],
'high_voltage':
[[PyTango.DevLong,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'clock_div':
[[PyTango.DevString,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'fixed_clock_div':
[[PyTango.DevBoolean,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'parallel_mode':
[[PyTango.DevString,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'max_frame_rate': 'max_frame_rate':
[[PyTango.DevDouble, [[PyTango.DevDouble,
PyTango.SCALAR, PyTango.SCALAR,
...@@ -755,66 +606,6 @@ class SlsDetectorClass(PyTango.DeviceClass): ...@@ -755,66 +606,6 @@ class SlsDetectorClass(PyTango.DeviceClass):
[[PyTango.DevBoolean, [[PyTango.DevBoolean,
PyTango.SCALAR, PyTango.SCALAR,
PyTango.READ_WRITE]], PyTango.READ_WRITE]],
'skip_frame_freq':
[[PyTango.DevLong,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'tx_frame_delay':
[[PyTango.DevLong,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'fpga_frame_ptr_diff':
[[PyTango.DevULong,
PyTango.SPECTRUM,
PyTango.READ, 64]],
'det_map':
[[PyTango.DevULong,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'gain_map':
[[PyTango.DevUChar,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'adc_map':
[[PyTango.DevUShort,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'gain_ped_map_type':
[[PyTango.DevString,
PyTango.SCALAR,
PyTango.READ_WRITE]],
'gain_ped_proc_map16':
[[PyTango.DevUShort,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'gain_ped_proc_map32':
[[PyTango.DevULong,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'gain_0_calib_map':
[[PyTango.DevDouble,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'gain_1_calib_map':
[[PyTango.DevDouble,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'gain_2_calib_map':
[[PyTango.DevDouble,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'ped_0_calib_map':
[[PyTango.DevDouble,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'ped_1_calib_map':
[[PyTango.DevDouble,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
'ped_2_calib_map':
[[PyTango.DevDouble,
PyTango.IMAGE,
PyTango.READ, 8192, 8192]],
} }
def __init__(self,name) : def __init__(self,name) :
...@@ -822,85 +613,17 @@ class SlsDetectorClass(PyTango.DeviceClass): ...@@ -822,85 +613,17 @@ class SlsDetectorClass(PyTango.DeviceClass):
self.set_type(name) self.set_type(name)
#----------------------------------------------------------------------------
# Plugin
#----------------------------------------------------------------------------
_SlsDetectorCam = None
_SlsDetectorHwInter = None
_SlsDetectorEiger = None
_SlsDetectorJungfrau = None
_SlsDetectorCorrection = None
_SlsDetectorImgProc = None
_SlsDetectorControl = None
def get_control(config_fname, full_config_fname=None, apply_corrections=None,
**keys) :
global _SlsDetectorCam, _SlsDetectorHwInter
global _SlsDetectorEiger, _SlsDetectorJungfrau
global _SlsDetectorCorrection, _SlsDetectorImgProc
global _SlsDetectorControl
def to_bool(x, default_val=False):
if x is None:
return default_val
elif type(x) is str:
x = x.lower()
if x == 'true':
return True
elif x == 'false':
return False
else:
return bool(int(x))
else:
return bool(x)
apply_corrections = to_bool(apply_corrections, True)
if _SlsDetectorControl is None:
if full_config_fname:
p = Process(target=setup_partial_config,
args=(config_fname, full_config_fname))
p.start()
p.join()
det_id = 0
_SlsDetectorCam = SlsDetectorHw.Camera(config_fname, det_id)
det_type = _SlsDetectorCam.getType()
if det_type == SlsDetectorHw.EigerDet:
for i, n in enumerate(_SlsDetectorCam.getHostnameList()):
print('Enabling: %s (%d)' % (n, i))
_SlsDetectorCam.setModuleActive(i, True)
_SlsDetectorHwInter = SlsDetectorHw.Interface(_SlsDetectorCam)
if det_type == SlsDetectorHw.EigerDet:
_SlsDetectorEiger = SlsDetectorHw.Eiger(_SlsDetectorCam)
if apply_corrections:
_SlsDetectorCorrection = _SlsDetectorEiger.createCorrectionTask()
elif det_type == SlsDetectorHw.JungfrauDet:
_SlsDetectorJungfrau = SlsDetectorHw.Jungfrau(_SlsDetectorCam)
_SlsDetectorImgProc = _SlsDetectorJungfrau.createImgProcTask()
else:
raise ValueError("Unknown detector type: %s" %
_SlsDetectorCam.getType())
_SlsDetectorControl = Core.CtControl(_SlsDetectorHwInter)
if _SlsDetectorCorrection:
_SlsDetectorControl.setReconstructionTask(_SlsDetectorCorrection)
if _SlsDetectorImgProc:
ext_op_mgr = _SlsDetectorControl.externalOperation()
alias = 'SlsDetectorImgProc'
stage_level = 10
soft_op = ext_op_mgr.addOp(Core.USER_SINK_TASK, alias, stage_level)
soft_op.setSinkTask(_SlsDetectorImgProc)
return _SlsDetectorControl
def get_tango_specific_class_n_device():
return SlsDetectorClass, SlsDetector
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Deactivate modules in partial config # Deactivate modules in partial config
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
def check_partial_config(config_name, full_config_name):
if full_config_fname:
p = Process(target=setup_partial_config,
args=(config_fname, full_config_fname))
p.start()
p.join()
def setup_partial_config(config_fname, full_config_fname): def setup_partial_config(config_fname, full_config_fname):
import re import re
...@@ -924,3 +647,20 @@ def setup_partial_config(config_fname, full_config_fname): ...@@ -924,3 +647,20 @@ def setup_partial_config(config_fname, full_config_fname):
print('Disabling: %s (%d)' % (n, i)) print('Disabling: %s (%d)' % (n, i))
cam.setModuleActive(i, False) cam.setModuleActive(i, False)
print('Partial config: Done!') print('Partial config: Done!')
#----------------------------------------------------------------------------
# Plugin
#----------------------------------------------------------------------------
_SlsDetectorCam = None
_SlsDetectorHwInter = None
_SlsDetectorControl = None
def set_slsdetector_objs(cam, hwinter, control):
global _SlsDetectorCam, _SlsDetectorHwInter, _SlsDetectorControl
_SlsDetectorCam = cam
_SlsDetectorHwInter = hwinter
_SlsDetectorControl = control
def get_slsdetector_objs():
return _SlsDetectorCam, _SlsDetectorHwInter, _SlsDetectorControl
############################################################################
# This file is part of LImA, a Library for Image Acquisition
#
# Copyright (C) : 2009-2011
# European Synchrotron Radiation Facility
# BP 220, Grenoble 38043
# FRANCE
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or