Ejemplo n.º 1
0
 def attenuation(self, x=None):
     '''Read or set the attenuation'''
     if self.test: return 0
     from PyTango import DeviceProxy
     Attenuator = DeviceProxy('i11-ma-c05/ex/att.1')
     labels = [
         '00 None', '01 Carbon 200um', '02 Carbon 250um', '03 Carbon 300um',
         '04 Carbon 500um', '05 Carbon 1mm', '06 Carbon 2mm',
         '07 Carbon 3mm', '10 Ref Fe 5um', '11 Ref Pt 5um'
     ]
     if x == None:
         status = Attenuator.Status()
         print 'status', status
         status = status[:status.index(':')]
         value = status
         return value
     NumToLabel = dict([(int(l.split()[0]), l) for l in labels])
     Attenuator.write_attribute(NumToLabel[x], True)
     self.wait(Attenuator)
Ejemplo n.º 2
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.º 3
0
class AttenuatorsPX2(Device):
    stateAttenuator = {
        'ALARM': 0,
        'EXTRACT': 1,
        'INSERT': 1,
        'UNKNOWN': 3,
        'ALARM': 'error',
        'OFF': 'error',
        'RUNNING': 'moving',
        'MOVING': 'moving',
        'STANDBY': 'ready',
        'UNKNOWN': 'changed',
        'EXTRACT': 'outlimits'
    }

    def __init__(self, name):
        Device.__init__(self, name)

        self.labels = []
        self.bits = []
        self.attno = 0
        self.deviceOk = True
        self.NumToLabel = {}

    def init(self):
        #cmdToggle = self.getCommandObject('toggle')
        #cmdToggle.connectSignal('connected', self.connected)
        #cmdToggle.connectSignal('disconnected', self.disconnected)

        # Connect to device Attenuator defined "tangoname" in the xml file
        try:
            #self.Attenuatordevice = SimpleDevice(self.getProperty("tangoname"), verbose=False)
            self.Attenuatordevice = DeviceProxy(self.getProperty("tangoname"))
            self.Attenuatordevice.waitMoves = False
            self.Attenuatordevice.timeout = 5000

        except:
            self.errorDeviceInstance(self.getProperty("tangoname"))

        if self.deviceOk:
            #self.connected()
            #self.chanAttState = self.getChannelObject('State')
            #print "self.chanAttState : ", self.chanAttState
            #self.chanAttState.connectSignal('update', self.attStateChanged)
            ##self.chanAttFactor = self.getChannelObject('appliedTransmission')
            ##self.chanAttFactor = self.getChannelObject('computedTransmission')
            ##self.chanAttFactor.connectSignal('update', self.attFactorChanged)

            ##self.chanAttToggle = self.getChannelObject('filtersCombination')
            ##self.chanAttToggle.connectSignal('update', self.attToggleChanged)

            #self.getAtteConfig()

            self.connected()
            self.chanAttState = self.getChannelObject('State')
            print "self.chanAttState : ", self.chanAttState
            self.chanAttState.connectSignal('update', self.attStateChanged)
            #self.chanAttFactor = self.getChannelObject('appliedTransmission')

            self.chanAttFactor = self.getChannelObject('Status')
            self.chanAttFactor.connectSignal('update', self.attFactorChanged)

            self.chanAttToggle = self.getChannelObject('State')
            self.chanAttToggle.connectSignal('update', self.attToggleChanged)

            self.getAtteConfig()

        logging.getLogger().debug(
            "AttenuatorsPX2: self.labels, self.bits, self.attno, %s, %s, %s" %
            (self.labels, self.bits, self.attno))

    def getAtteConfig(self):
        pass

    def getAtteConfig_OLD(self):
        logging.getLogger().debug("HOS Attenuator: passe dans getAtteConfig")
        self.attno = len(self['atte'])

        for att_i in range(self.attno):
            obj = self['atte'][att_i]
            self.labels.append(obj.label)
            self.bits.append(obj.bits)
        self.NumToLabel = dict([(int(l.split()[0]), l) for l in self.labels])

    def getAttState(self):
        logging.getLogger().debug("HOS Attenuator: passe dans getAttState")
        logging.getLogger().debug("Attenuator state read from the device %s",
                                  self.Attenuatordevice.State().name)
        try:
            #print "HEYO", self.Attenuatordevice.StatefiltersCombination
            print self.Attenuatordevice.Status()
            value = AttenuatorsPX2.stateAttenuator[
                self.Attenuatordevice.State().name]
        except:
            logging.getLogger("HWR").error(
                '%s: received value on channel is not a integer value',
                str(self.name()))
            value = None
        return value

    def getAttFactor(self):
        logging.getLogger().debug("HOS Attenuator: passe dans getAttFactor")
        print 'self.Attenuatordevice.Status()', self.Attenuatordevice.Status()
        try:
            #value = float(self.Attenuatordevice.appliedTransmission)
            status = self.Attenuatordevice.Status()
            status = status[:status.index(':')]
            print 'status', status
            value = status  #self.Attenuatordevice.Status() #1. #float(self.Attenuatordevice.computedTransmission)
        except:
            logging.getLogger("HWR").error(
                '%s: received value on channel is not a float value',
                str(self.name()))
            value = None
        return value

    def connected(self):
        self.setIsReady(True)

    def disconnected(self):
        self.setIsReady(False)

    def attStateChanged(self, channelValue):
        logging.getLogger("HWR").debug(
            "%s: AttenuatorsPX2.attStateChanged: %s", self.name(),
            channelValue)
        self.emit('attStateChanged',
                  (AttenuatorsPX2.stateAttenuator[str(channelValue)], ))

    def attFactorChanged(self, channelValue):
        print 'attFactorChanged', channelValue
        print 'self.Attenuatordevice.Status()', self.Attenuatordevice.Status()
        try:
            status = self.Attenuatordevice.Status()
            status = status[:status.index(':')]
            print 'status', status
            value = status
            #value = float(channelValue)
        except:
            logging.getLogger("HWR").error(
                '%s: received value on channel is not a float value',
                str(self.name()))
        else:
            logging.getLogger("HWR").info(
                '%s: AttenuatorsPX2, received value on channel',
                str(self.name()))
            self.emit('attFactorChanged', (value, ))

    def attToggleChanged(self, channelValue):
        #        print "Dans attToggleChanged  channelValue = %s" %channelValue
        logging.getLogger().debug(
            "HOS Attenuator: passe dans attToggleChanged")
        try:
            value = int(channelValue)
        except:
            logging.getLogger("HWR").error(
                '%s: received value on channel is not a float value',
                str(self.name()))
        else:
            self.emit('toggleFilter', (value, ))

    def setTransmission(self, value):
        logging.getLogger("HWR").debug(
            "%s: AttenuatorsPX2.setTransmission: %s", self.name(), value)
        print value
        self.Attenuatordevice.write_attribute(
            self.NumToLabel[value],
            True)  #.computedAttenuation = 1.0/(value/100.0)
        #try:
        #self.Attenuatordevice.write_attribute(value, True) #.computedAttenuation = 1.0/(value/100.0)
        #except:
        #logging.getLogger("HWR").error('%s: received value on channel is not valid', str(self.name()))
        #value=None
        return value

    def toggle(self, value):
        print "Toggle value = %s" % value
        logging.getLogger().debug("HOS Attenuator: passe dans toggle")
        self.Attenuatordevice.write_attribute(value, True)

        #        old_value = self.Attenuatordevice.filtersCombination
        #        try:
        #            self.Attenuatordevice.filtersCombination = old_value "sys/database/dbds1")+ (2**(value-1))
        #        except:
        #            logging.getLogger("HWR").error('%s: the filter doesn\'t exist', str(self.name()))
        #            value=None
        return value

    def errorDeviceInstance(self, device):
        #db = SimpleDevice("sys/database/dbds1")
        db = DeviceProxy("sys/database/dbds1")
        logging.getLogger().error("Check Instance of Device server %s" %
                                  db.DbGetDeviceInfo(device)[1][3])
        self.sDisconnected()
