diff --git a/analysis/analysisview.py b/analysis/analysisview.py index 67164a237a18132950ce8a710b4c390fe111de35..9f12aadb0c25b95ec2b7f8d3cfc517e5482f1cad 100644 --- a/analysis/analysisview.py +++ b/analysis/analysisview.py @@ -44,8 +44,8 @@ except: class ParticleAnalysis(QtWidgets.QMainWindow): - def __init__(self, dataset, parent=None): - super(ParticleAnalysis, self).__init__(parent) + def __init__(self, dataset, viewparent=None): + super(ParticleAnalysis, self).__init__(viewparent) self.setGeometry(100, 100, 1680, 1050) self.setWindowTitle('Results of polymer analysis') self.layout = QtWidgets.QHBoxLayout() @@ -53,7 +53,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.widget.setLayout(self.layout) self.setCentralWidget(self.widget) - self.parent = parent + self.viewparent = viewparent self.dataset = dataset self.particleContainer = dataset.particleContainer self.editor = ParticleEditor(self.particleContainer, self) @@ -114,21 +114,18 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.navigationGroup.setDisabled(True) navigationLayout = QtWidgets.QHBoxLayout() self.specNumberSelector = QtWidgets.QSpinBox() - self.specNumberSelector.setMinimumWidth(150) + self.specNumberSelector.setMinimumWidth(100) self.specNumberSelector.setMinimum(1) self.specNumberSelector.setMaximum(1E6) self.jumpToSpecBtn = QtWidgets.QPushButton('Jump To Spectrum of Number:') - self.jumpToSpecBtn.released.connect(self.jumpToSpectrumOfNumber) + self.jumpToSpecBtn.released.connect(self.jumpToIndicatedSpectrum) self.typeSelectorCombo = QtWidgets.QComboBox() - self.typeSelectorCombo.currentIndexChanged.connect(self.displayNewPolymerType) self.typeSelectorCombo.setMinimumWidth(150) self.particleSelector = QtWidgets.QSpinBox() - self.particleSelector.valueChanged.connect(self.updateSpecPlotToSelectedParticle) self.particleNumberLabel = QtWidgets.QLabel('of xx particles; ') self.spectrumSelector = QtWidgets.QSpinBox() - self.spectrumSelector.valueChanged.connect(self.selectSpectrum) self.spectrumNumberLabel = QtWidgets.QLabel('of xx spectra') for spinbox in [self.particleSelector, self.spectrumSelector]: spinbox.setMinimum(1) @@ -220,11 +217,10 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.createMenus() self.applyHQIThresholdToResults() self.createHistogramData() - self.updateDisplays() self.initializeSpecPlot() self.displayNewPolymerType() self.updateSpecPlotToSelectedParticle() -# self.createPolymerOverlay() + self.updateHistogramsAndContours() def createActions(self): self.loadTrueMatchAct = QtWidgets.QAction("Load &TrueMatch Results", self) @@ -253,6 +249,9 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.seedAct = QtWidgets.QAction("&Set Color Seed", self) self.seedAct.triggered.connect(self.updateColorSeed) + self.removeTinyParticlesAct = QtWidgets.QAction("&Remove not unknown Particles < 1 µm") + self.removeTinyParticlesAct.triggered.connect(self.removeTinyParticles) + self.databaseAct = QtWidgets.QAction("&ManageDatabase", self) self.databaseAct.triggered.connect(self.launchDBManager) @@ -272,7 +271,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.overlayActGroup = QtWidgets.QActionGroup(self.dispMenu) self.overlayActGroup.setExclusive(True) self.overlayActGroup.triggered.connect(self.updateContourColors) - self.overlayActGroup.triggered.connect(self.updateDisplays) + self.overlayActGroup.triggered.connect(self.updateHistogramsAndContours) for act in [self.noOverlayAct, self.selOverlayAct, self.fullOverlayAct]: self.dispMenu.addAction(act) @@ -281,8 +280,9 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.dispMenu.addSeparator() self.dispMenu.addActions([self.transpAct, self.hideLabelAct, self.darkenAct, self.seedAct]) - self.refMenu = QtWidgets.QMenu("&References") - self.refMenu.addAction(self.databaseAct) + self.toolMenu = QtWidgets.QMenu("&Tools") + self.toolMenu.addAction(self.removeTinyParticlesAct) + self.toolMenu.addAction(self.databaseAct) self.exportMenu = QtWidgets.QMenu("&Export", self) self.exportMenu.addAction(self.expExcelAct) @@ -290,7 +290,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.menuBar().addMenu(self.importMenu) self.menuBar().addMenu(self.dispMenu) - self.menuBar().addMenu(self.refMenu) + self.menuBar().addMenu(self.toolMenu) self.menuBar().addMenu(self.exportMenu) def launchDBManager(self): @@ -328,7 +328,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.dataset.resultParams['minHQI'] = hqi self.dataset.save() self.createHistogramData() - self.updateDisplays() + self.updateHistogramsAndContours() def createHistogramData(self): ###Handle Checkboxes for all polymers... @@ -342,7 +342,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): del i self.showTotalSelector.setParent(None) self.showTotalSelector.setDisabled(False) - self.showTotalSelector.stateChanged.connect(self.updateDisplays) + self.showTotalSelector.stateChanged.connect(self.updateHistogramsAndContours) del self.resultCheckBoxes del self.resultCheckBoxesLayout @@ -369,7 +369,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): if polymer in self.lastSelectedCheckBoxNames: self.polymerCheckBoxes[index].setChecked(True) - self.polymerCheckBoxes[index].stateChanged.connect(self.updateDisplays) + self.polymerCheckBoxes[index].stateChanged.connect(self.updateHistogramsAndContours) self.resultCheckBoxesLayout.addStretch() self.resultCheckBoxes.setLayout(self.resultCheckBoxesLayout) @@ -381,10 +381,10 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.expSQLAct.setDisabled(False) self.navigationGroup.setEnabled(True) - self.typeSelectorCombo.currentIndexChanged.disconnect() +# self.typeSelectorCombo.currentIndexChanged.disconnect() self.typeSelectorCombo.clear() self.typeSelectorCombo.addItems(uniquePolymers) - self.typeSelectorCombo.currentIndexChanged.connect(self.displayNewPolymerType) +# self.typeSelectorCombo.currentIndexChanged.connect(self.displayNewPolymerType) self.polymerIndex = self.typeSelectorCombo.currentIndex() # if self.lastSpectrumInFocus is not None: @@ -395,7 +395,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): # print('displaying new type with resetting index') # self.displayNewPolymerType() - def updateDisplays(self): + def updateHistogramsAndContours(self): self.createHistogramData() t0 = time.time() self.updateTypeHistogram() @@ -468,12 +468,10 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.lastSelectedCheckBoxNames = self.getSelectedPolymers() - def updateSpecPlot(self, centerOn=True, highlightContour=True): + def updateSpecPlot(self): particleSize = self.particleContainer.getSizeOfParticleByIndex(self.currentParticleIndex) hqi = self.particleContainer.getHQIOfSpectrumIndex(self.currentSpectrumIndex) self.specPlot.updateParticleSpectrum(self.currentSpectrumIndex, particleSize, hqi) - self.parent.centerOnRamanIndex(self.currentSpectrumIndex, centerOn=centerOn, highlightContour=highlightContour) #TODO: is this reasonable to do in that way??? - self.parent.highLightRamanIndex(self.currentSpectrumIndex) # self.lastSpectrumInFocus = self.currentSpectrumIndex if self.refSelector.isEnabled() and self.refSelector.currentText() != '': @@ -482,7 +480,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.specPlot.updateReferenceSpectrum(ref[:, 0], ref[:, 1]) def updateContourColors(self): - contours = self.parent.contourItems + contours = self.viewparent.contourItems alpha = (64 if self.transpAct.isChecked() else 255) selectedPolymers = self.getSelectedPolymers() @@ -495,7 +493,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): contour.setHidden(hidden) contour.setColor(color) contour.update() - + def updateLegend(self): if not self.noOverlayAct.isChecked(): legendItems = [] @@ -505,16 +503,31 @@ class ParticleAnalysis(QtWidgets.QMainWindow): color = getColorFromNameWithSeed(polymer, self.dataset.colorSeed) color = QtGui.QColor(color[0], color[1], color[2], 255) legendItems.append((polymer, color)) - self.parent.updateLegend(legendItems) + self.viewparent.updateLegend(legendItems) def getSelectedPolymers(self): return [checkbox.text() for checkbox in self.polymerCheckBoxes if checkbox.isChecked()] - def jumpToSpectrumOfNumber(self): + def getSpecIndexFromBoxesAndJumpThere(self): + self.currentSpectrumIndex = self.getSpectrumIndexFromSpectrumSelector() + self.specNumberSelector.setValue(self.currentSpectrumIndex+1) + self.jumpToIndicatedSpectrum() + + def jumpToIndicatedSpectrum(self, centerOn=True): + print('jumping to spec index with centerOn', centerOn) + ###disconnect Boxes + try: + self.typeSelectorCombo.currentIndexChanged.disconnect() + self.particleSelector.valueChanged.disconnect() + self.spectrumSelector.valueChanged.disconnect() + except TypeError: + pass #i.e., there was no connection + specIndex = self.specNumberSelector.value()-1 - assert specIndex is not None + print('specIndex', specIndex) partIndex = self.particleContainer.getParticleIndexContainingSpecIndex(specIndex) + print('partIndex', partIndex) assignment = self.particleContainer.getParticleAssignmentByIndex(partIndex) self.typeSelectorCombo.setCurrentText(assignment) @@ -523,19 +536,27 @@ class ParticleAnalysis(QtWidgets.QMainWindow): specIndices = self.particleContainer.getSpectraIndicesOfParticle(partIndex) self.spectrumSelector.setValue(specIndices.index(specIndex)+1) - - - def selectParticleOfIndex(self, particleIndex, centerOn=True): - assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex) - self.typeSelectorCombo.setCurrentText(assignment) - self.typeSelectorCombo.currentIndexChanged.connect(self.displayNewPolymerType) - self.particleSelector.valueChanged.disconnect() - particleIndices = self.particleContainer.getIndicesOfParticleType(assignment) - self.particleSelector.setValue(particleIndices.index(particleIndex)+1) - self.particleSelector.valueChanged.connect(self.updateSpecPlotToSelectedParticle) + if centerOn: + self.viewparent.centerOnRamanIndex(self.currentSpectrumIndex, centerOn=True, highlightContour=True) + self.viewparent.highLightContour(self.getParticleIndexFromParticleSelector()) + + ###connect Boxes + self.typeSelectorCombo.currentIndexChanged.connect(self.displayNewPolymerType) + self.typeSelectorCombo.currentIndexChanged.connect(self.getSpecIndexFromBoxesAndJumpThere) +# self.particleSelector.valueChanged.connect(self.updateSpecPlotToSelectedParticle) + self.particleSelector.valueChanged.connect(self.getSpecIndexFromBoxesAndJumpThere) +# self.spectrumSelector.valueChanged.connect(self.selectSpectrum) + self.spectrumSelector.valueChanged.connect(self.getSpecIndexFromBoxesAndJumpThere) + self.displayNewPolymerType() + self.updateSpecPlotToSelectedParticle() + self.updateHistogramsAndContours() - self.updateSpecPlotToSelectedParticle(resetSpectrumCount=True, centerOn=centerOn) + + def selectParticleOfIndex(self, particleIndex, centerOn=False): + specIndices = self.particleContainer.getSpectraIndicesOfParticle(particleIndex) + self.specNumberSelector.setValue(specIndices[0]+1) + self.jumpToIndicatedSpectrum(centerOn=centerOn) def displayNewPolymerType(self, resetCurrentIndex=True): polymerName = self.typeSelectorCombo.currentText() @@ -551,9 +572,9 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.spectrumSelector.setMaximum(numSpectra) self.spectrumNumberLabel.setText(f'of {numSpectra} Spectra') self.currentSpectrumIndex = self.getSpectrumIndexFromSpectrumSelector() - self.updateSpecPlot(centerOn=False) + self.updateSpecPlot() - def updateSpecPlotToSelectedParticle(self, resetSpectrumCount=True, centerOn=True): + def updateSpecPlotToSelectedParticle(self, resetSpectrumCount=True): polymerName = self.typeSelectorCombo.currentText() if polymerName != '': self.currentParticleIndex = self.getParticleIndexFromParticleSelector() @@ -564,11 +585,11 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.spectrumSelector.setValue(1) self.currentSpectrumIndex = self.getSpectrumIndexFromSpectrumSelector() - self.updateSpecPlot(centerOn) + self.updateSpecPlot() - def selectSpectrum(self): - self.currentSpectrumIndex = self.getSpectrumIndexFromSpectrumSelector() - self.updateSpecPlot() +# def selectSpectrum(self): +# self.currentSpectrumIndex = self.getSpectrumIndexFromSpectrumSelector() +# self.updateSpecPlot() def getSpectrumIndexFromSpectrumSelector(self): specIndicesOfParticle = self.particleContainer.getSpectraIndicesOfParticle(self.currentParticleIndex) @@ -582,24 +603,53 @@ class ParticleAnalysis(QtWidgets.QMainWindow): return particleIndicesOfType[self.particleSelector.value()-1] def darkenBackground(self): - self.parent.darkenPixmap = self.darkenAct.isChecked() + self.viewparent.darkenPixmap = self.darkenAct.isChecked() if self.darkenAct.isChecked(): - self.parent.scene().setBackgroundBrush(QtGui.QColor(5, 5, 5)) - self.parent.item.setOpacity(0.2) + self.viewparent.scene().setBackgroundBrush(QtGui.QColor(5, 5, 5)) + self.viewparent.item.setOpacity(0.2) else: - self.parent.scene().setBackgroundBrush(QtCore.Qt.darkGray) - self.parent.item.setOpacity(1) + self.viewparent.scene().setBackgroundBrush(QtCore.Qt.darkGray) + self.viewparent.item.setOpacity(1) def updateColorSeed(self): text, ok = QtWidgets.QInputDialog.getText(self, 'Color Seed', 'Enter New Seed here', text=self.dataset.colorSeed) if ok: self.dataset.colorSeed = text - self.updateDisplays() + self.updateHistogramsAndContours() + + def removeTinyParticles(self): + indices = [] + for particle in self.particleContainer.particles: + if particle.getParticleAssignment() != 'unknown' and particle.getParticleSize() < 1: + indices.append(particle.index) + + indices = sorted(indices, reverse=True) + numIndices = len(indices) + + for index, partIndex in enumerate(indices): + self.selectParticleOfIndex(partIndex, centerOn=True) + reply = QtWidgets.QMessageBox.question(self, f'Particle {index+1} of {numIndices}', + "Do you want to remove that particle?", + QtWidgets.QMessageBox.Yes | + QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.No) + if reply == QtWidgets.QMessageBox.Yes: + self.viewparent.removeParticleContour(partIndex) + self.particleContainer.removeParticles([partIndex]) + + elif reply == QtWidgets.QMessageBox.Cancel: + self.particleContainer.resetParticleIndices() + self.viewparent.resetContourIndices() + return + + self.particleContainer.resetParticleIndices() + self.viewparent.resetContourIndices() + + def show_hide_labels(self): hidden = self.hideLabelAct.isChecked() - for scanIndicator in self.parent.ramanscanitems: + for scanIndicator in self.viewparent.ramanscanitems: scanIndicator.hidden = hidden scanIndicator.update() @@ -615,7 +665,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): for window in [self.importWindow, self.dbWin]: try: window.close() except: pass - self.parent.imparent.particelAnalysisAct.setChecked(False) + self.viewparent.imparent.particelAnalysisAct.setChecked(False) event.accept() diff --git a/analysis/particleInfo.py b/analysis/particleInfo.py index 7e5d09c14f2a961ed743efb168a28941005a2845..d530311fb1ebca345236615489b807f03e91545f 100644 --- a/analysis/particleInfo.py +++ b/analysis/particleInfo.py @@ -254,9 +254,6 @@ class ParticleContainer(object): for index in sorted(indexList, reverse=True): particle = self.getParticleOfIndex(index) #just for asserting to have the correct particle! del self.particles[index] -# particle = self.getParticleOfIndex(index) -# print('removing particle of index', index) -# self.particles.remove(particle) def resetParticleIndices(self): for newIndex, particle in enumerate(self.particles): diff --git a/analysis/particlePainter.py b/analysis/particlePainter.py index 9a87322ca6662bd60800762dde2929cd3088b7e8..15f8f7cc9143d0f8783ae28a7a06a77981166d52 100644 --- a/analysis/particlePainter.py +++ b/analysis/particlePainter.py @@ -161,6 +161,7 @@ class ParticlePainter(QtWidgets.QGraphicsItem): for poly in self.polygons: painter.setBrush(QtGui.QColor(200, 200, 255, 128)) painter.drawPolygon(poly) + \ No newline at end of file diff --git a/analysis/particleeditor.py b/analysis/particleeditor.py index 8a69ff8d54beea2302da3c1b27938b7721d076ef..ce538662cfd408e5a63b021c9731d1e7586c4258 100644 --- a/analysis/particleeditor.py +++ b/analysis/particleeditor.py @@ -105,7 +105,7 @@ class ParticleContextMenu(QtWidgets.QMenu): class ParticleEditor(QtCore.QObject): - particleContoursChanged = QtCore.pyqtSignal() +# particleContoursChanged = QtCore.pyqtSignal() particleAssignmentChanged = QtCore.pyqtSignal() def __init__(self, viewparent, particleContainer): super(ParticleEditor, self).__init__() @@ -146,6 +146,7 @@ class ParticleEditor(QtCore.QObject): self.viewparent.resetContourIndices() self.viewparent.addParticleContour(newContour, len(self.viewparent.contourItems)) + self.particleAssignmentChanged.emit() #TODO: INCLUDE SANITY CHECK!!!!!!!!! @QtCore.pyqtSlot(list, str) @@ -177,6 +178,7 @@ class ParticleEditor(QtCore.QObject): for ind in self.storedIndices: self.viewparent.removeParticleContour(ind) + self.particleAssignmentChanged.emit() self.viewparent.resetContourIndices() self.viewparent.addParticleContour(newContour, len(self.viewparent.contourItems)) diff --git a/sampleview.py b/sampleview.py index 6fc50f52ad2ffba4cb0c928757c47e96f62883fa..d03c36dc8729ba6248d4346bce3f9cd93b3be9c5 100644 --- a/sampleview.py +++ b/sampleview.py @@ -270,14 +270,14 @@ class SampleView(QtWidgets.QGraphicsView): if self.particleEditor is None: self.particleEditor = ParticleEditor(self, self.dataset.particleContainer) #try disconnecting the signals. If they are connected multiple times, the functions will run accordingly... - tryDisconnectingSignal(self.particleEditor.particleContoursChanged) +# tryDisconnectingSignal(self.particleEditor.particleContoursChanged) tryDisconnectingSignal(self.particleEditor.particleAssignmentChanged) - self.particleEditor.particleContoursChanged.connect(self.resetParticleContours) +# self.particleEditor.particleContoursChanged.connect(self.resetParticleContours) if self.analysiswidget is not None: - self.particleEditor.particleContoursChanged.connect(self.analysiswidget.updateDisplays) - self.particleEditor.particleAssignmentChanged.connect(self.analysiswidget.updateDisplays) +# self.particleEditor.particleContoursChanged.connect(self.analysiswidget.updateHistogramsAndContours) + self.particleEditor.particleAssignmentChanged.connect(self.analysiswidget.updateHistogramsAndContours) def setMicroscopeMode(self): if self.ramanSwitchNeeded: @@ -320,7 +320,7 @@ class SampleView(QtWidgets.QGraphicsView): if event.button()==QtCore.Qt.MiddleButton: self.drag = event.pos() - elif self.particlePainter is None: + if self.particlePainter is None: if event.button()==QtCore.Qt.LeftButton: self.checkForContourSelection(event) @@ -336,7 +336,7 @@ class SampleView(QtWidgets.QGraphicsView): p0 = self.mapToScene(event.pos()) super(SampleView, self).mousePressEvent(event) - elif self.particlePainter is not None: + else: self.particlePainter.mousePressEvent(event) def mouseMoveEvent(self, event): @@ -412,14 +412,13 @@ class SampleView(QtWidgets.QGraphicsView): for index, cnt in enumerate(self.contourItems): if cnt.polygon.containsPoint(p, QtCore.Qt.OddEvenFill): #clicked on particle - if not event.modifiers()==QtCore.Qt.ShiftModifier: addContourToSelection(cnt) - self.analysiswidget.selectParticleOfIndex(cnt.particleIndex, centerOn=False) + self.analysiswidget.selectParticleOfIndex(cnt.particleIndex) else: if cnt.particleIndex not in self.selectedParticleIndices: addContourToSelection(cnt) - self.analysiswidget.selectParticleOfIndex(cnt.particleIndex, centerOn=False) + self.analysiswidget.selectParticleOfIndex(cnt.particleIndex) elif cnt.particleIndex in self.selectedParticleIndices: removeContourFromSelection(cnt) @@ -587,13 +586,6 @@ class SampleView(QtWidgets.QGraphicsView): if self.dataset is not None: for particleIndex, contour in enumerate(self.dataset.particleContainer.getParticleContours()): self.addParticleContour(contour, particleIndex) -# newCnt = SegmentationContour(self, contour) -# newCnt.setIndex(particleIndex) -# assignment = self.dataset.particleContainer.getParticleAssignmentByIndex(particleIndex) -# color = getColorFromNameWithSeed(assignment, self.dataset.colorSeed) -# newCnt.setColor(QtGui.QColor(color[0], color[1], color[2], 255)) -# self.contourItems.append(newCnt) -# self.scene().addItem(newCnt) self.update() print('resetted contours: {} ms'.format(round((time.time()-t0)*1000))) @@ -624,6 +616,12 @@ class SampleView(QtWidgets.QGraphicsView): item.setHighLight(False) self.ramanscanitems[index].setHighLight(True) + def highLightContour(self, index): + for contour in self.contourItems: + contour.isSelected = False + self.contourItems[index].isSelected = True + + def centerOnRamanIndex(self, index, centerOn=True, highlightContour=True): if centerOn: self.centerOn(self.ramanscanitems[index])