Loading analysis/analysisview.py +2 −177 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ If not, see <https://www.gnu.org/licenses/>. from PyQt5 import QtCore, QtGui, QtWidgets import numpy as np import pandas as pd import sys import operator import os Loading @@ -33,11 +32,12 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from .analysiswidgets import ExpExcelDialog, AdditiveViewer from .loadresults import LoadWITecResults from .editParticles import ParticleEditor from .database import DataBaseWindow try: from analysis.sqlexport import SQLExport from .sqlexport import SQLExport sqlEnabled = True except: sqlEnabled = False Loading Loading @@ -857,181 +857,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): event.accept() class ExpExcelDialog(QtWidgets.QDialog): def __init__(self, parent): super(ExpExcelDialog, self).__init__() self.setWindowTitle('Export Options') self.setGeometry(200,200, 300, 300) self.parent = parent self.particles = self.parent.particlestats self.polymers = self.parent.particleResults self.additives = self.parent.currentAdditives self.hqis = self.parent.hqis self.layout = QtWidgets.QHBoxLayout() self.setLayout(self.layout) excelvbox = QtWidgets.QVBoxLayout() excelvbox.addWidget(QtWidgets.QLabel('Select Parameters for Export')) excelgroup = QtWidgets.QGroupBox("Export to Excel", self) self.exportOptions = ['Polymer Type (mandatory)', 'Additives', 'Long Size (µm)', 'Short Size (µm)', 'Area (µm²)', 'HQI', 'Size Classes'] self.checkBoxes = [] self.sizeClasses = [5, 10, 20, 50, 100, 1e6] self.directory = self.parent.parent.dataset.path for index, option in enumerate(self.exportOptions): self.checkBoxes.append(QtWidgets.QCheckBox(self)) self.checkBoxes[-1].setText(option) self.checkBoxes[-1].setChecked(True) if option == 'Polymer Type (mandatory)': self.checkBoxes[-1].setEnabled(False) #is mandatory!!! if option == 'Additives': if self.additives is None: self.checkBoxes[-1].setEnabled(False) self.checkBoxes[-1].setChecked(False) excelvbox.addWidget(self.checkBoxes[-1]) self.xlsFileName = QtWidgets.QLineEdit() self.xlsFileName.setText('{}_Particle_List'.format(self.parent.parent.dataset.name)) excelvbox.addWidget(QtWidgets.QLabel('Filename:')) excelvbox.addWidget(self.xlsFileName) self.exlbtn = QtWidgets.QPushButton('Export to Excel') self.exlbtn.resize(self.exlbtn.sizeHint()) self.exlbtn.clicked.connect(self.toExcel) excelvbox.addWidget(self.exlbtn) excelgroup.setLayout(excelvbox) self.layout.addWidget(excelgroup) self.show() def toExcel(self): requiredcolumns = [] self.sizes = np.round(np.array([i[0] if np.isnan(i[2]) else i[2] for i in self.particles]), 1) for box in self.checkBoxes: if box.isChecked() == True: if box.text() != 'Size Classes': requiredcolumns.append(box.text()) if box.text() == 'Long Size (µm)': longSize = self.sizes elif box.text() == 'Short Size (µm)': shortSize = np.round(np.array([i[1] if np.isnan(i[3]) else i[3] for i in self.particles]), 1) elif box.text() == 'Area (µm²)': area = np.array([np.round(float(entry[4]), 1) for entry in self.particles]) else: requiredcolumns.append('0 - 5 µm') requiredcolumns.append('5 - 10 µm') requiredcolumns.append('10 - 20 µm') requiredcolumns.append('20 - 50 µm') requiredcolumns.append('50 - 100 µm') requiredcolumns.append('> 100 µm') finalData = np.zeros((self.polymers.shape[0],len(requiredcolumns)-1)) polymertypes = [""]*self.polymers.shape[0] rowindex = 0 for polymer in np.unique(self.polymers): indices = self.polymers == polymer numentries = int(np.sum(indices)) print("Num:", numentries) sys.stdout.flush() for colindex, column in enumerate(requiredcolumns): if column == 'Polymer Type (mandatory)': polymertypes[rowindex:rowindex+numentries] = self.polymers[indices] if column == 'Additives': finalData[rowindex:rowindex+numentries, colindex-1] = self.additives[indices] if column == 'Long Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = longSize[indices] if column == 'Short Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = shortSize[indices] if column == 'Area (µm²)': finalData[rowindex:rowindex+numentries, colindex-1] = area[indices] # hit quality index array does not match the data size if particles have been combined #if column == 'HQI': # finalData[rowindex:rowindex+numentries, colindex-1] = self.hqis[indices] if '> 100 µm' in requiredcolumns: ##append size classes numPrevCols = len(requiredcolumns) - 1 - len(self.sizeClasses) #number of previous columns for tableindex, dataindex in enumerate(np.arange(len(indices))[indices]): for classindex in range(len(self.sizeClasses)): upLimit = self.sizeClasses[classindex] if classindex == 0: lowLimit = 0 else: lowLimit = self.sizeClasses[classindex-1] curSize = self.sizes[dataindex] if curSize > lowLimit and curSize <= upLimit: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(1) else: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(0) rowindex = rowindex + numentries #dump into excel file xlsname = self.directory + '//' + self.xlsFileName.text() + '.xlsx' print('exporting excel to:\n file name: {} in directory: {}'.format(self.xlsFileName.text(), self.directory)) validFileName = False incr = 1 while not validFileName: if not os.path.exists(xlsname): validFileName = True else: xlsname = self.directory + self.xlsFileName.text() + ' {}.xlsx'.format(incr) incr += 1 writer = pd.ExcelWriter(xlsname, engine = 'xlsxwriter') df = pd.DataFrame(finalData, columns=requiredcolumns[1:]) df.insert(0, 'Polymer Type', polymertypes) df.to_excel(writer, sheet_name = 'Individual Particles', index = False) if '> 100 µm' in requiredcolumns: #generate particle statistics report header = ['0 - 5 µm', '5 - 10 µm', '10 - 20 µm', '20 - 50 µm', '50 - 100 µm', '> 100 µm'] index = np.unique(self.polymers) particleclasses = [] for polymer in index: indices = np.where(self.polymers == polymer)[0] sortind = np.searchsorted([5,10,20,50,100], self.sizes[indices], 'right') classes = np.bincount(sortind, minlength=6) particleclasses.append(classes) particleclasses = np.array(particleclasses) report = pd.DataFrame(np.array(particleclasses), columns=header, dtype=int) report.insert(0, 'Polymer Type', index) report.insert(len(report.columns), 'Sum total', particleclasses.sum(axis=1)) report.to_excel(writer, sheet_name = 'Particle Statistics', index=False) writer.save() self.accept() class AdditiveViewer(QtWidgets.QWidget): def __init__(self, polymername, sortedAdditives): super(AdditiveViewer, self).__init__() self.setGeometry(200,200, 800, 600) self.setWindowTitle('Additives of {}'.format(polymername)) self.layout = QtWidgets.QGridLayout() self.setLayout(self.layout) self.canvas = FigureCanvas(Figure(figsize=(5, 3))) self.ax = self.canvas.figure.subplots() self.layout.addWidget(self.canvas, 0, 0) self.ax.hist(sortedAdditives) self.ax.set_ylabel('Number', fontsize = 15) self.ax.tick_params(axis='both', which='both', labelsize=15) if __name__ == '__main__': def run(): app = QtWidgets.QApplication(sys.argv) Loading analysis/analysiswidgets.py 0 → 100644 +204 −0 Original line number Diff line number Diff line # -*- coding: utf-8 -*- """ GEPARD - Gepard-Enabled PARticle Detection Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program, see COPYING. If not, see <https://www.gnu.org/licenses/>. """ from PyQt5 import QtWidgets import numpy as np import pandas as pd import os import sys from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure class ExpExcelDialog(QtWidgets.QDialog): def __init__(self, parent): super(ExpExcelDialog, self).__init__() self.setWindowTitle('Export Options') self.setGeometry(200,200, 300, 300) self.parent = parent self.particles = self.parent.particlestats self.polymers = self.parent.particleResults self.additives = self.parent.currentAdditives self.hqis = self.parent.hqis self.layout = QtWidgets.QHBoxLayout() self.setLayout(self.layout) excelvbox = QtWidgets.QVBoxLayout() excelvbox.addWidget(QtWidgets.QLabel('Select Parameters for Export')) excelgroup = QtWidgets.QGroupBox("Export to Excel", self) self.exportOptions = ['Polymer Type (mandatory)', 'Additives', 'Long Size (µm)', 'Short Size (µm)', 'Area (µm²)', 'HQI', 'Size Classes'] self.checkBoxes = [] self.sizeClasses = [5, 10, 20, 50, 100, 1e6] self.directory = self.parent.parent.dataset.path for index, option in enumerate(self.exportOptions): self.checkBoxes.append(QtWidgets.QCheckBox(self)) self.checkBoxes[-1].setText(option) self.checkBoxes[-1].setChecked(True) if option == 'Polymer Type (mandatory)': self.checkBoxes[-1].setEnabled(False) #is mandatory!!! if option == 'Additives': if self.additives is None: self.checkBoxes[-1].setEnabled(False) self.checkBoxes[-1].setChecked(False) excelvbox.addWidget(self.checkBoxes[-1]) self.xlsFileName = QtWidgets.QLineEdit() self.xlsFileName.setText('{}_Particle_List'.format(self.parent.parent.dataset.name)) excelvbox.addWidget(QtWidgets.QLabel('Filename:')) excelvbox.addWidget(self.xlsFileName) self.exlbtn = QtWidgets.QPushButton('Export to Excel') self.exlbtn.resize(self.exlbtn.sizeHint()) self.exlbtn.clicked.connect(self.toExcel) excelvbox.addWidget(self.exlbtn) excelgroup.setLayout(excelvbox) self.layout.addWidget(excelgroup) self.show() def toExcel(self): requiredcolumns = [] self.sizes = np.round(np.array([i[0] if np.isnan(i[2]) else i[2] for i in self.particles]), 1) for box in self.checkBoxes: if box.isChecked() == True: if box.text() != 'Size Classes': requiredcolumns.append(box.text()) if box.text() == 'Long Size (µm)': longSize = self.sizes elif box.text() == 'Short Size (µm)': shortSize = np.round(np.array([i[1] if np.isnan(i[3]) else i[3] for i in self.particles]), 1) elif box.text() == 'Area (µm²)': area = np.array([np.round(float(entry[4]), 1) for entry in self.particles]) else: requiredcolumns.append('0 - 5 µm') requiredcolumns.append('5 - 10 µm') requiredcolumns.append('10 - 20 µm') requiredcolumns.append('20 - 50 µm') requiredcolumns.append('50 - 100 µm') requiredcolumns.append('> 100 µm') finalData = np.zeros((self.polymers.shape[0],len(requiredcolumns)-1)) polymertypes = [""]*self.polymers.shape[0] rowindex = 0 for polymer in np.unique(self.polymers): indices = self.polymers == polymer numentries = int(np.sum(indices)) print("Num:", numentries) sys.stdout.flush() for colindex, column in enumerate(requiredcolumns): if column == 'Polymer Type (mandatory)': polymertypes[rowindex:rowindex+numentries] = self.polymers[indices] if column == 'Additives': finalData[rowindex:rowindex+numentries, colindex-1] = self.additives[indices] if column == 'Long Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = longSize[indices] if column == 'Short Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = shortSize[indices] if column == 'Area (µm²)': finalData[rowindex:rowindex+numentries, colindex-1] = area[indices] # hit quality index array does not match the data size if particles have been combined #if column == 'HQI': # finalData[rowindex:rowindex+numentries, colindex-1] = self.hqis[indices] if '> 100 µm' in requiredcolumns: ##append size classes numPrevCols = len(requiredcolumns) - 1 - len(self.sizeClasses) #number of previous columns for tableindex, dataindex in enumerate(np.arange(len(indices))[indices]): for classindex in range(len(self.sizeClasses)): upLimit = self.sizeClasses[classindex] if classindex == 0: lowLimit = 0 else: lowLimit = self.sizeClasses[classindex-1] curSize = self.sizes[dataindex] if curSize > lowLimit and curSize <= upLimit: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(1) else: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(0) rowindex = rowindex + numentries #dump into excel file xlsname = self.directory + '//' + self.xlsFileName.text() + '.xlsx' print('exporting excel to:\n file name: {} in directory: {}'.format(self.xlsFileName.text(), self.directory)) validFileName = False incr = 1 while not validFileName: if not os.path.exists(xlsname): validFileName = True else: xlsname = self.directory + self.xlsFileName.text() + ' {}.xlsx'.format(incr) incr += 1 writer = pd.ExcelWriter(xlsname, engine = 'xlsxwriter') df = pd.DataFrame(finalData, columns=requiredcolumns[1:]) df.insert(0, 'Polymer Type', polymertypes) df.to_excel(writer, sheet_name = 'Individual Particles', index = False) if '> 100 µm' in requiredcolumns: #generate particle statistics report header = ['0 - 5 µm', '5 - 10 µm', '10 - 20 µm', '20 - 50 µm', '50 - 100 µm', '> 100 µm'] index = np.unique(self.polymers) particleclasses = [] for polymer in index: indices = np.where(self.polymers == polymer)[0] sortind = np.searchsorted([5,10,20,50,100], self.sizes[indices], 'right') classes = np.bincount(sortind, minlength=6) particleclasses.append(classes) particleclasses = np.array(particleclasses) report = pd.DataFrame(np.array(particleclasses), columns=header, dtype=int) report.insert(0, 'Polymer Type', index) report.insert(len(report.columns), 'Sum total', particleclasses.sum(axis=1)) report.to_excel(writer, sheet_name = 'Particle Statistics', index=False) writer.save() self.accept() class AdditiveViewer(QtWidgets.QWidget): def __init__(self, polymername, sortedAdditives): super(AdditiveViewer, self).__init__() self.setGeometry(200,200, 800, 600) self.setWindowTitle('Additives of {}'.format(polymername)) self.layout = QtWidgets.QGridLayout() self.setLayout(self.layout) self.canvas = FigureCanvas(Figure(figsize=(5, 3))) self.ax = self.canvas.figure.subplots() self.layout.addWidget(self.canvas, 0, 0) self.ax.hist(sortedAdditives) self.ax.set_ylabel('Number', fontsize = 15) self.ax.tick_params(axis='both', which='both', labelsize=15) No newline at end of file Loading
analysis/analysisview.py +2 −177 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ If not, see <https://www.gnu.org/licenses/>. from PyQt5 import QtCore, QtGui, QtWidgets import numpy as np import pandas as pd import sys import operator import os Loading @@ -33,11 +32,12 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from .analysiswidgets import ExpExcelDialog, AdditiveViewer from .loadresults import LoadWITecResults from .editParticles import ParticleEditor from .database import DataBaseWindow try: from analysis.sqlexport import SQLExport from .sqlexport import SQLExport sqlEnabled = True except: sqlEnabled = False Loading Loading @@ -857,181 +857,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): event.accept() class ExpExcelDialog(QtWidgets.QDialog): def __init__(self, parent): super(ExpExcelDialog, self).__init__() self.setWindowTitle('Export Options') self.setGeometry(200,200, 300, 300) self.parent = parent self.particles = self.parent.particlestats self.polymers = self.parent.particleResults self.additives = self.parent.currentAdditives self.hqis = self.parent.hqis self.layout = QtWidgets.QHBoxLayout() self.setLayout(self.layout) excelvbox = QtWidgets.QVBoxLayout() excelvbox.addWidget(QtWidgets.QLabel('Select Parameters for Export')) excelgroup = QtWidgets.QGroupBox("Export to Excel", self) self.exportOptions = ['Polymer Type (mandatory)', 'Additives', 'Long Size (µm)', 'Short Size (µm)', 'Area (µm²)', 'HQI', 'Size Classes'] self.checkBoxes = [] self.sizeClasses = [5, 10, 20, 50, 100, 1e6] self.directory = self.parent.parent.dataset.path for index, option in enumerate(self.exportOptions): self.checkBoxes.append(QtWidgets.QCheckBox(self)) self.checkBoxes[-1].setText(option) self.checkBoxes[-1].setChecked(True) if option == 'Polymer Type (mandatory)': self.checkBoxes[-1].setEnabled(False) #is mandatory!!! if option == 'Additives': if self.additives is None: self.checkBoxes[-1].setEnabled(False) self.checkBoxes[-1].setChecked(False) excelvbox.addWidget(self.checkBoxes[-1]) self.xlsFileName = QtWidgets.QLineEdit() self.xlsFileName.setText('{}_Particle_List'.format(self.parent.parent.dataset.name)) excelvbox.addWidget(QtWidgets.QLabel('Filename:')) excelvbox.addWidget(self.xlsFileName) self.exlbtn = QtWidgets.QPushButton('Export to Excel') self.exlbtn.resize(self.exlbtn.sizeHint()) self.exlbtn.clicked.connect(self.toExcel) excelvbox.addWidget(self.exlbtn) excelgroup.setLayout(excelvbox) self.layout.addWidget(excelgroup) self.show() def toExcel(self): requiredcolumns = [] self.sizes = np.round(np.array([i[0] if np.isnan(i[2]) else i[2] for i in self.particles]), 1) for box in self.checkBoxes: if box.isChecked() == True: if box.text() != 'Size Classes': requiredcolumns.append(box.text()) if box.text() == 'Long Size (µm)': longSize = self.sizes elif box.text() == 'Short Size (µm)': shortSize = np.round(np.array([i[1] if np.isnan(i[3]) else i[3] for i in self.particles]), 1) elif box.text() == 'Area (µm²)': area = np.array([np.round(float(entry[4]), 1) for entry in self.particles]) else: requiredcolumns.append('0 - 5 µm') requiredcolumns.append('5 - 10 µm') requiredcolumns.append('10 - 20 µm') requiredcolumns.append('20 - 50 µm') requiredcolumns.append('50 - 100 µm') requiredcolumns.append('> 100 µm') finalData = np.zeros((self.polymers.shape[0],len(requiredcolumns)-1)) polymertypes = [""]*self.polymers.shape[0] rowindex = 0 for polymer in np.unique(self.polymers): indices = self.polymers == polymer numentries = int(np.sum(indices)) print("Num:", numentries) sys.stdout.flush() for colindex, column in enumerate(requiredcolumns): if column == 'Polymer Type (mandatory)': polymertypes[rowindex:rowindex+numentries] = self.polymers[indices] if column == 'Additives': finalData[rowindex:rowindex+numentries, colindex-1] = self.additives[indices] if column == 'Long Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = longSize[indices] if column == 'Short Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = shortSize[indices] if column == 'Area (µm²)': finalData[rowindex:rowindex+numentries, colindex-1] = area[indices] # hit quality index array does not match the data size if particles have been combined #if column == 'HQI': # finalData[rowindex:rowindex+numentries, colindex-1] = self.hqis[indices] if '> 100 µm' in requiredcolumns: ##append size classes numPrevCols = len(requiredcolumns) - 1 - len(self.sizeClasses) #number of previous columns for tableindex, dataindex in enumerate(np.arange(len(indices))[indices]): for classindex in range(len(self.sizeClasses)): upLimit = self.sizeClasses[classindex] if classindex == 0: lowLimit = 0 else: lowLimit = self.sizeClasses[classindex-1] curSize = self.sizes[dataindex] if curSize > lowLimit and curSize <= upLimit: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(1) else: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(0) rowindex = rowindex + numentries #dump into excel file xlsname = self.directory + '//' + self.xlsFileName.text() + '.xlsx' print('exporting excel to:\n file name: {} in directory: {}'.format(self.xlsFileName.text(), self.directory)) validFileName = False incr = 1 while not validFileName: if not os.path.exists(xlsname): validFileName = True else: xlsname = self.directory + self.xlsFileName.text() + ' {}.xlsx'.format(incr) incr += 1 writer = pd.ExcelWriter(xlsname, engine = 'xlsxwriter') df = pd.DataFrame(finalData, columns=requiredcolumns[1:]) df.insert(0, 'Polymer Type', polymertypes) df.to_excel(writer, sheet_name = 'Individual Particles', index = False) if '> 100 µm' in requiredcolumns: #generate particle statistics report header = ['0 - 5 µm', '5 - 10 µm', '10 - 20 µm', '20 - 50 µm', '50 - 100 µm', '> 100 µm'] index = np.unique(self.polymers) particleclasses = [] for polymer in index: indices = np.where(self.polymers == polymer)[0] sortind = np.searchsorted([5,10,20,50,100], self.sizes[indices], 'right') classes = np.bincount(sortind, minlength=6) particleclasses.append(classes) particleclasses = np.array(particleclasses) report = pd.DataFrame(np.array(particleclasses), columns=header, dtype=int) report.insert(0, 'Polymer Type', index) report.insert(len(report.columns), 'Sum total', particleclasses.sum(axis=1)) report.to_excel(writer, sheet_name = 'Particle Statistics', index=False) writer.save() self.accept() class AdditiveViewer(QtWidgets.QWidget): def __init__(self, polymername, sortedAdditives): super(AdditiveViewer, self).__init__() self.setGeometry(200,200, 800, 600) self.setWindowTitle('Additives of {}'.format(polymername)) self.layout = QtWidgets.QGridLayout() self.setLayout(self.layout) self.canvas = FigureCanvas(Figure(figsize=(5, 3))) self.ax = self.canvas.figure.subplots() self.layout.addWidget(self.canvas, 0, 0) self.ax.hist(sortedAdditives) self.ax.set_ylabel('Number', fontsize = 15) self.ax.tick_params(axis='both', which='both', labelsize=15) if __name__ == '__main__': def run(): app = QtWidgets.QApplication(sys.argv) Loading
analysis/analysiswidgets.py 0 → 100644 +204 −0 Original line number Diff line number Diff line # -*- coding: utf-8 -*- """ GEPARD - Gepard-Enabled PARticle Detection Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program, see COPYING. If not, see <https://www.gnu.org/licenses/>. """ from PyQt5 import QtWidgets import numpy as np import pandas as pd import os import sys from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure class ExpExcelDialog(QtWidgets.QDialog): def __init__(self, parent): super(ExpExcelDialog, self).__init__() self.setWindowTitle('Export Options') self.setGeometry(200,200, 300, 300) self.parent = parent self.particles = self.parent.particlestats self.polymers = self.parent.particleResults self.additives = self.parent.currentAdditives self.hqis = self.parent.hqis self.layout = QtWidgets.QHBoxLayout() self.setLayout(self.layout) excelvbox = QtWidgets.QVBoxLayout() excelvbox.addWidget(QtWidgets.QLabel('Select Parameters for Export')) excelgroup = QtWidgets.QGroupBox("Export to Excel", self) self.exportOptions = ['Polymer Type (mandatory)', 'Additives', 'Long Size (µm)', 'Short Size (µm)', 'Area (µm²)', 'HQI', 'Size Classes'] self.checkBoxes = [] self.sizeClasses = [5, 10, 20, 50, 100, 1e6] self.directory = self.parent.parent.dataset.path for index, option in enumerate(self.exportOptions): self.checkBoxes.append(QtWidgets.QCheckBox(self)) self.checkBoxes[-1].setText(option) self.checkBoxes[-1].setChecked(True) if option == 'Polymer Type (mandatory)': self.checkBoxes[-1].setEnabled(False) #is mandatory!!! if option == 'Additives': if self.additives is None: self.checkBoxes[-1].setEnabled(False) self.checkBoxes[-1].setChecked(False) excelvbox.addWidget(self.checkBoxes[-1]) self.xlsFileName = QtWidgets.QLineEdit() self.xlsFileName.setText('{}_Particle_List'.format(self.parent.parent.dataset.name)) excelvbox.addWidget(QtWidgets.QLabel('Filename:')) excelvbox.addWidget(self.xlsFileName) self.exlbtn = QtWidgets.QPushButton('Export to Excel') self.exlbtn.resize(self.exlbtn.sizeHint()) self.exlbtn.clicked.connect(self.toExcel) excelvbox.addWidget(self.exlbtn) excelgroup.setLayout(excelvbox) self.layout.addWidget(excelgroup) self.show() def toExcel(self): requiredcolumns = [] self.sizes = np.round(np.array([i[0] if np.isnan(i[2]) else i[2] for i in self.particles]), 1) for box in self.checkBoxes: if box.isChecked() == True: if box.text() != 'Size Classes': requiredcolumns.append(box.text()) if box.text() == 'Long Size (µm)': longSize = self.sizes elif box.text() == 'Short Size (µm)': shortSize = np.round(np.array([i[1] if np.isnan(i[3]) else i[3] for i in self.particles]), 1) elif box.text() == 'Area (µm²)': area = np.array([np.round(float(entry[4]), 1) for entry in self.particles]) else: requiredcolumns.append('0 - 5 µm') requiredcolumns.append('5 - 10 µm') requiredcolumns.append('10 - 20 µm') requiredcolumns.append('20 - 50 µm') requiredcolumns.append('50 - 100 µm') requiredcolumns.append('> 100 µm') finalData = np.zeros((self.polymers.shape[0],len(requiredcolumns)-1)) polymertypes = [""]*self.polymers.shape[0] rowindex = 0 for polymer in np.unique(self.polymers): indices = self.polymers == polymer numentries = int(np.sum(indices)) print("Num:", numentries) sys.stdout.flush() for colindex, column in enumerate(requiredcolumns): if column == 'Polymer Type (mandatory)': polymertypes[rowindex:rowindex+numentries] = self.polymers[indices] if column == 'Additives': finalData[rowindex:rowindex+numentries, colindex-1] = self.additives[indices] if column == 'Long Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = longSize[indices] if column == 'Short Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = shortSize[indices] if column == 'Area (µm²)': finalData[rowindex:rowindex+numentries, colindex-1] = area[indices] # hit quality index array does not match the data size if particles have been combined #if column == 'HQI': # finalData[rowindex:rowindex+numentries, colindex-1] = self.hqis[indices] if '> 100 µm' in requiredcolumns: ##append size classes numPrevCols = len(requiredcolumns) - 1 - len(self.sizeClasses) #number of previous columns for tableindex, dataindex in enumerate(np.arange(len(indices))[indices]): for classindex in range(len(self.sizeClasses)): upLimit = self.sizeClasses[classindex] if classindex == 0: lowLimit = 0 else: lowLimit = self.sizeClasses[classindex-1] curSize = self.sizes[dataindex] if curSize > lowLimit and curSize <= upLimit: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(1) else: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(0) rowindex = rowindex + numentries #dump into excel file xlsname = self.directory + '//' + self.xlsFileName.text() + '.xlsx' print('exporting excel to:\n file name: {} in directory: {}'.format(self.xlsFileName.text(), self.directory)) validFileName = False incr = 1 while not validFileName: if not os.path.exists(xlsname): validFileName = True else: xlsname = self.directory + self.xlsFileName.text() + ' {}.xlsx'.format(incr) incr += 1 writer = pd.ExcelWriter(xlsname, engine = 'xlsxwriter') df = pd.DataFrame(finalData, columns=requiredcolumns[1:]) df.insert(0, 'Polymer Type', polymertypes) df.to_excel(writer, sheet_name = 'Individual Particles', index = False) if '> 100 µm' in requiredcolumns: #generate particle statistics report header = ['0 - 5 µm', '5 - 10 µm', '10 - 20 µm', '20 - 50 µm', '50 - 100 µm', '> 100 µm'] index = np.unique(self.polymers) particleclasses = [] for polymer in index: indices = np.where(self.polymers == polymer)[0] sortind = np.searchsorted([5,10,20,50,100], self.sizes[indices], 'right') classes = np.bincount(sortind, minlength=6) particleclasses.append(classes) particleclasses = np.array(particleclasses) report = pd.DataFrame(np.array(particleclasses), columns=header, dtype=int) report.insert(0, 'Polymer Type', index) report.insert(len(report.columns), 'Sum total', particleclasses.sum(axis=1)) report.to_excel(writer, sheet_name = 'Particle Statistics', index=False) writer.save() self.accept() class AdditiveViewer(QtWidgets.QWidget): def __init__(self, polymername, sortedAdditives): super(AdditiveViewer, self).__init__() self.setGeometry(200,200, 800, 600) self.setWindowTitle('Additives of {}'.format(polymername)) self.layout = QtWidgets.QGridLayout() self.setLayout(self.layout) self.canvas = FigureCanvas(Figure(figsize=(5, 3))) self.ax = self.canvas.figure.subplots() self.layout.addWidget(self.canvas, 0, 0) self.ax.hist(sortedAdditives) self.ax.set_ylabel('Number', fontsize = 15) self.ax.tick_params(axis='both', which='both', labelsize=15) No newline at end of file