Ejemplo n.º 4
0
class EnergyScanPX1(Equipment):
    
    MANDATORY_HO={"BLEnergy":"BLEnergy"}
    
    
    def init(self):
        self.scanning = None
#        self.moving = None
        self.scanThread = None
        self.pk = None
        self.ip = None
        self.roiwidth = 0.35 # en keV largeur de la roi 
        self.before = 0.10  #  en keV Ecart par rapport au seuil pour le point de depart du scan
        self.after = 0.20   # en keV Ecart par rapport au seuil pour le dernier point du scan
        self.canScan = True
        self.nbsteps = 100 #
        self.integrationtime = 5.0
        self.directoryPrefix = None

        self.directoryPrefix=self.getProperty("directoryprefix")
        if self.directoryPrefix is None:
            logging.getLogger("HWR").error("EnergyScan: you must specify the directory prefix property")
        else :
            logging.getLogger("HWR").info("EnergyScan: directoryPrefix : %s" %(self.directoryPrefix))
            
                    # Load mandatory hardware objects
#         for ho in EnergyScan.MANDATORY_HO:
#             desc=EnergyScan.MANDATORY_HO[ho]
#             name=self.getProperty(ho)
#             if name is None:
#                  logging.getLogger("HWR").error('EnergyScan: you must specify the %s hardware object' % desc)
#                  hobj=None
#                  self.configOk=False
#             else:
#                  hobj=HardwareRepository.HardwareRepository().getHardwareObject(name)
#                  if hobj is None:
#                      logging.getLogger("HWR").error('EnergyScan: invalid %s hardware object' % desc)
#                      self.configOk=False
#             exec("self.%sHO=hobj" % ho)
# 
#         print "BLEnergyHO : ", self.BLEnergyHO
        
        paramscan = self["scan"]   
        self.roiwidth = paramscan.roiwidth
        self.before = paramscan.before
        self.after = paramscan.after
        self.nbsteps = paramscan.nbsteps
        self.integrationTime = paramscan.integrationtime
      
      
        print("self.roiwidth :", self.roiwidth)
        print("self.before :", self.before)
        print("self.after :", self.after)
        print("self.nbsteps :", self.nbsteps)
        print("self.integrationtime :", self.integrationtime)
        

        self.dbConnection=self.getObjectByRole("dbserver")
        if self.dbConnection is None:
            logging.getLogger("HWR").warning('EnergyScan: you should specify the database hardware object')
        self.scanInfo=None

        if self.isSpecConnected():
            self.sConnected()
            
    def connectTangoDevices(self):
        try :
            self.BLEnergydevice = DeviceProxy(self.getProperty("blenergy")) #, verbose=False)
            self.BLEnergydevice.waitMoves = True
            self.BLEnergydevice.timeout = 30000
        except :
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("blenergy")))
            self.canScan = False
            
        # Connect to device mono defined "tangoname2" in the xml file 
        # used for conversion in wavelength
        try :    
            self.monodevice = DeviceProxy(self.getProperty("mono")) #, verbose=False)
            self.monodevice.waitMoves = True
            self.monodevice.timeout = 6000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("mono")))
            self.canScan = False
        #mono_mt_rx
        try :    
            self.mono_mt_rx_device = DeviceProxy(self.getProperty("mono_mt_rx")) #, verbose=False)
            #self.monodevice.waitMoves = True
            self.mono_mt_rx_device.timeout = 6000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("mono_mt_rx")))
            self.canScan = False
        # Nom du device bivu (Energy to gap) : necessaire pour amelioration du positionnement de l'onduleur (Backlash)
        try :    
            self.U20Energydevice = DeviceProxy(self.getProperty("U24Energy")) #, movingState="MOVING")
            self.U20Energydevice.timeout = 30000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("U24Energy")))
            self.canScan = False
            
        try :
            self.fluodetdevice = DeviceProxy(self.getProperty("ketek")) #, verbose=False)
            self.fluodetdevice.timeout = 1000
        except :
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("ketek")))
            self.canScan = False
            
        try :    
            self.counterdevice = DeviceProxy(self.getProperty("counter")) #, verbose=False)
            self.counterdevice.timeout = 1000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("counter")))
            self.canScan = False

        try :    
            self.xbpmdevice = DeviceProxy(self.getProperty("xbpm")) #, verbose=False)
            self.xbpmdevice.timeout = 30000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("xbpm")))
            self.canScan = False
       
        try :    
            self.attdevice = DeviceProxy(self.getProperty("attenuator")) #, verbose=False)
            self.attdevice.timeout = 6000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("attenuator")))
            self.canScan = False
        
