diff --git a/analysis/analysisview.py b/analysis/analysisview.py index 5982964545377a3853e3452d6d44020834379646..6e431ecc8898e65f6acae8643cf0c6aef3f3ca7f 100644 --- a/analysis/analysisview.py +++ b/analysis/analysisview.py @@ -160,11 +160,13 @@ class ParticleAnalysis(QtWidgets.QMainWindow): optionsLayout = QtWidgets.QFormLayout() self.hqiSpinBox = QtWidgets.QDoubleSpinBox() - self.hqiSpinBox.setValue(self.dataset.resultParams['minHQI']) self.hqiSpinBox.setDecimals(1) self.hqiSpinBox.setMinimum(0) self.hqiSpinBox.setMaximum(100) self.hqiSpinBox.setMaximumWidth(100) + minHQI = self.dataset.resultParams['minHQI'] + if minHQI is not None: + self.hqiSpinBox.setValue(minHQI) self.hqiSpinBox.valueChanged.connect(self.applyHQIThresholdToResults) optionsLayout.addRow(QtWidgets.QLabel('minimum HQI:'), self.hqiSpinBox) @@ -198,9 +200,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.layout.addLayout(self.menuLayout) self.layout.addLayout(viewLayout) - minHQI = self.dataset.resultParams['minHQI'] - if minHQI is not None: - self.hqiSpinBox.setValue(minHQI) + self.createActions() self.createMenus() @@ -611,8 +611,14 @@ class ParticleAnalysis(QtWidgets.QMainWindow): expWin.exec() def exportToSQL(self): - sqlexp = SQLExport(self.particleContainer, self) - sqlexp.exec() + if len(self.dataset.resultsUploadedToSQL) > 0: + reply = QtWidgets.QMessageBox.question(self, 'Warning!', + "The following results were already uploaded:\n\n{}\n\nContinue?".format('\n'.join(self.dataset.resultsUploadedToSQL)), + QtWidgets.QMessageBox.Yes | + QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) + if reply == QtWidgets.QMessageBox.Yes: + sqlexp = SQLExport(self.dataset) + sqlexp.exec() def closeEvent(self, event): for window in [self.importWindow, self.dbWin]: diff --git a/analysis/excelexport.py b/analysis/excelexport.py index de2e324f5c371449403fa8d01721d75ab7bb2d1f..9382c3743622b3c7c78a47464f29507d6dc3739c 100644 --- a/analysis/excelexport.py +++ b/analysis/excelexport.py @@ -45,7 +45,6 @@ class ExpExcelDialog(QtWidgets.QDialog): 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] - self.directory = self.dataset.path for index, option in enumerate(self.exportOptions): self.checkBoxes.append(QtWidgets.QCheckBox(self)) @@ -76,8 +75,8 @@ class ExpExcelDialog(QtWidgets.QDialog): def toExcel(self): requiredcolumns = [] uniquePolymers = self.particleContainer.getUniquePolymers() - polymers = self.particleContainer.getListOfParticleAssignments() - sizes = self.particleContainer.getSizesOfAllParticles() + polymers = np.array(self.particleContainer.getListOfParticleAssignments()) + sizes = np.array(self.particleContainer.getSizesOfAllParticles()) for box in self.checkBoxes: @@ -85,13 +84,13 @@ class ExpExcelDialog(QtWidgets.QDialog): if box.text() != 'Size Classes': requiredcolumns.append(box.text()) if box.text() == 'Long Size (µm)': - longSizes = sizes + longSizes = np.round(sizes) elif box.text() == 'Short Size (µm)': - shortSizes = self.particleContainer.getShortSizesOfAllParticles() + shortSizes = np.round(np.array(self.particleContainer.getShortSizesOfAllParticles())) elif box.text() == 'HQI': - hqis = self.particleContainer.getListOfHighestHQIs() + hqis = np.array(self.particleContainer.getListOfHighestHQIs()) elif box.text() == 'Area (µm²)': - areas = self.particleContainer.getAreasOfAllParticles() + areas = np.array(self.particleContainer.getAreasOfAllParticles()) else: requiredcolumns.append('0 - 5 µm') @@ -101,13 +100,12 @@ class ExpExcelDialog(QtWidgets.QDialog): requiredcolumns.append('50 - 100 µm') requiredcolumns.append('> 100 µm') - finalData = np.zeros((polymers.shape[0],len(requiredcolumns)-1)) - polymertypes = [""]*polymers.shape[0] + finalData = np.zeros((len(polymers),len(requiredcolumns)-1)) + polymertypes = [""]*len(polymers) rowindex = 0 for polymer in uniquePolymers: - indices = self.particleContainer.getgetIndicesOfParticleType(polymer) + indices = polymers == polymer numentries = int(np.sum(indices)) - print("Num:", numentries) sys.stdout.flush() for colindex, column in enumerate(requiredcolumns): @@ -130,7 +128,7 @@ class ExpExcelDialog(QtWidgets.QDialog): upLimit = self.sizeClasses[classindex] if classindex == 0: lowLimit = 0 else: lowLimit = self.sizeClasses[classindex-1] - curSize = self.sizes[dataindex] + curSize = sizes[dataindex] if curSize > lowLimit and curSize <= upLimit: finalData[rowindex+tableindex, numPrevCols + classindex] = np.int(1) @@ -140,17 +138,13 @@ class ExpExcelDialog(QtWidgets.QDialog): 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 + 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 not validFileName: - if not os.path.exists(xlsname): - validFileName = True - else: - xlsname = self.directory + '//' + self.xlsFileName.text() + ' {}.xlsx'.format(incr) - 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:]) @@ -159,20 +153,20 @@ class ExpExcelDialog(QtWidgets.QDialog): 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') + 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', index) + 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() \ No newline at end of file + self.accept() + QtWidgets.QMessageBox.about(self, 'Particles succesfully exported', 'List saved to\n' + str(xlsname)) \ No newline at end of file diff --git a/analysis/loadresults.py b/analysis/loadresults.py index 6dc9c31532b5b4c41d98fd5b8c3da69d8e75f630..8f55856985505e56565d02647ddeb43f464e8e6b 100644 --- a/analysis/loadresults.py +++ b/analysis/loadresults.py @@ -43,31 +43,6 @@ class LoadTrueMatchResults(QtWidgets.QDialog): self.loadBtn = QtWidgets.QPushButton('LoadTrueMatchResults') self.loadBtn.resize(self.loadBtn.sizeHint()) self.loadBtn.clicked.connect(self.loadFileManually) - -# optionsLayout = QtWidgets.QFormLayout() -# self.optionsGroup = QtWidgets.QGroupBox('Compute Options') -# self.optionsGroup.setDisabled(True) -# -# self.label1 = QtWidgets.QLabel('HQI-Threshold:') -# self.spinbox1 = QtWidgets.QDoubleSpinBox(self) -# self.spinbox1.valueChanged.connect(self.runCalculations) -# optionsLayout.addRow(self.label1, self.spinbox1) - -# self.label2 = QtWidgets.QLabel('ComponentThreshold:') -# self.spinbox2 = QtWidgets.QDoubleSpinBox(self) -# self.spinbox2.valueChanged.connect(self.updateParentSpinboxes) -# optionsLayout.addRow(self.label2, self.spinbox2) - -# for box in [self.spinbox1, self.spinbox2]: -# for box in [self.spinbox1]: -# box.setValue(50) -# box.setDecimals(1) -# box.setSingleStep(5) -# box.setMinimum(0) -# box.setMaximum(100) -## self.spinbox2.setValue(30) #more reasonable... -# -# self.optionsGroup.setLayout(optionsLayout) self.reviewGroup = QtWidgets.QGroupBox('Review Changes') self.reviewGroup.setDisabled(True) @@ -80,7 +55,6 @@ class LoadTrueMatchResults(QtWidgets.QDialog): self.reviewGroup.setLayout(reviewLayout) self.layout.addWidget(self.loadBtn, 0, 0) -# self.layout.addWidget(self.optionsGroup, 1, 0) self.layout.addWidget(self.reviewGroup, 2, 0) self.manualPolymers = {} @@ -144,7 +118,12 @@ class LoadTrueMatchResults(QtWidgets.QDialog): specName = entry[0] indexOpenBracket = specName.find('(') indexCloseBracket = specName.find(')') - specIndex = int(specName[indexOpenBracket+1:indexCloseBracket]) + inbrackets = specName[indexOpenBracket+1:indexCloseBracket] + try: + specIndex = int(inbrackets) + except: + print(inbrackets) + raise #find yes-flags flags = np.where(np.array(entry) == 'yes')[0] @@ -204,7 +183,6 @@ class LoadTrueMatchResults(QtWidgets.QDialog): if numcomps == 1: #####SINGLE COMPONENT SEARCH self.additives = None self.addhqis = None -# self.spinbox2.setEnabled(False) for index, entry in enumerate(self.resultList): if len(entry) == 0: del self.resultList[index] @@ -241,11 +219,6 @@ class LoadTrueMatchResults(QtWidgets.QDialog): def closeEvent(self, event): #TODO: SANITY CHECK FOR DATA CONSISTENCY!! - -# if not self.parent.datastats.saveAnalysisResults(minHQI, compHQI): -# QtWidgets.QMessageBox.warning(self.parent, 'Error!', -# 'Data inconsistency after saving!', -# QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok) self.parent.setEnabled(True) event.accept() diff --git a/analysis/particleAndMeasurement.py b/analysis/particleAndMeasurement.py index 8c3cb5e75ba5bda6e194ec6a0f845101ae3b52b1..cfc9c3e954dadd1d9eea2e9d57dfecf8ef5bc2ee 100644 --- a/analysis/particleAndMeasurement.py +++ b/analysis/particleAndMeasurement.py @@ -83,17 +83,19 @@ class Particle(object): else: print(f'Error, particle size requested, but not yet set.\nParticle Index is {self.index}') raise ValueError - assert size is not None, f'Error, size or particle {self.index} is None' - return round(size) + assert size is not None, f'Error, size of particle {self.index} is None' + return size def getShortParticleSize(self): if not np.isnan(self.shortSize_ellipse): - return self.shortSize_ellipse + size = self.shortSize_ellipse elif not np.isnan(self.shortSize_box): - return self.shortSize_box + size = self.shortSize_box else: print(f'Error, particle size requested, but not yet set.\nParticle Index is {self.index}') raise ValueError + assert size is not None, f'Error, short size of particle {self.index} is None' + return size def getNumberOfMeasurements(self): return len(self.measurements) diff --git a/analysis/particleContainer.py b/analysis/particleContainer.py index 42ad3ffda0079f71eee8d7c720517c92777fa16f..2b04bce8d400538edbc2954ec27be5471f450daa 100644 --- a/analysis/particleContainer.py +++ b/analysis/particleContainer.py @@ -33,7 +33,6 @@ class ParticleContainer(object): self.datasetParent = datasetParent self.particles = [] self.measurements = [] - self.spectra = None self.inconsistentParticles = [] self.typeHistogram = None @@ -83,7 +82,6 @@ class ParticleContainer(object): if spectra is not None: np.save(self.datasetParent.getSpectraFileName(), spectra) - return spectra def initializeParticles(self, numParticles): diff --git a/analysis/particlePainter.py b/analysis/particlePainter.py index 33fdb201384ab584144a9ab24c93783eabad8543..8cf00c926d0b748a620d0f547eff32ab05a3d2ec 100644 --- a/analysis/particlePainter.py +++ b/analysis/particlePainter.py @@ -142,7 +142,7 @@ class ParticlePainter(QtWidgets.QGraphicsItem): elif y_shift == 0: newImg[:, :self.img.shape[1]] = self.img elif y_shift > 0: - newImg[:y_shift, :self.img.shape[1]] = self.img + newImg[:self.img.shape[0], :self.img.shape[1]] = self.img self.img = np.uint8(newImg) self.setBrect() diff --git a/analysis/sqlexport.py b/analysis/sqlexport.py index 3ced72347aa9a1075b3f9b8a04a267598d53115c..376716deebaf4d48e50da66e4a48e679145399d8 100644 --- a/analysis/sqlexport.py +++ b/analysis/sqlexport.py @@ -1,11 +1,25 @@ # -*- coding: utf-8 -*- """ -Created on Thu Nov 8 13:50:05 2018 +GEPARD - Gepard-Enabled PARticle Detection +Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für +Polymerforschung Dresden e. V. -@author: brandt +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 +from PyQt5 import QtWidgets, QtCore import numpy as np import mysql.connector import difflib @@ -14,18 +28,24 @@ import os import datetime import json +import analysis.DBAssignments as dbassignments +from analysis.DBAssignments import DBAssignment + class SQLExport(QtWidgets.QDialog): - def __init__(self, particleContainer, parent): - super(SQLExport, self).__init__(parent) + def __init__(self, dataset): + super(SQLExport, self).__init__() self.setWindowTitle('Export to SQL Database') - self.particleContainer = particleContainer - self.longSizes = self.particleContainer.getSizesOfAllParticles() - self.shortSize = self.particleContainer.getShortSizesOfAllParticles() - self.spectra = self.particleContainer.spectra + self.dataset = dataset + self.particleContainer = dataset.particleContainer + + self.longSizes = np.round(self.particleContainer.getSizesOfAllParticles()) + self.shortSize = np.round(self.particleContainer.getShortSizesOfAllParticles()) + self.spectra = self.particleContainer.getSpectraFromDisk() self.particleImages = None self.log = [] + self.dbAssignments = None configfilename = os.path.join(os.path.split(__file__)[0], 'database_config.txt') @@ -40,7 +60,7 @@ class SQLExport(QtWidgets.QDialog): for key in ['user', 'password', 'host', 'database', 'raise_on_warnings', 'charset', 'use_unicode']: assert key in self.config, \ - 'all server config data must be defined in json file' + f'server config key {key} is missing databae_config json file' self.cnx = None self.createInterface() @@ -49,6 +69,14 @@ class SQLExport(QtWidgets.QDialog): layout = QtWidgets.QVBoxLayout() self.setLayout(layout) + assignmentFolder = QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppLocalDataLocation) + assignmentPath = os.path.join(assignmentFolder, 'dbassignments.pkl') + if not os.path.exists(assignmentPath): + self.dbAssignments = DBAssignment() + self.dbAssignments.setFileName(assignmentPath) + else: + self.dbAssignments = dbassignments.loadAssigments(assignmentPath) + self.connect() promptGroup = QtWidgets.QGroupBox('General Properties') @@ -64,10 +92,10 @@ class SQLExport(QtWidgets.QDialog): promptLayout.addWidget(self.sampleEdit, 0, 3) promptLayout.addWidget(QtWidgets.QLabel(')'), 0, 4) - methodList = self.getEntireTable('methods')[1] - self.methodIndices = [i[0] for i in methodList] + self.methodIndices = self.getMethodIDs() self.methodSelector = QtWidgets.QComboBox() - self.methodSelector.addItems([i[1] for i in methodList]) + self.methodSelector.addItems(self.getMethodNames()) + self.methodEdit = LinkedLineEdit(self.methodSelector) self.methodEdit.setMaximumWidth(250) promptLayout.addWidget(QtWidgets.QLabel('Analysis Method*: '), 1, 0) @@ -81,6 +109,7 @@ class SQLExport(QtWidgets.QDialog): self.analystSelector = QtWidgets.QComboBox() self.analystSelector.addItems([', '.join([i[2], i[1]]) for i in analystList]) self.analysisDate = QtWidgets.QDateEdit() + self.analysisDate.setDate(QtCore.QDate().currentDate()) self.arrivalDate = QtWidgets.QDateEdit() furtherProperties = {QtWidgets.QLabel('ArrivalDate*: '): self.arrivalDate, QtWidgets.QLabel('Analysis : '): self.analysisDate, @@ -108,37 +137,43 @@ class SQLExport(QtWidgets.QDialog): self.polymerTypes = self.particleContainer.getUniquePolymers() self.polymerCheckboxes = [] - self.db_polyms = [] - self.db_categs = [] - self.p_remarks = [] + self.db_result_combos = [] + self.db_categs_combos = [] + self.db_pRemark_combos = [] self.comments =[] for index, polymerType in enumerate(self.polymerTypes): self.polymerCheckboxes.append(QtWidgets.QCheckBox()) - self.db_polyms.append(QtWidgets.QComboBox()) - self.db_polyms[-1].addItems([i[1] for i in dbPolymResults]) - self.setToClosestMatch(polymerType, self.db_polyms[-1]) - self.db_categs.append(QtWidgets.QComboBox()) - self.db_categs[-1].addItems([i[1] for i in dbCategResults]) - self.setToClosestMatch(polymerType, self.db_categs[-1]) - self.p_remarks.append(QtWidgets.QComboBox()) - self.p_remarks[-1].addItems([i[1] for i in dbPaintRemark]) - self.p_remarks[-1].addItem('') - self.p_remarks[-1].setCurrentIndex(self.p_remarks[-1].count()-1) + newPolymCombo = QtWidgets.QComboBox() + newPolymCombo.addItems([i[1] for i in dbPolymResults]) + self.db_result_combos.append(newPolymCombo) + + newCategCombo = QtWidgets.QComboBox() + newCategCombo.addItems([i[1] for i in dbCategResults]) + self.db_categs_combos.append(newCategCombo) + + newPaintRemarksCombo = QtWidgets.QComboBox() + newPaintRemarksCombo.addItems([i[1] for i in dbPaintRemark]) + newPaintRemarksCombo.addItem('') + self.db_pRemark_combos.append(newPaintRemarksCombo) + + self.setComboBoxesToAssignment(newPolymCombo, newCategCombo, newPaintRemarksCombo, polymerType) + + self.comments.append(QtWidgets.QLineEdit()) self.polymerCheckboxes[-1].stateChanged.connect(self.makeStateChangedLambda(self.polymerCheckboxes[-1], - [self.db_polyms[-1], self.db_categs[-1], self.p_remarks[-1], self.comments[-1]])) + [self.db_result_combos[-1], self.db_categs_combos[-1], self.db_pRemark_combos[-1], self.comments[-1]])) self.polymerCheckboxes[-1].setChecked(True) self.polymerCheckboxes[-1].setChecked(False) #switch twice, so that the stateChanged-function is called typeLayout.addWidget(self.polymerCheckboxes[-1], index+1, 0) typeLayout.addWidget(QtWidgets.QLabel(polymerType), index+1, 1) - typeLayout.addWidget(self.db_polyms[-1], index+1, 2) - typeLayout.addWidget(self.db_categs[-1], index+1, 3) - typeLayout.addWidget(self.p_remarks[-1], index+1, 4) + typeLayout.addWidget(self.db_result_combos[-1], index+1, 2) + typeLayout.addWidget(self.db_categs_combos[-1], index+1, 3) + typeLayout.addWidget(self.db_pRemark_combos[-1], index+1, 4) typeLayout.addWidget(self.comments[-1], index+1, 5) - for element in (self.db_polyms + self.db_categs + self.p_remarks + self.comments): + for element in (self.db_result_combos + self.db_categs_combos + self.db_pRemark_combos + self.comments): element.setMaximumWidth(250) typeGroupBox.setLayout(typeLayout) @@ -153,16 +188,6 @@ class SQLExport(QtWidgets.QDialog): layout.addWidget(self.uploadBtn) layout.addStretch() - if len(self.datastats.dataset.resultsUploadedToSQL) > 0: - reply = QtWidgets.QMessageBox.question(self, 'Warning!', - "The following results were already uploaded:\n\n{}\n\nContinue?".format('\n'.join(self.datastats.dataset.resultsUploadedToSQL)), - QtWidgets.QMessageBox.Yes | - QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) - if reply == QtWidgets.QMessageBox.No: - self.close() - self.destroy() - - def uploadResults(self): if self.connectionIsValid(): cursor = self.cnx.cursor() @@ -196,9 +221,9 @@ class SQLExport(QtWidgets.QDialog): usedCols[sizeCols[1]] = str(self.shortSize[polymInd]) if self.particleImages is not None: usedCols['Image'] = self.particleImages[polymInd] - usedCols['Categorised_result'] = self.db_categs[polymerIndex].currentText() - if self.p_remarks[polymerIndex].currentText() != '': - usedCols['Indication_paint'] = self.p_remarks[polymerIndex].currentText() + usedCols['Categorised_result'] = self.db_categs_combos[polymerIndex].currentText() + if self.db_pRemark_combos[polymerIndex].currentText() != '': + usedCols['Indication_paint'] = self.db_pRemark_combos[polymerIndex].currentText() requiredColumns = '(`'+'`,`'.join(list(usedCols.keys())) + '`' vals = '","'.join(list(usedCols.values())) @@ -208,7 +233,7 @@ class SQLExport(QtWidgets.QDialog): cursor.execute(sql_command) except: print(sql_command) -# self.cnx.commit() + self.cnx.commit() newIndices = self.getPartIndicesOfSample(self.sampleSelector.currentText()) addedParticleIndex = list(set(newIndices) - set(currentParticleInd))[0] @@ -217,18 +242,18 @@ class SQLExport(QtWidgets.QDialog): particles2analasyses[addedParticleIndex] = [] self.log.append(sql_command) -# ##upload to analyses: + ##upload to analyses: method = self.methodIndices[self.methodSelector.currentIndex()] lib = polymerType hqi = str(0) - specIDs = self.particleContainer.getgetSpectraIndicesOfParticle() + specIDs = self.particleContainer.getSpectraIndicesOfParticle(polymInd) for specID in specIDs: spec = self.spectra[:, [0, specID+1]] fp = StringIO() np.savetxt(fp, spec) fp.seek(0) spec = fp.read() - res = self.dbPolymResultsIndices[self.db_polyms[polymerIndex].currentIndex()] + res = self.dbPolymResultsIndices[self.db_result_combos[polymerIndex].currentIndex()] com = self.comments[polymerIndex].text() format_str = """INSERT INTO analysis (Method, Library_entry, Spectrum, Result, Comment) @@ -239,7 +264,7 @@ class SQLExport(QtWidgets.QDialog): cursor.execute(sql_command) except: print(sql_command) -# self.cnx.commit() + self.cnx.commit() #remove spectrum for log... sql_command = format_str.format(method=method, lib=lib, hqi=hqi, spec='SpecFile', res=res, com=com) self.log.append(sql_command) @@ -251,25 +276,25 @@ class SQLExport(QtWidgets.QDialog): particles2analasyses[addedParticleIndex].append(addedAnalysisIndex) -# ##upload particles2analyses: -# for particleInd in particles2analasyses: -# for anaInd in particles2analasyses[particleInd]: -# sql_command = """INSERT INTO particles2analysis (IDParticles, IDAnalysis) VALUES ("{}", "{}");""".format(particleInd, anaInd) -# cursor.execute(sql_command) -# self.log.append(sql_command) -# self.cnx.commit() + ##upload particles2analyses: + for particleInd in particles2analasyses: + for anaInd in particles2analasyses[particleInd]: + sql_command = """INSERT INTO particles2analysis (IDParticles, IDAnalysis) VALUES ("{}", "{}");""".format(particleInd, anaInd) + cursor.execute(sql_command) + self.log.append(sql_command) + self.cnx.commit() for index, polymType in enumerate(self.polymerTypes): if self.polymerCheckboxes[index].isChecked(): - if polymType not in self.datastats.dataset.resultsUploadedToSQL: - self.datastats.dataset.resultsUploadedToSQL.append(polymType) - self.datastats.dataset.save() + if polymType not in self.dataset.resultsUploadedToSQL: + self.dataset.resultsUploadedToSQL.append(polymType) + self.dataset.save() #write log to file - logfile = os.path.join(self.datastats.dataset.path, 'sql_log.txt') + logfile = os.path.join(self.dataset.path, 'sql_log.txt') increment = 1 while os.path.exists(logfile): - logfile = os.path.join(self.datastats.dataset.path, 'sql_log ({}).txt'.format(increment)) + logfile = os.path.join(self.dataset.path, 'sql_log ({}).txt'.format(increment)) increment += 1 with open(logfile, 'w') as fp: @@ -303,10 +328,19 @@ class SQLExport(QtWidgets.QDialog): for element in elements: element.setEnabled(checkbox.isChecked()) - def setToClosestMatch(self, string, comboBox): - entries = [comboBox.itemText(i) for i in range(comboBox.count())] - sortedEntries = difflib.get_close_matches(string, entries, len(entries), 0) - comboBox.setCurrentIndex(entries.index(sortedEntries[0])) + def setComboBoxesToAssignment(self, resultCombo, categCombo, paintRemarkCombo, polymName): + if self.dbAssignments.hasAssignment(polymName): + assignment = self.dbAssignments.getAssignment(polymName) + resultCombo.setCurrentText(assignment.result) + categCombo.setCurrentText(assignment.categorizedResult) + paintRemarkCombo.setCurrentText(assignment.indication_paint) + else: + #set to closest Match + for comboBox in [resultCombo, categCombo]: + entries = [comboBox.itemText(i) for i in range(comboBox.count())] + sortedEntries = difflib.get_close_matches(polymName, entries, len(entries), 0) + comboBox.setCurrentIndex(entries.index(sortedEntries[0])) + paintRemarkCombo.setCurrentText('') def connectionIsValid(self): if self.cnx is None: @@ -350,6 +384,18 @@ class SQLExport(QtWidgets.QDialog): return data + def getMethodIDs(self): + if self.connectionIsValid(): + cursor = self.cnx.cursor() + cursor.execute("SELECT IDMethod FROM methods ORDER BY IDMethod") + return [row[0] for row in cursor] + + def getMethodNames(self): + if self.connectionIsValid(): + cursor = self.cnx.cursor() + cursor.execute("SELECT Method_name FROM methods ORDER BY IDMethod") + return [row[0] for row in cursor] + def getPartIndicesOfSample(self, sampleName): if self.connectionIsValid(): cursor = self.cnx.cursor() @@ -371,6 +417,22 @@ class SQLExport(QtWidgets.QDialog): print('returned None from Table '.format('tableName')) return data + + def closeEvent(self, event): + self.saveAssignments() + event.accept() + + def saveAssignments(self): + if self.dbAssignments is not None: + for index, polymerType in enumerate(self.polymerTypes): + if not self.dbAssignments.hasAssignment(polymerType): + self.dbAssignments.createNewAssignment(polymerType) + result = self.db_result_combos[index].currentText() + categ_result = self.db_categs_combos[index].currentText() + paint_remark = self.db_pRemark_combos[index].currentText() + self.dbAssignments.updateAssignment(polymerType, result, categ_result, paint_remark) + + self.dbAssignments.save() class LinkedLineEdit(QtWidgets.QLineEdit): def __init__(self, combobox): @@ -391,17 +453,4 @@ class LinkedLineEdit(QtWidgets.QLineEdit): if entry.find(curString) >= 0: matchingEntries.append(self.entries[index]) self.combobox.addItems(matchingEntries) - self.combobox.update() - - -if __name__ == '__main__': - import sys - try: - del(app) - except: - pass - - app = QtWidgets.QApplication(sys.argv) - mainWin = SQLExport(['polyethen', 'poly(tetrafluorethene)', 'polyester'], [1, 2, 3], None) - mainWin.show() - app.exec_() \ No newline at end of file + self.combobox.update() \ No newline at end of file diff --git a/dataset.py b/dataset.py index 6076ebcf099a38c9d20fb0e0af7f1a132ca21e5a..d75e92f8b8bcf5607f2d8bea6072bdc28b388a58 100644 --- a/dataset.py +++ b/dataset.py @@ -252,7 +252,7 @@ class DataSet(object): self.particleContainer.clearMeasurements() - if self.particles2spectra is None: + if not hasattr(self, 'particles2spectra') or self.particles2spectra is None: self.particles2spectra = [[int(np.where(self.ramanscansortindex == i)[0])] for i in range(len(self.ramanscansortindex))] if len(self.particlestats) > 0: #i.e., particle detection was completed and particle data is there @@ -268,11 +268,12 @@ class DataSet(object): self.particleContainer.setMeasurementScanIndex(indexOfNewMeas, scanIndex) curParticle.addMeasurement(self.particleContainer.measurements[indexOfNewMeas]) - for particle in self.particleContainer.particles: - for meas in particle.measurements: - specIndex = meas.getScanIndex() - meas.setAssignment(self.results['polymers'][specIndex]) - meas.setHQI(self.results['hqis'][specIndex]) + if hasattr(self, 'results') and self.results['polymers'] is not None: #transfer results + for particle in self.particleContainer.particles: + for meas in particle.measurements: + specIndex = meas.getScanIndex() + meas.setAssignment(self.results['polymers'][specIndex]) + meas.setHQI(self.results['hqis'][specIndex]) self.particleContainer.testForInconsistentParticles()