Skip to content
LimaCCDs.py 93.5 KiB
Newer Older
coutinho's avatar
coutinho committed
#!/usr/bin/env python
############################################################################
# This file is part of LImA, a Library for Image Acquisition
#
# European Synchrotron Radiation Facility
#
# 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
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
############################################################################
#=============================================================================
#
# file :        LimaCCDs.py
#
# description : Python source for the LimaCCDs and its commands. 
#               The class is derived from Device. It represents the
#               CORBA servant object which will be accessed from the
#               network. All commands which can be executed on the
#               LimaCCDs are implemented in this file.
#
# project :    TANGO Device Server
#
# copyleft :    European Synchrotron Radiation Facility
#        BP 220, Grenoble 38043
#        FRANCE
#
#=============================================================================
#        This file is generated by seb
#
#      (c) - BLISS - ESRF
#=============================================================================
#

import sys,os,glob
import PyTango
import weakref
import itertools
import numpy
import struct

# Before loading Lima.Core, must find out the version the plug-in
# was compiled with - horrible hack ...
#if 'linux' in sys.platform:
#    from EnvHelper import setup_lima_env
#    LimaCameraType = setup_lima_env(sys.argv)
from .EnvHelper import get_sub_devices
from .EnvHelper import get_lima_camera_type, get_lima_device_name
from .EnvHelper import create_tango_objects
from .AttrHelper import get_attr_4u
from Lima.Server.AttrHelper import getDictKey, getDictValue
from Lima.Server import plugins
from Lima.Server import camera
if len(sys.argv) >1: instance_name=sys.argv[1]
else: instance_name = ''

from Lima.Server import EdfFile
    
TacoSpecificDict = {}
TacoSpecificName = []

