Source code for PyMca5.PyMcaGui.pymca.Mca2Edf

#!/usr/bin/env python
#/*##########################################################################
# Copyright (C) 2004-2014 V.A. Sole, European Synchrotron Radiation Facility
#
# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
# the ESRF by the Software group.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#############################################################################*/
__author__ = "V.A. Sole - ESRF Data Analysis"
__contact__ = "sole@esrf.fr"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
import sys
import os
import numpy
import time

from PyMca5.PyMcaGui import PyMcaQt as qt
QTVERSION = qt.qVersion()
if QTVERSION >= '4.0.0':
    qt.Qt.WDestructiveClose = "TO BE DONE"
from PyMca5.PyMcaGui import IconDict
from PyMca5.PyMcaGui.pymca import McaCustomEvent
from PyMca5.PyMcaIO import EdfFile
from PyMca5.PyMcaCore import SpecFileLayer
from PyMca5 import PyMcaDirs


[docs]class Mca2EdfGUI(qt.QWidget): def __init__(self,parent=None,name="Mca to Edf Conversion",fl=qt.Qt.WDestructiveClose, filelist=None,outputdir=None, actions=0): if qt.qVersion() < '4.0.0': qt.QWidget.__init__(self,parent,name,fl) self.setIcon(qt.QPixmap(IconDict['gioconda16'])) self.setCaption(name) else: qt.QWidget.__init__(self, parent) self.setWindowTitle(name) self.setWindowIcon(qt.QIcon(qt.QPixmap(IconDict['gioconda16']))) self.mainLayout = qt.QVBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) #layout.setAutoAdd(1) self.__build(actions) if filelist is None: filelist = [] self.outputDir = None self.inputDir = None self.setFileList(filelist) self.setOutputDir(outputdir) def __build(self,actions): self.__grid= qt.QWidget(self) #self.__grid.setGeometry(qt.QRect(30,30,288,156)) if QTVERSION < '4.0.0': grid = qt.QGridLayout(self.__grid,3,3,11,6) grid.setColStretch(0,0) grid.setColStretch(1,1) grid.setColStretch(2,0) else: grid = qt.QGridLayout(self.__grid) grid.setContentsMargins(11, 11, 11, 11) grid.setSpacing(6) #input list listrow = 0 listlabel = qt.QLabel(self.__grid) listlabel.setText("Input File list:") if QTVERSION < '4.0.0': listlabel.setAlignment(qt.QLabel.WordBreak | qt.QLabel.AlignVCenter) self.__listView = qt.QTextView(self.__grid) else: self.__listView = qt.QTextEdit(self.__grid) self.__listView.setMaximumHeight(30*listlabel.sizeHint().height()) self.__listButton = qt.QPushButton(self.__grid) self.__listButton.setText('Browse') self.__listButton.clicked.connect(self.browseList) grid.addWidget(listlabel, listrow, 0, qt.Qt.AlignTop|qt.Qt.AlignLeft) grid.addWidget(self.__listView, listrow, 1) grid.addWidget(self.__listButton,listrow, 2, qt.Qt.AlignTop|qt.Qt.AlignRight) #output dir outrow = 1 outlabel = qt.QLabel(self.__grid) outlabel.setText("Output dir:") if QTVERSION < '4.0.0': outlabel.setAlignment(qt.QLabel.WordBreak | qt.QLabel.AlignVCenter) self.__outLine = qt.QLineEdit(self.__grid) self.__outLine.setReadOnly(True) #self.__outLine.setSizePolicy(qt.QSizePolicy(qt.QSizePolicy.Maximum, qt.QSizePolicy.Fixed)) self.__outButton = qt.QPushButton(self.__grid) self.__outButton.setText('Browse') self.__outButton.clicked.connect(self.browseOutputDir) grid.addWidget(outlabel, outrow, 0, qt.Qt.AlignLeft) grid.addWidget(self.__outLine, outrow, 1) grid.addWidget(self.__outButton, outrow, 2, qt.Qt.AlignLeft) #step filesteprow =2 filesteplabel = qt.QLabel(self.__grid) filesteplabel.setText("New EDF file each") filesteplabel2 = qt.QLabel(self.__grid) self.__fileSpin = qt.QSpinBox(self.__grid) if QTVERSION < '4.0.0': self.__fileSpin.setMinValue(1) self.__fileSpin.setMaxValue(999999) else: self.__fileSpin.setMinimum(1) self.__fileSpin.setMaximum(999999) self.__fileSpin.setValue(1) filesteplabel2.setText("mca") grid.addWidget(filesteplabel, filesteprow, 0, qt.Qt.AlignLeft) grid.addWidget(self.__fileSpin,filesteprow, 1) grid.addWidget(filesteplabel2, filesteprow, 2, qt.Qt.AlignLeft) self.mainLayout.addWidget(self.__grid) if actions: self.__buildActions() def __buildActions(self): box = qt.QWidget(self) boxLayout = qt.QHBoxLayout(box) boxLayout.addWidget(qt.HorizontalSpacer(box)) self.__dismissButton = qt.QPushButton(box) boxLayout.addWidget(self.__dismissButton) boxLayout.addWidget(qt.HorizontalSpacer(box)) self.__dismissButton.setText("Close") self.__startButton = qt.QPushButton(box) boxLayout.addWidget(self.__startButton) boxLayout.addWidget(qt.HorizontalSpacer(box)) self.__startButton.setText("Start") self.mainLayout.addWidget(box) self.__dismissButton.clicked.connect(self.close) self.__startButton.clicked.connect(self.start)
[docs] def setFileList(self,filelist=None): if filelist is None:filelist = [] if True or self.__goodFileList(filelist): text = "" #respect initial file list choice #filelist.sort() for ffile in filelist: text += "%s\n" % ffile self.fileList = filelist self.__listView.setText(text) if len(filelist): PyMcaDirs.inputDir = os.path.dirname(filelist[0])
[docs] def setOutputDir(self,outputdir=None): if outputdir is None:return if self.__goodOutputDir(outputdir): self.outputDir = outputdir self.__outLine.setText(outputdir) PyMcaDirs.outputDir = self.outputDir else: qt.QMessageBox.critical(self, "ERROR", "Cannot use output directory:\n%s"% (outputdir))
def __goodFileList(self,filelist): if not len(filelist):return True for file in filelist: if not os.path.exists(file): qt.QMessageBox.critical(self, "ERROR",'File %s\ndoes not exists' % file) self.raiseW() return False return True def __goodOutputDir(self,outputdir): if os.path.isdir(outputdir):return True else:return False
[docs] def browseList(self): if self.inputDir is None:self.inputDir = PyMcaDirs.inputDir if not os.path.exists(self.inputDir): self.inputDir = os.getcwd() wdir = self.inputDir if QTVERSION < '4.0.0': filedialog = qt.QFileDialog(self,"Open a set of files",1) filedialog.setMode(filedialog.ExistingFiles) filedialog.setDir(wdir) filedialog.setFilters("Mca Files (*.mca)\nSpec Files (*.dat)\nAll Files (*)\n") if filedialog.exec_loop() == qt.QDialog.Accepted: filelist0=filedialog.selectedFiles() else: self.raiseW() return else: filedialog = qt.QFileDialog(self) filedialog.setWindowTitle("Open a set of files") filedialog.setDirectory(wdir) filedialog.setFilters(["Mca Files (*.mca)", "Spec Files (*.dat)", "All Files (*)"]) filedialog.setModal(1) filedialog.setFileMode(filedialog.ExistingFiles) ret = filedialog.exec_() if ret == qt.QDialog.Accepted: filelist0=filedialog.selectedFiles() else: self.raise_() return filelist = [] for f in filelist0: filelist.append(qt.safe_str(f)) if len(filelist): self.setFileList(filelist) if QTVERSION < '4.0.0': self.raiseW() else: self.raise_()
[docs] def browseConfig(self): filename = qt.QFileDialog(self,"Open a new fit config file",1) filename.setMode(filename.ExistingFiles) filename.setFilters("Config Files (*.cfg)\nAll files (*)") if filename.exec_loop() == qt.QDialog.Accepted: filename = filename.selectedFile() else: self.raiseW() return filename= qt.safe_str(filename) if len(filename): self.setConfigFile(filename) self.raiseW()
[docs] def browseOutputDir(self): if self.outputDir is None: self.outputDir = PyMcaDirs.outputDir if not os.path.exists(self.outputDir): self.outputDir = os.getcwd() wdir = self.outputDir if QTVERSION < '4.0.0': outfile = qt.QFileDialog(self,"Output Directory Selection",1) outfile.setMode(outfile.DirectoryOnly) outfile.setDir(wdir) ret = outfile.exec_loop() else: outfile = qt.QFileDialog(self) outfile.setWindowTitle("Output Directory Selection") outfile.setModal(1) outfile.setDirectory(wdir) outfile.setFileMode(outfile.DirectoryOnly) ret = outfile.exec_() if ret: if QTVERSION < '4.0.0': outdir = qt.safe_str(outfile.selectedFile()) else: outdir = qt.safe_str(outfile.selectedFiles()[0]) outfile.close() del outfile self.setOutputDir(outdir) else: # pyflakes http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666494 outfile.close() del outfile if QTVERSION < '4.0.0': self.raiseW() else: self.raise_()
[docs] def start(self): if not len(self.fileList): qt.QMessageBox.critical(self, "ERROR",'Empty file list') if QTVERSION < '4.0.0': self.raiseW() else: self.raise_() return if (self.outputDir is None) or (not self.__goodOutputDir(self.outputDir)): qt.QMessageBox.critical(self, "ERROR",'Invalid output directory') if QTVERSION < '4.0.0': self.raiseW() else: self.raise_() return name = "Batch from %s to %s " % (os.path.basename(self.fileList[ 0]), os.path.basename(self.fileList[-1])) window = Mca2EdfWindow(name="Mca 2 Edf "+name,actions=1) self.fileStep = int(qt.safe_str(self.__fileSpin.text())) b = Mca2EdfBatch(window,self.fileList,self.outputDir, self.fileStep) def cleanup(): b.pleasePause = 0 b.pleaseBreak = 1 b.wait() qApp = qt.QApplication.instance() qApp.processEvents() def pause(): if b.pleasePause: b.pleasePause=0 window.pauseButton.setText("Pause") else: b.pleasePause=1 window.pauseButton.setText("Continue") window.pauseButton.clicked.connect(pause) window.abortButton.clicked.connect(window.close) qApp = qt.QApplication.instance() qApp.aboutToQuit.connect(cleanup) self.__window = window self.__b = b window.show() b.start()
[docs]class Mca2EdfBatch(qt.QThread): def __init__(self, parent, filelist=None, outputdir = None, filestep = 1): self._filelist = filelist self.outputdir = outputdir self.filestep = filestep qt.QThread.__init__(self) self.parent = parent self.pleasePause = 0
[docs] def processList(self): self.__ncols = None self.__nrows = self.filestep counter = 0 ffile = SpecFileLayer.SpecFileLayer() for fitfile in self._filelist: self.onNewFile(fitfile, self._filelist) ffile.SetSource(fitfile) fileinfo = ffile.GetSourceInfo() # nscans = len(fileinfo['KeyList']) for scankey in fileinfo['KeyList']: scan,order = scankey.split(".") info,data = ffile.LoadSource(scankey) scan_obj = ffile.Source.select(scankey) if info['NbMca'] > 0: for i in range(info['NbMca']): point = int(i/info['NbMcaDet']) + 1 mca = (i % info['NbMcaDet']) + 1 key = "%s.%s.%05d.%d" % (scan,order,point,mca) if i == 0: mcainfo,mcadata = ffile.LoadSource(key) mcadata = scan_obj.mca(i+1) y0 = numpy.array(mcadata, numpy.float) if counter == 0: key0 = "%s key %s" % (os.path.basename(fitfile), key) self.__ncols = len(y0) image = numpy.zeros((self.__nrows,self.__ncols), \ numpy.float) if self.__ncols != len(y0): print("spectrum has different number of columns") print("skipping it") else: image[counter,:] = y0[:] if (counter+1) == self.filestep: if self.filestep > 1: key1 = "%s key %s" % (os.path.basename(fitfile), key) title = "%s to %s" % (key0, key1) else: title = key0 if 1: ddict={} if 'Channel0' in mcainfo: ddict['MCA start ch'] =\ int(mcainfo['Channel0']) if 'McaCalib' in mcainfo: ddict['MCA a'] = mcainfo['McaCalib'][0] ddict['MCA b'] = mcainfo['McaCalib'][1] ddict['MCA c'] = mcainfo['McaCalib'][2] else: ddict = mcainfo ddict['Title'] = title edfname = os.path.join(self.outputdir,title.replace(" ","_")+".edf") edfout = EdfFile.EdfFile(edfname) edfout.WriteImage (ddict , image, Append=0) counter = 0 else: counter += 1 self.onEnd()
[docs] def run(self): self.processList()
[docs] def onNewFile(self, file, filelist): qt.QApplication.postEvent(self.parent, McaCustomEvent.McaCustomEvent({'file':file, 'filelist':filelist, 'event':'onNewFile'})) if self.pleasePause:self.__pauseMethod()
[docs] def onEnd(self): qt.QApplication.postEvent(self.parent, McaCustomEvent.McaCustomEvent({'event':'onEnd'})) if self.pleasePause:self.__pauseMethod()
def __pauseMethod(self): qt.QApplication.postEvent(self.parent, McaCustomEvent.McaCustomEvent({'event':'batchPaused'})) while(self.pleasePause): time.sleep(1) qt.QApplication.postEvent(self.parent, McaCustomEvent.McaCustomEvent({'event':'batchResumed'}))
[docs]class Mca2EdfWindow(qt.QWidget): def __init__(self,parent=None, name="BatchWindow", fl=0, actions = 0): if qt.qVersion() < '4.0.0': qt.QWidget.__init__(self, parent, name, fl) self.setCaption(name) else: qt.QWidget.__init__(self, parent) self.setWindowTitle(name) self.l = qt.QVBoxLayout(self) self.l.setContentsMargins(0, 0, 0, 0) self.l.setSpacing(0) self.bars =qt.QWidget(self) self.l.addWidget(self.bars) if QTVERSION < '4.0.0': self.barsLayout = qt.QGridLayout(self.bars,2,3) else: self.barsLayout = qt.QGridLayout(self.bars) self.barsLayout.setContentsMargins(2, 2, 2, 2) self.barsLayout.setSpacing(3) self.progressBar = qt.QProgressBar(self.bars) self.progressLabel = qt.QLabel(self.bars) self.progressLabel.setText('File Progress:') self.barsLayout.addWidget(self.progressLabel,0,0) self.barsLayout.addWidget(self.progressBar,0,1) self.status = qt.QLabel(self) self.l.addWidget(self.status) self.status.setText(" ") self.timeLeft = qt.QLabel(self) self.l.addWidget(self.timeLeft) self.timeLeft.setText("Estimated time left = ???? min") self.time0 = None if actions: self.addButtons() self.show() if QTVERSION < '4.0.0': self.raiseW() else: self.raise_()
[docs] def addButtons(self): self.actions = 1 self.buttonsBox = qt.QWidget(self) l = qt.QHBoxLayout(self.buttonsBox) l.addWidget(qt.HorizontalSpacer(self.buttonsBox)) self.pauseButton = qt.QPushButton(self.buttonsBox) l.addWidget(self.pauseButton) l.addWidget(qt.HorizontalSpacer(self.buttonsBox)) self.pauseButton.setText("Pause") self.abortButton = qt.QPushButton(self.buttonsBox) l.addWidget(self.abortButton) l.addWidget(qt.HorizontalSpacer(self.buttonsBox)) self.abortButton.setText("Abort") self.l.addWidget(self.buttonsBox) self.update()
[docs] def customEvent(self,event): if event.dict['event'] == 'onNewFile':self.onNewFile(event.dict['file'], event.dict['filelist']) elif event.dict['event'] == 'onEnd': self.onEnd(event.dict) elif event.dict['event'] == 'batchPaused': self.onPause() elif event.dict['event'] == 'batchResumed':self.onResume() else: print("Unhandled event %s" % event)
[docs] def onNewFile(self, file, filelist): indexlist = range(0,len(filelist)) index = indexlist.index(filelist.index(file)) nfiles = len(indexlist) self.status.setText("Processing file %s" % file) e = time.time() if QTVERSION < '4.0.0': self.progressBar.setTotalSteps(nfiles) self.progressBar.setProgress(index) else: self.progressBar.setMaximum(nfiles) self.progressBar.setValue(index) if self.time0 is not None: t = (e - self.time0) * (nfiles - index) self.time0 =e if t < 120: self.timeLeft.setText("Estimated time left = %d sec" % (t)) else: self.timeLeft.setText("Estimated time left = %d min" % (int(t / 60.))) else: self.time0 = e if sys.platform == 'darwin': qApp = qt.QApplication.instance() qApp.processEvents()
[docs] def onEnd(self,ddict): if QTVERSION < '4.0.0': n = self.progressBar.progress() self.progressBar.setProgress(n+1) else: n = self.progressBar.value() self.progressBar.setValue(n+1) self.status.setText ("Batch Finished") self.timeLeft.setText("Estimated time left = 0 sec") if self.actions: self.pauseButton.hide() self.abortButton.setText("OK")
[docs] def onPause(self): pass
[docs] def onResume(self): pass
[docs]def main(): import getopt options = 'f' longoptions = ['outdir=', 'listfile=', 'mcastep='] filelist = None outdir = None listfile = None mcastep = 1 opts, args = getopt.getopt( sys.argv[1:], options, longoptions) for opt,arg in opts: if opt in ('--outdir'): outdir = arg elif opt in ('--listfile'): listfile = arg elif opt in ('--mcastep'): mcastep = int(arg) if listfile is None: filelist=[] for item in args: filelist.append(item) else: fd = open(listfile) filelist = fd.readlines() fd.close() for i in range(len(filelist)): filelist[i]=filelist[i].replace('\n','') app=qt.QApplication(sys.argv) winpalette = qt.QPalette(qt.QColor(230,240,249),qt.QColor(238,234,238)) app.setPalette(winpalette) app.lastWindowClosed.connect(app.quit) if len(filelist) == 0: w = Mca2EdfGUI(actions=1) w.show() sys.exit(app.exec_()) else: text = "Batch from %s to %s" % (os.path.basename(filelist[0]), \ os.path.basename(filelist[-1])) window = Mca2EdfWindow(name=text,actions=1) b = Mca2EdfBatch(window,filelist,outdir,mcastep) def cleanup(): b.pleasePause = 0 b.pleaseBreak = 1 b.wait() qApp = qt.QApplication.instance() qApp.processEvents() def pause(): if b.pleasePause: b.pleasePause=0 window.pauseButton.setText("Pause") else: b.pleasePause=1 window.pauseButton.setText("Continue") window.pauseButton.clicked.connect(pause) window.abortButton.clicked.connect(window.close) app.aboutToQuit.connect(cleanup) window.show() b.start() sys.exit(app.exec_())
if __name__ == "__main__": main() # Mca2Edf.py --outdir=/tmp --mcastep=1 *.mca # PyMcaBatch.py --cfg=/mntdirect/_bliss/users/sole/COTTE/WithLead.cfg --outdir=/tmp/ /mntdirect/_bliss/users/sole/COTTE/ch09/ch09__mca_0003_0000_0007.edf /mntdirect/_bliss/users/sole/COTTE/ch09/ch09__mca_0003_0000_0008.edf /mntdirect/_bliss/users/sole/COTTE/ch09/ch09__mca_0003_0000_0009.edf /mntdirect/_bliss/users/sole/COTTE/ch09/ch09__mca_0003_0000_0010.edf /mntdirect/_bliss/users/sole/COTTE/ch09/ch09__mca_0003_0000_0011.edf /mntdirect/_bliss/users/sole/COTTE/ch09/ch09__mca_0003_0000_0012.edf /mntdirect/_bliss/users/sole/COTTE/ch09/ch09__mca_0003_0000_0013.edf & # PyMcaBatch.exe --cfg=E:/COTTE/WithLead.cfg --outdir=C:/tmp/ E:/COTTE/ch09/ch09__mca_0003_0000_0007.edf E:/COTTE/ch09/ch09__mca_0003_0000_0008.edf