# -*- coding: utf-8 -*- """ GEPARD - Gepard-Enabled PARticle Detection Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für Polymerforschung Dresden e. V. 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 . """ from PyQt5 import QtWidgets import numpy as np import pandas as pd import os import sys class ExpExcelDialog(QtWidgets.QDialog): def __init__(self, dataset): super(ExpExcelDialog, self).__init__() self.setWindowTitle('Export Options') self.setGeometry(200, 200, 300, 300) self.dataset = dataset self.particleContainer = dataset.particleContainer 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)', 'Long Size (µm)', 'Short Size (µm)', 'Area (µm²)', 'HQI', 'Size Classes'] self.checkBoxes = [] self.sizeClasses = [5, 10, 20, 50, 100, 1e6] 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!!! excelvbox.addWidget(self.checkBoxes[-1]) self.xlsFileName = QtWidgets.QLineEdit() self.xlsFileName.setText('{}_Particle_List'.format(self.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 = [] uniquePolymers = self.particleContainer.getUniquePolymers() polymers = np.array(self.particleContainer.getListOfParticleAssignments()) sizes = np.array(self.particleContainer.getSizesOfAllParticles()) for box in self.checkBoxes: if box.isChecked() == True: if box.text() != 'Size Classes': requiredcolumns.append(box.text()) if box.text() == 'Long Size (µm)': longSizes = np.round(sizes) elif box.text() == 'Short Size (µm)': shortSizes = np.round(np.array(self.particleContainer.getShortSizesOfAllParticles())) elif box.text() == 'HQI': hqis = np.array(self.particleContainer.getListOfHighestHQIs()) elif box.text() == 'Area (µm²)': areas = np.array(self.particleContainer.getAreasOfAllParticles()) 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((len(polymers),len(requiredcolumns)-1)) polymertypes = [""]*len(polymers) rowindex = 0 for polymer in uniquePolymers: indices = polymers == polymer numentries = int(np.sum(indices)) sys.stdout.flush() for colindex, column in enumerate(requiredcolumns): if column == 'Polymer Type (mandatory)': polymertypes[rowindex:rowindex+numentries] = polymers[indices] if column == 'Long Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = longSizes[indices] if column == 'Short Size (µm)': finalData[rowindex:rowindex+numentries, colindex-1] = shortSizes[indices] if column == 'Area (µm²)': finalData[rowindex:rowindex+numentries, colindex-1] = areas[indices] if column == 'HQI': finalData[rowindex:rowindex+numentries, colindex-1] = 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 = 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 = os.path.join(self.dataset.path, f'{self.xlsFileName.text()}.xlsx') print('exporting excel to:\n file name: {} in directory: {}'.format(self.xlsFileName.text(), self.dataset.path)) incr = 1 while os.path.exists(xlsname): xlsname = os.path.join(self.dataset.path, f'{self.xlsFileName.text()} {incr}.xlsx') 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'] particleclasses = [] for polymer in uniquePolymers: indices = self.particleContainer.getIndicesOfParticleType(polymer) sortind = np.searchsorted([5,10,20,50,100], 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', uniquePolymers) 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() QtWidgets.QMessageBox.about(self, 'Particles succesfully exported', 'List saved to\n' + str(xlsname))