class EnergyScanThread(QThread): def __init__(self, parent, e_edge, roi_center, filenameIn): QThread.__init__(self) self.parent = parent self.e_edge = e_edge self.roi_center = roi_center self.filenameIn = filenameIn self.mrtx = DeviceProxy('i11-ma-c03/op/mono1-mt_rx') self.miniSteps = 1 #30 self.integrationTime = 1. self.resultValues = { 'transmissionFactor': None, 'exposureTime': None, 'startEnergy': None, 'endEnergy': None, 'beamSizeHorizontal': None, 'beamSizeVertical': None, 'theoreticalEdge': None, } def wait(self, device): while device.state().name == 'MOVING': time.sleep(.1) while device.state().name == 'RUNNING': time.sleep(.1) def run(self): self.result = -1 logging.getLogger("HWR").debug('EnergyScanThread:run') # mono = SimpleDevice("i10-c-c02/op/mono1") # qbpm1 = SimpleDevice("i10-c-c02/dt/xbpm_diode.1") # counter = SimpleDevice("i10-c-c00/ca/bai.1144-pci.1h-cpt.1") # if self.parent.BLEnergyHO is not None: # self.parent.connect(self.parent.BLEnergyHO,qt.PYSIGNAL('setEnergy'),self.energyChanged) # self.parent.BLEnergyHO.setEnergy(7.0) self.prepare4EScan() logging.getLogger("HWR").debug( 'EnergyScanThread: starting Scan (fileName %s)' % self.filenameIn) self.scan( ((self.parent.counterdevice, "counter1"), (self.parent.xbpmdevice, "intensity")), # sSensors (self.parent.monodevice, "energy"), # sMotor self.e_edge - self.parent.before, # sStart self.e_edge + self.parent.after, # sEnd self.parent.nbsteps, # nbSteps sFileName=self.filenameIn, # sFileName integrationTime=self.integrationTime / self.miniSteps) #integrationTime=self.parent.integrationtime logging.getLogger("HWR").debug('EnergyScanThread: Scan finished %s' % str(self.result)) self.parent.scanCommandFinished(self.result) self.afterScan() def optimizeTransmission(self): import XfeCollect logging.info('EnergyScanPX2 optimizeTransmission') logging.getLogger("HWR").debug('EnergyScanPX2 optimizeTransmission') self.xfe = XfeCollect.XfeCollect(directory='/tmp/opt_test') self.xfe.optimizeTransmission(self.parent.element, self.parent.edge) def prepare4EScan(self): logging.getLogger("HWR").debug('EnergyScanThread:prepare4EScan') self.mrtx.On() logging.getLogger("HWR").debug('EnergyScanThread:prepare4EScan (2)') self.parent.connectTangoDevices() if not self.parent.canScan: return # Rontec configuration if self.parent.fluodetdevice.State().name == "RUNNING": self.parent.fluodetdevice.Abort() while self.parent.fluodetdevice.State().name != 'STANDBY': pass #self.parent.fluodetdevice.energyMode = 1 #time.sleep(0.5) #self.parent.fluodetdevice.readDataSpectrum = 0 #time.sleep(0.5) #self.parent.fluodetdevice.SetSpeedAndResolutionConfiguration(0) #time.sleep(0.5) self.parent.fluodetdevice.presettype = 1 self.parent.fluodetdevice.peakingtime = 2.5 #2.1 self.parent.fluodetdevice.presetvalue = 0.64 #1. #conversion factor: 2048 channels correspond to 20,000 eV hence we have approx 10eV per channel #channelToeV = self.parent.fluodetdevice.dynamicRange / len(self.parent.fluodetdevice.channel00) channelToeV = 10. #MS 2013-05-23 roi_debut = 1000.0 * (self.roi_center - self.parent.roiwidth / 2.0 ) #values set in eV roi_fin = 1000.0 * (self.roi_center + self.parent.roiwidth / 2.0 ) #values set in eV print('roi_debut', roi_debut) print('roi_fin', roi_fin) channel_debut = int(roi_debut / channelToeV) + 7 channel_fin = int(roi_fin / channelToeV) + 7 print('channel_debut', channel_debut) print('channel_fin', channel_fin) # just for testing MS 07.03.2013, has to be removed for production ##### remove for production #### #roi_debut = 1120. #roi_fin = 1124. ##### remove for production #### try: #self.xfe.setROI(channel_debut, channel_fin) self.parent.fluodetdevice.SetROIs( numpy.array((channel_debut, channel_fin))) time.sleep(0.1) except: import traceback traceback.print_exc() time.sleep(1) self.optimizeTransmission() #self.parent.fluodetdevice.integrationTime = 0 # Beamline Energy Positioning and Attenuation setting #self.parent.startMoveEnergy(self.e_edge - (self.parent.before - self.parent.after)/2.0) self.parent.startMoveEnergy(self.e_edge + (self.parent.after - self.parent.before) / 2.0) #self.parent.attdevice.computedAttenuation = currentAtt # Positioning Light, BST, Rontec #self.parent.lightdevice.Extract() self.parent.md2device.write_attribute('BackLightIsOn', False) time.sleep(1) #self.parent.bstdevice.Insert() #self.parent.rontecinsertdevice.Insert() self.parent.md2device.write_attribute('FluoDetectorBack', 0) time.sleep(4) self.parent.safetyshutterdevice.Open() while self.parent.md2device.State( ).name == "MOVING" or self.parent.BLEnergydevice.State( ).name == "MOVING": time.sleep(1) def scan(self, sSensors, sMotor, sStart, sEnd, nbSteps=100, sStepSize=None, sFileName=None, stabilisationTime=0.1, interactive=False, wait_beamline_status=True, integrationTime=0.25, mono_mt_rx=None): logging.getLogger("HWR").debug('EnergyScanThread:scan') print('sSensors', sSensors) print('sMotor', sMotor) #self.mrtx.On() time.sleep(1) if not self.parent.canScan: return # initialising sData = [] sSensorDevices = [] sMotorDevice = sMotor[0] print("sStepSize:", sStepSize) if not sStepSize: sStepSize = float(sEnd - sStart) / nbSteps nbSteps += 1 else: nbSteps = int( 1 + ((sEnd - sStart) / sStepionTime) ) #__setattr__("integrationTime", integrationTime)Size)) print("nbsteps:", nbSteps) print("Starting new scan using:") sSensorDevices = sSensors nbSensors = len(sSensorDevices) doIntegrationTime = False # Rechercher les sensors compteur car besoin d'integrer avant de lire la valeur sSensorCounters = [] for sSensor in sSensorDevices: try: sSensor[0].__getattr__("integrationTime") except: pass else: doIntegrationTime = True if sSensor[0].State == "RUNNING": sSennsor[0].Stop() sSensor[0].write_attribute( "integrationTime", integrationTime ) #__setattr__("integrationTime", integrationTime) sSensorCounters.append(sSensor[0]) print("sSensorDevices", sSensorDevices) print("nbSensors = ", nbSensors) print("Motor = %s" % sMotorDevice.name()) logging.debug( "Scanning %s from %f to %f by steps of %f (nsteps = %d)" % \ (sMotorDevice.name(),sStart, sEnd, sStepSize, nbSteps)) t = time.localtime() sDate = "%02d/%02d/%d - %02d:%02d:%02d" % (t[2], t[1], t[0], t[3], t[4], t[5]) sTitle = 'EScan - %s ' % (sDate) # Parametrage du SoleilPlotBrick scanParameter = {} scanParameter['title'] = sTitle scanParameter['xlabel'] = "Energy in keV" scanParameter['ylabel'] = "Normalized counts" self.parent.newScan(scanParameter) # Pre-positioning the motor if not self.parent.scanning: return try: while str(sMotorDevice.State()) == 'MOVING': time.sleep(1) sMotorDevice.write_attribute(sMotor[1], sStart) except: print("probleme sMotor") self.parent.scanCommandFailed() # while (sMotorDevice.State == 'MOVING') # complete record of the collect MS 23.05.2013 # How to represent a fluorescence emission spectra record # Element, Edge, DateTime, Total accumulation time per data point, Number of recordings per data point # DataPoints: Undulator energy, Mono energy, ROI counts, InCounts, OutCounts, Transmission, XBPM1 intensity, counts for all Channels #collectRecord = {} #time_format = "%04d-%02d-%02d - %02d:%02d:%02d" #DateTime = time_format % (t[0], t[1], t[2], t[3], t[4], t[5]) #collectRecord['DateTime'] = DateTime #collectRecord['Edge'] = self.parent.edge #collectRecord['Element'] = self.parent.element #collectRecord['TheoreticalEdge'] = self.parent.thEdge #collectRecord['ROIwidth'] = self.parent.roiwidth #collectRecord['ROIcenter'] = self.roi_center #collectRecord['ROIStartsEnds'] = self.roisStartsEnds #collectRecord['IntegrationTime'] = integrationTime #collectRecord['StabilisationTime'] = stabilisationTime #collectRecord['Transmission'] = ''c #collectRecord['Filter'] = '' #collectRecord['DataPoints'] = {} # Ecriture de l'entete du fichier logging.debug(" energy scan thread saving data to %s " % sFileName) try: f = open(sFileName, "w") except: print("probleme ouverture fichier") self.parent.scanCommandFailed() return f.write("# %s\n" % (sTitle)) f.write("# Motor = %s\n" % sMotorDevice.name()) # On insere les valeurs normalisees dans le deuxieme colonne f.write("# Normalized value\n") for sSensor in sSensorDevices: print("type(sSensor) = ", type(sSensor)) f.write("# %s\n" % (sSensor[0].name())) f.write("# Counts on the fluorescence detector: all channels") f.write( "# Counts on the fluorescence detector: channels up to end of ROI") tDebut = time.time() # On ajoute un sensor pour la valeur normalisee (specifique au EScan) nbSensors = nbSensors + 1 fmt_f = "%12.4e" + (nbSensors + 2) * "%12.4e" + "\n" _ln = 0 channel_debut, channel_end = self.parent.fluodetdevice.roisStartsEnds # Entering the Scan loop measurement = 0 for sI in range( nbSteps ): #range(nbSteps): MS. 11.03.2013 lower the number for quick tests print('Step sI', sI, 'of', nbSteps) # test sur l utilisateur n a pas demande un stop if not self.parent.scanning: break pos_i = sStart + (sI * sStepSize) # positionnement du moteur while str(sMotorDevice.State()) == 'MOVING': time.sleep(1) sMotorDevice.write_attribute( sMotor[1], pos_i) #sMotorDevice.__setattr__(sMotor[1], pos_i) # opening the fast shutter # self.parent.fastshutterdevice.Open() self.wait(self.parent.md2device) self.parent.md2device.OpenFastShutter( ) #write_attribute('FastShutterIsOpen', 1) self.parent.fast_shutter_hwo.openShutter() #while self.parent.md2device.read_attribute('FastShutterIsOpen') != 1: #time.nsleep(0.05) # Attente de stabilisation #time.sleep(stabilisationTime) # starting the measurement for the energy step #miniSteps = 3 roiCounts = 0 intensity = 0 eventsInRun = 0 eventsInRun_upToROI = 0 for mS in range(self.miniSteps): measurement += 1 self.parent.fluodetdevice.Start() #self.parent.counterdevice.Start() #time.sleep(integrationTime/self.miniSteps) #while self.parent.counterdevice.State().name != 'STANDBY': #pass #self.parent.fluodetdevice.Abort() while self.parent.fluodetdevice.State().name != 'STANDBY': pass roiCounts += self.parent.fluodetdevice.roi00_01 intensity += self.parent.xbpmdevice.intensity eventsInRun += self.parent.fluodetdevice.eventsInRun00 #print 5*'\n' #print 'realTime00', self.parent.fluodetdevice.realTime00 #print 5*'\n' eventsInRun_upToROI += sum( self.parent.fluodetdevice.channel00[channel_end + 10:] ) #elastic peak normalization #collectRecord['DataPoints'][measurement] = {} #collectRecord['DataPoints'][measurement]['MonoEnergy'] = pos_i #collectRecord['DataPoints'][measurement]['ROICounts'] = self.parent.fluodetdevice.roi00_01 #Lecture de la position du moteur pos_readed = sMotorDevice.read_attribute( sMotor[1]).value #__getattr__(sMotor[1]) # On laisse une place pour mettre la valeur normalisee (specifique au EScan) measures = [pos_readed, -1.0] print("Position: %12.4e Measures: " % pos_readed) # Lecture des differents sensors measures.append( roiCounts ) #(self.parent.fluodetdevice.roi00_01) #eventsInRun00) measures.append(intensity) #(self.parent.xbpmdevice.intensity) measures.append( eventsInRun) #(self.parent.fluodetdevice.eventsInRun00) measures.append(eventsInRun_upToROI) # closing the fastshutter #self.parent.fastshutterdevice.Close() self.wait(self.parent.md2device) #self.parent.md2device.CloseFastShutter() #write_attribute('FastShutterIsOpen', 0) self.parent.fast_shutter_hwo.closeShutter() #while self.parent.md2device.read_attribute('FastShutterIsOpen') != 0: #time.sleep(0.05) # Valeur normalisee specifique au EScan #(Oblige an mettre le sensor compteur en premier et le xbpm en deuxieme dans le liste des sensors) try: measures[1] = measures[2] / measures[5] #measures[3] except ZeroDivisionError as e: print(e) print('Please verify that the safety shutter is open.') measures[1] = 0.0 # Demande de mise a jour du SoleilPlotBrick #if sI % 5 == 0: self.parent.newPoint(measures[0], measures[1]) #Ecriture des mesures dans le fichier f.write(fmt_f % tuple(measures)) _ln += 1 if not _ln % 10: f.flush() # flush the buffer every 10 lines # Exiting the Scan loop #self.parent.fastshutterdevice.Close() #while self.parent.fastshutterdevice.State != "CLOSE": #time.sleep(0.1) #self.parent.md2device.CloseFastShutter() self.parent.fast_shutter_hwo.closeShutter() #while self.parent.md2device.read_attribute('FastShutterIsOpen') != 0: #time.sleep(0.05) self.parent.fluodetdevice.Abort() self.parent.md2device.write_attribute('FluoDetectorBack', 1) time.sleep(2) #self.parent.mono_mt_rx_device.On() if not self.parent.scanning: self.result = -1 else: self.result = 1 tScanTotal = time.time() - tDebut print("Time taken for the scan = %.2f sec" % (tScanTotal)) f.write("# Duration = %.2f sec\n" % (tScanTotal)) f.close() def afterScan(self): logging.getLogger("HWR").debug('EnergyScanThread:afterScan') self.parent.safetyshutterdevice.Close() if self.parent.pk: self.parent.startMoveEnergy(self.parent.pk)
class EnergyScanPX2(Equipment): MANDATORY_HO = {"BLEnergy": "BLEnergy"} def init(self): self.ready_event = gevent.event.Event() self.scanning = None # self.moving = None self.scanThread = None self.pk = None self.ip = None self.roiwidth = 0.3 # 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): self.fast_shutter_hwo = self.getObjectByRole("fast_shutter") 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.safetyshutterdevice = DeviceProxy( self.getProperty("safetyshutter")) #, verbose=False) self.safetyshutterdevice.timeout = 2000 except: logging.getLogger("HWR").error("%s not found" % (self.getProperty("safetyshutter"))) self.canScan = False try: self.bstdevice = DeviceProxy( self.getProperty("bst")) #, verbose=False) self.bstdevice.timeout = 6000 except: logging.getLogger("HWR").error("%s not found" % (self.getProperty("bst"))) 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): self._scan_edge = edge self._scan_element = element 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 self.ready_event.set() 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', ()) self.ready_event.set() def scanCommandAborted(self): logging.getLogger("HWR").debug('EnergyScan:scanCommandAborted') def scanCommandFinished(self, result): with cleanup(self.ready_event.set): 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.scanInfo=None try: t = float(result["transmissionFactor"]) except: pass else: self.scanInfo["transmissionFactor"] = t try: et = float(result['exposureTime']) except: pass else: self.scanInfo["exposureTime"] = et try: se = float(result['startEnergy']) except: pass else: self.scanInfo["startEnergy"] = se try: ee = float(result['endEnergy']) except: pass else: self.scanInfo["endEnergy"] = ee try: bsX = float(result['beamSizeHorizontal']) except: pass else: self.scanInfo["beamSizeHorizontal"] = bsX try: bsY = float(result['beamSizeVertical']) except: pass else: self.scanInfo["beamSizeVertical"] = bsY try: self.thEdge = float(result['theoreticalEdge']) / 1000.0 self.thEdge = self._scan_edge except: pass self.emit('energyScanFinished', (self.scanInfo, )) def doChooch(self, scanObject, elt, edge, scanArchiveFilePrefix, scanFilePrefix): symbol = "_".join((elt, edge)) scanArchiveFilePrefix = "_".join((scanArchiveFilePrefix, symbol)) i = 1 while os.path.isfile( os.path.extsep.join((scanArchiveFilePrefix + str(i), "raw"))): i = i + 1 scanArchiveFilePrefix = scanArchiveFilePrefix + str(i) 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.makedirs(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 = [] if scanObject is None: raw_data_file = os.path.join(os.path.dirname(scanFilePrefix), 'data.raw') try: raw_file = open(raw_data_file, 'r') except: self.storeEnergyScan() self.emit("energyScanFailed", ()) return for line in raw_file.readlines()[2:]: (x, y) = line.split('\t') x = float(x.strip()) y = float(y.strip()) x = x < 1000 and x * 1000.0 or x scanData.append((x, y)) f.write("%f,%f\r\n" % (x, y)) pyarch_f.write("%f,%f\r\n" % (x, y)) else: 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) pk, fppPeak, fpPeak, ip, fppInfl, fpInfl, chooch_graph_data = PyChooch.calc( scanData, elt, edge, scanFile) rm = (pk + 30) / 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) > self.thEdgeThreshold: pk = 0 ip = 0 rm = self.thEdge + 0.03 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 20eV %s the theoretical value (%f). Please check your scan and choose the energies manually' % (savpk, (self.thEdge - ip) > 0.02 and "below" or "above", self.thEdge)) archiveEfsFile = 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 = os.path.extsep.join((scanFilePrefix, "png")) escan_archivepng = 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") self.emit('chooch_finished', (pk, fppPeak, fpPeak, ip, fppInfl, fpInfl, rm, chooch_graph_x, chooch_graph_y1, chooch_graph_y2, title)) return pk, fppPeak, fpPeak, ip, fppInfl, fpInfl, rm, chooch_graph_x, chooch_graph_y1, chooch_graph_y2, title def doChooch_old(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 logging.debug( "DOING ENERGY SCAN: e_edge = %5.4f , roi_center = %5.4f" % (e_edge, roi_center)) 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