#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Thu May 31 10:07:45 2018 @author: brandt """ import numpy as np from PyQt5 import QtWidgets import sys from os import chdir, getcwd class LoadWITecResults(QtWidgets.QDialog): def __init__(self, parent): super(LoadWITecResults, self).__init__() self.setGeometry(400, 400, 200, 300) self.setWindowTitle('Get Truematch Results') self.layout = QtWidgets.QGridLayout() self.setLayout(self.layout) self.parent = parent self.parent.setDisabled(True) self.trueMatchResults = None self.polymertypes = None self.additives = None self.hqis = None self.addhqis = None self.btn1 = QtWidgets.QPushButton('LoadTrueMatchResults') self.btn1.resize(self.btn1.sizeHint()) self.btn1.clicked.connect(self.loadFileManually) optionsLayout = QtWidgets.QFormLayout() self.optionsGroup = QtWidgets.QGroupBox('Compute Options') self.optionsGroup.setDisabled(True) self.btn3 = QtWidgets.QPushButton('Compute') self.btn3.clicked.connect(self.runCalculations) self.label1 = QtWidgets.QLabel('HQI-Threshold:') self.spinbox1 = QtWidgets.QDoubleSpinBox(self) self.spinbox1.valueChanged.connect(self.updateParentSpinboxes) 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) self.label3 = QtWidgets.QLabel('Max Items in Display:') self.numDispSpinbox = QtWidgets.QSpinBox(self) self.numDispSpinbox.setValue(20) self.numDispSpinbox.setMinimum(1) self.numDispSpinbox.setMaximum(40) self.numDispSpinbox.valueChanged.connect(self.updateParentSpinboxes) optionsLayout.addRow(self.label3, self.numDispSpinbox) optionsLayout.addRow(self.btn3) for box in [self.spinbox1, self.spinbox2]: 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) reviewLayout = QtWidgets.QVBoxLayout() self.otherBtn = QtWidgets.QPushButton('manual overwrite') self.otherBtn.clicked.connect(self.show3FlagsReview) reviewLayout.addWidget(self.otherBtn) reviewLayout.addStretch() self.reviewGroup.setLayout(reviewLayout) self.layout.addWidget(self.btn1, 0, 0) self.layout.addWidget(self.optionsGroup, 1, 0) self.layout.addWidget(self.reviewGroup, 2, 0) self.manualPolymers = {} self.manualAdditives = {} self.expWindow = None self.additivePlot = None self.editEntryWindow = None self.numFlagForTakeSpectrum = 1 self.numFlagForSetUnknown = 2 self.numFlagForPrompt = 3 def updateParentSpinboxes(self): self.parent.hqiSpinBox.setValue(self.spinbox1.value()) self.parent.compHqiSpinBox.setValue(self.spinbox2.value()) self.parent.dispResultSpinBox.setValue(self.numDispSpinbox.value()) def show3FlagsReview(self): self.editEntryWindow = ModifyManualEdits(self, self.manualPolymers, self.manualAdditives) self.editEntryWindow.show() def loadFileManually(self): dsetpath = self.parent.parent.dataset.path fnames =QtWidgets.QFileDialog.getOpenFileNames(self, 'Select TrueMatch result file', dsetpath, 'text file (*.txt)')[0] if len(fnames) > 1: QtWidgets.QMessageBox.about(self, 'Info', 'The following order of files was loaded. If incorrect, please call a coder!\n{}'.format('\n'.join([fname for fname in fnames]))) self.trueMatchResults = [] for fileindex, fname in enumerate(fnames): with open(fname) as file: if fileindex == 0: for line in file: self.trueMatchResults.append(line) else: ##for additional files skip first line (header..) for lineindex, line in enumerate(file): if lineindex > 0: self.trueMatchResults.append(line) self.btn1.setText('Data loaded') self.optionsGroup.setDisabled(False) def formatResults(self, rawResults): #get rid of header line, first data interpretation results = [] for index,line in enumerate(rawResults): if index == 0: line = line.strip().split(';')[:-1] #disregard the last entry of each line, as each line ends with ; <- that produces an empty entry... if line[0] != 'Search Spectrum Name': print('incompatible data format') break #detect, whether one- or multicomponent-search was done if line[-1] == 'IsMarked': numhits = np.int(line[-2].split(' ')[-1]) numcomps = 1 else: numhits = np.int(line[-1].split(' ')[-1]) numcomps = np.int(line[-1].split(' ')[-3]) else: results.append(line) numspectra = len(results) if numspectra > 0: print('{} components, {} hits per sample, {} spectra'.format(numcomps, numhits, numspectra)) return results, numspectra, numcomps, numhits def interpretEntry(self, index, entry, numhits, numcomps): entry = entry.split(';') polymertype, additive, hqi, addhqi = None, None, None, None #assign default None #find yes-flags flags = np.where(np.array(entry) == 'yes')[0] if len(flags) == 0: #take highest HQI entry if numcomps == 1: if float(entry[1]) > self.spinbox1.value(): polymertype = entry[2] hqi = entry[1] else: polymertype = 'unknown' hqi = 0 else: if float(entry[1]) > self.spinbox1.value(): polymertype = entry[5] hqi = entry[1] if float(entry[6]) > self.spinbox2.value(): additive = entry[7] addhqi = entry[6] else: additive = 'none' addhqi = 0 else: polymertype = 'unknown' additive = 'none' hqi = 0 addhqi = 0 elif len(flags) == 1: #exactly one flag was placed, take this entry if numcomps == 1: polymertype = entry[int(flags[0])-1] hqi = 100 else: polymertype = entry[int(flags[0])+2] additive = entry[int(flags[0])+4] hqi = 100 addhqi = 100 elif len(flags) == 2: polymertype = 'unknown' hqi = 0 if numcomps > 1: additive = 'none' addhqi = 0 elif len(flags) == 3: hqi = 100 if index not in self.manualPolymers: polymertype, ok = QtWidgets.QInputDialog.getText(self, 'Name of main component', 'Spectrum at index {} is:'.format(index)) self.manualPolymers[index] = polymertype else: polymertype = self.manualPolymers[index] if numcomps > 1: addhqi = 100 if entry[0] not in self.manualAdditives: additive, ok = QtWidgets.QInputDialog.getText(self, 'Name of additive', 'Additive at index {} is:'.format(index)) self.manualAdditives[index] = additive else: additive = self.manualAdditives[index] else: QtWidgets.QMessageBox.about(self, 'Error!', 'No rule for {} flags, found at spectrum index {}'.format(len(flags), index)) if addhqi is None: addhqi = 0 return polymertype, additive, float(hqi), float(addhqi) def runCalculations(self): self.resultList, numspectra, numcomps, numhits = self.formatResults(self.trueMatchResults) self.dispresults = self.numDispSpinbox.value() self.polymertypes =[] self.hqis = [] 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] else: polymertype, additive, hqi, addhqi = self.interpretEntry(index, entry, numhits, numcomps) self.polymertypes.append(polymertype) self.hqis.append(hqi) else: #####MULTI-COMPONENT SEARCH self.additives = [] self.addhqis = [] for index, entry in enumerate(self.resultList): if len(entry) > 0: polymertype, additive, hqi = self.interpretEntry(index, entry, numhits, numcomps) self.polymertypes.append(polymertype) self.hqis.append(hqi) self.additives.append(additive) self.addhqis.append(addhqi) assert len(self.polymertypes) == len(self.resultList), 'incorrect number of polymer types added...' del self.parent.spectraResults, self.parent.additiveResults, self.parent.hqis, self.parent.addhqis self.parent.spectraResults = self.polymertypes self.parent.additiveResults = self.additives self.parent.hqis = self.hqis self.parent.addhqis = self.addhqis self.parent.formatResults() if len(self.manualPolymers) > 0: self.reviewGroup.setDisabled(False) def closeEvent(self, event): del self.parent.spectraResults, self.parent.additiveResults, self.parent.hqis, self.parent.addhqis self.parent.spectraResults = self.polymertypes self.parent.additiveResults = self.additives self.parent.hqis = self.hqis self.parent.addhqis = self.addhqis self.parent.updateBtn.clicked.connect(self.parent.formatResults) self.parent.formatResults() self.parent.show_hide_labels() self.parent.saveAnalysisResults() self.parent.setEnabled(True) event.accept() class ModifyManualEdits(QtWidgets.QWidget): def __init__(self, parentWindow, polymerEdits, additiveEdits = None): super(ModifyManualEdits, self).__init__() self.setWindowTitle('Edit Manual Changes') self.setGeometry(200, 200, 800, 500) layout = QtWidgets.QVBoxLayout() self.setLayout(layout) self.parent = parentWindow self.polymerEdits = polymerEdits self.additiveEdits = additiveEdits self.labels = [] self.polymerLineEdits = [] self.additiveLineEdits = [] groupBox = QtWidgets.QGroupBox('Manually entered edits') groupLayout = QtWidgets.QGridLayout() #create Labels and LineEdits for index in self.polymerEdits: self.labels.append(QtWidgets.QLabel('Spectrum index:' + str(index))) print(self.labels[-1].text()) self.polymerLineEdits.append(QtWidgets.QLineEdit()) self.polymerLineEdits[-1].setText(self.polymerEdits[index]) if len(self.additiveEdits) > 0: self.additiveLineEdits.append(QtWidgets.QLineEdit()) self.additiveLineEdits[-1].setText(self.additiveEdits[index]) for i in range(len(self.labels)): groupLayout.addWidget(self.labels[i], i, 0) groupLayout.addWidget(self.polymerLineEdits[i], i, 1) if len(self.additiveEdits) > 0: groupLayout.addWidget(self.additiveLineEdits[i], i, 2) groupBox.setLayout(groupLayout) scrollarea = QtWidgets.QScrollArea() scrollarea.setWidget(groupBox) scrollarea.setMaximumHeight(600) layout.addWidget(scrollarea) saveAndCloseBtn = QtWidgets.QPushButton('Save and Exit') saveAndCloseBtn.clicked.connect(self.closeEvent) layout.addWidget(saveAndCloseBtn) def closeEvent(self, event): #read out LineEdits: for index, key in enumerate(self.polymerEdits): self.polymerEdits[key] = self.polymerLineEdits[index].text() if len(self.additiveEdits) > 0: self.additiveEdits[key] = self.additiveLineEdits[index].text() #copy values to parent Window self.parent.manualPolymers, self.parent.manualAdditives = self.polymerEdits, self.additiveEdits self.parent.runCalculations() self.close() if __name__ == "__main__": wd=getcwd() chdir(wd) try: del(app) except: pass app = QtWidgets.QApplication(sys.argv) mainWin = LoadWITecResults(None) mainWin.show() app.exec_()