Ejemplo n.º 1
0
class BLEnergy(Device):

    stateEnergy = {
        'ALARM': 'error',
        'FAULT': 'error',
        'RUNNING': 'moving',
        'MOVING': 'moving',
        'STANDBY': 'ready',
        'UNKNOWN': 'unknown',
        'DISABLE': 'disable',
        'EXTRACT': 'outlimits'
    }

    def init(self):

        self.moving = None
        self.deviceOk = True
        self.prev_state = None
        self.doBacklashCompensation = False

        # Channel and commands for monochormator pitch.
        #    it will be used here to make sure it is on before moving energy (PX2)
        #    not needed on PX1
        self.mono_mt_rx_statech = None
        self.mono_mt_rx_oncmd = None

        # Connect to device BLEnergy defined "tangoname" in the xml file
        try:
            self.BLEnergydevice = DeviceProxy(self.getProperty("tangoname"))
        except:
            self.errorDeviceInstance(self.getProperty("tangoname"))

        # Connect to device mono defined "tangoname2" in the xml file
        # used for conversion in wavelength
        try:
            self.monodevice = DeviceProxy(self.getProperty("tangoname2"))
        except:
            self.errorDeviceInstance(self.getProperty("tangoname2"))

        # Nom du device bivu (Energy to gap) : necessaire pour amelioration du positionnement de l'onduleur (Backlash)
        try:
            #            self.U20Energydevice = DeviceProxy(self.getProperty("tangoname3"), movingState="RUNNING")
            # Modif suite a changement par ICA de l etat du device U20 RUNNING devient MOVING
            self.U20Energydevice = DeviceProxy(self.getProperty("tangoname3"))
        except:
            self.errorDeviceInstance(self.getProperty("tangoname3"))

        self.doBacklashCompensation = self.getProperty("backlash")
        #        print self.doBacklashCompensation

        try:
            self.mono_mt_rx_statech = self.getChannelObject("mono_mt_rx_state")
            self.mono_mt_rx_oncmd = self.getCommandObject("mono_mt_rx_on")
        except KeyError:
            logging.info(
                "Beware that mt_rx control is not properly defined for BLEnergy"
            )

        try:
            self.mono_mt_rx_fine_statech = self.getChannelObject(
                "mono_mt_rx_fine_state")
            self.mono_mt_rx_fine_oncmd = self.getCommandObject(
                "mono_mt_rx_fine_on")
        except KeyError:
            logging.info(
                "Beware that mt_rx control is not properly defined for BLEnergy"
            )

        self.get_energy_limits = self.getEnergyLimits
        self.get_wavelength_limits = self.getWavelengthLimits
        # parameters for polling
        if self.deviceOk:
            self.isConnected()
            self.prev_state = str(self.BLEnergydevice.State())

            energyChan = self.getChannelObject("energy")
            energyChan.connectSignal("update", self.energyChanged)

            stateChan = self.getChannelObject(
                "state"
            )  # utile seulement si statechan n'est pas defini dans le code
            stateChan.connectSignal("update", self.stateChanged)
        self.can_move_energy = self.canMoveEnergy
        self.move_energy = self.startMoveEnergy
        self.move_wavelength = self.startMoveWavelength

    def stateChanged(self, value):
        if (str(value) == 'MOVING'):
            self.moveEnergyCmdStarted()
        if self.prev_state == 'MOVING' or self.moving == True:
            if str(value) != 'MOVING':
                self.moveEnergyCmdFinished()

        self.prev_state = str(value)

        self.emit('stateChanged', BLEnergy.stateEnergy[str(value)])

    # function called during polling
    def energyChanged(self, value):
        #logging.getLogger("HWR").debug("%s: BLEnergy.energyChanged: %.3f", self.name(), value)
        #logging.info(">>>>>>>>  %s: BLEnergy.energyChanged: %.3f", self.name(), value)
        wav = self.monodevice.read_attribute("lambda").value
        if wav is not None:
            self.emit('energyChanged', (value, wav))

    def connectNotify(self, signal):
        logging.getLogger("HWR").info("%s: BLEnergy.connectNotify, : %s",
                                      self.name(), signal)
        if signal == 'energyChanged':
            self.energyChanged(self.BLEnergydevice.energy)
        if signal == 'stateChanged':
            self.stateChanged(str(self.BLEnergydevice.State()))
        self.setIsReady(True)

    # called by brick : not useful
    def isSpecConnected(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.isSpecConnected",
                                       self.name())
        return True

    def isConnected(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.isConnected", self.name())
        return True

    def sConnected(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.sConnected", self.name())
        self.deviceOk = True
        self.emit('connected', ())

    def sDisconnected(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.sDisconnected",
                                       self.name())
        self.deviceOk = False
        self.emit('disconnected', ())

    def isDisconnected(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.isDisconnected",
                                       self.name())
        return True

    # Definit si la beamline est a energie fixe ou variable
    def canMoveEnergy(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.canMoveEnergy",
                                       self.name())
        return True

    def getPosition(self):
        return self.getCurrentEnergy()

    def getCurrentEnergy(self):
        if self.deviceOk:
            return self.BLEnergydevice.energy
        else:
            return None

    def getState(self):
        return self.BLEnergydevice.State().name

    def getEnergyComputedFromCurrentGap(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.getCurrentEnergy",
                                       self.name())
        if self.deviceOk:
            # PL. Rq: if the device is not redy, it send a NaN...
            return self.U20Energydevice.energy
        else:
            return None

    def getCurrentUndulatorGap(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.getCurrentEnergy",
                                       self.name())
        if self.deviceOk:
            return self.U20Energydevice.gap
        else:
            return None

    def getCurrentWavelength(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.getCurrentWavelength",
                                       self.name())
        # Pb with the attribute name "lamdda" which is a keyword for python
        if self.deviceOk:
            # using calculation of the device mono
            return self.monodevice.read_attribute("lambda").value
        else:
            return None

    def getEnergyLimits(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.getEnergyLimits",
                                       self.name())
        if self.deviceOk:
            # limits defined in tango
            enconfig = self.BLEnergydevice.get_attribute_config("energy")
            max = float(enconfig.max_value)
            min = float(enconfig.min_value)
            lims = (min, max)

            logging.getLogger("HWR").info("HOS : energy Limits: %.4f %.4f" %
                                          lims)
            return lims
        else:
            return None

    def getWavelengthLimits(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.getWavelengthLimits",
                                       self.name())
        if self.deviceOk:
            lims = []
            # Recuperation des limites en energie
            energylims = self.getEnergyLimits()
            # Conversion de la limite inferieure en wavelength superieure (Utilisation des fonctions de conversion du device mono)
            self.monodevice.simEnergy = energylims[1]
            lims.append(self.monodevice.simLambda)
            # Conversion de la limite superieure en wavelength inferieure (Utilisation des fonctions de conversion du device mono)
            self.monodevice.simEnergy = energylims[0]
            lims.append(self.monodevice.simLambda)
            #        logging.getLogger("HWR").info("HOS : wavelength Limits: %.4f %.4f" % lims)
            logging.getLogger("HWR").info("HOS : wavelength Limits: %s" % lims)
            return lims
        else:
            return None

    def startMoveEnergy(self, value, wait=False):
        logging.getLogger("HWR").debug("%s: BLEnergy.startMoveEnergy: %.3f",
                                       self.name(), float(value))

        # MODIFICATION DE CETTE FONCTION POUR COMPENSER LE PROBLEME D'HYSTERESIS DE L"ONDULEUR
        # PAR CETTE METHODE ON APPLIQUE TOUJOURS UN GAP CROISSANT
        backlash = 0.1  # en mm
        gaplimite = 5.5  # en mm

        if self.mono_mt_rx_statech is not None and self.mono_mt_rx_oncmd is not None:
            while str(self.mono_mt_rx_statech.getValue()) == 'OFF':
                logging.getLogger("HWR").info(
                    "BLEnergy : turning mono1-mt_rx on")
                self.mono_mt_rx_oncmd()
                time.sleep(0.2)

        if self.mono_mt_rx_fine_statech is not None and self.mono_mt_rx_fine_oncmd is not None:
            while str(self.mono_mt_rx_fine_statech.getValue()) == 'OFF':
                logging.getLogger("HWR").info(
                    "BLEnergy : turning mono1-mt_rx_fine on")
                self.mono_mt_rx_fine_oncmd()
                time.sleep(0.2)

        if (str(self.BLEnergydevice.State()) != "MOVING" and self.deviceOk):
            if self.doBacklashCompensation:
                try:
                    # Recuperation de la valeur de gap correspondant a l'energie souhaitee
                    self.U20Energydevice.autoApplyComputedParameters = False
                    self.U20Energydevice.energy = value
                    newgap = self.U20Energydevice.computedGap
                    actualgap = self.U20Energydevice.gap

                    self.U20Energydevice.autoApplyComputedParameters = True

                    # On applique le backlash que si on doit descendre en gap
                    if newgap < actualgap + backlash:
                        # Envoi a un gap juste en dessous (backlash)
                        if newgap - backlash > gaplimite:
                            self.U20Energydevice.gap = newgap - backlash
                        else:
                            self.U20Energydevice.gap = gaplimite
                            self.U20Energydevice.gap = newgap + backlash
                        time.sleep(1)
                except:
                    logging.getLogger("HWR").error(
                        "%s: Cannot move undulator U20 : State device = %s",
                        self.name(), str(self.U20Energydevice.State()))

            try:
                # Envoi a l'energie desiree
                self.BLEnergydevice.energy = value
            except:
                logging.getLogger("HWR").error(
                    "%s: Cannot move BLEnergy : State device = %s",
                    self.name(), str(self.BLEnergydevice.State()))

        else:
            statusBLEnergydevice = self.BLEnergydevice.Status()
            logging.getLogger("HWR").error(
                "%s: Cannot move : State device = %s", self.name(),
                str(self.BLEnergydevice.State()))

            for i in statusBLEnergydevice.split("\n"):
                logging.getLogger().error("\t%s\n" % i)
            logging.getLogger().error("\tCheck devices")

    def startMoveWavelength(self, value, wait=False):
        logging.getLogger("HWR").debug(
            "%s: BLEnergy.startMoveWavelength: %.3f", self.name(), value)
        self.monodevice.simLambda = value
        self.startMoveEnergy(self.monodevice.simEnergy)


#        return self.startMoveEnergy(energy_val)

    def cancelMoveEnergy(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.cancelMoveEnergy",
                                       self.name())
        self.BLEnergydevice.Stop()
        self.moving = False

    def energyLimitsChanged(self, limits):
        logging.getLogger("HWR").debug(
            "%s: BLEnergy.energyLimitsChanged: %.3f", self.name(), value)
        self.monodevice.simEnergy = limits[0]
        wav_limits.append[self.monodevice.simLambda]
        self.monodevice.simEnergy = limits[1]
        wav_limits.append[self.monodevice.simLambda]
        self.emit('energyLimitsChanged', (limits, ))
        if wav_limits[0] != None and wav_limits[1] != None:
            self.emit('wavelengthLimitsChanged', (wav_limits, ))
        else:
            self.emit('wavelengthLimitsChanged', (None, ))

    def moveEnergyCmdReady(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.moveEnergyCmdReady",
                                       self.name())
        if not self.moving:
            self.emit('moveEnergyReady', (True, ))

    def moveEnergyCmdNotReady(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.moveEnergyCmdNotReady",
                                       self.name())
        if not self.moving:
            self.emit('moveEnergyReady', (False, ))

    def moveEnergyCmdStarted(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.moveEnergyCmdStarted",
                                       self.name())
        self.moving = True
        #self.emit('moveEnergyStarted',(BLEnergy.stateEnergy[str(self.BLEnergydevice.State())]))
        self.emit('moveEnergyStarted', ())

    def moveEnergyCmdFailed(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.moveEnergyCmdFailed",
                                       self.name())
        self.moving = False
        self.emit('moveEnergyFailed', ())

    def moveEnergyCmdAborted(self):
        self.moving = False
        logging.getLogger("HWR").debug("%s: BLEnergy.moveEnergyCmdAborted",
                                       self.name())

    def moveEnergyCmdFinished(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.moveEnergyCmdFinished",
                                       self.name())
        self.moving = False
        print 'moveEnergyFinished'
        #self.emit('moveEnergyFinished',(BLEnergy.stateEnergy[str(self.BLEnergydevice.State())]))
        self.emit('moveEnergyFinished', ())

    def getPreviousResolution(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.getPreviousResolution",
                                       self.name())
        return (None, None)

    def restoreResolution(self):
        logging.getLogger("HWR").debug("%s: BLEnergy.restoreResolution",
                                       self.name())
        return (False, "Resolution motor not defined")

    def errorDeviceInstance(self, device):
        logging.getLogger("HWR").debug("%s: BLEnergy.errorDeviceInstance: %s",
                                       self.name(), device)
        db = DeviceProxy("sys/database/dbds1")
        logging.getLogger().error("Check Instance of Device server %s" %
                                  db.DbGetDeviceInfo(device)[1][3])
        self.sDisconnected()
Ejemplo n.º 2
0
class TangoResolutionComplex(BaseHardwareObjects.Equipment):
#     resoState = {
#         None: 'unknown',
#         'UNKNOWN': 'unknown',
#         'CLOSE': 'closed',
#         'OPEN': 'opened',
#         'MOVING': 'moving',
#         'FAULT': 'fault',
#         'DISABLE': 'disabled',
#         'OFF': 'fault',
#         'ON': 'unknown'
#         }
        
    stateDict = {
         "UNKNOWN": 0,
         "OFF":     1,
         "ALARM":   1,
         "STANDBY": 2,
         "RUNNING": 4,
         "MOVING":  4,
         "2":       2,
         "1":       1}
   
    
    def _init(self):
        self.currentResolution = None
        self.currentDistance = None
        self.currentWavelength = None
        self.currentEnergy = None
        self.connect("equipmentReady", self.equipmentReady)
        self.connect("equipmentNotReady", self.equipmentNotReady)
        #self.device = SimpleDevice(self.getProperty("tangoname"), waitMoves = False, verbose=False)
        self.device = DeviceProxy(self.getProperty("tangoname"))
        #self.device.timeout = 3000 # Setting timeout to 3 sec
        
        #self.monodevice = SimpleDevice(self.getProperty("tangoname2"), waitMoves = False, verbose=False)

        hobj = self.getProperty("BLEnergy")
        logging.getLogger("HWR").debug('TangoResolution: load specify the %s hardware object' % hobj)
        self.blenergyHO = None
        if hobj is not None:
            try:
                self.blenergyHO=HardwareRepository.HardwareRepository().getHardwareObject(hobj)
            except:
                logging.getLogger("HWR").error('TangoResolutionComplex: BLEnergy is not defined in resolution equipment %s', str(self.name()))
       
        if self.blenergyHO is not None:
            #self.connect(self.blenergyHO, "energyChanged",self.energyChanged)
            self.blenergyHO.connect("energyChanged",self.energyChanged)
        else:
            logging.info('TANGORESOLUTION : BLENERGY is not defined in TangoResolution equipment %s', str(self.name()))

        #self.connect(self.blenergyHO,, "energyChanged",self.energyChanged)
        #self.connect(self.beam_info_hwobj, 
        #                 "beamPosChanged", 
        #                 self.beam_position_changed)
            #self.blenergyHO.connectSignal('energyChanged', self.energyChanged)
        # creer un chanel sur l'energy: pour faire un update 
        positChan = self.getChannelObject("position") # utile seulement si statechan n'est pas defini dans le code
        positChan.connectSignal("update", self.positionChanged)
        stateChan = self.getChannelObject("state") # utile seulement si statechan n'est pas defini dans le code
        stateChan.connectSignal("update", self.stateChanged)
        
        self.currentDistance = self.device.position
        self.currentEnergy = self.blenergyHO.getCurrentEnergy()
        self.currentWavelength = self.blenergyHO.getCurrentWavelength()
        return BaseHardwareObjects.Equipment._init(self)

        
    def init(self):
        #self.detm = self.getDeviceByRole("detm")
        #self.dtox = self.getDeviceByRole("dtox")
        #self.dist2res = self.getCommandObject("dist2res")
        #self.res2dist = self.getCommandObject("res2dist")
        self.__resLimitsCallback = None
        
        
        self.__resLimitsErrCallback = None
        self.__resLimits = {}

        #self.connect(self.device, "stateChanged", self.detmStateChanged)
        #self.dist2res.connectSignal("commandReplyArrived", self.newResolution)
        #self.res2dist.connectSignal("commandReplyArrived", self.newDistance)
    
    def positionChanged(self, value):
        res = self.dist2res(value)
        try:
            logging.getLogger("HWR").debug("%s: TangoResolution.positionChanged: %.3f", self.name(), res)
        except:
            logging.getLogger("HWR").error("%s: TangoResolution not responding, %s", self.name(), '')       
        self.emit('positionChanged', (res,))

    
    def getState(self):
        return TangoResolutionComplex.stateDict[str(self.device.State())] 

                
    def equipmentReady(self):
        self.emit("deviceReady")


    def equipmentNotReady(self):    
        self.emit("deviceNotReady")
        

    def get_value(self):
        return self.getPosition()
        

    def getPosition(self):
        #if self.currentResolution is None:
        self.recalculateResolution()
        return self.currentResolution

    def energyChanged(self, energy,wave=None):
        #logging.getLogger("HWR").debug(" %s energychanged : %.3f wave is %.3f", self.name(), energy,wave)
        if self.currentEnergy is None:
            self.currentEnergy = energy
        if type(energy) is not float:
            logging.getLogger("HWR").error("%s: TangoResolution Energy not a float: %s", energy, '')
            return
        if abs(self.currentEnergy - energy) > 0.0002:
            self.currentEnergy = energy # self.blenergyHO.getCurrentEnergy()
            self.wavelengthChanged(self.blenergyHO.getCurrentWavelength())
        
    def wavelengthChanged(self, wavelength):
        self.currentWavelength = wavelength
        self.recalculateResolution()
        
    def recalculateResolution(self):
        self.currentDistance = self.device.position
        self.currentResolution = self.dist2res(self.currentDistance)
        if self.currentResolution is None:
            return
        self.newResolution(self.currentResolution) 

    def newResolution(self, res):      
        if self.currentResolution is None:
            self.currentResolution = self.recalculateResolution()
        logging.getLogger().info("new resolution = %.3f" % res)
        self.currentResolution = res
        self.emit("positionChanged", (res, ))
    
    def connectNotify(self, signal):
        #logging.getLogger("HWR").debug("%s: TangoResolution.connectNotify, : %s", \
        #                                                  self.name(), signal)
        if signal == "stateChanged":
            self.stateChanged(self.getState())
        
        #elif signal == 'limitsChanged':
        #    self.motorLimitsChanged()
            
        elif signal == 'positionChanged':
            self.positionChanged(self.device.position)
#        self.setIsReady(True)

    def stateChanged(self, state):
        #logging.getLogger("HWR").debug("%s: TangoResolution.stateChanged: %s"\
        #                                            % (self.name(), state))
        try:
            self.emit('stateChanged', (TangoResolutionComplex.stateDict[str(state)], ))
        except KeyError:
            self.emit('stateChanged', (TangoResolutionComplex.stateDict['UNKNOWN'], )) #ms 2015-03-26 trying to get rid of the fatal error with connection to detector ts motor


    def getLimits(self, callback=None, error_callback=None):
        #low, high = self.device.getLimits("position")
        # MS 18.09.2012 adapted for use without SimpleDevice
        position_info = self.device.attribute_query("position")
        low  = float(position_info.min_value)
        high = float(position_info.max_value)
        logging.getLogger("HWR").debug("%s: DetectorDistance.getLimits: [%.2f - %.2f]"\
                                                    % (self.name(), low, high))
        
        if callable(callback):
            self.__resLimitsCallback = callback
            self.__resLimitsErrCallback = error_callback

            self.__resLimits = {}
            rlow = self.dist2res(low, callback=self.__resLowLimitCallback, \
                                   error_callback=self.__resLimitsErrCallback)
            rhigh = self.dist2res(high, callback=self.__resHighLimitCallback,\
                                   error_callback=self.__resLimitsErrCallback)
        else:
            #rlow, rhigh = map(self.dist2res, self.device.getLimits("position"))
            # MS 18.09.2012 adapted for use without SimpleDevice
            #rhigh = self.device.attribute_query("positon").max_value
            rlow  = self.dist2res(low)
            rhigh   = self.dist2res(high)
            #position_info = self.device.attribute_query("position")
            #rlow  = float(position_info.min_value)
            #rhigh = float(position_info.max_value)
            
        
        logging.getLogger("HWR").debug("%s: TangoResolution.getLimits: [%.3f - %.3f]"\
                                                     % (self.name(), rlow, rhigh))
        return (rlow, rhigh)


    def isSpecConnected(self):
        #logging.getLogger().debug("%s: TangoResolution.isSpecConnected()" % self.name())
        return True
    
    def __resLowLimitCallback(self, rlow):
        self.__resLimits["low"]=float(rlow)

        if len(self.__resLimits) == 2:
            if callable(self.__resLimitsCallback):
              self.__resLimitsCallback((self.__resLimits["low"], self.__resLimits["high"]))
            self.__resLimitsCallback = None
            self.__dist2resA1 = None
            self.__dist2resA2 = None


    def __resHighLimitCallback(self, rhigh):
        self.__resLimits["high"]=float(rhigh)

        if len(self.__resLimits) == 2:
            if callable(self.__resLimitsCallback):
              self.__resLimitsCallback((self.__resLimits["low"], self.__resLimits["high"]))
            self.__resLimitsCallback = None
            self.__dist2resA1 = None
            self.__dist2resA2 = None
            

    def __resLimitsErrCallback(self):
        if callable(self.__resLimitsErrCallback):
            self.__resLimitsErrCallback()
            self.__resLimitsErrCallback = None
            self.__dist2resA1 = None
            self.__dist2resA2 = None


    def move(self, res, mindist=114, maxdist=1000):
        self.currentWavelength = self.blenergyHO.getCurrentWavelength()
        distance = self.res2dist(res)
        if distance >= mindist and distance <= maxdist:
            self.device.position = distance
        elif distance < mindist:
            logging.getLogger("user_level_log").warning("TangoResolution: requested resolution is above limit for specified energy, moving to maximum allowed resolution")
            self.device.position = mindist
        elif distance > maxdist:
            logging.getLogger("user_level_log").warning("TangoResolution: requested resolution is below limit for specified energy, moving to minimum allowed resolution")
            self.device.position = maxdist
            

    def newDistance(self, dist):
        self.device.position = dist

    def motorIsMoving(self):
        return self.device.state().name in ['MOVING', 'RUNNING']
        
    def stop(self):
        try:
            self.device.Stop()
        except:
            logging.getLogger("HWR").err("%s: TangoResolution.stop: error while trying to stop!", self.name())
            pass
        
    def dist2res(self, Distance, callback=None, error_callback=None):

        #Distance = float(Distance)# MS 2015-03-26 moving statement inside try loop
        try:
            Distance = float(Distance)
            #Wavelength = self.monodevice._SimpleDevice__DevProxy.read_attribute("lambda").value
            if self.currentWavelength is None:
                self.currentWavelength = self.blenergyHO.getCurrentWavelength()
            thetaangle2 = math.atan(DETECTOR_DIAMETER/2./Distance)
            Resolution = 0.5*self.currentWavelength /math.sin(thetaangle2/2.)
            if callable(callback):
                callback(Resolution)
            return Resolution
        except:
            if callable(error_callback):
                error_callback()
    
    def dist2resWaveLenght(self,wavelength, Distance, callback=None, error_callback=None):

        #Distance = float(Distance)# MS 2015-03-26 moving statement inside try loop
        try:
            #Distance = Distance
            #Wavelength = self.monodevice._SimpleDevice__DevProxy.read_attribute("lambda").value
            
            thetaangle2 = math.atan(DETECTOR_DIAMETER/2./Distance)
            Resolution = 0.5*wavelength /math.sin(thetaangle2/2.)
            if callable(callback):
                callback(Resolution)
            return Resolution
        except:
            if callable(error_callback):
                error_callback()

    
    def res2dist(self, Resolution):
        #print "********* In res2dist with ", Resolution
        Resolution = float(Resolution)
        #Wavelength = self.monodevice._SimpleDevice__DevProxy.read_attribute("lambda").value
        if self.currentWavelength is None:
            self.currentWavelength = self.blenergyHO.getCurrentWavelength()
        thetaangle=math.asin(self.currentWavelength / 2. / Resolution)
        Distance=DETECTOR_DIAMETER/2./math.tan(2.*thetaangle)
        #print "********* Distance ", Distance
        return Distance
Ejemplo n.º 3
0
class TangoMotor3(Device):
    
    stateDict = {
         "UNKNOWN": 0,
         "ALARM":   1,
         "FAULT":   1,
         "STANDBY": 2,
         "RUNNING": 4,
         "MOVING":  4,
         "ON": 2,
         '2':         2}


    def __init__(self, name):
        Device.__init__(self, name)
        self.GUIstep = 0.1

    def _init(self):
        
        self.MOVESTARTED = 0
        self.NOTINITIALIZED = 0
        self.UNUSABLE = 0
        self.READY = 2
        self.MOVING = 4
        self.ONLIMITS = 1

        self.device = DeviceProxy(self.getProperty("tangoname"))
        self.device.waitMoves = False
        self.setIsReady(True)
        print("TangoMotor._init of device %s" % self.device.name)

        self.positionChan = self.getChannelObject("attributeName") # utile seulement si statechan n'est pas defini dans le code
        self.positionChan.connectSignal("update", self.positionChanged) 

        self.stateChan = self.getChannelObject("state") # utile seulement si statechan n'est pas defini dans le code
        self.stateChan.connectSignal("update", self.stateChanged) 
#         
#        logging.getLogger("HWR").info("%s: TangoMotor._init, %s", self.name(), '')
        

    def positionChanged(self, value):
        try:
            logging.getLogger("HWR").info("%s: TangoMotor.positionChanged: %.3f", self.name(), value)
        except:
            logging.getLogger("HWR").error("%s: TangoMotor not responding, %s", self.name(), '')
        
        self.emit('positionChanged', (value,))
    
    def isReady(self):
        #logging.getLogger("HWR").info("%s: TangoMotor.isReady", self.name())
        return self.motorState() == TangoMotor3.stateDict["STANDBY"]
        
        
    def connectNotify(self, signal):
        #logging.getLogger("HWR").info("%s: TangoMotor.connectNotify, : %s", \
        #                                                  self.name(), signal)
        if signal == 'hardwareObjectName,stateChanged':
            self.motorStateChanged(self.motorState())
        elif signal == 'limitsChanged':
            self.motorLimitsChanged()
            #print "Not implemented yet."
            
        elif signal == 'positionChanged':
            self.motorPositionChanged(self.positionChan.getValue())
            
        self.setIsReady(True)
    
    def motorState(self):
        return self.getState()
    
    def stateChanged(self, state):
        logging.getLogger("HWR").info("State Changed, %s / %s" % (self.name(), str(state)))
        self.motorStateChanged(state)
      
    def motorStateChanged(self, state):
        logging.getLogger("HWR").info("%s: TangoMotor.motorStateChanged, %s", self.name(), state)
        #self.setIsReady(state == 'STANDBY')
        self.setIsReady(True)
        print("motorStateChanged", str(state),self.motorState())
        self.emit('stateChanged', (self.motorState(), ))
        
    def getState(self):
        state = str(self.device.State())
        #logging.getLogger("HWR").info("%s: TangoMotor.getState, %s", self.name(), state)
        #return self.motorState()
        return TangoMotor3.stateDict[ state ]
    
    def getLimits(self):
        #limits = self.device.getLimits(str(self.positionChan.attributeName))
        try:
           atprops = self.device.attribute_query(str(self.positionChan.attributeName))
           limits = list(map(float, [atprops.min_value, atprops.max_value]))
           logging.getLogger("HWR").info("TangoMotor3 getLimits returning %.4f %.4f" % (limits[0], limits[1]))
           return limits
        except IndexError:
           logging.getLogger("HWR").info("TangoMotor3 cannot getLimits returning -1,1" )
           return (-1,1)
        
    def motorLimitsChanged(self):
        #self.emit('limitsChanged', (self.getLimits(), ))
        #logging.getLogger("HWR").info("%s: TangoMotor.limitsChanged", self.name())
        self.emit('limitsChanged', (self.getLimits(), )) 
                      
    def motorMoveDone(self, channelValue):
       #SpecMotorA.motorMoveDone(self, channelValue)
       #logging.getLogger("HWR").info("TangoMotor.motorMoveDone")
       if str(self.device.State()) == 'STANDBY':
           
          #self.emit('moveDone', (self.specversion, self.specname, ))
          self.emit('moveDone', ("EH3","toto" ))
          
    def motorPositionChanged(self, absolutePosition):
        self.motorStateChanged(self.device.State())
        self.emit('positionChanged', (absolutePosition, ))

    def syncQuestionAnswer(self, specSteps, controllerSteps):
        return '0' #NO ('1' means YES)
    
    def getPosition(self):
        pos = self.positionChan.getValue()
        #logging.getLogger("HWR").info("%s: TangoMotor.getPosition, pos = %.3f", self.name(), pos)
        return pos
    
    def syncMove(self, position):
        #print 'about to start moving', self.motorState
        import time; t0=time.time()
        prev_position = self.getPosition()
        self.positionChan.value = position

        print('move started from %s to %s, state is %s' % (prev_position, position, self.getState()))
        
        while self.getState() == "RUNNING" or self.getState() == "MOVING": # or str(self.device.State()) == SpecMotor.MOVESTARTED:
            #print 'processing events...', self.motorState
            qApp.processEvents(100)

        print('move done (%s s), state is %s' % (time.time()-t0,  str(self.device.State())))
        

    def syncMoveRelative(self, position):
        old_pos = self.positionChan.getValue()
        self.positionChan.value = old_pos + position
        #self.moveRelahardwareObjectName,tive(position)

        while self.getState() == "RUNNING" or self.getState() == "MOVING":
            qApp.processEvents(100)
        
    def moveRelative(self, position):
        old_pos = self.positionChan.getValue()
        self.positionChan.value = old_pos + position
        #self.moveRelahardwareObjectName,tive(position)
        self.syncMove(self.positionChan.value)
            
    def getMotorMnemonic(self):
        return self.specName

    def move(self, absolutePosition):
        """Move the motor to the required position

        Arguments:
        absolutePosition -- position to move to
        """
        if type(absolutePosition) != float and type(absolutePosition) != int:
            logging.getLogger("TangoClient").error("Cannot move %s: position '%s' is not a number", self.device.name, absolutePosition)
            
        #self.__changeMotorState(MOVESTARTED)

        #c = self.connection.getChannel(self.chanNamePrefix % 'start_one')
        logging.getLogger("HWR").info("TangoMotor.move to absolute position: %.3f" % absolutePosition)
        self.positionChan.value = absolutePosition
        print(self.positionChan.value)
        nom_attribut=self.positionChan.attributeName
        setattr(self.device,nom_attribut,absolutePosition)
        self.motorPositionChanged(absolutePosition)

    def stop(self):
        logging.getLogger("HWR").info("TangoMotor.stop")
        self.device.Stop()

    def isSpecConnected(self):
        logging.getLogger().debug("%s: TangoMotor.isSpecConnected()" % self.name())
        return TruehardwareObjectName,
Ejemplo n.º 4
0
class TangoResolution(BaseHardwareObjects.Equipment):
    #     resoState = {
    #         None: 'unknown',
    #         'UNKNOWN': 'unknown',
    #         'CLOSE': 'closed',
    #         'OPEN': 'opened',
    #         'MOVING': 'moving',
    #         'FAULT': 'fault',
    #         'DISABLE': 'disabled',
    #         'OFF': 'fault',
    #         'ON': 'unknown'
    #         }

    stateDict = {
        "UNKNOWN": 0,
        "ALARM": 1,
        "STANDBY": 2,
        "RUNNING": 4,
        "MOVING": 4,
        "1": 1,
        "2": 2
    }

    def _init(self):
        self.currentResolution = None
        self.currentDistance = None
        self.currentWavelength = None
        self.currentEnergy = None
        self.connect("equipmentReady", self.equipmentReady)
        self.connect("equipmentNotReady", self.equipmentNotReady)
        self.device = DeviceProxy(self.getProperty("tangoname"))

        #self.monodevice = SimpleDevice(self.getProperty("tangoname2"), waitMoves = False, verbose=False)
        self.blenergyHOname = self.getProperty("BLEnergy")
        if self.blenergyHOname is None:
            logging.getLogger("HWR").error(
                'TangoResolution: you must specify the %s hardware object' %
                self.blenergyHOname)
            hobj = None
            self.configOk = False
        else:
            hobj = HardwareRepository.HardwareRepository().getHardwareObject(
                self.blenergyHOname)
            if hobj is None:
                logging.getLogger("HWR").error(
                    'TangoResolution: invalid %s hardware object' %
                    self.blenergyHOname)
                self.configOk = False
            self.blenergyHO = hobj
            self.connect(self.blenergyHO, qt.PYSIGNAL('energyChanged'),
                         self.energyChanged)
        # creer un chanel sur l'energy: pour faire un update
        positChan = self.getChannelObject(
            "position"
        )  # utile seulement si statechan n'est pas defini dans le code
        positChan.connectSignal("update", self.positionChanged)
        stateChan = self.getChannelObject(
            "state"
        )  # utile seulement si statechan n'est pas defini dans le code
        stateChan.connectSignal("update", self.stateChanged)

        self.currentDistance = self.device.position
        self.currentEnergy = self.blenergyHO.getCurrentEnergy()
        self.currentWavelength = self.blenergyHO.getCurrentWavelength()
        return BaseHardwareObjects.Equipment._init(self)

    def init(self):
        #self.detm = self.getDeviceByRole("detm")
        #self.dtox = self.getDeviceByRole("dtox")
        #self.dist2res = self.getCommandObject("dist2res")
        #self.res2dist = self.getCommandObject("res2dist")
        self.__resLimitsCallback = None

        self.__resLimitsErrCallback = None
        self.__resLimits = {}

        #self.connect(self.device, "stateChanged", self.detmStateChanged)
        #self.dist2res.connectSignal("commandReplyArrived", self.newResolution)
        #self.res2dist.connectSignal("commandReplyArrived", self.newDistance)

    def positionChanged(self, value):
        res = self.dist2res(value)
        self.emit('positionChanged', (res, ))

    def getState(self):
        return TangoResolution.stateDict[str(self.device.State())]

    def equipmentReady(self):
        self.emit("deviceReady")

    def equipmentNotReady(self):
        self.emit("deviceNotReady")

    def getPosition(self):
        if self.currentResolution is None:
            self.recalculateResolution()
        return self.currentResolution

    def energyChanged(self, energy):
        if self.currentEnergy is None:
            self.currentEnergy = energy
        if type(energy) is not float:
            logging.getLogger("HWR").error(
                "%s: TangoResolution Energy not a float: %s", energy, '')
            return
        if abs(self.currentEnergy - energy) > 0.0002:
            self.currentEnergy = energy  # self.blenergyHO.getCurrentEnergy()
            self.wavelengthChanged(self.blenergyHO.getCurrentWavelength())

    def wavelengthChanged(self, wavelength):
        self.currentWavelength = wavelength
        self.recalculateResolution()

    def recalculateResolution(self):
        self.currentDistance = self.device.position
        self.currentResolution = self.dist2res(self.currentDistance)
        if self.currentResolution is None:
            return
        self.newResolution(self.currentResolution)

    def newResolution(self, res):
        if self.currentResolution is None:
            self.currentResolution = self.recalculateResolution()
        self.currentResolution = res
        self.emit("positionChanged", (res, ))

    def connectNotify(self, signal):
        #logging.getLogger("HWR").debug("%s: TangoResolution.connectNotify, : %s", \
        #                                                  self.name(), signal)
        if signal == "stateChanged":
            self.stateChanged(TangoResolution.stateDict[self.device.State])

        elif signal == 'positionChanged':
            self.positionChanged(self.device.position)

    def stateChanged(self, state):
        self.emit('stateChanged', (TangoResolution.stateDict[str(state)], ))

    def getLimits(self, callback=None, error_callback=None):

        positionChan = self.getChannelObject("position")
        info = positionChan.getInfo()

        high = float(info.max_value)
        low = float(info.min_value)

        #logging.getLogger("HWR").debug("%s: DetectorDistance.getLimits: [%.2f - %.2f]" % (self.name(), low, high))

        if callable(callback):
            #logging.getLogger("HWR").debug("getLimits with callback: %s" % callback)

            self.__resLimitsCallback = callback
            self.__resLimitsErrCallback = error_callback

            self.__resLimits = {}
            rlow = self.dist2res(low, callback=self.__resLowLimitCallback, \
                                   error_callback=self.__resLimitsErrCallback)
            rhigh = self.dist2res(high, callback=self.__resHighLimitCallback,\
                                   error_callback=self.__resLimitsErrCallback)
        else:
            #logging.getLogger("HWR").debug("getLimits with no callback")
            rhigh = self.dist2res(low)
            rlow = self.dist2res(high)

        #logging.getLogger("HWR").debug("%s: TangoResolution.getLimits: [%.3f - %.3f]"\
        #% (self.name(), rlow, rhigh))
        return (rlow, rhigh)

    def isSpecConnected(self):
        #logging.getLogger().debug("%s: TangoResolution.isSpecConnected()" % self.name())
        return True

    def __resLowLimitCallback(self, rlow):
        self.__resLimits["low"] = float(rlow)

        if len(self.__resLimits) == 2:
            if callable(self.__resLimitsCallback):
                self.__resLimitsCallback(
                    (self.__resLimits["low"], self.__resLimits["high"]))
            self.__resLimitsCallback = None
            self.__dist2resA1 = None
            self.__dist2resA2 = None

    def __resHighLimitCallback(self, rhigh):
        self.__resLimits["high"] = float(rhigh)

        if len(self.__resLimits) == 2:
            if callable(self.__resLimitsCallback):
                self.__resLimitsCallback(
                    (self.__resLimits["low"], self.__resLimits["high"]))
            self.__resLimitsCallback = None
            self.__dist2resA1 = None
            self.__dist2resA2 = None

    def __resLimitsErrCallback(self):
        if callable(self.__resLimitsErrCallback):
            self.__resLimitsErrCallback()
            self.__resLimitsErrCallback = None
            self.__dist2resA1 = None
            self.__dist2resA2 = None

    def move(self, res):
        self.currentWavelength = self.blenergyHO.getCurrentWavelength()
        self.device.position = self.res2dist(res)

    def newDistance(self, dist):
        self.device.position = dist

    def stop(self):
        try:
            self.device.Stop()
        except:
            logging.getLogger("HWR").err(
                "%s: TangoResolution.stop: error while trying to stop!",
                self.name())
            pass

    def dist2res(self, Distance, callback=None, error_callback=None):

        Distance = float(Distance)
        try:
            #Wavelength = self.monodevice._SimpleDevice__DevProxy.read_attribute("lambda").value
            if self.currentWavelength is None:
                self.currentWavelength = self.blenergyHO.getCurrentWavelength()
            thetaangle2 = math.atan(DETECTOR_DIAMETER / 2. / Distance)
            Resolution = 0.5 * self.currentWavelength / math.sin(
                thetaangle2 / 2.)
            if callable(callback):
                callback(Resolution)
            return Resolution
        except:
            if callable(error_callback):
                error_callback()

    def res2dist(self, Resolution):
        #print "********* In res2dist with ", Resolution
        Resolution = float(Resolution)
        #Wavelength = self.monodevice._SimpleDevice__DevProxy.read_attribute("lambda").value
        if self.currentWavelength is None:
            self.currentWavelength = self.blenergyHO.getCurrentWavelength()
        thetaangle = math.asin(self.currentWavelength / 2. / Resolution)
        Distance = DETECTOR_DIAMETER / 2. / math.tan(2. * thetaangle)
        #print "********* Distance ", Distance
        return Distance
class TangoMotorZoomPX2(Device):

    stateDict = {
        "UNKNOWN": 0,
        "ALARM": 1,
        "FAULT": 1,
        "STANDBY": 2,
        "RUNNING": 4,
        "MOVING": 4,
        "ON": 2,
        '2': 2
    }

    def __init__(self, name):
        Device.__init__(self, name)
        self.GUIstep = 0.1

    def _init(self):

        self.MOVESTARTED = 0
        self.NOTINITIALIZED = 0
        self.UNUSABLE = 0
        self.READY = 2
        self.MOVING = 4
        self.ONLIMITS = 1

        #self.device = SimpleDevice(self.getProperty("tangoname"), verbose=False)
        #self.device.timeout = 6000 # Setting timeout to 6 sec
        self.device = DeviceProxy(self.getProperty("tangoname"))
        self.device.waitMoves = False
        logging.getLogger("HWR").info("TangoMotorZoomPX2._init of device %s" %
                                      self.device.name)
        self.setIsReady(True)
        print("TangoMotorZoomPX2._init of device %s" % self.device.name)
        positionChan = self.getChannelObject(
            "position"
        )  # utile seulement si statechan n'est pas defini dans le code
        positionChan.connectSignal("update", self.positionChanged)
        #focus_positionChan = self.getChannelObject("focus_position")
        #focus_positionChan.connectSignal("update", self.positionChanged)
        stateChan = self.getChannelObject(
            "state"
        )  # utile seulement si statechan n'est pas defini dans le code
        stateChan.connectSignal("update", self.motorStateChanged)

        #logging.getLogger("HWR").info("%s: TangoMotorZoomPX2._init, %s", self.name(), '')

    def positionChanged(self, value):
        try:
            logging.getLogger("HWR").info(
                "%s: TangoMotorZoomPX2.positionChanged: %.3f", self.name(),
                value)
        except:
            logging.getLogger("HWR").error("%s: TangoMotor not responding, %s",
                                           self.name(), '')

        self.emit('positionChanged', (value, ))

    def isReady(self):
        #logging.getLogger("HWR").info("%s: TangoMotorZoomPX2.isReady", self.name())
        return str(self.device.State()) == 'STANDBY'

    def connectNotify(self, signal):
        #logging.getLogger("HWR").info("%s: TangoMotorZoomPX2.connectNotify, : %s", self.name(), signal)
        if signal == 'hardwareObjectName,stateChanged':
            self.motorStateChanged(TangoMotorZoomPX2.stateDict[str(
                self.device.State())])
        elif signal == 'limitsChanged':
            self.motorLimitsChanged()
            #print "Not implemented yet."PhiTableXAxisPosition

        elif signal == 'positionChanged':
            #self.motorPositionChanged(self.device.position)
            print('MS debug 18.10.2012')
            #print self.device
            print(self.device.read_attribute("ZoomLevel").value)
            self.motorPositionChanged(
                self.device.read_attribute(
                    "ZoomLevel").value)  #MS debug 18.10.2012

        self.setIsReady(True)

    def motorState(self):
        return TangoMotorZoomPX2.stateDict[str(self.device.State())]

    def motorStateChanged(self, state):
        #logging.getLogger("HWR").info("%s: TangoMotorZoomPX2.motorStateChanged, %s", self.name(), state)
        #self.setIsReady(state == 'STANDBY')
        self.setIsReady(True)
        #print "motorStateChanged", str(state)
        self.emit('stateChanged',
                  (TangoMotorZoomPX2.stateDict[str(self.device.State())], ))

    def getState(self):
        state = str(self.device.State())
        #logging.getLogger("HWR").info("%s: TangoMotorZoomPX2.getState, %s", self.name(), state)
        return TangoMotorZoomPX2.stateDict[str(self.device.State())]

    def getLimits(self):
        #limits = self.device.getLimits("positiopositionChan.connectSignal("update", self.positionChanged)n")
        # MS 18.09.2012 adapted for use without SimpleDevice
        position_info = self.device.attribute_query("ZoomLevel")
        rlow = 1  # position_info.min_value
        rhigh = 10  #position_info.max_value
        #logging.getLogger("HWR").info("TangoMotorZoomPX2.getLimits: %.4f %.4f" % limits)
        return rlow, rhigh

    def motorLimitsChanged(self):
        #self.emit('limitsChanged', (self.getLimits(), ))
        #logging.getLogger("HWR").info("%s: TangoMotorZoomPX2.limitsChanged", self.name())
        self.emit('limitsChanged', (self.getLimits(), ))

    def motorMoveDone(self, channelValue):
        #SpecMotorA.motorMoveDone(self, channelValue)
        #logging.getLogger("HWR").info("TangoMotorZoomPX2.motorMoveDone")
        if str(self.device.State()) == 'STANDBY':

            #self.emit('moveDone', (self.specversion, self.specname, ))
            self.emit('moveDone', ("EH3", "toto"))

    def motorPositionChanged(self, absolutePosition):
        self.emit('positionChanged', (absolutePosition, ))

    def syncQuestionAnswer(self, specSteps, controllerSteps):
        return '0'  #NO ('1' means YES)

    def getPosition(self):
        pos = self.device.read_attribute(
            "ZoomLevel").value  #self.device.position
        #logging.getLogger("HWR").info("%s: TangoMotorZoomPX2.getPosition, pos = %.3f", self.name(), pos)
        return pos

    def syncMove(self, position):
        #print 'about to start moving', self.motorState
        t0 = time.time()
        prev_position = self.getPosition()
        self.device.position = position

        print('move started from %s to %s, state is %s' %
              (prev_position, position, str(self.device.State())))

        while str(self.device.State()) == "RUNNING" or str(
                self.device.State()
        ) == "MOVING":  # or str(self.device.State()) == SpecMotor.MOVESTARTED:
            #print 'processing events...', self.motorState
            qApp.processEvents(100)

        print('move done (%s s), state is %s' %
              (time.time() - t0, str(self.device.State())))

    def moveRelative(self, position):
        old_pos = self.device.position
        self.device.position = old_pos + position
        #self.moveRelahardwareObjectName,tive(position)

        while str(self.device.State()) == "RUNNING" or str(
                self.device.State()) == "MOVING":
            qApp.processEvents(100)

    def syncMoveRelative(self, position):
        old_pos = self.device.position
        self.device.position = old_pos + position
        #self.moveRelahardwareObjectName,tive(position)

        while str(self.device.State()) == "RUNNING" or str(
                self.device.State()) == "MOVING":
            qApp.processEvents(100)

    def getMotorMnemonic(self):
        return self.specName

    def move(self, absolutePosition):
        """Move the motor to the required position

        Arguments:
        absolutePosition -- position to move to
        """
        if type(absolutePosition) != float and type(absolutePosition) != int:
            logging.getLogger("TangoClient").error(
                "Cannot move %s: position '%s' is not a number",
                self.device.name, absolutePosition)

        #self.__changeMotorState(MOVESTARTED)

        #c = self.connection.getChannel(self.chanNamePrefix % 'start_one')
        logging.getLogger("HWR").info(
            "TangoMotorZoomPX2.move to absolute position: %.3f" %
            absolutePosition)
        self.device.position = absolutePosition

    def stop(self):
        logging.getLogger("HWR").info("TangoMotorZoomPX2.stop")
        self.device.Stop()

    def isSpecConnected(self):
        logging.getLogger().debug("%s: TangoMotorZoomPX2.isSpecConnected()" %
                                  self.name())
        return TruehardwareObjectName,