#        try :    
#            self.md2device = DeviceProxy(self.getProperty("md2")) #, verbose=False)
#            self.md2device.timeout = 2000
#        except :    
#            logging.getLogger("HWR").error("%s not found" %(self.getProperty("md2")))
#            self.canScan = False
        
        try:
            self.lightdevice = DeviceProxy(self.getProperty("lightextract")) #, verbose=False)
            self.lightdevice.timeout = 2000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("lightextract")))
            self.canScan = False

        try:
            self.bstdevice = DeviceProxy(self.getProperty("bst")) #, verbose=False)
            self.bstdevice.timeout = 2000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("bst")))
            self.canScan = False

        try:
            self.ketekinsertdevice = DeviceProxy(self.getProperty("ketekinsert")) #, verbose=False)
            self.ketekinsertdevice.timeout = 2000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("ketekinsert")))
            self.canScan = False

        try:
            self.fastshutterdevice = DeviceProxy(self.getProperty("fastshutter")) #, verbose=False)
            self.fastshutterdevice.timeout = 2000
        except :    
            logging.getLogger("HWR").error("%s not found" %(self.getProperty("fastshutter")))
            self.canScan = False
        
                            
    def isConnected(self):
        return self.isSpecConnected()
        
    def isSpecConnected(self):
        logging.getLogger("HWR").debug('EnergyScan:isSpecConnected')
        return True

    # Handler for spec connection
    def sConnected(self):
        logging.getLogger("HWR").debug('EnergyScan:sConnected')
        self.emit('connected', ())
        self.emit('setDirectory', (self.directoryPrefix,))


    # Handler for spec disconnection
    def sDisconnected(self):
        logging.getLogger("HWR").debug('EnergyScan:sDisconnected')
        self.emit('disconnected', ())

    # Energy scan commands
    def canScanEnergy(self):
        logging.getLogger("HWR").debug('EnergyScan:canScanEnergy : %s' %(str(self.canScan)))
        return self.canScan

 
#        return self.doEnergyScan is not None
	
    def startEnergyScan(self, 
                        element, 
                        edge, 
                        directory, 
                        prefix, 
                        session_id = None, 
                        blsample_id = None):
        
        logging.getLogger("HWR").debug('EnergyScan:startEnergyScan')
        print('edge', edge)
        print('element', element)
        print('directory', directory)
        print('prefix', prefix)
        #logging.getLogger("HWR").debug('EnergyScan:edge', edge)
        #logging.getLogger("HWR").debug('EnergyScan:element', element)
        #logging.getLogger("HWR").debug('EnergyScan:directory', directory)
        #logging.getLogger("HWR").debug('EnergyScan:prefix', prefix)
        #logging.getLogger("HWR").debug('EnergyScan:edge', edge)
        self.scanInfo={"sessionId":session_id,
                       "blSampleId":blsample_id,
                       "element":element,
                       "edgeEnergy":edge}
#        if self.fluodetectorHO is not None:
#            self.scanInfo['fluorescenceDetector']=self.fluodetectorHO.userName()
        if not os.path.isdir(directory):
            logging.getLogger("HWR").debug("EnergyScan: creating directory %s" % directory)
            try:
                os.makedirs(directory)
            except OSError as diag:
                logging.getLogger("HWR").error("EnergyScan: error creating directory %s (%s)" % (directory,str(diag)))
                self.emit('scanStatusChanged', ("Error creating directory",))
                return False
        self.doEnergyScan(element, edge, directory, prefix)
        return True
        
    def cancelEnergyScan(self):
        logging.getLogger("HWR").debug('EnergyScan:cancelEnergyScan')
        if self.scanning:
            self.scanning = False
            
    def scanCommandReady(self):
        logging.getLogger("HWR").debug('EnergyScan:scanCommandReady')
        if not self.scanning:
            self.emit('energyScanReady', (True,))
            
    def scanCommandNotReady(self):
        logging.getLogger("HWR").debug('EnergyScan:scanCommandNotReady')
        if not self.scanning:
            self.emit('energyScanReady', (False,))
            
    def scanCommandStarted(self):
        logging.getLogger("HWR").debug('EnergyScan:scanCommandStarted')

        self.scanInfo['startTime']=time.strftime("%Y-%m-%d %H:%M:%S")
        self.scanning = True
        self.emit('energyScanStarted', ())
    
    def scanCommandFailed(self):
        logging.getLogger("HWR").debug('EnergyScan:scanCommandFailed')
        self.scanInfo['endTime']=time.strftime("%Y-%m-%d %H:%M:%S")
        self.scanning = False
        self.storeEnergyScan()
        self.emit('energyScanFailed', ())
        
    def scanCommandAborted(self):
        logging.getLogger("HWR").debug('EnergyScan:scanCommandAborted')
    
    def scanCommandFinished(self,result):
        logging.getLogger("HWR").debug("EnergyScan: energy scan result is %s" % result)
        self.scanInfo['endTime']=time.strftime("%Y-%m-%d %H:%M:%S")
        self.scanning = False
        if result==-1:
            self.storeEnergyScan()
            self.emit('scanStatusChanged', ("Scan aborted",))
            self.emit('energyScanFailed', ())
            return

        self.storeEnergyScan()
        self.emit('energyScanFinished', (self.scanInfo,))
        self.scanInfo=None
        
    def doChooch(self, scanObject, scanDesc):
                 #elt, 
                 #edge):
                 #scanArchiveFilePrefix = 'scanArchiveFilePrefix', 
                 #scanFilePrefix = 'scanFilePrefix'):
                     
        logging.getLogger().info("EnergyScan: doChooch")
        print('scanObject', scanObject)
        print('scanDesc', scanDesc)
        #archiveRawScanFile=os.path.extsep.join((scanArchiveFilePrefix, "raw"))
        #rawScanFile=os.path.extsep.join((scanFilePrefix, "raw"))
        #scanFile=os.path.extsep.join((scanFilePrefix, "efs"))
      
        #if not os.path.exists(os.path.dirname(scanArchiveFilePrefix)):
            #os.mkdir(os.path.dirname(scanArchiveFilePrefix))
        
        #try:
            #f=open(rawScanFile, "w")
            #pyarch_f=open(archiveRawScanFile, "w")
        #except:
            #logging.getLogger("HWR").exception("could not create raw scan files")
            #self.storeEnergyScan()
            #self.emit("energyScanFailed", ())
            #return
        #else:
            #scanData = []
            #for i in range(len(scanObject.x)):
                    #x = float(scanObject.x[i])
                    #x = x < 1000 and x*1000.0 or x 
                    #y = float(scanObject.y[i])
                    #scanData.append((x, y))
                    #f.write("%f,%f\r\n" % (x, y))
                    #pyarch_f.write("%f,%f\r\n"% (x, y)) 
            #f.close()
            #pyarch_f.close()
            #self.scanInfo["scanFileFullPath"]=str(archiveRawScanFile)
        
        filenameIn = self.filenameIn
        filenameOut = filenameIn[:-3] + 'efs'
        scanData = []
        
        contents = file(filenameIn).readlines()
        file(filenameIn).close()
        
        for value in contents:
          if value[0] != '#' :
              vals = value.split()
              x = float(vals[0])
              x = x < 1000 and x*1000.0 or x #This is rather cryptic but seems to work (MS 11.03.13)
              y = float(vals[1])
              #if y == 0.0:
                  #self.scanCommandFailed()
                  #self.scanStatus.setText("data not valid for chooch")
                  #print "data not valid for chooch"
                  #return
              scanData.append((x, y))
              
        elt = scanDesc['element']
        edge = scanDesc['edgeEnergy']
        
        try:
            pk, fppPeak, fpPeak, ip, fppInfl, fpInfl, chooch_graph_data = PyChooch.calc(scanData,
                                                                                    elt, 
                                                                                    edge, 
                                                                                    filenameOut)
        except:
            pk = self.thEdge
            rm = (pk + 50.) / 1000.0
            savpk = pk
            ip = pk - 5. / 1000.0
            logging.getLogger("HWR").info("Chooch failed badly")
            #, fppPeak, fpPeak, ip, fppInfl, fpInfl, chooch_graph_data = self.thEdge, 
            
        rm = (pk + 50.) / 1000.0
        pk = pk / 1000.0
        savpk = pk
        ip = ip / 1000.0
        comm = ""
        logging.getLogger("HWR").info("th. Edge %s ; chooch results are pk=%f, ip=%f, rm=%f" % (self.thEdge,  pk, ip, rm))

        if math.fabs(self.thEdge - ip) > 0.01:
            pk = 0
            ip = 0
            rm = self.thEdge + 0.05
            comm = 'Calculated peak (%f) is more that 10eV away from the theoretical value (%f). Please check your scan' % (savpk, self.thEdge)
    
            logging.getLogger("HWR").warning('EnergyScan: calculated peak (%f) is more that 10eV %s the theoretical value (%f). Please check your scan and choose the energies manually' % (savpk, (self.thEdge - ip) > 0.01 and "below" or "above", self.thEdge))
        
        scanFile = filenameIn
        archiveEfsFile = filenameOut #os.path.extsep.join((scanArchiveFilePrefix, "efs"))
        try:
            fi = open(scanFile)
            fo = open(archiveEfsFile, "w")
        except:
            self.storeEnergyScan()
            self.emit("energyScanFailed", ())
            return
        else:
            fo.write(fi.read())
            fi.close()
            fo.close()

        self.scanInfo["peakEnergy"]=pk
        self.scanInfo["inflectionEnergy"]=ip
        self.scanInfo["remoteEnergy"]=rm
        self.scanInfo["peakFPrime"]=fpPeak
        self.scanInfo["peakFDoublePrime"]=fppPeak
        self.scanInfo["inflectionFPrime"]=fpInfl
        self.scanInfo["inflectionFDoublePrime"]=fppInfl
        self.scanInfo["comments"] = comm

        chooch_graph_x, chooch_graph_y1, chooch_graph_y2 = list(zip(*chooch_graph_data))
        chooch_graph_x = list(chooch_graph_x)
        for i in range(len(chooch_graph_x)):
          chooch_graph_x[i]=chooch_graph_x[i]/1000.0

        logging.getLogger("HWR").info("<chooch> Saving png" )
        # prepare to save png files
        title="%10s  %6s  %6s\n%10s  %6.2f  %6.2f\n%10s  %6.2f  %6.2f" % ("energy", "f'", "f''", pk, fpPeak, fppPeak, ip, fpInfl, fppInfl) 
        fig=Figure(figsize=(15, 11))
        ax=fig.add_subplot(211)
        ax.set_title("%s\n%s" % (scanFile, title))
        ax.grid(True)
        ax.plot(*(list(zip(*scanData))), **{"color":'black'})
        ax.set_xlabel("Energy")
        ax.set_ylabel("MCA counts")
        ax2=fig.add_subplot(212)
        ax2.grid(True)
        ax2.set_xlabel("Energy")
        ax2.set_ylabel("")
        handles = []
        handles.append(ax2.plot(chooch_graph_x, chooch_graph_y1, color='blue'))
        handles.append(ax2.plot(chooch_graph_x, chooch_graph_y2, color='red'))
        canvas=FigureCanvasAgg(fig)

        escan_png = filenameOut[:-3] + 'png' #.replace('.esf', '.png') #os.path.extsep.join((scanFilePrefix, "png"))
        escan_archivepng = filenameOut[:-4] + '_archive.png'  #os.path.extsep.join((scanArchiveFilePrefix, "png")) 
        self.scanInfo["jpegChoochFileFullPath"]=str(escan_archivepng)
        try:
            logging.getLogger("HWR").info("Rendering energy scan and Chooch graphs to PNG file : %s", escan_png)
            canvas.print_figure(escan_png, dpi=80)
        except:
            logging.getLogger("HWR").exception("could not print figure")
        try:
            logging.getLogger("HWR").info("Saving energy scan to archive directory for ISPyB : %s", escan_archivepng)
            canvas.print_figure(escan_archivepng, dpi=80)
        except:
            logging.getLogger("HWR").exception("could not save figure")

        self.storeEnergyScan()
        self.scanInfo=None

        logging.getLogger("HWR").info("<chooch> returning" )
        return pk, fppPeak, fpPeak, ip, fppInfl, fpInfl, rm, chooch_graph_x, chooch_graph_y1, chooch_graph_y2, title
    
    def scanStatusChanged(self,status):
        logging.getLogger("HWR").debug('EnergyScan:scanStatusChanged')
        self.emit('scanStatusChanged', (status,))
        
    def storeEnergyScan(self):
        logging.getLogger("HWR").debug('EnergyScan:storeEnergyScan')
        #if self.dbConnection is None:
            #return
        #try:
            #session_id=int(self.scanInfo['sessionId'])
        #except:
            #return
        return
        
    def updateEnergyScan(self, scan_id, jpeg_scan_filename):
        logging.getLogger("HWR").debug('EnergyScan:updateEnergyScan')

    # Elements commands
    def getElements(self):
        logging.getLogger("HWR").debug('EnergyScan:getElements')
        elements=[]
        try:
            for el in self["elements"]:
                elements.append({"symbol":el.symbol, "energy":el.energy})
        except IndexError:
            pass
        return elements

    # Mad energies commands
    def getDefaultMadEnergies(self):
        logging.getLogger("HWR").debug('EnergyScan:getDefaultMadEnergies')
        energies=[]
        try:
            for el in self["mad"]:
                energies.append([float(el.energy), el.directory])
        except IndexError:
            pass
        return energies
        
    def getFilename(self, directory, filename, element, edge):
        filenameIn = os.path.join(directory, filename)
        filenameIn += "_" + element + "_" + "_".join(edge) + ".dat"
        return filenameIn
    
    def doEnergyScan(self, element, edge, directory, filename):
        logging.getLogger("HWR").info('EnergyScan: Element:%s Edge:%s' %(element,edge))    	

        e_edge, roi_center = self.getEdgefromXabs(element, edge)
        self.thEdge = e_edge
        self.element = element
        self.edge = edge
        
        print('e_edge = %5.4f , roi_center = %5.4f' %(e_edge, roi_center)) 
        
        filenameIn = self.getFilename(directory, filename, element, edge) # filenameIn
        self.filenameIn = filenameIn
        
        # Demarrage du thread de scan
        self.scanCommandStarted()
        self.pk = None
        self.ip = None
        self.scanThread = EnergyScanThread(self,
                                           e_edge,
                                           roi_center,
                                           filenameIn)
        self.scanThread.start()

    def getEdgefromXabs(self, el, edge):
        edge = string.upper(edge)
        roi_center = McMaster[el]['edgeEnergies'][edge + '-alpha']
        if edge == 'L':
            edge = 'L3'
        e_edge = McMaster[el]['edgeEnergies'][edge]
        return (e_edge, roi_center)    
        
    def newPoint(self, x, y):
        logging.getLogger("HWR").debug('EnergyScan:newPoint')
        print('newPoint', x, y)
        self.emit('addNewPoint', (x, y))
    
    def newScan(self,scanParameters):
        logging.getLogger("HWR").debug('EnergyScan:newScan')
        self.emit('newScan', (scanParameters,))
        
    def startMoveEnergy(self, value):   # Copie du code ecrit dans BLEnergy.py pour gestion du backlash onduleur.
   
        # 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 mmte
        gaplimite = 5.5  # en mm
        self.doBacklashCompensation = False # True #MS 2013-05-21
#        self.mono_mt_rx_device.On()
        #time.sleep(5)
        
        if (str(self.BLEnergydevice.State()) != "MOVING") :# MS .State -> .State() 06.03.2013
            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(), 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(), self.BLEnergydevice.State())
        
        else : 
            statusBLEnergydevice = self.BLEnergydevice.Status()
            logging.getLogger("HWR").error("%s: Cannot move : State device = %s", self.name(), self.BLEnergydevice.State())

            for i in statusBLEnergydevice.split("\n") :
                logging.getLogger().error("\t%s\n" % i)
            logging.getLogger().error("\tCheck devices")
                # Envoi a l'energie desiree    
#        self.BLEnergydevice.energy = value
    def getChoochValue(self, pk, ip) :
        logging.getLogger("HWR").debug('EnergyScan:getChoochValue')
        self.pk = pk
        self.ip = ip