Commit c5d0ae61 authored by JosefBrandt's avatar JosefBrandt

BugFix in Particle Reassignment, Combination.
Performance increase..
parent 96e55786
......@@ -502,16 +502,20 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
def getSelectedPolymers(self):
return [checkbox.text() for checkbox in self.polymerCheckBoxes if checkbox.isChecked()]
# @QtCore.pyqtSlot(int) #TODO: Connect to widget that allows jumping to particular particle
# def selectParticleIndex(self, particleIndex, centerOn=True):
# assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex)
# self.typeSelectorCombo.setCurrentText(assignment)
# particleIndices = self.particleContainer.getIndicesOfParticleType(assignment)
# self.particleSelector.setValue(particleIndices.index(particleIndex)+1)
#
# self.updateToSelectedParticle(resetSpectrumCount=True, centerOn=False)
#TODO: Connect to widget that allows jumping to particular particle
def selectParticleIndex(self, particleIndex, centerOn=True):
self.typeSelectorCombo.currentIndexChanged.disconnect()
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.updateToSelectedParticle)
self.updateToSelectedParticle(resetSpectrumCount=True, centerOn=centerOn)
def displayNewPolymerType(self, resetCurrentIndex=True):
polymerName = self.typeSelectorCombo.currentText()
numParticles = self.particleContainer.getNumberOfParticlesOfAssignment(polymerName)
......
......@@ -238,15 +238,20 @@ class ParticleContainer(object):
newParticle.area = area
newParticle.contour = newContour
self.particles.append(newParticle)
self.removeParticles(particleIndices)
print('removed particles')
self.particles.append(newParticle)
print('added new particle')
self.resetParticleIndices()
print('resetted indices')
def removeParticles(self, indexList):
for index in indexList:
particle = self.getParticleOfIndex(index)
print('removing particle of index', index)
self.particles.remove(particle)
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):
......
......@@ -32,11 +32,11 @@ from PyQt5 import QtWidgets, QtCore
class ParticleContextMenu(QtWidgets.QMenu):
combineParticlesSignal = QtCore.pyqtSignal(list, str)
reassignParticlesSignal = QtCore.pyqtSignal(list, str)
def __init__(self, sampleView):
def __init__(self, viewparent):
super(ParticleContextMenu, self).__init__()
self.sampleView = sampleView
self.selectedParticleIndices = self.sampleView.selectedParticleIndices
self.particleContainer = self.sampleView.dataset.particleContainer
self.viewparent = viewparent
self.selectedParticleIndices = self.viewparent.selectedParticleIndices
self.particleContainer = self.viewparent.dataset.particleContainer
def executeAtScreenPos(self, screenPos):
self.combineActs = []
......@@ -44,7 +44,10 @@ class ParticleContextMenu(QtWidgets.QMenu):
assignments = []
for particleIndex in self.selectedParticleIndices:
assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex)
try:
assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex)
except:
return
assignments.append(assignment)
for assignment in np.unique(assignments):
......@@ -88,12 +91,12 @@ class ParticleContextMenu(QtWidgets.QMenu):
class ParticleEditor(QtCore.QObject):
particleEditProcessStarted = QtCore.pyqtSignal()
particlesEdited = QtCore.pyqtSignal()
def __init__(self, sampleView, particleContainer):
particleContoursChanged = QtCore.pyqtSignal()
particleAssignmentChanged = QtCore.pyqtSignal()
def __init__(self, analysisparent, particleContainer):
super(ParticleEditor, self).__init__()
self.particleContainer = particleContainer
self.sampleView = sampleView #the assigned analysis widget
self.analysisparent = analysisparent #the assigned analysis widget
self.backupFreq = 3 #save a backup every n actions
self.neverBackedUp = True
self.actionCounter = 0
......@@ -101,18 +104,17 @@ class ParticleEditor(QtCore.QObject):
def connectToSignals(self, contextMenu):
contextMenu.combineParticlesSignal.connect(self.combineParticles)
contextMenu.reassignParticlesSignal.connect(self.reassignParticles)
def createSafetyBackup(self):
self.actionCounter += 1
if self.actionCounter == self.backupFreq-1 or self.neverBackedUp:
backupname = self.sampleView.dataset.saveBackup()
backupname = self.analysisparent.dataset.saveBackup()
print('backing up as', backupname)
self.neverBackedUp = False
self.actionCounter = 0
@QtCore.pyqtSlot(list, str)
def combineParticles(self, contourIndices, newAssignment):
self.particleEditProcessStarted.emit()
self.createSafetyBackup()
print(f'Combining particles {contourIndices} into {newAssignment}')
contours = self.particleContainer.getParticleContoursByIndex(contourIndices)
......@@ -120,8 +122,7 @@ class ParticleEditor(QtCore.QObject):
stats = self.characterizeParticle(newContour)
self.particleContainer.mergeParticles(contourIndices, newContour, stats, newAssignment=newAssignment)
self.particlesEdited.emit()
self.particleContoursChanged.emit()
# #save data
# minHQI = self.parent.hqiSpinBox.value()
# compHQI = self.parent.compHqiSpinBox.value()
......@@ -132,13 +133,12 @@ class ParticleEditor(QtCore.QObject):
@QtCore.pyqtSlot(list, str)
def reassignParticles(self, contourindices, newAssignment):
self.particleEditProcessStarted.emit()
self.createSafetyBackup()
print(f'reassigning indices {contourindices} into {newAssignment}')
for partIndex in contourindices:
self.particleContainer.reassignParticleToAssignment(partIndex, newAssignment)
self.particlesEdited.emit()
self.particleAssignmentChanged.emit()
def mergeContours(self, contours):
cnt = np.vstack(tuple(contours)) #combine contous
......@@ -166,7 +166,7 @@ class ParticleEditor(QtCore.QObject):
temp, contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
if len(contours)>1:
QtWidgets.QMessageBox.critical(self.parent, 'ERROR!',
QtWidgets.QMessageBox.critical(self.viewparent, 'ERROR!',
'Particle contours are not connected and cannot be combined!')
return
......@@ -194,7 +194,8 @@ class ParticleEditor(QtCore.QObject):
long, short = short, long
return long, short, longellipse, shortellipse, cv2.contourArea(cnt)
\ No newline at end of file
......@@ -22,6 +22,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
import numpy as np
import os
import cv2
import time
from dataset import DataSet, loadData
from ramancom.ramancontrol import RamanControl, simulatedRaman
......@@ -179,7 +180,6 @@ class SampleView(QtWidgets.QGraphicsView):
self.detectionwidget.close()
self.detectionwidget.destroy()
self.ramanwidget.setVisible(False)
self.resetParticleContours()
self.mode = mode
self.loadPixmap(self.microscopeMode)
if mode == "OpticalScan":
......@@ -231,7 +231,6 @@ class SampleView(QtWidgets.QGraphicsView):
del widget
self.dataset = loadData(fname)
self.resetParticleContours()
self.setupParticleEditor()
self.setMicroscopeMode()
self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else ""))
......@@ -259,14 +258,23 @@ class SampleView(QtWidgets.QGraphicsView):
self.imparent.snapshotAct.setEnabled(True)
def setupParticleEditor(self):
def tryDisconnectingSignal(signal):
try:
signal.disconnect()
except TypeError:
pass
if self.particleEditor is None:
self.particleEditor = ParticleEditor(self, self.dataset.particleContainer)
self.particleEditor.particleEditProcessStarted.connect(self.disableContourSelection)
self.particleEditor.particlesEdited.connect(self.resetParticleContours)
self.particleEditor.particlesEdited.connect(self.enableContourSelection)
if self.analysiswidget is not None:
self.particleEditor.particlesEdited.connect(self.analysiswidget.updateDisplays)
#try disconnecting the signals. If they are connected multiple times, the functions will run accordingly...
tryDisconnectingSignal(self.particleEditor.particleContoursChanged)
tryDisconnectingSignal(self.particleEditor.particleAssignmentChanged)
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)
def setMicroscopeMode(self):
if self.ramanSwitchNeeded:
......@@ -360,6 +368,11 @@ class SampleView(QtWidgets.QGraphicsView):
self.scaleImage(factor)
def checkForContourSelection(self, event):
'''
Iam not yet happy how this selection is handled.
I would prefer having it in the viewitems themselves, but somehow the sampleview has to check
for already selected indices and also check when nothing is hit...
'''
def addContourToSelection(cnt):
cnt.isSelected = True
cnt.update()
......@@ -378,9 +391,11 @@ class SampleView(QtWidgets.QGraphicsView):
if not event.modifiers()==QtCore.Qt.ShiftModifier:
addContourToSelection(cnt)
self.analysiswidget.selectParticleIndex(cnt.particleIndex, centerOn=False)
else:
if cnt.particleIndex not in self.selectedParticleIndices:
addContourToSelection(cnt)
self.analysiswidget.selectParticleIndex(cnt.particleIndex, centerOn=False)
elif cnt.particleIndex in self.selectedParticleIndices:
removeContourFromSelection(cnt)
......@@ -540,16 +555,12 @@ class SampleView(QtWidgets.QGraphicsView):
self.ramanscanitems.append(item)
def resetParticleContours(self):
t0 = time.time()
for cnt in self.contourItems:
self.scene().removeItem(cnt)
self.contourItems = []
if self.dataset is not None:
for particleIndex, contour in enumerate(self.dataset.particleContainer.getParticleContours()):
###
part = self.dataset.particleContainer.getParticleOfIndex(particleIndex)
if part.index != particleIndex:
print('missmatch at countour index and particleIndex', part.index, particleIndex)
###
newCnt = SegmentationContour(self, contour)
newCnt.setIndex(particleIndex)
assignment = self.dataset.particleContainer.getParticleAssignmentByIndex(particleIndex)
......@@ -558,17 +569,8 @@ class SampleView(QtWidgets.QGraphicsView):
self.contourItems.append(newCnt)
self.scene().addItem(newCnt)
self.update()
print('resetted contours:', round((time.time()-t0)*1000))
def disableContourSelection(self):
self.disableSelection = True
# for contourItem in self.contourItems:
# contourItem.setAcceptedMouseButtons(QtCore.Qt.NoButton)
def enableContourSelection(self):
self.disableSelection = False
# for contourItem in self.contourItems:
# contourItem.setAcceptedMouseButtons(QtCore.Qt.AllButtons)
def updateLegend(self, legendItems):
self.imparent.legend.setTextColorItems(legendItems)
......@@ -581,6 +583,8 @@ class SampleView(QtWidgets.QGraphicsView):
def centerOnRamanIndex(self, index, centerOn=True, highlightContour=True):
if centerOn:
self.centerOn(self.ramanscanitems[index])
if highlightContour:
self.highLightRamanIndex(index)
def clearItems(self):
for item in self.fititems:
......
......@@ -82,9 +82,9 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
def contextMenuEvent(self, event):
if self.isSelected:
contextMenu = ParticleContextMenu(self.parent)
self.parent.particleEditor.connectToSignals(contextMenu)
contextMenu.executeAtScreenPos(event.screenPos())
self.contextMenu = ParticleContextMenu(self.parent)
self.parent.particleEditor.connectToSignals(self.contextMenu)
self.contextMenu.executeAtScreenPos(event.screenPos())
#class SegmentationContours(QtWidgets.QGraphicsItem):
# def __init__(self, parent, contours=[], pos=(0,0)):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment