Loading analysis/analysisview.py +2 −5 Original line number Diff line number Diff line Loading @@ -149,7 +149,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): navigationLayout.addWidget(QtWidgets.QLabel('Select Spectrum')) navigationLayout.addWidget(self.spectrumSelector) navigationLayout.addWidget(self.spectrumNumberLabel) # navigationLayout.addStretch() self.navigationGroup.setLayout(navigationLayout) Loading Loading @@ -579,14 +578,12 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.currentSpectrumIndex = self.specNumberSelector.value()-1 self.currentParticleIndex = self.particleContainer.getParticleIndexContainingSpecIndex(self.currentSpectrumIndex) self.centerOnSpecIndex(self.currentSpectrumIndex) self.highLightContour(self.currentParticleIndex) self.viewparent.highLightContour(self.currentParticleIndex) self.updateSpecPlot() def centerOnSpecIndex(self, index): self.viewparent.centerOnRamanIndex(index) def highLightContour(self, index): self.viewparent.highLightContour(index) def darkenBackground(self): self.viewparent.darkenPixmap = self.darkenAct.isChecked() Loading analysis/analysiswidgets.py +4 −5 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ class ExpExcelDialog(QtWidgets.QDialog): self.dataset = dataset self.particleContainer = particleContainer # self.particles = self.datastats.getParticleStats() self.polymers = self.particleContainer.getListOfParticleAssignments # self.additives = self.datastats.currentAdditives self.hqis = self.particleContainer.getListOfHighestHQIs Loading @@ -62,10 +61,10 @@ class ExpExcelDialog(QtWidgets.QDialog): if option == 'Polymer Type (mandatory)': self.checkBoxes[-1].setEnabled(False) #is mandatory!!! if option == 'Additives': if self.additives is None: self.checkBoxes[-1].setEnabled(False) self.checkBoxes[-1].setChecked(False) # if option == 'Additives': # if self.additives is None: # self.checkBoxes[-1].setEnabled(False) # self.checkBoxes[-1].setChecked(False) excelvbox.addWidget(self.checkBoxes[-1]) Loading analysis/particleInfo.py +10 −20 Original line number Diff line number Diff line Loading @@ -18,21 +18,13 @@ 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 os import numpy as np 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): def __init__(self, parent): def __init__(self, datasetParent): super(ParticleContainer, self).__init__() self.parent = parent self.datasetParent = datasetParent self.particles = [] self.spectra = None self.inconsistentParticles = [] Loading Loading @@ -223,7 +215,7 @@ class ParticleContainer(object): final_typehistogram = {i[0]: i[1] for i in sorted_typehistogram} return final_typehistogram def mergeParticles(self, particleIndices, newContour, newStats, newAssignment=None): def addMergedParticle(self, particleIndices, newContour, newStats, newAssignment=None): newParticle = Particle() #copy Measurements for index in particleIndices: Loading @@ -243,15 +235,10 @@ class ParticleContainer(object): 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): def removeParticle(self, index): particle = self.getParticleOfIndex(index) #just for asserting to have the correct particle! del self.particles[index] Loading @@ -259,7 +246,6 @@ class ParticleContainer(object): for newIndex, particle in enumerate(self.particles): particle.index = newIndex class Particle(object): def __init__(self): super(Particle, self).__init__() Loading @@ -271,6 +257,7 @@ class Particle(object): self.area = None self.contour = None self.measurements = [] self.viewItem = None def addExistingMeasurement(self, meas): self.measurements.append(meas) Loading Loading @@ -362,6 +349,9 @@ class Particle(object): for measurement in self.measurements: measurement.applyHQIThreshold(minHQI) # def recreateViewItem(self): # pass class Measurement(object): def __init__(self): Loading analysis/particleeditor.py +56 −43 Original line number Diff line number Diff line Loading @@ -29,7 +29,27 @@ import numpy as np import cv2 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): combineParticlesSignal = QtCore.pyqtSignal(list, str) Loading Loading @@ -110,7 +130,6 @@ class ParticleContextMenu(QtWidgets.QMenu): class ParticleEditor(QtCore.QObject): # particleContoursChanged = QtCore.pyqtSignal() particleAssignmentChanged = QtCore.pyqtSignal() def __init__(self, viewparent, particleContainer): super(ParticleEditor, self).__init__() Loading Loading @@ -142,19 +161,15 @@ class ParticleEditor(QtCore.QObject): self.createSafetyBackup() print(f'Combining particles {contourIndices} into {newAssignment}') contours = self.particleContainer.getParticleContoursByIndex(contourIndices) try: newContour = self.mergeContours(contours.copy()) pixelscale = self.viewparent.dataset.getPixelScale() stats = self.characterizeParticle(newContour, pixelscale) self.particleContainer.mergeParticles(contourIndices, newContour, stats, newAssignment=newAssignment) for ind in contourIndices: self.viewparent.removeParticleContour(ind) except NotConnectedContoursError: return self.viewparent.resetContourIndices() self.viewparent.addParticleContour(newContour, len(self.viewparent.contourItems)) pixelscale = self.viewparent.dataset.getPixelScale() stats = getContourStatsWithPixelScale(newContour, pixelscale) self.particleAssignmentChanged.emit() #TODO: INCLUDE SANITY CHECK!!!!!!!!! self.mergeParticlesInParticleContainerAndSampleView(contourIndices,newContour, stats, newAssignment) @QtCore.pyqtSlot(list, str) def reassignParticles(self, contourindices, newAssignment): Loading @@ -167,7 +182,8 @@ class ParticleEditor(QtCore.QObject): @QtCore.pyqtSlot(list, str) def paintParticles(self, contourIndices, newAssignment): self.createSafetyBackup print(f'painting indices {contourIndices} into {newAssignment}') self.createSafetyBackup() self.storedIndices = contourIndices self.storedAssignmend = newAssignment contours = self.particleContainer.getParticleContoursByIndex(contourIndices) Loading @@ -178,19 +194,19 @@ class ParticleEditor(QtCore.QObject): self.viewparent.update() def acceptPaintedResult(self): try: newContour = self.mergeContours(self.particlePainter.contours.copy()) pixelscale = self.viewparent.dataset.getPixelScale() 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) for ind in self.storedIndices: self.viewparent.removeParticleContour(ind) pixelscale = self.viewparent.dataset.getPixelScale() stats = getContourStatsWithPixelScale(newContour, pixelscale) self.particleAssignmentChanged.emit() self.viewparent.resetContourIndices() self.viewparent.addParticleContour(newContour, len(self.viewparent.contourItems)) self.mergeParticlesInParticleContainerAndSampleView(self.storedIndices, newContour, stats, self.storedAssignmend) #TODO: INCLUDE SANITY CHECK!!!!!!!!! self.storedIndices = [] self.storedAssignmend = None self.destroyParticlePainter() Loading Loading @@ -230,7 +246,7 @@ class ParticleEditor(QtCore.QObject): if len(contours)>1: QtWidgets.QMessageBox.critical(self.viewparent, 'ERROR!', 'Particle contours are not connected and cannot be combined!') return raise NotConnectedContoursError newContour = contours[0] for i in range(len(newContour)): Loading @@ -239,24 +255,18 @@ class ParticleEditor(QtCore.QObject): return newContour def characterizeParticle(self, 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 def mergeParticlesInParticleContainerAndSampleView(self, indices, newContour, stats, assignment): self.viewparent.addParticleContourToIndex(newContour, len(self.viewparent.contourItems)-1) self.particleContainer.addMergedParticle(indices, newContour, stats, newAssignment=assignment) area = cv2.contourArea(cnt) for ind in sorted(indices, reverse=True): self.viewparent.removeParticleContour(ind) self.particleContainer.removeParticle(ind) return long*pixelscale, short*pixelscale, longellipse*pixelscale, shortellipse*pixelscale, area*pixelscale**2 self.viewparent.resetContourIndices() self.particleContainer.resetParticleIndices() self.particleAssignmentChanged.emit() #TODO: INCLUDE SANITY CHECK!!!!!!!!! @QtCore.pyqtSlot(list) def deleteParticles(self, contourIndices): Loading @@ -274,4 +284,7 @@ class ParticleEditor(QtCore.QObject): self.viewparent.analysiswidget.updateHistogramsAndContours() class NotConnectedContoursError(Exception): pass No newline at end of file sampleview.py +9 −7 Original line number Diff line number Diff line Loading @@ -422,9 +422,11 @@ class SampleView(QtWidgets.QGraphicsView): removeContourFromSelection(cnt) else: #not clicked on particle if event.modifiers()!=QtCore.Qt.ShiftModifier and cnt.particleIndex in self.selectedParticleIndices: removeContourFromSelection(cnt) if event.modifiers()!=QtCore.Qt.ShiftModifier: cnt.isSelected = False cnt.update() if cnt.particleIndex in self.selectedParticleIndices: self.selectedParticleIndices.remove(cnt.particleIndex) self.update() Loading Loading @@ -584,11 +586,11 @@ class SampleView(QtWidgets.QGraphicsView): self.contourItems = [] if self.dataset is not None: for particleIndex, contour in enumerate(self.dataset.particleContainer.getParticleContours()): self.addParticleContour(contour, particleIndex) self.addParticleContourToIndex(contour, particleIndex) self.update() 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.setIndex(index) assignment = self.dataset.particleContainer.getParticleAssignmentByIndex(index) Loading Loading @@ -616,10 +618,10 @@ class SampleView(QtWidgets.QGraphicsView): self.ramanscanitems[index].setHighLight(True) def highLightContour(self, index): print('highlighting contour', index) for contour in self.contourItems: contour.isSelected = False self.contourItems[index].isSelected = True self.selectedParticleIndices =[index] def centerOnRamanIndex(self, index, centerOn=True, highlightIndex=True): if centerOn: Loading Loading
analysis/analysisview.py +2 −5 Original line number Diff line number Diff line Loading @@ -149,7 +149,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): navigationLayout.addWidget(QtWidgets.QLabel('Select Spectrum')) navigationLayout.addWidget(self.spectrumSelector) navigationLayout.addWidget(self.spectrumNumberLabel) # navigationLayout.addStretch() self.navigationGroup.setLayout(navigationLayout) Loading Loading @@ -579,14 +578,12 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.currentSpectrumIndex = self.specNumberSelector.value()-1 self.currentParticleIndex = self.particleContainer.getParticleIndexContainingSpecIndex(self.currentSpectrumIndex) self.centerOnSpecIndex(self.currentSpectrumIndex) self.highLightContour(self.currentParticleIndex) self.viewparent.highLightContour(self.currentParticleIndex) self.updateSpecPlot() def centerOnSpecIndex(self, index): self.viewparent.centerOnRamanIndex(index) def highLightContour(self, index): self.viewparent.highLightContour(index) def darkenBackground(self): self.viewparent.darkenPixmap = self.darkenAct.isChecked() Loading
analysis/analysiswidgets.py +4 −5 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ class ExpExcelDialog(QtWidgets.QDialog): self.dataset = dataset self.particleContainer = particleContainer # self.particles = self.datastats.getParticleStats() self.polymers = self.particleContainer.getListOfParticleAssignments # self.additives = self.datastats.currentAdditives self.hqis = self.particleContainer.getListOfHighestHQIs Loading @@ -62,10 +61,10 @@ class ExpExcelDialog(QtWidgets.QDialog): if option == 'Polymer Type (mandatory)': self.checkBoxes[-1].setEnabled(False) #is mandatory!!! if option == 'Additives': if self.additives is None: self.checkBoxes[-1].setEnabled(False) self.checkBoxes[-1].setChecked(False) # if option == 'Additives': # if self.additives is None: # self.checkBoxes[-1].setEnabled(False) # self.checkBoxes[-1].setChecked(False) excelvbox.addWidget(self.checkBoxes[-1]) Loading
analysis/particleInfo.py +10 −20 Original line number Diff line number Diff line Loading @@ -18,21 +18,13 @@ 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 os import numpy as np 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): def __init__(self, parent): def __init__(self, datasetParent): super(ParticleContainer, self).__init__() self.parent = parent self.datasetParent = datasetParent self.particles = [] self.spectra = None self.inconsistentParticles = [] Loading Loading @@ -223,7 +215,7 @@ class ParticleContainer(object): final_typehistogram = {i[0]: i[1] for i in sorted_typehistogram} return final_typehistogram def mergeParticles(self, particleIndices, newContour, newStats, newAssignment=None): def addMergedParticle(self, particleIndices, newContour, newStats, newAssignment=None): newParticle = Particle() #copy Measurements for index in particleIndices: Loading @@ -243,15 +235,10 @@ class ParticleContainer(object): 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): def removeParticle(self, index): particle = self.getParticleOfIndex(index) #just for asserting to have the correct particle! del self.particles[index] Loading @@ -259,7 +246,6 @@ class ParticleContainer(object): for newIndex, particle in enumerate(self.particles): particle.index = newIndex class Particle(object): def __init__(self): super(Particle, self).__init__() Loading @@ -271,6 +257,7 @@ class Particle(object): self.area = None self.contour = None self.measurements = [] self.viewItem = None def addExistingMeasurement(self, meas): self.measurements.append(meas) Loading Loading @@ -362,6 +349,9 @@ class Particle(object): for measurement in self.measurements: measurement.applyHQIThreshold(minHQI) # def recreateViewItem(self): # pass class Measurement(object): def __init__(self): Loading
analysis/particleeditor.py +56 −43 Original line number Diff line number Diff line Loading @@ -29,7 +29,27 @@ import numpy as np import cv2 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): combineParticlesSignal = QtCore.pyqtSignal(list, str) Loading Loading @@ -110,7 +130,6 @@ class ParticleContextMenu(QtWidgets.QMenu): class ParticleEditor(QtCore.QObject): # particleContoursChanged = QtCore.pyqtSignal() particleAssignmentChanged = QtCore.pyqtSignal() def __init__(self, viewparent, particleContainer): super(ParticleEditor, self).__init__() Loading Loading @@ -142,19 +161,15 @@ class ParticleEditor(QtCore.QObject): self.createSafetyBackup() print(f'Combining particles {contourIndices} into {newAssignment}') contours = self.particleContainer.getParticleContoursByIndex(contourIndices) try: newContour = self.mergeContours(contours.copy()) pixelscale = self.viewparent.dataset.getPixelScale() stats = self.characterizeParticle(newContour, pixelscale) self.particleContainer.mergeParticles(contourIndices, newContour, stats, newAssignment=newAssignment) for ind in contourIndices: self.viewparent.removeParticleContour(ind) except NotConnectedContoursError: return self.viewparent.resetContourIndices() self.viewparent.addParticleContour(newContour, len(self.viewparent.contourItems)) pixelscale = self.viewparent.dataset.getPixelScale() stats = getContourStatsWithPixelScale(newContour, pixelscale) self.particleAssignmentChanged.emit() #TODO: INCLUDE SANITY CHECK!!!!!!!!! self.mergeParticlesInParticleContainerAndSampleView(contourIndices,newContour, stats, newAssignment) @QtCore.pyqtSlot(list, str) def reassignParticles(self, contourindices, newAssignment): Loading @@ -167,7 +182,8 @@ class ParticleEditor(QtCore.QObject): @QtCore.pyqtSlot(list, str) def paintParticles(self, contourIndices, newAssignment): self.createSafetyBackup print(f'painting indices {contourIndices} into {newAssignment}') self.createSafetyBackup() self.storedIndices = contourIndices self.storedAssignmend = newAssignment contours = self.particleContainer.getParticleContoursByIndex(contourIndices) Loading @@ -178,19 +194,19 @@ class ParticleEditor(QtCore.QObject): self.viewparent.update() def acceptPaintedResult(self): try: newContour = self.mergeContours(self.particlePainter.contours.copy()) pixelscale = self.viewparent.dataset.getPixelScale() 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) for ind in self.storedIndices: self.viewparent.removeParticleContour(ind) pixelscale = self.viewparent.dataset.getPixelScale() stats = getContourStatsWithPixelScale(newContour, pixelscale) self.particleAssignmentChanged.emit() self.viewparent.resetContourIndices() self.viewparent.addParticleContour(newContour, len(self.viewparent.contourItems)) self.mergeParticlesInParticleContainerAndSampleView(self.storedIndices, newContour, stats, self.storedAssignmend) #TODO: INCLUDE SANITY CHECK!!!!!!!!! self.storedIndices = [] self.storedAssignmend = None self.destroyParticlePainter() Loading Loading @@ -230,7 +246,7 @@ class ParticleEditor(QtCore.QObject): if len(contours)>1: QtWidgets.QMessageBox.critical(self.viewparent, 'ERROR!', 'Particle contours are not connected and cannot be combined!') return raise NotConnectedContoursError newContour = contours[0] for i in range(len(newContour)): Loading @@ -239,24 +255,18 @@ class ParticleEditor(QtCore.QObject): return newContour def characterizeParticle(self, 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 def mergeParticlesInParticleContainerAndSampleView(self, indices, newContour, stats, assignment): self.viewparent.addParticleContourToIndex(newContour, len(self.viewparent.contourItems)-1) self.particleContainer.addMergedParticle(indices, newContour, stats, newAssignment=assignment) area = cv2.contourArea(cnt) for ind in sorted(indices, reverse=True): self.viewparent.removeParticleContour(ind) self.particleContainer.removeParticle(ind) return long*pixelscale, short*pixelscale, longellipse*pixelscale, shortellipse*pixelscale, area*pixelscale**2 self.viewparent.resetContourIndices() self.particleContainer.resetParticleIndices() self.particleAssignmentChanged.emit() #TODO: INCLUDE SANITY CHECK!!!!!!!!! @QtCore.pyqtSlot(list) def deleteParticles(self, contourIndices): Loading @@ -274,4 +284,7 @@ class ParticleEditor(QtCore.QObject): self.viewparent.analysiswidget.updateHistogramsAndContours() class NotConnectedContoursError(Exception): pass No newline at end of file
sampleview.py +9 −7 Original line number Diff line number Diff line Loading @@ -422,9 +422,11 @@ class SampleView(QtWidgets.QGraphicsView): removeContourFromSelection(cnt) else: #not clicked on particle if event.modifiers()!=QtCore.Qt.ShiftModifier and cnt.particleIndex in self.selectedParticleIndices: removeContourFromSelection(cnt) if event.modifiers()!=QtCore.Qt.ShiftModifier: cnt.isSelected = False cnt.update() if cnt.particleIndex in self.selectedParticleIndices: self.selectedParticleIndices.remove(cnt.particleIndex) self.update() Loading Loading @@ -584,11 +586,11 @@ class SampleView(QtWidgets.QGraphicsView): self.contourItems = [] if self.dataset is not None: for particleIndex, contour in enumerate(self.dataset.particleContainer.getParticleContours()): self.addParticleContour(contour, particleIndex) self.addParticleContourToIndex(contour, particleIndex) self.update() 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.setIndex(index) assignment = self.dataset.particleContainer.getParticleAssignmentByIndex(index) Loading Loading @@ -616,10 +618,10 @@ class SampleView(QtWidgets.QGraphicsView): self.ramanscanitems[index].setHighLight(True) def highLightContour(self, index): print('highlighting contour', index) for contour in self.contourItems: contour.isSelected = False self.contourItems[index].isSelected = True self.selectedParticleIndices =[index] def centerOnRamanIndex(self, index, centerOn=True, highlightIndex=True): if centerOn: Loading