#/*##########################################################################
#
# The PyMca X-Ray Fluorescence Toolkit
#
# Copyright (c) 2004-2014 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. Armando Sole - ESRF Data Analysis"
__contact__ = "sole@esrf.fr"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
import sys
import os
import numpy
from . import QXTube
from PyMca5.PyMcaCore import PyMcaDirs
from PyMca5.PyMcaGui import PyMca_Icons as Icons
from PyMca5.PyMcaGui.pymca import PyMcaFileDialogs
qt = QXTube.qt
QTVERSION = qt.qVersion()
DEBUG=0
[docs]class EnergyTab(qt.QWidget):
def __init__(self,parent=None, name="Energy Tab"):
qt.QWidget.__init__(self, parent)
layout = qt.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(4)
hbox = qt.QWidget(self)
self.hbox = qt.QHBoxLayout(hbox)
self.hbox.setContentsMargins(0, 0, 0, 0)
self.hbox.setSpacing(0)
self.tube = QXTube.QXTube(hbox)
self.table = EnergyTable(hbox)
self.hbox.addWidget(self.tube)
self.hbox.addWidget(self.table)
self.tube.plot()
self.tube.hide()
self.outputFilter = None
self.inputDir = None
self.outputDir = None
self.__calculating = 0
self.tubeActionsBox = qt.QWidget(self)
actionsLayout = qt.QHBoxLayout(self.tubeActionsBox)
actionsLayout.setContentsMargins(0, 0, 0, 0)
actionsLayout.setSpacing(0)
#tube setup button
self.tubeButton = qt.QPushButton(self.tubeActionsBox)
self.tubeButton.setText("Open X-Ray Tube Setup")
actionsLayout.addWidget(self.tubeButton, 1)
#load new energy table
self.tubeLoadButton = qt.QPushButton(self.tubeActionsBox)
self.tubeLoadButton.setText("Load Table")
actionsLayout.addWidget(self.tubeLoadButton, 0)
#save seen energy table
self.tubeSaveButton = qt.QPushButton(self.tubeActionsBox)
self.tubeSaveButton.setText("Save Table")
actionsLayout.addWidget(self.tubeSaveButton, 0)
layout.addWidget(self.tubeActionsBox)
layout.addWidget(hbox)
self.tubeButton.clicked.connect(self.tubeButtonClicked)
self.tubeLoadButton.clicked.connect(self.loadButtonClicked)
self.tubeSaveButton.clicked.connect(self.saveButtonClicked)
self.tube.sigQXTubeSignal.connect(self.__tubeUpdated)
[docs] def loadEnergyTableParameters(self, filename):
if sys.platform == "win32" and (sys.version < "3.0.0"):
ffile = open(filename, "rb")
else:
ffile = open(filename, "r")
lines = ffile.read()
ffile.close()
lines = lines.replace("\r","\n")
lines = lines.replace('\n\n',"\n")
lines = lines.replace(";"," ")
lines = lines.replace("\t"," ")
lines = lines.replace('"',"")
lines = lines.split("\n")
if (len(lines) == 1) or\
((len(lines) == 2) and (len(lines[1])==0)):
#clear table
ddict={}
ddict['energylist'] = [None]
ddict['weightlist'] = [1.0]
ddict['flaglist'] = [1]
ddict['scatterlist'] = [1]
else:
ddict={}
ddict['energylist'] = []
ddict['weightlist'] = []
ddict['flaglist'] = []
ddict['scatterlist'] = []
for i in range(1, len(lines)):
line = lines[i]
if not len(line):
continue
ene, weight, useflag, scatterflag = map(float,
line.split(" "))
if ene > 0:
ddict['energylist'].append(ene)
else:
ddict['energylist'].append(None)
ddict['weightlist'].append(weight)
ddict['flaglist'].append(int(useflag))
ddict['scatterlist'].append(int(scatterflag))
energylist, weightlist, flaglist, scatterlist = self.table.getParameters()
lold = len(energylist)
lnew = len(ddict['energylist'])
if lold > lnew:
energylist = [None] * lold
weightlist = [0.0] * lold
flaglist = [0] * lold
scatterlist = [0] * lold
energylist[0:lnew] = ddict['energylist'][0:lnew]
weightlist[0:lnew] = ddict['weightlist'][0:lnew]
flaglist[0:lnew] = ddict['flaglist'][0:lnew]
scatterlist[0:lnew] = ddict['scatterlist'][0:lnew]
self.table.setParameters(energylist,
weightlist,
flaglist,
scatterlist)
else:
self.table.setParameters(ddict["energylist"],
ddict["weightlist"],
ddict["flaglist"],
ddict["scatterlist"])
def __tubeUpdated(self, d):
if self.__calculating:return
else: self.__calculating = 1
self.table.setParameters(d["energylist"],
d["weightlist"],
d["flaglist"],
d["scatterlist"])
self.__calculating = 0
self.tubeButtonClicked()
QTable = qt.QTableWidget
[docs]class EnergyTable(QTable):
sigEnergyTableSignal = qt.pyqtSignal(object)
def __init__(self, parent=None, name="Energy Table",
energylist=None, weightlist=None, flaglist=None,offset=None,scatterlist=None):
QTable.__init__(self, parent)
if energylist is None:energylist=[]
if weightlist is None:weightlist =[]
if flaglist is None:flaglist =[]
if scatterlist is None:scatterlist =[]
if offset is None:offset = 0
self.energyList = energylist
self.weightList = weightlist
self.flagList = flaglist
self.offset = offset
self.scatterList = scatterlist
self.verticalHeader().hide()
self.dataColumns = 20
if QTVERSION < '4.0.0':
self.setLeftMargin(0)
self.setFrameShape(qttable.QTable.NoFrame)
#self.setFrameShadow(qttable.QTable.Sunken)
self.setSelectionMode(qttable.QTable.Single)
self.setNumCols(3 * self.dataColumns)
self.setFocusStyle(qttable.QTable.FollowStyle)
else:
if DEBUG:
print("margin")
print("frame shape")
print("selection mode")
print("focus style")
print("all of them missing")
self.setColumnCount(3 * self.dataColumns)
labels = []
for i in range(self.dataColumns):
labels.append("Use" + i * " ")
labels.append("Energy" + i * " ")
labels.append("Weight" + i * " ")
if QTVERSION < '4.0.0':
for label in labels:
self.horizontalHeader().setLabel(labels.index(label),label)
else:
if DEBUG:
print("margin to addjust")
print("focus style")
self.setFrameShape(qt.QTableWidget.NoFrame)
self.setSelectionMode(qt.QTableWidget.NoSelection)
self.setColumnCount(len(labels))
for i in range(len(labels)):
item = self.horizontalHeaderItem(i)
if item is None:
item = qt.QTableWidgetItem(labels[i],qt.QTableWidgetItem.Type)
self.setHorizontalHeaderItem(i,item)
self.__rows = 20
self.__build(self.dataColumns * 20)
self.__disconnected = False
for i in range(self.dataColumns):
if DEBUG:
print("column adjustment missing")
self.cellChanged[int, int].connect(self.mySlot)
def _itemSlot(self, *var):
self.mySlot(self.currentRow(), self.currentColumn())
def __build(self,nrows=None):
#self.setNumRows(int(nrows/2))
if nrows is None: nrows = self.__rows *self.dataColumns
if QTVERSION < '4.0.0':
self.setNumRows(int(nrows/self.dataColumns))
else:
self.setRowCount(int(nrows/self.dataColumns))
if QTVERSION > '4.0.0':
rheight = self.horizontalHeader().sizeHint().height()
for idx in range(self.rowCount()):
self.setRowHeight(idx, rheight)
coloffset = 0
rowoffset = 0
for idx in range(nrows):
text = "Energy %3d" % (idx)
if idx >= (nrows/self.dataColumns):
rowoffset= (-int(idx/self.__rows))*(nrows/self.dataColumns)
coloffset= 3*int(idx/self.__rows)
r = idx + rowoffset
color = qt.Qt.white
if len(self.scatterList):
if idx < len(self.scatterList):
if (self.scatterList[idx] is not None)and \
(self.scatterList[idx] != "None"):
if self.scatterList[idx]:color = qt.QColor(255, 20, 147)
elif idx == 0:
color = qt.QColor(255, 20, 147)
if QTVERSION < '4.0.0':
#item= qttable.QCheckTableItem(self, text)
self.viewport().setPaletteBackgroundColor(color)
item= ColorQTableItem(self, text, color)
self.setItem(r, 0+coloffset, item)
else:
item = self.cellWidget(r, 0+coloffset)
if item is None:
item= ColorQTableItem(self, text, color)
self.setCellWidget(r, 0+coloffset, item)
item.stateChanged[int].connect(self._itemSlot)
else:
item.setText(text)
oldcolor = item.color
if color != oldcolor:
item.setColor(color)
item.repaint(item.rect())
if idx < len(self.energyList):
item.setChecked(self.flagList[idx])
if (self.energyList[idx] is not None) and \
(self.energyList[idx] != "None"):
self.setText(r, 1+coloffset,
"%f" % self.energyList[idx])
else:
self.setText(r, 1+coloffset,"")
else:
item.setChecked(False)
self.setText(r, 1+coloffset,"")
if idx < len(self.weightList):
self.setText(r, 2+coloffset,"%f" % self.weightList[idx])
else:
self.setText(r, 2+coloffset,"")
[docs] def setParameters(self, energylist, weightlist, flaglist, scatterlist=None):
if isinstance(energylist, numpy.ndarray):
self.energyList=energylist.tolist()
elif type(energylist) != type([]):
self.energyList=[energylist]
else:
self.energyList =energylist
if isinstance(weightlist, numpy.ndarray):
self.weightList=weightlist.tolist()
elif type(weightlist) != type([]):
self.energyList=[weightlist]
else:
self.weightList =weightlist
if isinstance(flaglist, numpy.ndarray):
self.flagList=flaglist.tolist()
elif type(flaglist) != type([]):
self.flagList=[flaglist]
else:
self.flagList =flaglist
if scatterlist is None:
scatterlist = numpy.zeros(len(self.energyList)).tolist()
scatterlist[0] = 1
if isinstance(scatterlist, numpy.ndarray):
self.scatterList=scatterlist.tolist()
elif type(scatterlist) != type([]):
self.scatterList=[scatterlist]
else:
self.scatterList =scatterlist
self.__fillTable()
[docs] def getParameters(self):
if QTVERSION < '4.0.0':
nrows = self.numRows()*self.dataColumns
else:
nrows = self.rowCount() * self.dataColumns
coloffset = 0
rowoffset = 0
energyList = []
weightList = []
flagList = []
scatterList = []
for idx in range(nrows):
if idx >= (nrows/self.dataColumns):
rowoffset= (-int(idx/self.__rows))*(nrows/self.dataColumns)
coloffset= 3*int(idx/self.__rows)
r = idx + rowoffset
if QTVERSION < '4.0.0':
item = self.item(r,0+coloffset)
energyflag = int(item.isChecked())
else:
item = self.cellWidget(r,0+coloffset)
if item is None:
#this should never happen
continue
else:
energyflag = int(item.isChecked())
if item.color == qt.Qt.white:
scatterflag = 0
else:
scatterflag = 1
text = str(self.text(r,1+coloffset))
text=text.replace(" ","")
if len(text):
try:
energy = float(text)
except:
energyflag = 0
energy = None
else:
energyflag = 0
energy = None
text = str(self.text(r,2+coloffset))
text=text.replace(" ","")
if len(text):
try:
energyweight = float(text)
except:
energyflag = 0
energyweight= 0.0
else:
energyflag = 0
energyweight = 0.0
energyList.append(energy)
weightList.append(energyweight)
flagList.append(energyflag)
scatterList.append(scatterflag)
return energyList, weightList, flagList, scatterList
def __fillTable(self):
self.__disconnected = True
try:
self.__build(max(self.__rows*self.dataColumns,len(self.energyList)))
for i in range(self.dataColumns):
if QTVERSION < '4.0.0':
self.adjustColumn(0 + 3*i)
else:
if DEBUG:
print("column adjustment missing")
except:
self.__disconnected = False
raise
self.__disconnected = False
ddict = self._getDict()
if ddict != {}:
ddict['event'] = "TableFilled"
ddict['row'] = 0
ddict['col'] = 0
self.sigEnergyTableSignal.emit(ddict)
[docs] def mySlot(self,row,col):
if self.__disconnected:return
if DEBUG:
print("Value changed row = %d col = %d" % (row, col))
print("Text = %s" % self.text(row,col))
if (col != 0) and (col !=3) and (col != 6) and (col != 9):
try:
s = str(self.text(row, col))
s=s.replace(" ","")
if len(s):
float(s)
except:
msg = qt.QMessageBox(self)
msg.setIcon(qt.QMessageBox.Critical)
msg.setText("Invalid Float")
msg.exec_()
return
ddict = self._getDict()
if ddict != {}:
ddict['event'] = "ValueChanged"
ddict['row'] = row
ddict['col'] = col
self.sigEnergyTableSignal.emit(ddict)
[docs] def text(self, row, col):
if (col % 3) in [1,2]:
item = self.item(row , col)
if item is not None:
return item.text()
else:
return ''
[docs] def setText(self, row, col, text):
#ncol = self.columnCount()
if (col % 3) in [1,2]:
item = self.item(row, col)
if item is None:
item = qt.QTableWidgetItem(text,
qt.QTableWidgetItem.Type)
self.setItem(row, col, item)
else:
item.setText(text)
else:
if DEBUG:
print("checkbox can be called?")
pass
def _getDict(self):
ddict ={}
n = self.rowCount()
ddict['energy'] = []
ddict['rate'] = []
ddict['flag'] = []
ddict['scatterflag'] = []
for i in range(n * self.dataColumns):
if i >= (n*self.__rows/self.dataColumns):
rowoffset= (-int(i/self.__rows))*(self.__rows)
r = i + rowoffset
coffset= 3*int(i/self.__rows)
else:
r = i
coffset= 0
try:
#if 1:
s = str(self.text(r, 1+coffset))
s=s.replace(" ","")
if len(s):
ene=float(s)
selfitem = self.cellWidget(r, 0+coffset)
if selfitem.isChecked():
flag = 1
else:
flag = 0
if selfitem.color != qt.Qt.white:
scatterflag = 1
else:
scatterflag = 0
s = str(self.text(r, 2+coffset))
s=s.replace(" ","")
if len(s):
rate = float(s)
ddict['flag'].append(flag)
ddict['energy'].append(ene)
ddict['rate'].append(rate)
ddict['scatterflag'].append(scatterflag)
except:
#else:
msg = qt.QMessageBox(self)
msg.setIcon(qt.QMessageBox.Critical)
msg.setText("EnergyTable: Error on energy %d" % i)
msg.exec_()
return {}
return ddict
[docs]class ColorQTableItem(qt.QCheckBox):
def __init__(self, table, text, color=qt.Qt.white,bold=0):
qt.QCheckBox.__init__(self, table)
self.color = color
self.bold = bold
self.setText(text)
#this is one critical line
self.setAutoFillBackground(1)
[docs] def setColor(self, color):
self.color = color
[docs] def paintEvent(self, painter):
#this is the other (self.palette() is not appropriate)
palette = qt.QPalette()
role = self.backgroundRole()
palette.setColor(role, self.color)
self.setPalette(palette)
return qt.QCheckBox.paintEvent(self, painter)
[docs]def main(args):
app=qt.QApplication(args)
#tab = AttenuatorsTableWidget(None)
def dummy(ddict):
print("dict =",ddict)
tab = EnergyTable(None)
energy = numpy.arange(100.).astype(numpy.float)+ 1.5
weight = numpy.ones(len(energy), numpy.float)
flag = numpy.zeros(len(energy)).tolist()
scatterlist = numpy.zeros(len(energy))
scatterlist[0:10] = 1
tab.setParameters(energy, weight, flag, scatterlist)
tab.sigEnergyTableSignal.connect(dummy)
tab.show()
app.exec_()
if __name__=="__main__":
main(sys.argv)