VerboseLevel2TypeFlags = {
    0: ['Fatal'],
    1: ['Error'],
    2: ['Warning'],
    3: ['Trace'],
    4: ['Funct', 'Param', 'Return']
SystemFeatures = {}

def SystemHasFeature(feature):
    global SystemFeatures

    if feature in SystemFeatures:
        return SystemFeatures[feature]

    ok = True
    for i, name in enumerate(feature.split('.')):
        try:
            if i == 0:
                obj = globals()[name]
            else:
                obj = getattr(obj, name)
        except AttributeError:
            ok = False
            break

    SystemFeatures[feature] = ok
    return ok

def RequiresSystemFeature(feature):
    def method_decorator(f):
        def unsupported_method(*args, **kws):
            if SystemHasFeature(feature):
                return f(*args, **kws)
            re_obj = re.compile('(?P<op>(read|write))_(?P<attr>.+)')
            m = re_obj.match(f.__name__)
            if m:
                head = 'attr. %s [%s]' % (m.group('attr'), m.group('op'))
            else:
                head = 'method %s' % f.__name__
            op = re.compile
            msg = ('Error: %s cannot be called because %s is not supported ' \
                   'in this (detector-required) version of LIMA' % 
                    (head, feature))
            raise RuntimeError(msg)
        return unsupported_method
    return method_decorator

class LimaCCDs(PyTango.Device_4Impl) :

    Core.DEB_CLASS(Core.DebModApplication, 'LimaCCDs')
    _debugModuleList = ["None",
                        "Common",
                        "Hardware",
                        "HardwareSerial",
                        "Control",
                        "Espia",
                        "EspiaSerial",
                        "Focla",
                        "Camera",
                        "CameraCom",
                        "Test",
                        "Application"]
    
    _debugTypeList = ["Fatal",
                      "Error",
                      "Warning",
                      "Trace",
                      "Funct",
                      "Param",
                      "Return",
                      "Always"]
    
    ImageType2NbBytes = {
        Core.Bpp8 : (1,0) ,
        Core.Bpp8S : (1,1) ,
        Core.Bpp10 : (2,0) ,
        Core.Bpp10S : (2,1) ,
        Core.Bpp12 : (2,0) ,
        Core.Bpp12S : (2,1) ,
        Core.Bpp14 : (2,0) ,
        Core.Bpp14S : (2,1) , 
        Core.Bpp16 : (2,0),
        Core.Bpp16S : (2,1),
        Core.Bpp32 : (4,0) ,
        Core.Bpp32S : (4,1),
        }        

    ImageType2String = {
        Core.Bpp8 : "Bpp8" ,
        Core.Bpp8S : "Bpp8S" ,
        Core.Bpp10 : "Bpp10" ,
        Core.Bpp10S : "Bpp10S" ,
        Core.Bpp12 : "Bpp12" ,
        Core.Bpp12S : "Bpp12S" ,
        Core.Bpp14 : "Bpp14" ,
        Core.Bpp14S : "Bpp14S" , 
        Core.Bpp16 : "Bpp16" ,
        Core.Bpp16S : "Bpp16S" ,
        Core.Bpp32 : "Bpp32" ,
        Core.Bpp32S : "Bpp32S",
    #enum DataArrayCategory {
        #ScalarStack = 0;
        #Spectrum;
        #Image;
        #SpectrumStack;
        #ImageStack;
    #};

    class DataArrayCategory:
        ScalarStack, Spectrum, Image, SpectrumStack, ImageStack = range(5)

    #enum DataArrayType{
      #DARRAY_UINT8 = 0;
      #DARRAY_UINT16;
      #DARRAY_UINT32;
      #DARRAY_UINT64;
      #DARRAY_INT8;
      #DARRAY_INT16;
      #DARRAY_INT32;
      #DARRAY_INT64;
      #DARRAY_FLOAT32;
      #DARRAY_FLOAT64;
    #};

    ImageType2DataArrayType = {
        Core.Bpp8 : 0 ,
        Core.Bpp10 : 1 ,
        Core.Bpp12 : 1 ,
        Core.Bpp14 : 1 ,
        Core.Bpp16 : 1,
        Core.Bpp32 : 2 ,
        Core.Bpp8S : 4 ,
        Core.Bpp10S : 5 ,
        Core.Bpp12S : 5 ,
        Core.Bpp14S : 5 ,
        Core.Bpp16S : 5,
        Core.Bpp32S : 6 ,
        }        

    # The DATA_ARRAY definition
    #struct {
      #unsigned int Magic= 0x44544159;
      #unsigned short Version;
      #unsigned  short HeaderLength;
      #DataArrayCategory Category;
      #DataArrayType DataType;
      #unsigned short DataEndianness;
      #unsigned short NbDim;
      #unsigned short Dim[8]
      #unsigned int DimStep[8]
    #} DataArrayHeaderStruct;

    DataArrayPackStr = '<IHHIIHHHHHHHHIIIIIIII'
    DataArrayMagic = struct.unpack('>I', b'DTAY')[0]	# 0x44544159
    def DataArrayUser(klass, DataArrayCategory=DataArrayCategory):
        klass.DataArrayCategory = DataArrayCategory
        return klass

    # INIT events on video_last_image
    class VideoImageCallback(Core.CtVideo.ImageCallback):
        def __init__(self, device):
            Core.CtVideo.ImageCallback.__init__(self)
            self.__device = weakref.ref(device)
            self.__video_last_image_timestamp = 0
        
        def newImage(self, image):
            ts = time.time()
            device = self.__device()
            dt = ts - self.__video_last_image_timestamp
            if device.MaxVideoFPS <= 0 or dt >= 1.0 / device.MaxVideoFPS:
                self.__video_last_image_timestamp = ts
                device.push_change_event("video_last_image_counter",
                                         image.frameNumber())
                device.push_change_event("video_last_image", "VIDEO_IMAGE",
                                         _video_image_2_struct(image))          

    @DataArrayUser
    class ImageStatusCallback(Core.CtControl.ImageStatusCallback):
        def __init__(self, device, control):
            Core.CtControl.ImageStatusCallback.__init__(self)
            self.__device = weakref.ref(device)
            self.__control = weakref.ref(control)
            self.__last_base_image_ready = None
            self.__last_counter_ready = None
            self.__last_image_acquired = None
            self.__last_image_ready = None
            self.__last_image_saved = None
            self.__image_events_push_data = False
            self.__last_event_time = 0
            self.__image_events_max_rate = self.DefaultMaxEventRate

        def imageStatusChanged(self, image_status):
            last_base_image_ready = image_status.LastBaseImageReady
            last_counter_ready = image_status.LastCounterReady
            last_image_acquired = image_status.LastImageAcquired
            last_image_ready = image_status.LastImageReady
            last_image_saved = image_status.LastImageSaved
            device = self.__device()
            if self.__last_base_image_ready != last_base_image_ready:
                device.push_change_event("last_base_image_ready",
                                         last_base_image_ready)
                self.__last_base_image_ready = last_base_image_ready
            if self.__last_counter_ready != last_counter_ready:
                device.push_change_event("last_counter_ready",
                                         last_counter_ready)
            if self.__last_image_acquired != last_image_acquired:
                device.push_change_event("last_image_acquired",
                                         last_image_acquired)
                self.__last_image_acquired = last_image_acquired
            if self.__last_image_ready != last_image_ready:
                device.push_change_event("last_image_ready", last_image_ready)
                self.__last_image_ready = last_image_ready
                if (last_image_ready >= 0) and self.__image_events_push_data:
                    control = self.__control()
                    image = control.ReadImage(last_image_ready)
                    category = self.DataArrayCategory.Image
                    data = device._image_2_data_array(image, category)
                    device.push_change_event("last_image", 'DATA_ARRAY', data)
            if self.__last_image_saved != last_image_saved:
                device.push_change_event("last_image_saved",
                                         last_image_saved)
                self.__last_image_saved = last_image_saved                
            tn = time.time()
            te = self.__last_event_time + 1.0 / self.__image_events_max_rate
            if tn < te:
                time.sleep(te - tn)
            self.__last_event_time = tn

        def getImageEventsPushData(self):
            return self.__image_events_push_data

        def setImageEventsPushData(self, events):
            self.__image_events_push_data = events
        def getImageEventsMaxRate(self):
            return self.__image_events_max_rate

        def setImageEventsMaxRate(self, max_rate):
            self.__image_events_max_rate = max_rate
#------------------------------------------------------------------
#    Device constructor
#------------------------------------------------------------------
    def __init__(self,*args) :
        PyTango.Device_4Impl.__init__(self,*args)
        self.__className2deviceName = {}
        self.init_device()
        self.__lima_control = None

coutinho's avatar
coutinho committed
        self.__key_header_delimiter = '='
        self.__entry_header_delimiter = '\n'
        self.__image_number_header_delimiter = ';'
coutinho's avatar
coutinho committed
        self.__readImage_frame_number = 0
        self.__configInit = False
       
#------------------------------------------------------------------
#    Device destructor
#------------------------------------------------------------------
    @Core.DEB_MEMBER_FUNCT
    def delete_device(self) :
        try:
            m = __import__('Lima.Server.camera.%s' % (self.LimaCameraType),None,None,'Lima.Server.camera.%s' % (self.LimaCameraType))
        except ImportError:
            pass
        else:
            try:
                m.close_interface()
            except AttributeError: pass

#------------------------------------------------------------------
#    Device initialization
#------------------------------------------------------------------
    @Core.DEB_MEMBER_FUNCT
    def init_device(self) :
        self.set_state(PyTango.DevState.ON)
        self.get_device_properties(self.get_device_class())
        self.__className2deviceName = get_sub_devices()
        dataBase = PyTango.Database()

        TacoSpecificName.append(self.LimaCameraType)
coutinho's avatar
coutinho committed

        self.__control = _get_control()
        # For performance settings Pool thread (default 2) and Writing tasks (default 1)
        nb_thread = int(self.NbProcessingThread)
        Core.Processlib.PoolThreadMgr.get().setNumberOfThread(nb_thread)

        max_concurrent_writing_task = int(self.SavingMaxConcurrentWritingTask)
        if SystemHasFeature('Core.CtSaving.setMaxConcurrentWritingTask'):
            saving = self.__control.saving()
            saving.setMaxConcurrentWritingTask(max_concurrent_writing_task)
        interface = self.__control.hwInterface()
        self.__detinfo = interface.getHwCtrlObj(Core.HwCap.DetInfo)

        self.__accThresholdCallback = None
coutinho's avatar
coutinho committed

        accThresholdCallbackModule = self.AccThresholdCallbackModule
        if not accThresholdCallbackModule:
        # if NO property accThresholdCallbackModule has been set the member var. is set to []
            pass
                m = __import__('Lima.Server.plugins.%s' % (accThresholdCallbackModule),None,None,
                               'Lima.Server.plugins.%s' % (accThresholdCallbackModule))
            except ImportError:
                deb.Error("Couldn't import plugins.%s" % accThresholdCallbackModule)
            else:
                try:
                    func = getattr(m,'get_acc_threshold_callback')
                    self.__accThresholdCallback = func()
                    acc = self.__control.accumulation()
                    acc.registerThresholdCallback(self.__accThresholdCallback)
                except AttributeError:
                    deb.Error("Accumulation threshold plugins module don't have get_acc_threshold_callback function")

        #ImageType Bpp32F (Float 32)
        if SystemHasFeature('Core.Bpp32F'):
            self.ImageType2NbBytes[Core.Bpp32F] = (4,1)
            self.ImageType2String[Core.Bpp32F] = 'Bpp32F'
            self.ImageType2DataArrayType[Core.Bpp32F] = 8
            
        #ImageType Bpp1 to Bpp24
        if SystemHasFeature('Core.Bpp1'):
            for Bpp_type,Bpp_def,Bpp_name,Bpp_size in [(Core.Bpp1,(1,0),"Bpp1",0),
                                                       (Core.Bpp6,(1,0),"Bpp6", 0),
                                                       (Core.Bpp12,(2,0),"Bpp12",1),
                                                       (Core.Bpp24,(4,0),"Bpp24",2)] :
                self.ImageType2NbBytes[Bpp_type] = Bpp_def
                self.ImageType2String[Bpp_type] = Bpp_name
                self.ImageType2DataArrayType[Bpp_type] = Bpp_size
coutinho's avatar
coutinho committed
        self.__Name2SubClass = {'acc_time_mode' : self.__control.acquisition}

        self.__Prefix2SubClass = {'acc' : self.__control.accumulation,
                                  'acq' : self.__control.acquisition,
                                  'shutter' : self.__control.shutter,
                                  'saving' : self.__control.saving,
                                  'image' : self.__control.image,
                                  'video' : self.__control.video,
                                  'buffer' : self.__control.buffer}

        self.__Attribute2FunctionBase = {'acq_trigger_mode':'TriggerMode',
                                         'saving_managed_mode' : 'ManagedMode',
                                         'shutter_mode' : 'Mode',
					 'image_rotation':'Rotation',
                                         'video_mode':'Mode',
                                         'buffer_max_number': 'MaxNumber',
                                         'acc_mode': 'Mode',
                                         'acc_threshold_before': 'ThresholdBefore',
                                         'acc_offset_before': 'OffsetBefore'}
    
            
        self.__ShutterMode = {'MANUAL': Core.ShutterManual,
                              'AUTO_FRAME': Core.ShutterAutoFrame,
                              'AUTO_SEQUENCE': Core.ShutterAutoSequence}
        
        self.__AcqMode = {'SINGLE': Core.Single,
                          'CONCATENATION': Core.Concatenation,
                          'ACCUMULATION': Core.Accumulation}

        if SystemHasFeature('Core.CtAcquisition.Live'):
            self.__AccTimeMode = {'LIVE' : Core.CtAcquisition.Live,
                                  'REAL' : Core.CtAcquisition.Real}
        self.__SavingManagedMode = {'SOFTWARE' : Core.CtSaving.Software,
                                    'HARDWARE' : Core.CtSaving.Hardware}

        # default saving stream
        self.__SavingStream = 0;

        saving = self.__control.saving()
        self.__SavingFormat = saving.getFormatListAsString()

        self.__SavingMode = {'MANUAL' : Core.CtSaving.Manual,
                             'AUTO_FRAME' : Core.CtSaving.AutoFrame,
                             'AUTO_HEADER' : Core.CtSaving.AutoHeader}

        self.__SavingOverwritePolicy = {'ABORT' : Core.CtSaving.Abort,
                                        'OVERWRITE' : Core.CtSaving.Overwrite,
                                        'APPEND' : Core.CtSaving.Append}

        if SystemHasFeature('Core.CtSaving.MultiSet'):
            self.__SavingOverwritePolicy['MULTISET'] = Core.CtSaving.MultiSet

        self.__AcqTriggerMode = {'INTERNAL_TRIGGER' : Core.IntTrig,
                                 'EXTERNAL_TRIGGER' : Core.ExtTrigSingle,
                                 'EXTERNAL_TRIGGER_MULTI' : Core.ExtTrigMult,
                                 'EXTERNAL_GATE' : Core.ExtGate,
                                 'EXTERNAL_START_STOP' : Core.ExtStartStop}
coutinho's avatar
coutinho committed

        if SystemHasFeature('Core.IntTrigMult'):
coutinho's avatar
coutinho committed
            self.__AcqTriggerMode['INTERNAL_TRIGGER_MULTI'] = Core.IntTrigMult

        if SystemHasFeature('Core.ExtTrigReadout'):
coutinho's avatar
coutinho committed
            self.__AcqTriggerMode['EXTERNAL_TRIGGER_READOUT'] = Core.ExtTrigReadout
        if SystemHasFeature('Core.Rotation_0'):
            self.__ImageRotation = {'NONE' : Core.Rotation_0,
                                    '90' : Core.Rotation_90,
                                    '180' : Core.Rotation_180,
                                    '270' : Core.Rotation_270}
 
        if SystemHasFeature('Core.CtAccumulation.Parameters.STANDARD'):
            self.__AccMode = {'STANDARD': Core.CtAccumulation.Parameters.STANDARD,
                              'THRESHOLD_BEFORE': Core.CtAccumulation.Parameters.THRESHOLD_BEFORE,
                              'OFFSET_THEN_THRESHOLD_BEFORE': Core.CtAccumulation.Parameters.OFFSET_THEN_THRESHOLD_BEFORE}

        try:
            self.__VideoMode = {'Y8'         : Core.Y8,
                                'Y16'        : Core.Y16,
                                'Y32'        : Core.Y32,
                                'Y64'        : Core.Y64,
                                'RGB555'     : Core.RGB555,
                                'RGB565'     : Core.RGB565,
                                'RGB24'      : Core.RGB24,
                                'RGB32'      : Core.RGB32,
                                'BGR24'      : Core.BGR24,
                                'BGR32'      : Core.BGR32,
                                'BAYER_RG8'  : Core.BAYER_RG8,
                                'BAYER_RG16' : Core.BAYER_RG16,
                                'I420'       : Core.I420,
                                'YUV411'     : Core.YUV411,
                                'YUV422'     : Core.YUV422,
                                'YUV444'     : Core.YUV444}
        except AttributeError:
            import traceback
            traceback.print_exc()

        if SystemHasFeature('Core.BAYER_BG8'):
            self.__VideoMode['BAYER_BG8'] = Core.BAYER_BG8
            self.__VideoMode['BAYER_BG16'] = Core.BAYER_BG16
        #new formats added in core 1.7
        if SystemHasFeature('Core.YUV411PACKED'):
            self.__VideoMode['YUV411PACKED'] = Core.YUV411PACKED
            self.__VideoMode['YUV422PACKED'] = Core.YUV422PACKED
            self.__VideoMode['YUV444PACKED'] = Core.YUV444PACKED

        self.__VideoSource = {}
        if SystemHasFeature('Core.CtVideo.BASE_IMAGE'):
            self.__VideoSource = {'BASE_IMAGE': Core.CtVideo.BASE_IMAGE,
                                  'LAST_IMAGE': Core.CtVideo.LAST_IMAGE}
            self.__shared_memory_names = ['LimaCCds',instance_name]
            shared_memory = self.__control.display()
            shared_memory.setNames(*self.__shared_memory_names)
        except AttributeError:
            pass

        # INIT events on attributes
        attr_list = self.get_device_attr()
        for attr_name in ["last_image", "last_base_image_ready",
                          "last_counter_ready", "last_image_acquired",
                          "last_image_ready", "last_image_saved",
                          "video_last_image", "video_last_image_counter"]:
            attr = attr_list.get_attr_by_name(attr_name)
            attr.set_change_event(True, False)
        
        if self.TangoEvent:
            self.__video_image_cbk = self.VideoImageCallback(self)
            self.__control.video().registerImageCallback(self.__video_image_cbk)
            # INIT events on last_image_ready
            self.__image_status_cbk = self.ImageStatusCallback(self, self.__control)
            self.__control.registerImageStatusCallback(self.__image_status_cbk)
        # Setup a user-defined detector name if it exists
        if self.UserInstrumentName:
            if SystemHasFeature('Core.HwDetInfoCtrlObj.setUserInstrumentName'):
                self.__detinfo.setUserInstrumentName(self.UserInstrumentName)
                deb.Warning('UserInstrumentName not supported in this version')
        # Setup a user-defined detector name if it exists
        if self.UserDetectorName:
            if SystemHasFeature('Core.HwDetInfoCtrlObj.setUserDetectorName'):
                self.__detinfo.setUserDetectorName(self.UserDetectorName)
            else:
                deb.Warning('UserDetectorName not supported in this version')

        # Setup the max memory usage (%)
        if self.BufferMaxMemory:
            self.__control.buffer().setMaxMemory(int(self.BufferMaxMemory))

        unsupported_feature = 'Core.Never.Unsupported.Feature'
        if SystemHasFeature(unsupported_feature):
            deb.Error('System reports having %s' % unsupported_feature)

        for feature in SystemFeatures:
            is_not = (SystemHasFeature(feature) and 'is') or 'is not'
            deb.Trace('Feature %s %s present' % (feature, is_not))
    def __getattr__(self,name) :
        if name.startswith('is_') and name.endswith('_allowed') :
            split_name = name.split('_')[1:-1]
            attr_name = ''.join([x.title() for x in split_name])
            dict_name = '_' + self.__class__.__name__ + '__' + attr_name
            d = getattr(self,dict_name,None)
            func = _allowed
            if d is not None:
                if not d:
                    func = _not_allowed
            self.__dict__[name] = func
            return func
        else :
             split_name = name.split('_')[1:]
coutinho's avatar
coutinho committed
             subClass = self.__Name2SubClass.get("_".join(split_name),None)
             if subClass is None:
                 subClass = self.__Prefix2SubClass.get(split_name[0],None)
             if subClass:
                 obj = subClass()
                 return get_attr_4u(self,name, obj)
        
        raise AttributeError('LimaCCDs has no attribute %s' % name)

    @Core.DEB_MEMBER_FUNCT
    def apply_config(self) :
        '''
        Apply configuration. Identification of config to apply is found
        in DS properties "ConfigurationDefaultName" and
        "ConfigurationFilePath".
        Apply by default "default" config.
        '''
        if not self.__configInit:
            self.__configInit = True
            #Configuration mgt
            config_file_path = self.ConfigurationFilePath
            config_default_name = self.ConfigurationDefaultName

            deb.Always("Applied config : %s : %s " % (config_file_path, config_default_name))
            self.__configDefaultActiveFlag = False
                config = self.__control.config()
                config.setFilename(config_file_path)
                if os.access(config_file_path,os.R_OK):
                    try:
                        config.load()
                        if config_default_name in config.getAlias() :
                            config.apply(config_default_name)
                            self.__configDefaultActiveFlag = True
                    except Core.Exception:
                        pass

#==================================================================
#
#    LimaCCDs read/write attribute methods
#
#==================================================================

    ## @brief Read the Lima Type
    #
    @Core.DEB_MEMBER_FUNCT
    def read_lima_type(self,attr) :        
        value  = self.LimaCameraType	
        attr.set_value(value)

    ## @brief Read the Camera Type
    #
    @Core.DEB_MEMBER_FUNCT
    def read_camera_type(self,attr) :        
        value = self.__detinfo.getDetectorType()
        attr.set_value(value)

    ## @brief Read the Camera Model
    #
    @Core.DEB_MEMBER_FUNCT
    def read_camera_model(self,attr) :        
        value = self.__detinfo.getDetectorModel()
coutinho's avatar
coutinho committed
        attr.set_value(value)
    @RequiresSystemFeature('Core.HwDetInfoCtrlObj.getUserDetectorName')
    @Core.DEB_MEMBER_FUNCT
    def read_user_detector_name(self,attr) :        
        value = self.__detinfo.getUserDetectorName() 
        attr.set_value(value)
    @RequiresSystemFeature('Core.HwDetInfoCtrlObj.setUserDetectorName')
    @Core.DEB_MEMBER_FUNCT
    def write_user_detector_name(self,attr) :
        data = attr.get_write_value()
        self.__detinfo.setUserDetectorName(data)
    ## @brief Read the user instrument name
    @RequiresSystemFeature('Core.HwDetInfoCtrlObj.getUserInstrumentName')
    @Core.DEB_MEMBER_FUNCT
    def read_user_instrument_name(self,attr) :        
        value = self.__detinfo.getUserInstrumentName() 
        attr.set_value(value)
    ## @brief Write the user instrument name
    @RequiresSystemFeature('Core.HwDetInfoCtrlObj.setUserInstrumentName')
    @Core.DEB_MEMBER_FUNCT
    def write_user_instrument_name(self,attr) :
        data = attr.get_write_value()
        self.__detinfo.setUserInstrumentName(data)
    ## @brief Read the Camera pixelsize
    #
    @Core.DEB_MEMBER_FUNCT
    def read_camera_pixelsize(self,attr) :        
coutinho's avatar
coutinho committed
        attr.set_value(value)
        
    ## @brief get the status of the acquisition
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acq_status(self,attr) :
        status = self.__control.getStatus()
        state2string = {Core.AcqReady : "Ready",
                        Core.AcqRunning : "Running",
                        Core.AcqFault : "Fault"}
            state2string[Core.AcqConfig] = "Configuration"

        attr.set_value(state2string.get(status.AcquisitionStatus,"?"))
    ## @brief get the errir message when acq_status is in Fault stat
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acq_status_fault_error(self,attr) :
        status = self.__control.getStatus()
        state2string = {Core.CtControl.NoError : "No error",
                        Core.CtControl.SaveUnknownError : "Saving: unknown error",
                        Core.CtControl.SaveOpenError : "Saving: file open error",
                        Core.CtControl.SaveCloseError : "Saving: file close error",
                        Core.CtControl.SaveAccessError : "Saving: access error",
                        Core.CtControl.SaveOverwriteError : "Saving: overwrite error",
                        Core.CtControl.SaveDiskFull : "Saving: disk full",
                        Core.CtControl.SaveOverun : "Saving: overun",
                        Core.CtControl.ProcessingOverun : "Processing: overun",
                        Core.CtControl.CameraError : "Camera: error"}
        attr.set_value(state2string.get(status.Error,"?"))
        
    ## @brief read the number of frame for an acquisition
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acq_nb_frames(self,attr) :
        acquisition = self.__control.acquisition()
        nb_frames = acquisition.getAcqNbFrames()
        attr.set_value(nb_frames)

    ## @brief write the number of frame for an acquisition
    #
    @Core.DEB_MEMBER_FUNCT
    def write_acq_nb_frames(self,attr) :
        data = attr.get_write_value()
        acquisition = self.__control.acquisition()
        acquisition.setAcqNbFrames(data)
        
    ## @brief read the number of frame for an acquisition
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acq_expo_time(self,attr) :
        acquisition = self.__control.acquisition()
        expo_time = acquisition.getAcqExpoTime()
        attr.set_value(expo_time)

    ## @brief write the number of frame for an acquisition
    #
    @Core.DEB_MEMBER_FUNCT
    def write_acq_expo_time(self,attr) :
        data = attr.get_write_value()
        acquisition = self.__control.acquisition()
        acquisition.setAcqExpoTime(data)
        
    ## @brief Read maximum accumulation exposure time
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acc_max_expo_time(self,attr) :        
coutinho's avatar
coutinho committed
        acq = self.__control.acquisition()

        value = acq.getAccMaxExpoTime()
coutinho's avatar
coutinho committed
        if value is None: value = -1
	
        attr.set_value(value)

    ## @brief Write the accumulation max exposure time
    #
    @Core.DEB_MEMBER_FUNCT
    def write_acc_max_expo_time(self,attr) :
        data = attr.get_write_value()
coutinho's avatar
coutinho committed
        acq = self.__control.acquisition()
        acq.setAccMaxExpoTime(data)

    ## @brief Read maximum accumulation exposure time
    #
    @Core.DEB_MEMBER_FUNCT
    def read_concat_nb_frames(self,attr) :        
coutinho's avatar
coutinho committed
        acq = self.__control.acquisition()
        value = acq.getConcatNbFrames()
        attr.set_value(value)

    ## @brief Write the accumulation max exposure time
    #
    @Core.DEB_MEMBER_FUNCT
    def write_concat_nb_frames(self,attr) :
        data = attr.get_write_value()
coutinho's avatar
coutinho committed
        acq = self.__control.acquisition()
        acq.setConcatNbFrames(data)

    ## @brief Read calculated accumulation exposure time
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acc_expo_time(self,attr) :        
coutinho's avatar
coutinho committed
        acq = self.__control.acquisition()
coutinho's avatar
coutinho committed
        if value is None: value = -1
	
        attr.set_value(value)
	
    ## @brief Read calculated accumulation number of frames
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acc_nb_frames(self,attr) :        
coutinho's avatar
coutinho committed
        acq = self.__control.acquisition()
        value = acq.getAccNbFrames()
coutinho's avatar
coutinho committed
        if value is None: value = -1
	
        attr.set_value(value)

    ## @brief Read calculated accumulation dead time
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acc_dead_time(self,attr) :        
coutinho's avatar
coutinho committed
        acq = self.__control.acquisition()
        value = acq.getAccDeadTime()

        attr.set_value(value)

    ## @brief Read calculated accumulation live time
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acc_live_time(self,attr) :        
coutinho's avatar
coutinho committed
        acq = self.__control.acquisition()
        value = acq.getAccLiveTime()
	
        attr.set_value(value)

    ## @brief Read if saturated calculation is active
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acc_saturated_active(self,attr) :        
coutinho's avatar
coutinho committed
        acc = self.__control.accumulation()
        value = acc.getActive()
	
        attr.set_value(value)

    ## @brief active/unactive calculation of saturated images and counters
    #
    @Core.DEB_MEMBER_FUNCT
    def write_acc_saturated_active(self,attr) :            
        data = attr.get_write_value()

coutinho's avatar
coutinho committed
        acc = self.__control.accumulation()
        acc.setActive(data)

    ## @brief Read saturated threshold
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acc_saturated_threshold(self,attr) :        
coutinho's avatar
coutinho committed
        acc = self.__control.accumulation()
        value = acc.getPixelThresholdValue()
	
        attr.set_value(value)

    ## @brief Set saturated threshold
    #
    @Core.DEB_MEMBER_FUNCT
    def write_acc_saturated_threshold(self,attr) :        
Laurent Claustre's avatar
Laurent Claustre committed
        data = attr.get_write_value()
coutinho's avatar
coutinho committed
        acc = self.__control.accumulation()
        acc.setPixelThresholdValue(data)

    ## @brief Read if saturated calculation is active
    #
    @Core.DEB_MEMBER_FUNCT
    def read_acc_saturated_cblevel(self,attr) :
        if self.__accThresholdCallback is not None:
            attr.set_value(self.__accThresholdCallback.m_max)
        else:
            msg = "Accumulation threshold plugins not loaded"
            deb.Error(msg)

    ## @brief active/unactive calculation of saturated images and counters
    #
    @Core.DEB_MEMBER_FUNCT
    def write_acc_saturated_cblevel(self,attr) :        
        data = attr.get_write_value()
        if self.__accThresholdCallback is not None:
            self.__accThresholdCallback.m_max = data
        else:
            msg = "Accumulation threshold plugins not loaded"
            deb.Error(msg)
coutinho's avatar
coutinho committed
            raise Exception(msg)
    ## @brief Read latency time 
    #
    @Core.DEB_MEMBER_FUNCT
    def read_latency_time(self,attr) :
        acq = self.__control.acquisition()

        value = acq.getLatencyTime()
        if value is None: value = -1

        attr.set_value(value)

    ## @brief Write Latency time 
    #
    @Core.DEB_MEMBER_FUNCT
    def write_latency_time(self,attr) :
        data = attr.get_write_value()
        acq = self.__control.acquisition()

        acq.setLatencyTime(data)

    ## @brief Read the valid latency and exposure valid ranges
    #
    @Core.DEB_MEMBER_FUNCT
    def read_valid_ranges(self,attr) :        
        interface = self.__control.hwInterface()
coutinho's avatar
coutinho committed
        sync = interface.getHwCtrlObj(Core.HwCap.Sync)
        ranges = sync.getValidRanges()
        attr.set_value([ranges.min_exp_time,ranges.max_exp_time,ranges.min_lat_time,ranges.max_lat_time])


    ## @brief Read image Roi
    #
    @Core.DEB_MEMBER_FUNCT
    def read_image_roi(self,attr) :
        image = self.__control.image()
        roi = image.getRoi()
        point = roi.getTopLeft()
        size = roi.getSize()
        
        attr.set_value([point.x,point.y,
                        size.getWidth(),size.getHeight()])

    ## @brief Write image Roi
    #
    @Core.DEB_MEMBER_FUNCT
    def write_image_roi(self,attr) :
        data = attr.get_write_value()
        image = self.__control.image()
        roi = Core.Roi(*data)
        image.setRoi(roi)

    ## @brief Read image type
    #
    @Core.DEB_MEMBER_FUNCT
    def read_image_sizes(self,attr) :
        image = self.__control.image()
        imageType = image.getImageType()
        dim = image.getImageDim()
        depth, signed = self.ImageType2NbBytes.get(imageType,(0,0))
        sizes = [signed, depth, dim.getSize().getWidth(), dim.getSize().getHeight()]
        
        attr.set_value(sizes)

    ## @brief Read image type
    #
    @Core.DEB_MEMBER_FUNCT
    def read_image_type(self,attr) :
        image = self.__control.image()
        imageType = image.getImageType()
        stringType = self.ImageType2String.get(imageType,"?")
                
        attr.set_value(stringType)

    ## @brief Read image width
    #
    @Core.DEB_MEMBER_FUNCT
    def read_image_width(self,attr) :
        image = self.__control.image()
coutinho's avatar
coutinho committed
        dim = image.getImageDim()
                        
        attr.set_value(dim.getSize().getWidth())

    ## @brief Read image height
    #
    @Core.DEB_MEMBER_FUNCT
    def read_image_height(self,attr) :
        image = self.__control.image()
coutinho's avatar
coutinho committed
        dim = image.getImageDim()
                        
        attr.set_value(dim.getSize().getHeight())