...
 
Commits (6)
......@@ -113,11 +113,18 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.navigationGroup = QtWidgets.QGroupBox('Navigate through polymers')
self.navigationGroup.setDisabled(True)
navigationLayout = QtWidgets.QHBoxLayout()
self.specNumberSelector = QtWidgets.QSpinBox()
self.specNumberSelector.setMinimumWidth(150)
self.specNumberSelector.setMinimum(1)
self.specNumberSelector.setMaximum(1E6)
self.jumpToSpecBtn = QtWidgets.QPushButton('Jump To Spectrum of Number:')
self.jumpToSpecBtn.released.connect(self.jumpToSpectrumOfNumber)
self.typeSelectorCombo = QtWidgets.QComboBox()
self.typeSelectorCombo.currentIndexChanged.connect(self.displayNewPolymerType)
self.typeSelectorCombo.setMinimumWidth(150)
self.particleSelector = QtWidgets.QSpinBox()
self.particleSelector.valueChanged.connect(self.updateToSelectedParticle)
self.particleSelector.valueChanged.connect(self.updateSpecPlotToSelectedParticle)
self.particleNumberLabel = QtWidgets.QLabel('of xx particles; ')
self.spectrumSelector = QtWidgets.QSpinBox()
......@@ -128,6 +135,8 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
spinbox.setSingleStep(1)
spinbox.setValue(1)
navigationLayout.addWidget(self.jumpToSpecBtn)
navigationLayout.addWidget(self.specNumberSelector)
navigationLayout.addWidget(QtWidgets.QLabel('Select Polymer Type:'))
navigationLayout.addWidget(self.typeSelectorCombo)
navigationLayout.addStretch()
......@@ -214,7 +223,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.updateDisplays()
self.initializeSpecPlot()
self.displayNewPolymerType()
self.updateToSelectedParticle()
self.updateSpecPlotToSelectedParticle()
# self.createPolymerOverlay()
def createActions(self):
......@@ -229,7 +238,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.fullOverlayAct = QtWidgets.QAction("&Full Overlay", self)
self.transpAct = QtWidgets.QAction("&Transparent Overlay", self)
self.transpAct.triggered.connect(self.updateContours)
self.transpAct.triggered.connect(self.updateContourColors)
self.hideLabelAct = QtWidgets.QAction('&Hide Polymer Numbers', self)
self.hideLabelAct.triggered.connect(self.show_hide_labels)
......@@ -262,7 +271,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.dispMenu = QtWidgets.QMenu("&Display", self)
self.overlayActGroup = QtWidgets.QActionGroup(self.dispMenu)
self.overlayActGroup.setExclusive(True)
self.overlayActGroup.triggered.connect(self.updateContours)
self.overlayActGroup.triggered.connect(self.updateContourColors)
self.overlayActGroup.triggered.connect(self.updateDisplays)
for act in [self.noOverlayAct, self.selOverlayAct, self.fullOverlayAct]:
......@@ -385,20 +394,22 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
# else:
# print('displaying new type with resetting index')
# self.displayNewPolymerType()
def updateDisplays(self):
self.createHistogramData()
t0 = time.time()
self.updateTypeHistogram()
print('update type hist:', round((time.time()-t0)*1000))
print('update type hist: {} ms'.format(round((time.time()-t0)*1000)))
t0 = time.time()
self.updateSizeHistogram()
print('update size hist:', round((time.time()-t0)*1000))
print('update size hist: {} ms'.format(round((time.time()-t0)*1000)))
t0 = time.time()
self.updateContours()
print('update contours:', round((time.time()-t0)*1000))
self.updateContourColors()
print('update contours: {} ms'.format(round((time.time()-t0)*1000)))
t0 = time.time()
self.updateLegend()
print('update legend:', round((time.time()-t0)*1000))
print('update legend: {} ms'.format(round((time.time()-t0)*1000)))
self.dataset.save()
def initializeSpecPlot(self):
self.specPlot.loadSpectraAndInitializeSpecPlot()
......@@ -470,9 +481,9 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
ref = self.dbWin.activeDatabase.spectra[refID]
self.specPlot.updateReferenceSpectrum(ref[:, 0], ref[:, 1])
def updateContours(self):
def updateContourColors(self):
contours = self.parent.contourItems
alpha = (128 if self.transpAct.isChecked() else 255)
alpha = (64 if self.transpAct.isChecked() else 255)
selectedPolymers = self.getSelectedPolymers()
for particleIndex, contour in enumerate(contours):
......@@ -499,17 +510,33 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
def getSelectedPolymers(self):
return [checkbox.text() for checkbox in self.polymerCheckBoxes if checkbox.isChecked()]
def jumpToSpectrumOfNumber(self):
specIndex = self.specNumberSelector.value()-1
assert specIndex is not None
partIndex = self.particleContainer.getParticleIndexContainingSpecIndex(specIndex)
assignment = self.particleContainer.getParticleAssignmentByIndex(partIndex)
self.typeSelectorCombo.setCurrentText(assignment)
@QtCore.pyqtSlot(int)
def selectParticleIndex(self, particleIndex, centerOn=True):
partIndices = self.particleContainer.getIndicesOfParticleType(assignment)
self.particleSelector.setValue(partIndices.index(partIndex)+1)
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)
self.updateToSelectedParticle(resetSpectrumCount=True, centerOn=False)
self.updateSpecPlotToSelectedParticle(resetSpectrumCount=True, centerOn=centerOn)
def displayNewPolymerType(self, resetCurrentIndex=True):
polymerName = self.typeSelectorCombo.currentText()
numParticles = self.particleContainer.getNumberOfParticlesOfAssignment(polymerName)
......@@ -520,11 +547,13 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.spectrumSelector.setValue(1)
self.currentParticleIndex = self.getParticleIndexFromParticleSelector()
self.spectrumSelector.setMaximum(self.particleContainer.getNumberOfSpectraOfParticle(self.currentParticleIndex))
numSpectra = self.particleContainer.getNumberOfSpectraOfParticle(self.currentParticleIndex)
self.spectrumSelector.setMaximum(numSpectra)
self.spectrumNumberLabel.setText(f'of {numSpectra} Spectra')
self.currentSpectrumIndex = self.getSpectrumIndexFromSpectrumSelector()
self.updateSpecPlot(centerOn=False)
def updateToSelectedParticle(self, resetSpectrumCount=True, centerOn=True):
def updateSpecPlotToSelectedParticle(self, resetSpectrumCount=True, centerOn=True):
polymerName = self.typeSelectorCombo.currentText()
if polymerName != '':
self.currentParticleIndex = self.getParticleIndexFromParticleSelector()
......
......@@ -38,13 +38,15 @@ class ParticleContainer(object):
self.inconsistentParticles = []
self.typeHistogram = None
def initializeParticles(self, numParticles):
self.particles = []
for i in range(numParticles):
self.particles.append(Particle(i))
newParticle = Particle()
newParticle.index = i
self.particles.append(newParticle)
def setParticlecontours(self, contours):
def setParticleContours(self, contours):
assert len(self.particles) == len(contours)
for index, particle in enumerate(self.particles):
particle.contour = contours[index]
......@@ -94,7 +96,7 @@ class ParticleContainer(object):
meas.setAssignment(assignmentList[scanIndex])
indicesOfTransferredAssignments[scanIndex] = scanIndex
assert not None in indicesOfTransferredAssignments
def applyHQIListToParticleMeasurements(self, hqiList):
'''HQI-List is list of spectra hqis in order of spectra indices'''
indicesOfTransferredHQIs = [None]*len(hqiList)
......@@ -105,11 +107,20 @@ class ParticleContainer(object):
indicesOfTransferredHQIs[scanIndex] = scanIndex
assert not None in indicesOfTransferredHQIs
def reassignParticleToAssignment(self, particleIndex, newAssignment):
particle = self.getParticleOfIndex(particleIndex)
particle.setAllSpectraToNewAssignment(newAssignment)
def getParticleOfIndex(self, index):
particle = self.particles[index]
assert particle.index == index, f'particle.index ({particle.index}) does match requested index in particleList ({index})'
return particle
def getParticleIndexContainingSpecIndex(self, index):
for particle in self.particles:
if index in particle.getMeasurementIndices():
return particle.index
def getNumberOfParticles(self):
return len(self.particles)
......@@ -208,14 +219,54 @@ class ParticleContainer(object):
typehistogram[assignment] += 1
##sort typehistogram, it will be converted into a list!!
sorted_typehistogram = sorted(typehistogram.items(), key = operator.itemgetter(1), reverse = True)
#convert back to dict
#convert back to dsetParticlecontoursict
final_typehistogram = {i[0]: i[1] for i in sorted_typehistogram}
return final_typehistogram
def mergeParticles(self, particleIndices, newContour, newStats, newAssignment=None):
newParticle = Particle()
#copy Measurements
for index in particleIndices:
particle = self.getParticleOfIndex(index)
for meas in particle.getMeasurements():
if newAssignment is not None:
meas.setAssignment(newAssignment)
meas.setHQI(100)
newParticle.addExistingMeasurement(meas)
#set Particle Stats
long, short, longellipse, shortellipse, area = newStats
newParticle.longSize_box = long
newParticle.shortSize_box = short
newParticle.longSize_ellipse = longellipse
newParticle.shortSize_ellipse = shortellipse
newParticle.area = area
newParticle.contour = newContour
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 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):
particle.index = newIndex
class Particle(object):
def __init__(self, index):
self.index = index
def __init__(self):
super(Particle, self).__init__()
self.index = None
self.longSize_ellipse = np.nan
self.shortSize_ellipse = np.nan
self.longSize_box = np.nan
......@@ -223,7 +274,10 @@ class Particle(object):
self.area = None
self.contour = None
self.measurements = []
def addExistingMeasurement(self, meas):
self.measurements.append(meas)
def addEmptyMeasurement(self):
self.measurements.append(Measurement())
indexOfNewMeasurment = len(self.measurements)-1
......@@ -236,6 +290,11 @@ class Particle(object):
self.measurements[indexOfMeasurment].pixelcoord_x= x
self.measurements[indexOfMeasurment].pixelcoord_y = y
def setAllSpectraToNewAssignment(self, newAssignment):
for meas in self.measurements:
meas.setAssignment(newAssignment)
meas.setHQI(100)
def getParticleAssignment(self):
return self.getMeasAssignmentWithHighestHQI() #probably another method could be more suitable...
......@@ -309,6 +368,7 @@ class Particle(object):
class Measurement(object):
def __init__(self):
super(Measurement, self).__init__()
self.ramanScanIndex = None
self.pixelcoord_x= None
self.pixelcoord_y = None
......@@ -319,17 +379,18 @@ class Measurement(object):
def setAssignment(self, assignment):
self.assignment_orig = assignment
self.assignment_afterHQI = 'unknown'
self.applyHQIThreshold()
def setHQI(self, hqi):
self.hqi = hqi
self.applyHQIThreshold()
def applyHQIThreshold(self, minHQI=0):
if self.hqi >= minHQI:
self.assignment_afterHQI = self.assignment_orig
else:
self.assignment_afterHQI = 'unknown'
if self.hqi is not None: #i.e. skip for initial setup, when hqi is not yet aplied...
if self.hqi >= minHQI:
self.assignment_afterHQI = self.assignment_orig
else:
self.assignment_afterHQI = 'unknown'
def getHQI(self):
return self.hqi
......
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
GEPARD - Gepard-Enabled PARticle Detection
Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für
Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de>
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 <https://www.gnu.org/licenses/>.
"""
from PyQt5 import QtWidgets, QtCore, QtGui
import numpy as np
import cv2
class ParticlePainter(QtWidgets.QGraphicsItem):
def __init__(self, editorParent, contours, pos=(500,500)):
super(ParticlePainter, self).__init__()
self.editorParent = editorParent
self.viewparent = self.editorParent.viewparent
self.setZValue(5)
self.polygons = None
self.contours = contours
self.mousePos = None
self.minRadius = 10
self.maxRadius = 500
self.radius = 50
self.brect = QtCore.QRectF(0,0,1,1)
self.getBrectAndPolygon()
self.painting = False
self.erasing = False
def getBrectAndPolygon(self):
polygons = []
x0 = None
for c in self.contours:
polygon = QtGui.QPolygonF()
if x0 is None:
x0 = c[:,0,0].min()
x1 = c[:,0,0].max()
y0 = c[:,0,1].min()
y1 = c[:,0,1].max()
else:
x0 = min(x0, c[:,0,0].min())
x1 = max(x1, c[:,0,0].max())
y0 = min(y0, c[:,0,1].min())
y1 = max(y1, c[:,0,1].max())
for ci in c:
polygon.append(QtCore.QPointF(ci[0,0],ci[0,1]))
polygons.append(polygon)
if x0 is None:
self.brect = QtCore.QRectF(0,0,1,1)
else:
self.brect.setCoords(x0,y0,x1,y1)
self.polygons = polygons
def boundingRect(self):
return self.brect
def mousePressEvent(self, event):
self.mousePos = self.viewparent.mapToScene(event.pos())
self.erasing = self.painting = False
if event.modifiers()==QtCore.Qt.ControlModifier:
self.painting = True
elif event.modifiers()==QtCore.Qt.ShiftModifier:
self.erasing = True
if self.painting or self.erasing:
drawPos = self.viewparent.mapToScene(event.pos()) - self.brect.topLeft()
self.drawParticle(drawPos)
def mouseMoveEvent(self, event):
self.mousePos = self.viewparent.mapToScene(event.pos())
self.update()
if self.painting or self.erasing:
drawPos = self.viewparent.mapToScene(event.pos()) - self.brect.topLeft()
self.drawParticle(drawPos)
def wheelEvent(self, event):
if event.angleDelta().y() < 0:
self.radius = int(np.clip(self.radius+self.radius*0.1, self.minRadius, self.maxRadius))
else:
self.radius = int(np.clip(self.radius-self.radius*0.1, self.minRadius, self.maxRadius))
self.update()
def mouseReleaseEvent(self, event):
self.erasing = self.painting = False
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape:
self.editorParent.destroyParticlePainter()
elif event.key() == QtCore.Qt.Key_Return:
self.editorParent.acceptPaintedResult()
def drawParticle(self, pos):
img, xmin, ymin, padding = self.contoursToImg(self.contours)
center = (int(pos.x()+self.radius), int(pos.y()+self.radius))
if self.painting:
cv2.circle(img, center, self.radius, 255, -1)
elif self.erasing:
cv2.circle(img, center, self.radius, 0, -1)
img = np.uint8(img)
self.contours = self.imgToCnt(img, xmin, ymin, padding)
self.getBrectAndPolygon()
self.update()
def contoursToImg(self, contours):
cnt = np.vstack(tuple(contours)) #combine contous
#draw contours
xmin, xmax = cnt[:,0,:][:, 0].min(), cnt[:,0,:][:, 0].max()
ymin, ymax = cnt[:,0,:][:, 1].min(), cnt[:,0,:][:, 1].max()
padding = self.radius+2 #pixel in each direction
rangex = int(np.round((xmax-xmin)+2*padding))
rangey = int(np.round((ymax-ymin)+2*padding))
img = np.zeros((rangey, rangex), dtype = np.uint8)
for curCnt in contours:
for i in range(len(curCnt)):
curCnt[i][0][0] -= xmin-padding
curCnt[i][0][1] -= ymin-padding
cv2.drawContours(img, [curCnt], -1, 255, -1)
cv2.drawContours(img, [curCnt], -1, 255, 1)
return img, xmin, ymin, padding
def imgToCnt(self, img, xmin, ymin, padding):
if cv2.__version__ > '3.5':
contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
else:
temp, contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
for contour in contours:
for i in range(len(contour)):
contour[i][0][0] += xmin-padding
contour[i][0][1] += ymin-padding
return contours
def paint(self, painter, option, widget):
painter.setPen(QtCore.Qt.white)
painter.drawRect(self.brect)
if self.mousePos is not None:
p = [self.mousePos.x(), self.mousePos.y(), self.radius]
painter.drawEllipse(p[0]-p[2], p[1]-p[2], 2*p[2], 2*p[2])
if self.polygons is not None:
for poly in self.polygons:
painter.setBrush(QtGui.QColor(200, 200, 255, 128))
painter.drawPolygon(poly)
\ No newline at end of file
This diff is collapsed.
......@@ -257,7 +257,7 @@ class DataSet(object):
self.particleContainer.initializeParticles(len(self.particlestats))
self.particleContainer.setParticlecontours(self.particlecontours)
self.particleContainer.setParticleContours(self.particlecontours)
self.particleContainer.setParticleStats(self.particlestats)
self.particleContainer.applyPixelScaleToParticleStats(self.getPixelScale())
if hasattr(self, 'particles2spectra'):
......
......@@ -208,10 +208,6 @@ class ImageView(QtWidgets.QLabel):
self.overlay = None
def updateSeedPoints(self, seedpoints=[], seeddeletepoints=[]):
# if len(seedpoints) > 0 and len(self.seedpoints) > 0:
# print(seedpoints[0, :], self.seedpoints[0, :])
# else:
# print('else...', len(seedpoints), len(self.seedpoints))
self.seedpoints = seedpoints
self.seeddeletepoints = seeddeletepoints
......@@ -664,7 +660,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
particleContainer = self.dataset.particleContainer
particleContainer.initializeParticles(numParticles)
particleContainer.setParticlecontours(contours)
particleContainer.setParticleContours(contours)
particleContainer.setParticleStats(particlestats)
particleContainer.applyPixelScaleToParticleStats(self.dataset.getPixelScale())
......
This diff is collapsed.
......@@ -18,23 +18,18 @@ You should have received a copy of the GNU General Public License
along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
import numpy as np
#import numpy as np
from PyQt5 import QtCore, QtWidgets, QtGui
class ContourSignalEmitter(QtCore.QObject):
contourSelected = QtCore.pyqtSignal(int)
def __init__(self):
super(ContourSignalEmitter, self).__init__()
from analysis.particleeditor import ParticleContextMenu
class SegmentationContour(QtWidgets.QGraphicsItem):
def __init__(self, parent, contourData, pos=(0,0)):
super().__init__()
self.parent = parent
self.signalEmitter = ContourSignalEmitter()
self.setZValue(1)
self.setPos(pos[0], pos[1])
self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable)
self.setAcceptedMouseButtons(QtCore.Qt.AllButtons)
# self.setAcceptedMouseButtons(QtCore.Qt.AllButtons)
self.brect = QtCore.QRectF(0,0,1,1)
self.contourData = contourData
......@@ -45,10 +40,7 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
self.particleIndex = None
self.isSelected = False
self.getBrectAndPolygon()
def connectContourSelectedSignalTo(self, targetMethod):
self.signalEmitter.contourSelected.connect(targetMethod)
def getBrectAndPolygon(self):
polygon = QtGui.QPolygonF()
x0 = self.contourData[:,0,0].min()
......@@ -72,14 +64,8 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
def setHidden(self, hidden):
self.hidden = hidden
def mousePressEvent(self, event):
if event.button()==QtCore.Qt.LeftButton:
print('selected particle index', self.particleIndex)
self.isSelected = True
self.signalEmitter.contourSelected.emit(self.particleIndex)
def paint(self, painter, option, widget):
def paint(self, painter, option, widget):
if self.polygon is not None and not self.hidden:
painter.setPen(QtCore.Qt.green)
if self.isSelected:
......@@ -93,144 +79,20 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
painter.setBrush(self.color)
painter.drawPolygon(self.polygon)
class SegmentationContours(QtWidgets.QGraphicsItem):
def __init__(self, parent, contours=[], pos=(0,0)):
super().__init__()
self.parent = parent
self.setPos(pos[0], pos[1])
self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable)
self.setAcceptedMouseButtons(QtCore.Qt.AllButtons)
self.brect = QtCore.QRectF(0,0,1,1)
self.resetContours(contours)
self.colorList = []
self.selectedContours = []
def boundingRect(self):
return self.brect
def resetContours(self, contours=[]):
cp = []
x0 = None
for c in contours:
polygon = QtGui.QPolygonF()
if x0 is None:
x0 = c[:,0,0].min()
x1 = c[:,0,0].max()
y0 = c[:,0,1].min()
y1 = c[:,0,1].max()
else:
x0 = min(x0, c[:,0,0].min())
x1 = max(x1, c[:,0,0].max())
y0 = min(y0, c[:,0,1].min())
y1 = max(y1, c[:,0,1].max())
for ci in c:
polygon.append(QtCore.QPointF(ci[0,0],ci[0,1]))
cp.append(polygon)
if x0 is None:
self.brect = QtCore.QRectF(0,0,1,1)
else:
self.brect.setCoords(x0,y0,x1,y1)
self.contours = cp
self.update()
def paint(self, painter, option, widget):
painter.setPen(QtCore.Qt.green)
lenColorList = len(self.colorList)
if self.parent.analysiswidget is not None:
nonePaintMode = self.parent.analysiswidget.noOverlayAct.isChecked()
else:
nonePaintMode = False
for index, c in enumerate(self.contours):
if index not in self.selectedContours:
if lenColorList > 0:
color = self.colorList[index]
painter.setPen(QtGui.QColor(int(color.red()*0.7), int(color.green()*0.7), int(color.blue()*0.7), color.alpha()))
else:
color = QtCore.Qt.green
painter.setPen(color)
if not nonePaintMode:
painter.setBrush(color)
painter.drawPolygon(c)
else:
if lenColorList > 0:
alpha = self.colorList[index].alpha()
else:
alpha = 255
if not nonePaintMode:
painter.setBrush(QtGui.QColor(200, 200, 200, alpha))
painter.setPen(QtCore.Qt.white)
painter.drawPolygon(c)
def mousePressEvent(self, event):
if event.button()==QtCore.Qt.LeftButton:
p = event.pos()
p = QtCore.QPointF(p.x(), p.y())
for index, cnt in enumerate(self.contours):
if cnt.containsPoint(p, QtCore.Qt.OddEvenFill):
if event.modifiers()==QtCore.Qt.ShiftModifier:
if index not in self.selectedContours:
self.selectedContours.append(index)
else:
self.selectedContours.remove(index)
else:
self.selectedContours = [index]
self.parent.selectContour(index, centerOn=False)
self.update()
return
self.selectedContours = [] #reset selection, if nothing was hit...
self.update()
# def mousePressEvent(self, event):
# print('press in contour')
#
# def mouseMoveEvent(self, event):
# print('move in contour')
#
def contextMenuEvent(self, event):
contextMenu = QtWidgets.QMenu("Particle options")
if self.isSelected:
self.contextMenu = ParticleContextMenu(self.parent)
self.parent.particleEditor.connectToSignals(self.contextMenu)
self.contextMenu.executeAtScreenPos(event.screenPos())
combineMenu = QtWidgets.QMenu("Combine Particles into")
combineActs = []
assignments = []
for index in self.selectedContours:
partIndex = index
assignments.append(self.parent.dataset.particleContainer.particles[partIndex].getParticleAssignment()) #TODO: Entangle...
assignments.append("other")
for assignment in np.unique(np.array(assignments)):
combineActs.append(combineMenu.addAction(assignment))
reassignActs = []
reassignMenu = QtWidgets.QMenu("Reassign particle(s) into")
for polymer in self.parent.analysiswidget.datastats.getUniquePolymers():
reassignActs.append(reassignMenu.addAction(polymer))
reassignActs.append(reassignMenu.addAction("other"))
contextMenu.addMenu(combineMenu)
contextMenu.addMenu(reassignMenu)
deleteAct = contextMenu.addAction("Delete Particle(s)")
numParticles = len(self.selectedContours)
if numParticles == 0:
reassignMenu.setDisabled(True)
combineMenu.setDisabled(True)
deleteAct.setDisabled(True)
elif numParticles == 1:
combineMenu.setDisabled(True)
action = contextMenu.exec_(event.screenPos())
if action == deleteAct:
print('deleting')
elif action in combineActs:
newAssignment = action.text()
self.parent.analysiswidget.editor.combineParticles(self.selectedContours, newAssignment)
elif action in reassignActs:
newAssignment = action.text()
self.parent.analysiswidget.editor.reassignParticles(self.selectedContours, newAssignment)
class FitPosIndicator(QtWidgets.QGraphicsItem):
indicatorSize = 80
......@@ -265,6 +127,7 @@ class RamanScanIndicator(QtWidgets.QGraphicsItem):
super().__init__()
# self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable)
self.setAcceptedMouseButtons(QtCore.Qt.NoButton)
self.setZValue(100) #higher numbers will be in foreground. Shall always be in foreground!
self.view = view
self.number = number
self.radius = radius
......