Commit a974f0be authored by JosefBrandt's avatar JosefBrandt

Bugfix in selection

parent fcca6561
...@@ -149,7 +149,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): ...@@ -149,7 +149,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
navigationLayout.addWidget(QtWidgets.QLabel('Select Spectrum')) navigationLayout.addWidget(QtWidgets.QLabel('Select Spectrum'))
navigationLayout.addWidget(self.spectrumSelector) navigationLayout.addWidget(self.spectrumSelector)
navigationLayout.addWidget(self.spectrumNumberLabel) navigationLayout.addWidget(self.spectrumNumberLabel)
# navigationLayout.addStretch()
self.navigationGroup.setLayout(navigationLayout) self.navigationGroup.setLayout(navigationLayout)
...@@ -579,14 +578,12 @@ class ParticleAnalysis(QtWidgets.QMainWindow): ...@@ -579,14 +578,12 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.currentSpectrumIndex = self.specNumberSelector.value()-1 self.currentSpectrumIndex = self.specNumberSelector.value()-1
self.currentParticleIndex = self.particleContainer.getParticleIndexContainingSpecIndex(self.currentSpectrumIndex) self.currentParticleIndex = self.particleContainer.getParticleIndexContainingSpecIndex(self.currentSpectrumIndex)
self.centerOnSpecIndex(self.currentSpectrumIndex) self.centerOnSpecIndex(self.currentSpectrumIndex)
self.highLightContour(self.currentParticleIndex) self.viewparent.highLightContour(self.currentParticleIndex)
self.updateSpecPlot()
def centerOnSpecIndex(self, index): def centerOnSpecIndex(self, index):
self.viewparent.centerOnRamanIndex(index) self.viewparent.centerOnRamanIndex(index)
def highLightContour(self, index):
self.viewparent.highLightContour(index)
def darkenBackground(self): def darkenBackground(self):
self.viewparent.darkenPixmap = self.darkenAct.isChecked() self.viewparent.darkenPixmap = self.darkenAct.isChecked()
......
...@@ -37,7 +37,6 @@ class ExpExcelDialog(QtWidgets.QDialog): ...@@ -37,7 +37,6 @@ class ExpExcelDialog(QtWidgets.QDialog):
self.dataset = dataset self.dataset = dataset
self.particleContainer = particleContainer self.particleContainer = particleContainer
# self.particles = self.datastats.getParticleStats()
self.polymers = self.particleContainer.getListOfParticleAssignments self.polymers = self.particleContainer.getListOfParticleAssignments
# self.additives = self.datastats.currentAdditives # self.additives = self.datastats.currentAdditives
self.hqis = self.particleContainer.getListOfHighestHQIs self.hqis = self.particleContainer.getListOfHighestHQIs
...@@ -62,10 +61,10 @@ class ExpExcelDialog(QtWidgets.QDialog): ...@@ -62,10 +61,10 @@ class ExpExcelDialog(QtWidgets.QDialog):
if option == 'Polymer Type (mandatory)': if option == 'Polymer Type (mandatory)':
self.checkBoxes[-1].setEnabled(False) #is mandatory!!! self.checkBoxes[-1].setEnabled(False) #is mandatory!!!
if option == 'Additives': # if option == 'Additives':
if self.additives is None: # if self.additives is None:
self.checkBoxes[-1].setEnabled(False) # self.checkBoxes[-1].setEnabled(False)
self.checkBoxes[-1].setChecked(False) # self.checkBoxes[-1].setChecked(False)
excelvbox.addWidget(self.checkBoxes[-1]) excelvbox.addWidget(self.checkBoxes[-1])
......
...@@ -18,21 +18,13 @@ You should have received a copy of the GNU General Public License ...@@ -18,21 +18,13 @@ You should have received a copy of the GNU General Public License
along with this program, see COPYING. along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>. If not, see <https://www.gnu.org/licenses/>.
""" """
#import os
import numpy as np import numpy as np
import operator import operator
#from PyQt5 import QtWidgets, QtCore
#try:
# from dataset import loadData, recursiveDictCompare
# print('exported dataset methods from datastats')
#except:
# print('failed exported dataset methods from datastats')
class ParticleContainer(object): class ParticleContainer(object):
def __init__(self, parent): def __init__(self, datasetParent):
super(ParticleContainer, self).__init__() super(ParticleContainer, self).__init__()
self.parent = parent self.datasetParent = datasetParent
self.particles = [] self.particles = []
self.spectra = None self.spectra = None
self.inconsistentParticles = [] self.inconsistentParticles = []
...@@ -223,7 +215,7 @@ class ParticleContainer(object): ...@@ -223,7 +215,7 @@ class ParticleContainer(object):
final_typehistogram = {i[0]: i[1] for i in sorted_typehistogram} final_typehistogram = {i[0]: i[1] for i in sorted_typehistogram}
return final_typehistogram return final_typehistogram
def mergeParticles(self, particleIndices, newContour, newStats, newAssignment=None): def addMergedParticle(self, particleIndices, newContour, newStats, newAssignment=None):
newParticle = Particle() newParticle = Particle()
#copy Measurements #copy Measurements
for index in particleIndices: for index in particleIndices:
...@@ -243,22 +235,16 @@ class ParticleContainer(object): ...@@ -243,22 +235,16 @@ class ParticleContainer(object):
newParticle.area = area newParticle.area = area
newParticle.contour = newContour newParticle.contour = newContour
self.removeParticles(particleIndices)
print('removed particles')
self.particles.append(newParticle) self.particles.append(newParticle)
print('added new particle') print('added new particle')
self.resetParticleIndices()
print('resetted indices')
def removeParticles(self, indexList): def removeParticle(self, index):
for index in sorted(indexList, reverse=True): particle = self.getParticleOfIndex(index) #just for asserting to have the correct particle!
particle = self.getParticleOfIndex(index) #just for asserting to have the correct particle! del self.particles[index]
del self.particles[index]
def resetParticleIndices(self): def resetParticleIndices(self):
for newIndex, particle in enumerate(self.particles): for newIndex, particle in enumerate(self.particles):
particle.index = newIndex particle.index = newIndex
class Particle(object): class Particle(object):
def __init__(self): def __init__(self):
...@@ -271,6 +257,7 @@ class Particle(object): ...@@ -271,6 +257,7 @@ class Particle(object):
self.area = None self.area = None
self.contour = None self.contour = None
self.measurements = [] self.measurements = []
self.viewItem = None
def addExistingMeasurement(self, meas): def addExistingMeasurement(self, meas):
self.measurements.append(meas) self.measurements.append(meas)
...@@ -362,6 +349,9 @@ class Particle(object): ...@@ -362,6 +349,9 @@ class Particle(object):
for measurement in self.measurements: for measurement in self.measurements:
measurement.applyHQIThreshold(minHQI) measurement.applyHQIThreshold(minHQI)
# def recreateViewItem(self):
# pass
class Measurement(object): class Measurement(object):
def __init__(self): def __init__(self):
......
...@@ -29,7 +29,27 @@ import numpy as np ...@@ -29,7 +29,27 @@ import numpy as np
import cv2 import cv2
from PyQt5 import QtWidgets, QtCore from PyQt5 import QtWidgets, QtCore
from analysis.particlePainter import ParticlePainter from .particlePainter import ParticlePainter
def getContourStatsWithPixelScale(contours, pixelscale):
##characterize particle
longellipse, shortellipse = np.nan, np.nan
cnt = contours
if cnt.shape[0] >= 5: ##at least 5 points required for ellipse fitting...
ellipse = cv2.fitEllipse(cnt)
shortellipse, longellipse = ellipse[1]
rect = cv2.minAreaRect(cnt)
long, short = rect[1]
if short>long:
long, short = short, long
area = cv2.contourArea(cnt)
return long*pixelscale, short*pixelscale, longellipse*pixelscale, shortellipse*pixelscale, area*pixelscale**2
class ParticleContextMenu(QtWidgets.QMenu): class ParticleContextMenu(QtWidgets.QMenu):
combineParticlesSignal = QtCore.pyqtSignal(list, str) combineParticlesSignal = QtCore.pyqtSignal(list, str)
...@@ -110,7 +130,6 @@ class ParticleContextMenu(QtWidgets.QMenu): ...@@ -110,7 +130,6 @@ class ParticleContextMenu(QtWidgets.QMenu):
class ParticleEditor(QtCore.QObject): class ParticleEditor(QtCore.QObject):
# particleContoursChanged = QtCore.pyqtSignal()
particleAssignmentChanged = QtCore.pyqtSignal() particleAssignmentChanged = QtCore.pyqtSignal()
def __init__(self, viewparent, particleContainer): def __init__(self, viewparent, particleContainer):
super(ParticleEditor, self).__init__() super(ParticleEditor, self).__init__()
...@@ -142,19 +161,15 @@ class ParticleEditor(QtCore.QObject): ...@@ -142,19 +161,15 @@ class ParticleEditor(QtCore.QObject):
self.createSafetyBackup() self.createSafetyBackup()
print(f'Combining particles {contourIndices} into {newAssignment}') print(f'Combining particles {contourIndices} into {newAssignment}')
contours = self.particleContainer.getParticleContoursByIndex(contourIndices) contours = self.particleContainer.getParticleContoursByIndex(contourIndices)
newContour = self.mergeContours(contours.copy()) try:
newContour = self.mergeContours(contours.copy())
except NotConnectedContoursError:
return
pixelscale = self.viewparent.dataset.getPixelScale() pixelscale = self.viewparent.dataset.getPixelScale()
stats = self.characterizeParticle(newContour, pixelscale) stats = getContourStatsWithPixelScale(newContour, pixelscale)
self.particleContainer.mergeParticles(contourIndices, newContour, stats, newAssignment=newAssignment) self.mergeParticlesInParticleContainerAndSampleView(contourIndices,newContour, stats, newAssignment)
for ind in contourIndices:
self.viewparent.removeParticleContour(ind)
self.viewparent.resetContourIndices()
self.viewparent.addParticleContour(newContour, len(self.viewparent.contourItems))
self.particleAssignmentChanged.emit()
#TODO: INCLUDE SANITY CHECK!!!!!!!!!
@QtCore.pyqtSlot(list, str) @QtCore.pyqtSlot(list, str)
def reassignParticles(self, contourindices, newAssignment): def reassignParticles(self, contourindices, newAssignment):
...@@ -167,7 +182,8 @@ class ParticleEditor(QtCore.QObject): ...@@ -167,7 +182,8 @@ class ParticleEditor(QtCore.QObject):
@QtCore.pyqtSlot(list, str) @QtCore.pyqtSlot(list, str)
def paintParticles(self, contourIndices, newAssignment): def paintParticles(self, contourIndices, newAssignment):
self.createSafetyBackup print(f'painting indices {contourIndices} into {newAssignment}')
self.createSafetyBackup()
self.storedIndices = contourIndices self.storedIndices = contourIndices
self.storedAssignmend = newAssignment self.storedAssignmend = newAssignment
contours = self.particleContainer.getParticleContoursByIndex(contourIndices) contours = self.particleContainer.getParticleContoursByIndex(contourIndices)
...@@ -178,19 +194,19 @@ class ParticleEditor(QtCore.QObject): ...@@ -178,19 +194,19 @@ class ParticleEditor(QtCore.QObject):
self.viewparent.update() self.viewparent.update()
def acceptPaintedResult(self): def acceptPaintedResult(self):
newContour = self.mergeContours(self.particlePainter.contours.copy()) try:
pixelscale = self.viewparent.dataset.getPixelScale() newContour = self.mergeContours(self.particlePainter.contours.copy())
stats = self.characterizeParticle(newContour, pixelscale) except NotConnectedContoursError:
self.storedIndices = []
self.storedAssignmend = None
self.destroyParticlePainter()
return
self.particleContainer.mergeParticles(self.storedIndices, newContour, stats, newAssignment=self.storedAssignmend) pixelscale = self.viewparent.dataset.getPixelScale()
for ind in self.storedIndices: stats = getContourStatsWithPixelScale(newContour, pixelscale)
self.viewparent.removeParticleContour(ind)
self.particleAssignmentChanged.emit() self.mergeParticlesInParticleContainerAndSampleView(self.storedIndices, newContour, stats, self.storedAssignmend)
self.viewparent.resetContourIndices()
self.viewparent.addParticleContour(newContour, len(self.viewparent.contourItems))
#TODO: INCLUDE SANITY CHECK!!!!!!!!!
self.storedIndices = [] self.storedIndices = []
self.storedAssignmend = None self.storedAssignmend = None
self.destroyParticlePainter() self.destroyParticlePainter()
...@@ -230,7 +246,7 @@ class ParticleEditor(QtCore.QObject): ...@@ -230,7 +246,7 @@ class ParticleEditor(QtCore.QObject):
if len(contours)>1: if len(contours)>1:
QtWidgets.QMessageBox.critical(self.viewparent, 'ERROR!', QtWidgets.QMessageBox.critical(self.viewparent, 'ERROR!',
'Particle contours are not connected and cannot be combined!') 'Particle contours are not connected and cannot be combined!')
return raise NotConnectedContoursError
newContour = contours[0] newContour = contours[0]
for i in range(len(newContour)): for i in range(len(newContour)):
...@@ -238,26 +254,20 @@ class ParticleEditor(QtCore.QObject): ...@@ -238,26 +254,20 @@ class ParticleEditor(QtCore.QObject):
newContour[i][0][1] += ymin-padding newContour[i][0][1] += ymin-padding
return newContour return newContour
def mergeParticlesInParticleContainerAndSampleView(self, indices, newContour, stats, assignment):
self.viewparent.addParticleContourToIndex(newContour, len(self.viewparent.contourItems)-1)
self.particleContainer.addMergedParticle(indices, newContour, stats, newAssignment=assignment)
def characterizeParticle(self, contours, pixelscale): for ind in sorted(indices, reverse=True):
##characterize particle self.viewparent.removeParticleContour(ind)
longellipse, shortellipse = np.nan, np.nan self.particleContainer.removeParticle(ind)
cnt = contours
if cnt.shape[0] >= 5: ##at least 5 points required for ellipse fitting...
ellipse = cv2.fitEllipse(cnt)
shortellipse, longellipse = ellipse[1]
rect = cv2.minAreaRect(cnt)
long, short = rect[1]
if short>long:
long, short = short, long
area = cv2.contourArea(cnt) self.viewparent.resetContourIndices()
self.particleContainer.resetParticleIndices()
self.particleAssignmentChanged.emit()
#TODO: INCLUDE SANITY CHECK!!!!!!!!!
return long*pixelscale, short*pixelscale, longellipse*pixelscale, shortellipse*pixelscale, area*pixelscale**2
@QtCore.pyqtSlot(list) @QtCore.pyqtSlot(list)
def deleteParticles(self, contourIndices): def deleteParticles(self, contourIndices):
reply = QtWidgets.QMessageBox.question(self, f'About to delete {len(contourIndices)} particles.', reply = QtWidgets.QMessageBox.question(self, f'About to delete {len(contourIndices)} particles.',
...@@ -272,6 +282,9 @@ class ParticleEditor(QtCore.QObject): ...@@ -272,6 +282,9 @@ class ParticleEditor(QtCore.QObject):
self.viewparent.dataset.particleContainer.resetParticleIndices() self.viewparent.dataset.particleContainer.resetParticleIndices()
self.viewparent.resetContourIndices() self.viewparent.resetContourIndices()
self.viewparent.analysiswidget.updateHistogramsAndContours() self.viewparent.analysiswidget.updateHistogramsAndContours()
class NotConnectedContoursError(Exception):
pass
\ No newline at end of file
...@@ -422,10 +422,12 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -422,10 +422,12 @@ class SampleView(QtWidgets.QGraphicsView):
removeContourFromSelection(cnt) removeContourFromSelection(cnt)
else: #not clicked on particle else: #not clicked on particle
if event.modifiers()!=QtCore.Qt.ShiftModifier:
if event.modifiers()!=QtCore.Qt.ShiftModifier and cnt.particleIndex in self.selectedParticleIndices: cnt.isSelected = False
removeContourFromSelection(cnt) cnt.update()
if cnt.particleIndex in self.selectedParticleIndices:
self.selectedParticleIndices.remove(cnt.particleIndex)
self.update() self.update()
def scaleImage(self, factor): def scaleImage(self, factor):
...@@ -584,11 +586,11 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -584,11 +586,11 @@ class SampleView(QtWidgets.QGraphicsView):
self.contourItems = [] self.contourItems = []
if self.dataset is not None: if self.dataset is not None:
for particleIndex, contour in enumerate(self.dataset.particleContainer.getParticleContours()): for particleIndex, contour in enumerate(self.dataset.particleContainer.getParticleContours()):
self.addParticleContour(contour, particleIndex) self.addParticleContourToIndex(contour, particleIndex)
self.update() self.update()
print('resetted contours: {} ms'.format(round((time.time()-t0)*1000))) print('resetted contours: {} ms'.format(round((time.time()-t0)*1000)))
def addParticleContour(self, contour, index): def addParticleContourToIndex(self, contour, index):
newCnt = SegmentationContour(self, contour) newCnt = SegmentationContour(self, contour)
newCnt.setIndex(index) newCnt.setIndex(index)
assignment = self.dataset.particleContainer.getParticleAssignmentByIndex(index) assignment = self.dataset.particleContainer.getParticleAssignmentByIndex(index)
...@@ -616,10 +618,10 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -616,10 +618,10 @@ class SampleView(QtWidgets.QGraphicsView):
self.ramanscanitems[index].setHighLight(True) self.ramanscanitems[index].setHighLight(True)
def highLightContour(self, index): def highLightContour(self, index):
print('highlighting contour', index)
for contour in self.contourItems: for contour in self.contourItems:
contour.isSelected = False contour.isSelected = False
self.contourItems[index].isSelected = True self.contourItems[index].isSelected = True
self.selectedParticleIndices =[index]
def centerOnRamanIndex(self, index, centerOn=True, highlightIndex=True): def centerOnRamanIndex(self, index, centerOn=True, highlightIndex=True):
if centerOn: if centerOn:
......
...@@ -23,9 +23,9 @@ from PyQt5 import QtCore, QtWidgets, QtGui ...@@ -23,9 +23,9 @@ from PyQt5 import QtCore, QtWidgets, QtGui
from analysis.particleeditor import ParticleContextMenu from analysis.particleeditor import ParticleContextMenu
class SegmentationContour(QtWidgets.QGraphicsItem): class SegmentationContour(QtWidgets.QGraphicsItem):
def __init__(self, parent, contourData, pos=(0,0)): def __init__(self, viewparent, contourData, pos=(0,0)):
super().__init__() super().__init__()
self.parent = parent self.viewparent = viewparent
self.setZValue(1) self.setZValue(1)
self.setPos(pos[0], pos[1]) self.setPos(pos[0], pos[1])
self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable) self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable)
...@@ -56,6 +56,9 @@ class SegmentationContour(QtWidgets.QGraphicsItem): ...@@ -56,6 +56,9 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
def boundingRect(self): def boundingRect(self):
return self.brect return self.brect
# def createRamanScanIndices(self):
def setIndex(self, index): def setIndex(self, index):
self.particleIndex = index self.particleIndex = index
...@@ -89,8 +92,8 @@ class SegmentationContour(QtWidgets.QGraphicsItem): ...@@ -89,8 +92,8 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
def contextMenuEvent(self, event): def contextMenuEvent(self, event):
if self.isSelected: if self.isSelected:
self.contextMenu = ParticleContextMenu(self.parent) self.contextMenu = ParticleContextMenu(self.viewparent)
self.parent.particleEditor.connectToSignals(self.contextMenu) self.viewparent.particleEditor.connectToSignals(self.contextMenu)
self.contextMenu.executeAtScreenPos(event.screenPos()) self.contextMenu.executeAtScreenPos(event.screenPos())
......
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