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)
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()
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()
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