diff --git a/analysis/analysisview.py b/analysis/analysisview.py
index f5ca7e00bf5a6c397a855f02f3928a5f3846c4eb..2d8df4a072192084c6620d6834a6d926722356b3 100644
--- a/analysis/analysisview.py
+++ b/analysis/analysisview.py
@@ -399,7 +399,8 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.resultCheckBoxesLayout.addWidget(self.showTotalSelector)
#generate new checkboxes
self.polymerCheckBoxes = []
- for index, polymer in enumerate(self.datastats.uniquePolymers):
+ uniquePolymers = self.datastats.getUniquePolymers()
+ for index, polymer in enumerate(uniquePolymers):
self.polymerCheckBoxes.append(QtWidgets.QCheckBox(self))
self.polymerCheckBoxes[index].setText(polymer)
self.resultCheckBoxesLayout.addWidget(self.polymerCheckBoxes[index])
@@ -427,7 +428,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.navigationGroup.setEnabled(True)
self.polymerComboBox.currentIndexChanged.disconnect()
self.polymerComboBox.clear()
- self.polymerComboBox.addItems(self.datastats.uniquePolymers)
+ self.polymerComboBox.addItems(uniquePolymers)
self.polymerComboBox.currentIndexChanged.connect(self.displayNewPolymerType)
self.polymerIndex = self.polymerComboBox.currentIndex()
@@ -489,6 +490,48 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.parent.centerOnRamanIndex(specIndex, centerOn=centerOn, highlightContour=highlightContour)
self.parent.highLightRamanIndex(specIndex)
self.lastSpectrumInFocus = specIndex
+
+ def selectContour(self, index, centerOn=True):
+ uniquePolymers = self.datastats.getUniquePolymers()
+ if uniquePolymers is not None:
+ #the index is the contour index, find particle index:
+ specIndex = self.datastats.particles2spectra[index][0] #select first spectrum of partoicle
+ self.datastats.currentParticleIndex = index
+ self.datastats.currentSpectrumIndex = specIndex
+
+ selectedPolymer = self.datastats.currentPolymers[specIndex]
+ try:
+ self.polymerIndex = uniquePolymers.index(selectedPolymer)
+ except:
+ print(selectedPolymer)
+ raise
+
+ #subparticleIndex
+ partIndicesOfThatPolymer = self.datastats.indices[self.polymerIndex]
+ subPartInd = partIndicesOfThatPolymer.index(index)
+
+ #disconnect analysis widgets:
+ self.particleSelector.valueChanged.disconnect()
+ self.spectrumSelector.valueChanged.disconnect()
+ self.polymerComboBox.currentIndexChanged.disconnect()
+
+ #set widgets...
+ self.particleSelector.setValue(subPartInd+1)
+ self.particleSelector.setMaximum(len(partIndicesOfThatPolymer))
+
+ self.spectrumSelector.setValue(1)
+ self.spectrumSelector.setMaximum(len(self.datastats.particles2spectra[index]))
+
+ selectedPolymer = self.datastats.currentPolymers[specIndex]
+ self.polymerIndex = uniquePolymers.index(selectedPolymer)
+ self.polymerComboBox.setCurrentIndex(self.polymerIndex)
+
+ #reconnect all widgets:
+ self.particleSelector.valueChanged.connect(self.selectParticle)
+ self.spectrumSelector.valueChanged.connect(self.selectSpectrum)
+ self.polymerComboBox.currentIndexChanged.connect(self.displayNewPolymerType)
+
+ self.updateSpecPlot(centerOn=centerOn)
def displayNewPolymerType(self, resetCurrentIndex=True):
self.polymerIndex = self.polymerComboBox.currentIndex()
@@ -676,6 +719,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
return color
def createPolymerOverlay(self):
+ uniquePolymers = self.datastats.getUniquePolymers()
if not self.noOverlayAct.isChecked() and self.datastats.indices is not None:
if len(self.datastats.indices) > 0:
@@ -686,9 +730,9 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
for index, indexList in enumerate(self.datastats.indices):
if self.fullOverlayAct.isChecked() or (self.selOverlayAct.isChecked() and self.polymerCheckBoxes[index].isChecked()):
- color = self.getColorFromName(self.datastats.uniquePolymers[index], base255=True)
+ color = self.getColorFromName(uniquePolymers[index], base255=True)
color = QtGui.QColor(color[0], color[1], color[2], alpha=alpha)
- legendItems.append((self.datastats.uniquePolymers[index], color))
+ legendItems.append((uniquePolymers[index], color))
for i in indexList:
colorList[i] = color
diff --git a/analysis/datastats.py b/analysis/datastats.py
index f2ca564f6fd6f13a1e58af2ef595b36f5b6501a4..31b747b105f4fe01e1631caa5bc78ab2f7cd81b0 100644
--- a/analysis/datastats.py
+++ b/analysis/datastats.py
@@ -21,6 +21,19 @@ If not, see .
import os
import numpy as np
import operator
+from dataset import loadData
+
+
+def readDataStats(fname):
+ ds = loadData(fname)
+ datastats = DataStats(ds)
+ datastats.update()
+ datastats.loadParticleData()
+ minHQI = datastats.dataset.resultParams['minHQI']
+ compHQI = datastats.dataset.resultParams['compHQI']
+ datastats.formatResults(minHQI, compHQI)
+ datastats.createHistogramData()
+ return datastats
class DataStats(object):
def __init__(self, dataset):
@@ -34,7 +47,6 @@ class DataStats(object):
self.currentPolymers = None #list of polymers after setting entries with low hqi to unknown
self.currentAdditives = None #same thing for the additives
- self.uniquePolymers = None #list of present polymer types
self.spectra = None #acquired spectra
self.indices = None #assignment of what spectra-indices belong to what substance
@@ -103,7 +115,7 @@ class DataStats(object):
def loadParticleData(self):
self.particlestats = np.array(self.dataset.particlestats)
- pixelscale = (self.dataset.pixelscale_df if self.dataset.imagescanMode == 'df' else self.dataset.pixelscale_bf)
+ pixelscale = self.dataset.getPixelScale()
#convert to mikrometer scale
for index in range(len(self.particlestats)):
for subindex in range(5):
@@ -145,6 +157,11 @@ class DataStats(object):
if self.currentAdditives is not None:
self.currentAdditives[self.addhqis < compHqi] = 'unknown'
+ def getUniquePolymers(self):
+ if self.currentPolymers is None:
+ return None
+ return self.uniquePolymers
+
def createHistogramData(self):
self.uniquePolymers = np.unique(self.currentPolymers)
self.particleResults = [None]*len(self.particlestats)
@@ -192,4 +209,11 @@ class DataStats(object):
self.dataset.resultParams = {'minHQI': minHQI,
'compHQI': compHQI}
self.dataset.save()
- print('saved dataset')
\ No newline at end of file
+ print('saved dataset; Valid:', self.testRead())
+
+
+ def testRead(self):
+ statsread = readDataStats(self.dataset.fname)
+ return statsread.__dict__ == self.__dict__
+
+
\ No newline at end of file
diff --git a/dataset.py b/dataset.py
index ba4f294ae27ad2c2e0481610c841a9117b8f2ae4..c19f75b9195136fc6129c1b7067fe458ec07fdcb 100644
--- a/dataset.py
+++ b/dataset.py
@@ -53,6 +53,52 @@ def saveData(dataset, fname):
pickle.dump(dataset, fp, protocol=-1)
dataset.zvalimg = zvalimg
+def arrayCompare(a1, a2):
+ print("array compare")
+ ind = np.isnan(a1)
+ if not np.any(ind):
+ return np.all(a1==a2)
+ if a1.shape!=a2.shape:
+ return False
+ return np.all(a1[~ind]==a2[~ind])
+
+def listCompare(l1, l2):
+ print("list compare")
+ if len(l1)!=len(l2):
+ return False
+ for l1i, l2i in zip(l1, l2):
+ if isinstance(l1i, np.ndarray):
+ if not isinstance(l2i, np.ndarray) or not arrayCompare(l1i, l2i):
+ return False
+ elif isinstance(l1i, (list, tuple)):
+ if not isinstance(l2i, (list, tuple)) or not listCompare(l1i, l2i):
+ return False
+ elif l1i!=l2i and ((~np.isnan(l1i)) or (~np.isnan(l2i))):
+ return False
+ return True
+
+def recursiveDictCompare(d1, d2):
+ for key in d1:
+ if not key in d2:
+ return False
+ a = d1[key]
+ b = d2[key]
+ print(key, type(a), type(b))
+ if isinstance(a, np.ndarray):
+ if not isinstance(b, np.ndarray) or not arrayCompare(a, b):
+ return False
+ elif isinstance(a, dict):
+ if not isinstance(b, dict):
+ return False
+ if not recursiveDictCompare(a, b):
+ return False
+ elif isinstance(a, (list, tuple)):
+ if not isinstance(b, (list, tuple)) or not listCompare(a, b):
+ return False
+ elif a != b:
+ return False
+ return True
+
class DataSet(object):
def __init__(self, fname, newProject=False):
self.fname = fname
@@ -115,6 +161,14 @@ class DataSet(object):
self.fname = self.newProject(fname)
self.updatePath()
+ def __eq__(self, other):
+ return recursiveDictCompare(self.__dict__, other.__dict__)
+
+ def getPixelScale(self, mode=None):
+ if mode is None:
+ mode = self.imagescanMode
+ return (self.pixelscale_df if mode == 'df' else self.pixelscale_bf)
+
def saveZvalImg(self):
if self.zvalimg is not None:
cv2imwrite_fix(self.getZvalImageName(), self.zvalimg)
@@ -243,8 +297,7 @@ class DataSet(object):
p0[1] += self.imagedim_bf[1]/2
return (pixelpos[0]*self.pixelscale_bf + p0[0]), (p0[1] - pixelpos[1]*self.pixelscale_bf)
else:
- print('mapToRamanMode not understood')
- return
+ raise ValueError(f'mapToLength mode: {mode} not understood')
def mapToLengthRaman(self, pixelpos, microscopeMode='df', noz=False):
p0x, p0y = self.mapToLength(pixelpos, mode = microscopeMode)
@@ -315,9 +368,7 @@ class DataSet(object):
saveData(self, self.fname)
def saveBackup(self):
-# backupNameNotFound = True
inc = 0
-# while backupNameNotFound:
while True:
directory = os.path.dirname(self.fname)
filename = self.name + '_backup_' + str(inc) + '.pkl'
@@ -327,5 +378,4 @@ class DataSet(object):
else:
saveData(self, path)
return filename
-# backupNameNotFound = False
diff --git a/sampleview.py b/sampleview.py
index c82a0730d9e586f828e09af483cce72932cb225e..dfae213bf99bde60d5ff11fb2c28b79a68b6d17c 100644
--- a/sampleview.py
+++ b/sampleview.py
@@ -1,578 +1,537 @@
-# -*- coding: utf-8 -*-
-"""
-GEPARD - Gepard-Enabled PARticle Detection
-Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für
-Polymerforschung Dresden e. V.
-
-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 .
-"""
-from PyQt5 import QtCore, QtGui, QtWidgets
-import numpy as np
-import os
-from dataset import DataSet, loadData
-from ramancom.ramancontrol import RamanControl, simulatedRaman
-from opticalscan import OpticalScan
-from ramanscanui import RamanScanUI
-from detectionview import ParticleDetectionView
-from analysis.analysisview import ParticleAnalysis
-from zeissimporter import ZeissImporter
-from viewitems import FitPosIndicator, Node, Edge, ScanIndicator, RamanScanIndicator, SegmentationContours
-from helperfunctions import polygoncovering, cv2imread_fix
-import cv2
-from ramancom.configRaman import RamanConfigWin
-
-class SampleView(QtWidgets.QGraphicsView):
- ScalingChanged = QtCore.pyqtSignal(float)
-
- def __init__(self, logpath):
- super(SampleView, self).__init__()
-
- self.logpath = logpath
- self.item = QtWidgets.QGraphicsPixmapItem()
- self.item.setPos(0, 0)
- self.item.setAcceptedMouseButtons(QtCore.Qt.NoButton)
- self.scaleFactor = 1.0
- scene = QtWidgets.QGraphicsScene(self)
- scene.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex)
- scene.addItem(self.item)
- scene.setBackgroundBrush(QtCore.Qt.darkGray)
- self.setScene(scene)
- self.setCacheMode(QtWidgets.QGraphicsView.CacheBackground)
- self.setViewportUpdateMode(QtWidgets.QGraphicsView.BoundingRectViewportUpdate)
- self.setRenderHint(QtGui.QPainter.Antialiasing)
- self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
- self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorViewCenter)
- self.ramanctrl = RamanControl()
- self.simulatedRaman = simulatedRaman
- #determine, if ramanSwitch is needed:
- self.ramanctrl.connect()
- if not self.ramanctrl.connected:
- QtWidgets.QMessageBox.warning(self, 'Error', 'Please enable Raman Connection')
- return
- if self.ramanctrl.getImageDimensions(mode='bf')[0] == self.ramanctrl.getImageDimensions(mode='df')[0]:
- self.ramanSwitchNeeded = False
- else:
- self.ramanSwitchNeeded = True
- self.ramanctrl.disconnect()
-
- self.drag = None
- self.mode = None
- self.dataset = None
- self.fititems = []
- self.boundaryitems = [[],[]]
- self.scanitems = []
- self.ramanscanitems = []
- self.imgdata = None
- self.isblocked = False
- self.contouritem = SegmentationContours(self)
- scene.addItem(self.contouritem)
- self.detectionwidget = None
- self.ramanwidget = RamanScanUI(self.ramanctrl, None, self.logpath, self)
- self.ramanwidget.imageUpdate.connect(self.loadPixmap)
- self.oscanwidget = OpticalScan(self.ramanctrl, None, self.logpath, self)
- self.oscanwidget.imageUpdate.connect(self.loadPixmap)
- self.oscanwidget.boundaryUpdate.connect(self.resetBoundary)
- self.analysiswidget = None
- self.setMinimumSize(600, 600)
- self.darkenPixmap = False
- self.microscopeMode = None
- self.coordTestMode = False
-
- def takeScreenshot(self):
- #TODO:
- #LIMIT SCREENSHOT TO ACTUAL VIEWSIZE OF LOADED IMAGE...
- #hide scrollbars
- self.setHorizontalScrollBarPolicy(1)
- self.setVerticalScrollBarPolicy(1)
- #capture screen
- screen = QtWidgets.QApplication.primaryScreen()
- self.repaint()
- screenshot = screen.grabWindow(self.winId())
- #unhide scrollbars
- self.setHorizontalScrollBarPolicy(0)
- self.setVerticalScrollBarPolicy(0)
-
- fname = self.dataset.path + '/screenshot.png'
- validFileName = False
- incr = 1
- while not validFileName:
- if not os.path.exists(fname):
- validFileName = True
- else:
- fname = self.dataset.path + '/screenshot ({}).png'.format(incr)
- incr += 1
- screenshot.save(fname , 'png')
- QtWidgets.QMessageBox.about(self, 'Message', 'Saved as {} to project directory.'.format(fname.split('/')[-1]))
-
- def closeEvent(self, event):
- reply = QtWidgets.QMessageBox.question(self, 'Message',
- "Are you sure to quit?", QtWidgets.QMessageBox.Yes |
- QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
-
- if reply == QtWidgets.QMessageBox.Yes:
- self.disconnectRaman()
- self.saveDataSet()
- event.accept()
- self.oscanwidget.close()
- if self.detectionwidget is not None:
- self.detectionwidget.close()
- if self.analysiswidget is not None:
- self.analysiswidget.close()
- self.ramanwidget.close()
- else:
- event.ignore()
-
- def configureRamanControl(self):
- self.configWin = RamanConfigWin(self)
- self.configWin.show()
-
- def saveDataSet(self):
- if self.dataset is not None:
- self.dataset.save()
-
- @QtCore.pyqtSlot()
- def zoomIn(self):
- self.scaleImage(1.25)
-
- @QtCore.pyqtSlot()
- def zoomOut(self):
- self.scaleImage(0.8)
-
- @QtCore.pyqtSlot()
- def normalSize(self):
- self.scaleFactor = 1.0
- self.setTransform(QtGui.QTransform.fromScale(1., 1.))
- self.announceScaling()
-
- @QtCore.pyqtSlot()
- def fitToWindow(self):
-# print("fitting to Window")
- brect = self.item.sceneBoundingRect()
- self.fitInView(0, 0, brect.width(), brect.height(), QtCore.Qt.KeepAspectRatio)
- self.scaleFactor = self.transform().m11()
- self.announceScaling()
-
- def switchMode(self, mode, loadnew=False):
- if mode is None:
- return
- assert mode in ["OpticalScan", "ParticleDetection", "RamanScan", "ParticleAnalysis"]
- self.oscanwidget.setVisible(False)
- if self.detectionwidget is not None:
- self.detectionwidget.close()
- self.detectionwidget.destroy()
- self.ramanwidget.setVisible(False)
- self.contouritem.resetContours([])
- self.mode = mode
- self.loadPixmap(self.microscopeMode)
- if mode == "OpticalScan":
- self.oscanwidget.setVisible(True)
- self.oscanwidget.resetDataset(self.dataset)
-
- elif mode == "ParticleDetection":
- if self.detectionwidget is None:
- self.detectionwidget = ParticleDetectionView(self.imgdata, self.dataset, self)
- self.detectionwidget.show()
- self.detectionwidget.imageUpdate.connect(self.detectionUpdate)
- self.detectionwidget.detectionFinished.connect(self.activateMaxMode)
-
- elif mode == "RamanScan":
- self.ramanwidget.resetDataset(self.dataset)
- self.ramanwidget.setVisible(True)
-
- elif mode == "ParticleAnalysis":
- if self.ramanwidget.isVisible():
- self.ramanwidget.setVisible(False)
- if self.analysiswidget is None:
- print('creating new analysiswidget')
- self.analysiswidget = ParticleAnalysis(self.dataset, self)
- self.analysiswidget.showMaximized()
- else:
- print('show maximized already exisiting analysiswidget')
- self.analysiswidget.showMaximized()
-
-# self.ramanwidget.setVisible(False)
- if self.detectionwidget is not None:
- self.detectionwidget.setVisible(False)
-
- #show legend:
- self.imparent.legend.show()
-
- if loadnew:
- self.fitToWindow()
- self.imparent.updateModes(mode, self.getMaxMode())
-
- def open(self, fname):
- self.saveDataSet()
-
- #close all widgets
- for widget in [self.detectionwidget, self.ramanwidget, self.oscanwidget, self.analysiswidget]:
- if widget is not None:
- widget.close()
- widget.destroy()
- del widget
-
- self.contouritem.resetContours()
-# if self.dataset is not None:
-# del self.dataset
-# self.scene().removeItem(self.contouritem)
-# del self.contouritem
-# self.contouritem = SegmentationContours(self)
-# self.scene().addItem(self.contouritem)
-
- self.dataset = loadData(fname)
- self.setMicroscopeMode()
- self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else ""))
- self.imgdata = None
- self.activateMaxMode(loadnew=True)
- self.imparent.snapshotAct.setEnabled(True)
-
- def importProject(self, fname):
- zimp = ZeissImporter(fname, self.ramanctrl, self)
- if zimp.validimport:
- zimp.exec()
- if zimp.result() == QtWidgets.QDialog.Accepted:
- self.open(zimp.gepardname)
-
- def new(self, fname):
- self.saveDataSet()
- if self.dataset is not None:
- self.dataset.save()
- self.dataset = DataSet(fname, newProject=True)
- self.setMicroscopeMode()
- self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else ""))
- self.imgdata = None
- self.activateMaxMode(loadnew=True)
- self.imparent.snapshotAct.setEnabled(True)
-
- def setMicroscopeMode(self):
- if self.ramanSwitchNeeded:
- self.imparent.ramanSwitch.connectToSampleView()
- self.imparent.ramanSwitch.show()
- self.microscopeMode = ('df' if self.imparent.ramanSwitch.df_btn.isChecked() else 'bf')
-
- @QtCore.pyqtSlot()
- def activateMaxMode(self, loadnew=False):
- mode = self.getMaxMode()
- self.imparent.updateModes(self.mode, self.getMaxMode())
- self.switchMode(mode, loadnew=loadnew)
-
- def blockUI(self):
- self.isblocked = True
- self.imparent.blockUI()
-
- def unblockUI(self):
- self.isblocked = False
- self.imparent.unblockUI(self.ramanctrl.connected)
- self.imparent.updateModes(self.mode, self.getMaxMode())
-
- def getMaxMode(self):
- if self.dataset is None:
- return None
- if not self.ramanctrl.connected:
- self.connectRaman()
- if not self.ramanctrl.connected:
- return None
- maxmode = "OpticalScan"
- if os.path.exists(self.dataset.getImageName()):
- maxmode = "ParticleDetection"
- if len(self.dataset.ramanpoints)>0:
- maxmode = "RamanScan"
- if self.dataset.ramanscandone: #uncomment!!
- maxmode = "ParticleAnalysis"
- return maxmode
-
- def mousePressEvent(self, event):
-# if event.button()==QtCore.Qt.RightButton:
- if event.button()==QtCore.Qt.MiddleButton:
- self.drag = event.pos()
- elif event.button()==QtCore.Qt.LeftButton and self.mode in ["OpticalScan", "RamanScan"] \
- and event.modifiers()==QtCore.Qt.ControlModifier:
- p0 = self.mapToScene(event.pos())
- if self.dataset is not None and self.dataset.pshift is not None:
- if self.dataset.readin:
- reply = QtWidgets.QMessageBox.critical(self, 'Dataset is newly read from disk!',
- "Coordinate systems might have changed since. Do you want to continue with saved coordinates?",
- QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
-
- if reply == QtWidgets.QMessageBox.Yes:
- self.dataset.readin = False
- else:
- return
- x, y, z = self.dataset.mapToLengthRaman([p0.x(), p0.y()],
- microscopeMode=self.microscopeMode,
- noz=(False if self.mode=="RamanScan" else True))
- if z is not None:
- assert z>-100.
- self.ramanctrl.moveToAbsolutePosition(x, y, z)
- elif event.button()==QtCore.Qt.LeftButton and self.mode=="ParticleDetection":
- p0 = self.mapToScene(event.pos())
- self.detectionwidget.setImageCenter([p0.x(), p0.y()])
-# elif event.button()==QtCore.Qt.LeftButton and self.mode=="ParticleAnalysis":
-# p0 = self.mapToScene(event.pos())
-
- else:
- p0 = self.mapToScene(event.pos())
- super(SampleView, self).mousePressEvent(event)
-
- def mouseMoveEvent(self, event):
- if self.drag is not None:
- p0 = event.pos()
- move = self.drag-p0
- self.horizontalScrollBar().setValue(move.x() + self.horizontalScrollBar().value())
- self.verticalScrollBar().setValue(move.y() + self.verticalScrollBar().value())
-
- self.drag = p0
- else:
- super(SampleView, self).mouseMoveEvent(event)
-
- def mouseReleaseEvent(self, event):
- self.drag = None
- super(SampleView, self).mouseReleaseEvent(event)
-
- def wheelEvent(self, event):
- factor = 1.01**(event.angleDelta().y()/8)
- self.scaleImage(factor)
-
- def scaleImage(self, factor):
- if factor<1 and not self.imparent.zoomOutAct.isEnabled():
- return
- if factor>1 and not self.imparent.zoomInAct.isEnabled():
- return
- self.scaleFactor *= factor
- self.scale(factor, factor)
- self.announceScaling()
-
- def announceScaling(self):
- pixelscale = (self.dataset.pixelscale_df if self.microscopeMode == 'df' else self.dataset.pixelscale_bf)
- if self.dataset is None or pixelscale is None:
- self.ScalingChanged.emit(-1.0)
- else:
- self.ScalingChanged.emit(pixelscale/self.scaleFactor) ##CURRENTLY ONLY DARKFIELD!!! FIX NEEDED!!!
-
- def connectRaman(self):
- if not self.ramanctrl.connect():
- msg = QtWidgets.QMessageBox()
- msg.setText("Connection failed! Please enable remote control.")
- msg.exec()
- else:
- mode = self.getMaxMode()
- self.switchMode(mode)
- self.imparent.updateConnected(self.ramanctrl.connected)
-
- def disconnectRaman(self):
- self.ramanctrl.disconnect()
- self.imparent.updateConnected(self.ramanctrl.connected)
-
- @QtCore.pyqtSlot(str)
- def detectionUpdate(self):
- self.contouritem.resetContours(self.dataset.particlecontours)
- self.prepareAnalysis()
- self.update()
-
- @QtCore.pyqtSlot(str)
- def loadPixmap(self, microscope_mode='df'):
- self.clearItems()
- if self.dataset is None:
- self.item.setPixmap(QtGui.QPixmap())
- else:
- data = self.imgdata
- fname = self.dataset.getImageName()
- if self.mode == "ParticleDetection" or self.mode == "ParticleAnalysis":
- self.contouritem.resetContours(self.dataset.particlecontours)
- if data is None and os.path.exists(fname):
- data = cv2.cvtColor(cv2imread_fix(fname), cv2.COLOR_BGR2RGB)
- self.imgdata = data
- if data is not None:
-
- height, width, channel = data.shape
- bytesPerLine = 3 * width
- pix = QtGui.QPixmap()
- pix.convertFromImage(QtGui.QImage(data.data,
- width, height, bytesPerLine, QtGui.QImage.Format_RGB888))
-
- self.item.setPixmap(pix)
-
- if self.darkenPixmap:
- self.scene().setBackgroundBrush(QtGui.QColor(5, 5, 5))
- self.item.setOpacity(0.2)
- else:
- self.scene().setBackgroundBrush(QtCore.Qt.darkGray)
- self.item.setOpacity(1)
-
-
- else:
- self.item.setPixmap(QtGui.QPixmap())
- if self.mode == "OpticalScan":
- for i, p in zip(self.dataset.fitindices, self.dataset.fitpoints):
- p = self.dataset.mapToPixel(p, mode=microscope_mode, force=True)
- fititem = FitPosIndicator(i+1, pos=p)
- self.scene().addItem(fititem)
- self.fititems.append(fititem)
- if self.mode == "ParticleDetection" or self.mode == "ParticleAnalysis":
- self.prepareAnalysis()
- else:
- self.fitToWindow()
-
- @QtCore.pyqtSlot()
- def resetScanPositions(self):
- micMode = ('df' if self.oscanwidget.df_btn.isChecked() else 'bf')
- for item in self.scanitems:
- self.scene().removeItem(item)
- edges, nodes = self.boundaryitems
- boundary = []
- for n in nodes:
- p = n.pos().x(), n.pos().y()
- boundary.append(self.dataset.mapToLength(p, self.microscopeMode, force=True))
- boundary = np.array(boundary)
-# print(boundary)
- self.dataset.boundary = boundary
- if micMode == 'df':
- width, height, angle = self.dataset.imagedim_df
- else:
- width, height, angle = self.dataset.imagedim_bf
-
- margin = min(width, height)*0.02
- wx, wy = width-margin, height-margin
- print(wx,wy)
- p1 = polygoncovering(boundary, wx, wy)
- b2 = boundary.copy()
- b2 = b2[:,[1,0]]
- p2 = polygoncovering(b2, wy, wx)
- if len(p2)
+
+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 .
+"""
+from PyQt5 import QtCore, QtGui, QtWidgets
+import numpy as np
+import os
+from dataset import DataSet, loadData
+from ramancom.ramancontrol import RamanControl, simulatedRaman
+from opticalscan import OpticalScan
+from ramanscanui import RamanScanUI
+from detectionview import ParticleDetectionView
+from analysis.analysisview import ParticleAnalysis
+from zeissimporter import ZeissImporter
+from viewitems import FitPosIndicator, Node, Edge, ScanIndicator, RamanScanIndicator, SegmentationContours
+from helperfunctions import polygoncovering, cv2imread_fix
+import cv2
+from ramancom.configRaman import RamanConfigWin
+
+class SampleView(QtWidgets.QGraphicsView):
+ ScalingChanged = QtCore.pyqtSignal(float)
+
+ def __init__(self, logpath):
+ super(SampleView, self).__init__()
+
+ self.logpath = logpath
+ self.item = QtWidgets.QGraphicsPixmapItem()
+ self.item.setPos(0, 0)
+ self.item.setAcceptedMouseButtons(QtCore.Qt.NoButton)
+ self.scaleFactor = 1.0
+ scene = QtWidgets.QGraphicsScene(self)
+ scene.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex)
+ scene.addItem(self.item)
+ scene.setBackgroundBrush(QtCore.Qt.darkGray)
+ self.setScene(scene)
+ self.setCacheMode(QtWidgets.QGraphicsView.CacheBackground)
+ self.setViewportUpdateMode(QtWidgets.QGraphicsView.BoundingRectViewportUpdate)
+ self.setRenderHint(QtGui.QPainter.Antialiasing)
+ self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
+ self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorViewCenter)
+ self.ramanctrl = RamanControl()
+ self.simulatedRaman = simulatedRaman
+ #determine, if ramanSwitch is needed:
+ self.ramanctrl.connect()
+ if not self.ramanctrl.connected:
+ QtWidgets.QMessageBox.warning(self, 'Error', 'Please enable Raman Connection')
+ return
+ if self.ramanctrl.getImageDimensions(mode='bf')[0] == self.ramanctrl.getImageDimensions(mode='df')[0]:
+ self.ramanSwitchNeeded = False
else:
- wxs, wys = width/self.dataset.pixelscale_bf, height/self.dataset.pixelscale_bf
-
- self.scanitems = []
- for i, p in enumerate(p1):
- p = self.dataset.mapToPixel(p, self.microscopeMode, force=True)
- s = ScanIndicator(i+1, wxs, wys, p)
- self.scene().addItem(s)
- self.scanitems.append(s)
-
- @QtCore.pyqtSlot()
- def resetBoundary(self):
- micMode = self.microscopeMode
- edges, nodes = self.boundaryitems
- for item in edges:
- self.scene().removeItem(item)
- for item in nodes:
- self.scene().removeItem(item)
- edges, nodes = [], []
- for p in self.dataset.boundary:
- p = self.dataset.mapToPixel(p, micMode, force=True)
- n = Node(p, self)
- nodes.append(n)
- self.scene().addItem(n)
- for i in range(len(nodes)):
- e = Edge(nodes[i-1], nodes[i])
- edges.append(e)
- self.scene().addItem(e)
- self.boundaryitems = edges, nodes
- self.resetScanPositions()
-
- @QtCore.pyqtSlot(int, bool)
- def selectContour(self, index, centerOn=True):
- if self.analysiswidget is not None:
- if self.analysiswidget.uniquePolymers is not None:
- #the index is the contour index, find particle index:
- specIndex = self.analysiswidget.particles2spectra[index][0] #select first spectrum of partoicle
- self.analysiswidget.currentParticleIndex = index
- self.analysiswidget.currentSpectrumIndex = specIndex
+ self.ramanSwitchNeeded = True
+ self.ramanctrl.disconnect()
+
+ self.drag = None
+ self.mode = None
+ self.dataset = None
+ self.fititems = []
+ self.boundaryitems = [[],[]]
+ self.scanitems = []
+ self.ramanscanitems = []
+ self.imgdata = None
+ self.isblocked = False
+ self.contouritem = SegmentationContours(self)
+ scene.addItem(self.contouritem)
+ self.detectionwidget = None
+ self.ramanwidget = RamanScanUI(self.ramanctrl, None, self.logpath, self)
+ self.ramanwidget.imageUpdate.connect(self.loadPixmap)
+ self.oscanwidget = OpticalScan(self.ramanctrl, None, self.logpath, self)
+ self.oscanwidget.imageUpdate.connect(self.loadPixmap)
+ self.oscanwidget.boundaryUpdate.connect(self.resetBoundary)
+ self.analysiswidget = None
+ self.setMinimumSize(600, 600)
+ self.darkenPixmap = False
+ self.microscopeMode = None
+ self.coordTestMode = False
+
+ def takeScreenshot(self):
+ #TODO:
+ #LIMIT SCREENSHOT TO ACTUAL VIEWSIZE OF LOADED IMAGE...
+ #hide scrollbars
+ self.setHorizontalScrollBarPolicy(1)
+ self.setVerticalScrollBarPolicy(1)
+ #capture screen
+ screen = QtWidgets.QApplication.primaryScreen()
+ self.repaint()
+ screenshot = screen.grabWindow(self.winId())
+ #unhide scrollbars
+ self.setHorizontalScrollBarPolicy(0)
+ self.setVerticalScrollBarPolicy(0)
+
+ fname = self.dataset.path + '/screenshot.png'
+ validFileName = False
+ incr = 1
+ while not validFileName:
+ if not os.path.exists(fname):
+ validFileName = True
+ else:
+ fname = self.dataset.path + '/screenshot ({}).png'.format(incr)
+ incr += 1
+ screenshot.save(fname , 'png')
+ QtWidgets.QMessageBox.about(self, 'Message', 'Saved as {} to project directory.'.format(fname.split('/')[-1]))
+
+ def closeEvent(self, event):
+ reply = QtWidgets.QMessageBox.question(self, 'Message',
+ "Are you sure to quit?", QtWidgets.QMessageBox.Yes |
+ QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
+
+ if reply == QtWidgets.QMessageBox.Yes:
+ self.disconnectRaman()
+ self.saveDataSet()
+ event.accept()
+ self.oscanwidget.close()
+ if self.detectionwidget is not None:
+ self.detectionwidget.close()
+ if self.analysiswidget is not None:
+ self.analysiswidget.close()
+ self.ramanwidget.close()
+ else:
+ event.ignore()
+
+ def configureRamanControl(self):
+ self.configWin = RamanConfigWin(self)
+ self.configWin.show()
+
+ def saveDataSet(self):
+ if self.dataset is not None:
+ self.dataset.save()
+
+ @QtCore.pyqtSlot()
+ def zoomIn(self):
+ self.scaleImage(1.25)
+
+ @QtCore.pyqtSlot()
+ def zoomOut(self):
+ self.scaleImage(0.8)
+
+ @QtCore.pyqtSlot()
+ def normalSize(self):
+ self.scaleFactor = 1.0
+ self.setTransform(QtGui.QTransform.fromScale(1., 1.))
+ self.announceScaling()
+
+ @QtCore.pyqtSlot()
+ def fitToWindow(self):
+# print("fitting to Window")
+ brect = self.item.sceneBoundingRect()
+ self.fitInView(0, 0, brect.width(), brect.height(), QtCore.Qt.KeepAspectRatio)
+ self.scaleFactor = self.transform().m11()
+ self.announceScaling()
+
+ def switchMode(self, mode, loadnew=False):
+ if mode is None:
+ return
+ assert mode in ["OpticalScan", "ParticleDetection", "RamanScan", "ParticleAnalysis"]
+ self.oscanwidget.setVisible(False)
+ if self.detectionwidget is not None:
+ self.detectionwidget.close()
+ self.detectionwidget.destroy()
+ self.ramanwidget.setVisible(False)
+ self.contouritem.resetContours([])
+ self.mode = mode
+ self.loadPixmap(self.microscopeMode)
+ if mode == "OpticalScan":
+ self.oscanwidget.setVisible(True)
+ self.oscanwidget.resetDataset(self.dataset)
+
+ elif mode == "ParticleDetection":
+ if self.detectionwidget is None:
+ self.detectionwidget = ParticleDetectionView(self.imgdata, self.dataset, self)
+ self.detectionwidget.show()
+ self.detectionwidget.imageUpdate.connect(self.detectionUpdate)
+ self.detectionwidget.detectionFinished.connect(self.activateMaxMode)
+
+ elif mode == "RamanScan":
+ self.ramanwidget.resetDataset(self.dataset)
+ self.ramanwidget.setVisible(True)
+
+ elif mode == "ParticleAnalysis":
+ if self.ramanwidget.isVisible():
+ self.ramanwidget.setVisible(False)
+ if self.analysiswidget is None:
+ print('creating new analysiswidget')
+ self.analysiswidget = ParticleAnalysis(self.dataset, self)
+ self.analysiswidget.showMaximized()
+ else:
+ print('show maximized already exisiting analysiswidget')
+ self.analysiswidget.showMaximized()
+
+# self.ramanwidget.setVisible(False)
+ if self.detectionwidget is not None:
+ self.detectionwidget.setVisible(False)
+
+ #show legend:
+ self.imparent.legend.show()
+
+ if loadnew:
+ self.fitToWindow()
+ self.imparent.updateModes(mode, self.getMaxMode())
+
+ def open(self, fname):
+ self.saveDataSet()
+
+ #close all widgets
+ for widget in [self.detectionwidget, self.ramanwidget, self.oscanwidget, self.analysiswidget]:
+ if widget is not None:
+ widget.close()
+ widget.destroy()
+ del widget
- selectedPolymer = self.analysiswidget.currentPolymers[specIndex]
- try:
- self.analysiswidget.polymerIndex = self.analysiswidget.uniquePolymers.index(selectedPolymer)
- except:
- print(selectedPolymer)
- raise
+ self.contouritem.resetContours()
+# if self.dataset is not None:
+# del self.dataset
+# self.scene().removeItem(self.contouritem)
+# del self.contouritem
+# self.contouritem = SegmentationContours(self)
+# self.scene().addItem(self.contouritem)
+
+ self.dataset = loadData(fname)
+ self.setMicroscopeMode()
+ self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else ""))
+ self.imgdata = None
+ self.activateMaxMode(loadnew=True)
+ self.imparent.snapshotAct.setEnabled(True)
+
+ def importProject(self, fname):
+ zimp = ZeissImporter(fname, self.ramanctrl, self)
+ if zimp.validimport:
+ zimp.exec()
+ if zimp.result() == QtWidgets.QDialog.Accepted:
+ self.open(zimp.gepardname)
+
+ def new(self, fname):
+ self.saveDataSet()
+ if self.dataset is not None:
+ self.dataset.save()
+ self.dataset = DataSet(fname, newProject=True)
+ self.setMicroscopeMode()
+ self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else ""))
+ self.imgdata = None
+ self.activateMaxMode(loadnew=True)
+ self.imparent.snapshotAct.setEnabled(True)
+
+ def setMicroscopeMode(self):
+ if self.ramanSwitchNeeded:
+ self.imparent.ramanSwitch.connectToSampleView()
+ self.imparent.ramanSwitch.show()
+ self.microscopeMode = ('df' if self.imparent.ramanSwitch.df_btn.isChecked() else 'bf')
+
+ @QtCore.pyqtSlot()
+ def activateMaxMode(self, loadnew=False):
+ mode = self.getMaxMode()
+ self.imparent.updateModes(self.mode, self.getMaxMode())
+ self.switchMode(mode, loadnew=loadnew)
+
+ def blockUI(self):
+ self.isblocked = True
+ self.imparent.blockUI()
+
+ def unblockUI(self):
+ self.isblocked = False
+ self.imparent.unblockUI(self.ramanctrl.connected)
+ self.imparent.updateModes(self.mode, self.getMaxMode())
+
+ def getMaxMode(self):
+ if self.dataset is None:
+ return None
+ if not self.ramanctrl.connected:
+ self.connectRaman()
+ if not self.ramanctrl.connected:
+ return None
+ maxmode = "OpticalScan"
+ if os.path.exists(self.dataset.getImageName()):
+ maxmode = "ParticleDetection"
+ if len(self.dataset.ramanpoints)>0:
+ maxmode = "RamanScan"
+ if self.dataset.ramanscandone: #uncomment!!
+ maxmode = "ParticleAnalysis"
+ return maxmode
+
+ def mousePressEvent(self, event):
+# if event.button()==QtCore.Qt.RightButton:
+ if event.button()==QtCore.Qt.MiddleButton:
+ self.drag = event.pos()
+ elif event.button()==QtCore.Qt.LeftButton and self.mode in ["OpticalScan", "RamanScan"] \
+ and event.modifiers()==QtCore.Qt.ControlModifier:
+ p0 = self.mapToScene(event.pos())
+ if self.dataset is not None and self.dataset.pshift is not None:
+ if self.dataset.readin:
+ reply = QtWidgets.QMessageBox.critical(self, 'Dataset is newly read from disk!',
+ "Coordinate systems might have changed since. Do you want to continue with saved coordinates?",
+ QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
+
+ if reply == QtWidgets.QMessageBox.Yes:
+ self.dataset.readin = False
+ else:
+ return
+ x, y, z = self.dataset.mapToLengthRaman([p0.x(), p0.y()],
+ microscopeMode=self.microscopeMode,
+ noz=(False if self.mode=="RamanScan" else True))
+ if z is not None:
+ assert z>-100.
+ self.ramanctrl.moveToAbsolutePosition(x, y, z)
+ elif event.button()==QtCore.Qt.LeftButton and self.mode=="ParticleDetection":
+ p0 = self.mapToScene(event.pos())
+ self.detectionwidget.setImageCenter([p0.x(), p0.y()])
+# elif event.button()==QtCore.Qt.LeftButton and self.mode=="ParticleAnalysis":
+# p0 = self.mapToScene(event.pos())
+
+ else:
+ p0 = self.mapToScene(event.pos())
+ super(SampleView, self).mousePressEvent(event)
+
+ def mouseMoveEvent(self, event):
+ if self.drag is not None:
+ p0 = event.pos()
+ move = self.drag-p0
+ self.horizontalScrollBar().setValue(move.x() + self.horizontalScrollBar().value())
+ self.verticalScrollBar().setValue(move.y() + self.verticalScrollBar().value())
+
+ self.drag = p0
+ else:
+ super(SampleView, self).mouseMoveEvent(event)
+
+ def mouseReleaseEvent(self, event):
+ self.drag = None
+ super(SampleView, self).mouseReleaseEvent(event)
+
+ def wheelEvent(self, event):
+ factor = 1.01**(event.angleDelta().y()/8)
+ self.scaleImage(factor)
+
+ def scaleImage(self, factor):
+ if factor<1 and not self.imparent.zoomOutAct.isEnabled():
+ return
+ if factor>1 and not self.imparent.zoomInAct.isEnabled():
+ return
+ self.scaleFactor *= factor
+ self.scale(factor, factor)
+ self.announceScaling()
+
+ def announceScaling(self):
+ pixelscale = self.dataset.getPixelScale(self.microscopeMode)
+ if self.dataset is None or pixelscale is None:
+ self.ScalingChanged.emit(-1.0)
+ else:
+ self.ScalingChanged.emit(pixelscale/self.scaleFactor) ##CURRENTLY ONLY DARKFIELD!!! FIX NEEDED!!!
+
+ def connectRaman(self):
+ if not self.ramanctrl.connect():
+ msg = QtWidgets.QMessageBox()
+ msg.setText("Connection failed! Please enable remote control.")
+ msg.exec()
+ else:
+ mode = self.getMaxMode()
+ self.switchMode(mode)
+ self.imparent.updateConnected(self.ramanctrl.connected)
+
+ def disconnectRaman(self):
+ self.ramanctrl.disconnect()
+ self.imparent.updateConnected(self.ramanctrl.connected)
+
+ @QtCore.pyqtSlot(str)
+ def detectionUpdate(self):
+ self.contouritem.resetContours(self.dataset.particlecontours)
+ self.prepareAnalysis()
+ self.update()
+
+ @QtCore.pyqtSlot(str)
+ def loadPixmap(self, microscope_mode='df'):
+ self.clearItems()
+ if self.dataset is None:
+ self.item.setPixmap(QtGui.QPixmap())
+ else:
+ data = self.imgdata
+ fname = self.dataset.getImageName()
+ if self.mode == "ParticleDetection" or self.mode == "ParticleAnalysis":
+ self.contouritem.resetContours(self.dataset.particlecontours)
+ if data is None and os.path.exists(fname):
+ data = cv2.cvtColor(cv2imread_fix(fname), cv2.COLOR_BGR2RGB)
+ self.imgdata = data
+ if data is not None:
- #subparticleIndex
- partIndicesOfThatPolymer = self.analysiswidget.indices[self.analysiswidget.polymerIndex]
- subPartInd = partIndicesOfThatPolymer.index(index)
+ height, width, channel = data.shape
+ bytesPerLine = 3 * width
+ pix = QtGui.QPixmap()
+ pix.convertFromImage(QtGui.QImage(data.data,
+ width, height, bytesPerLine, QtGui.QImage.Format_RGB888))
- #disconnect analysis widgets:
- self.analysiswidget.particleSelector.valueChanged.disconnect()
- self.analysiswidget.spectrumSelector.valueChanged.disconnect()
- self.analysiswidget.polymerComboBox.currentIndexChanged.disconnect()
+ self.item.setPixmap(pix)
- #set widgets...
- self.analysiswidget.particleSelector.setValue(subPartInd+1)
- self.analysiswidget.particleSelector.setMaximum(len(partIndicesOfThatPolymer))
+ if self.darkenPixmap:
+ self.scene().setBackgroundBrush(QtGui.QColor(5, 5, 5))
+ self.item.setOpacity(0.2)
+ else:
+ self.scene().setBackgroundBrush(QtCore.Qt.darkGray)
+ self.item.setOpacity(1)
- self.analysiswidget.spectrumSelector.setValue(1)
- self.analysiswidget.spectrumSelector.setMaximum(len(self.analysiswidget.particles2spectra[index]))
- selectedPolymer = self.analysiswidget.currentPolymers[specIndex]
- self.analysiswidget.polymerIndex = self.analysiswidget.uniquePolymers.index(selectedPolymer)
- self.analysiswidget.polymerComboBox.setCurrentIndex(self.analysiswidget.polymerIndex)
-
- #reconnect all widgets:
- self.analysiswidget.particleSelector.valueChanged.connect(self.analysiswidget.selectParticle)
- self.analysiswidget.spectrumSelector.valueChanged.connect(self.analysiswidget.selectSpectrum)
- self.analysiswidget.polymerComboBox.currentIndexChanged.connect(self.analysiswidget.displayNewPolymerType)
+ else:
+ self.item.setPixmap(QtGui.QPixmap())
+ if self.mode == "OpticalScan":
+ for i, p in zip(self.dataset.fitindices, self.dataset.fitpoints):
+ p = self.dataset.mapToPixel(p, mode=microscope_mode, force=True)
+ fititem = FitPosIndicator(i+1, pos=p)
+ self.scene().addItem(fititem)
+ self.fititems.append(fititem)
+ if self.mode == "ParticleDetection" or self.mode == "ParticleAnalysis":
+ self.prepareAnalysis()
+ else:
+ self.fitToWindow()
+
+ @QtCore.pyqtSlot()
+ def resetScanPositions(self):
+ micMode = ('df' if self.oscanwidget.df_btn.isChecked() else 'bf')
+ for item in self.scanitems:
+ self.scene().removeItem(item)
+ edges, nodes = self.boundaryitems
+ boundary = []
+ for n in nodes:
+ p = n.pos().x(), n.pos().y()
+ boundary.append(self.dataset.mapToLength(p, self.microscopeMode, force=True))
+ boundary = np.array(boundary)
+# print(boundary)
+ self.dataset.boundary = boundary
+ if micMode == 'df':
+ width, height, angle = self.dataset.imagedim_df
+ else:
+ width, height, angle = self.dataset.imagedim_bf
+
+ margin = min(width, height)*0.02
+ wx, wy = width-margin, height-margin
+ print(wx,wy)
+ p1 = polygoncovering(boundary, wx, wy)
+ b2 = boundary.copy()
+ b2 = b2[:,[1,0]]
+ p2 = polygoncovering(b2, wy, wx)
+ if len(p2)0:
+ data = []
+ for i in self.dataset.ramanscansortindex:
+# data.append(list(self.dataset.ramanpoints[i])+list(self.dataset.particlestats[i]))
+ data.append(list(self.dataset.ramanpoints[i])) #particlestats are not needed here. Plus, they dont need to match spectra indices anymore..
+ for i in range(len(data)):
+ item = RamanScanIndicator(self, i+1, 20, (data[i][0],data[i][1]))
+ self.scene().addItem(item)
+ self.ramanscanitems.append(item)
- self.analysiswidget.updateSpecPlot(centerOn=centerOn)
+ def highLightRamanIndex(self, index):
+ if index < len(self.ramanscanitems):
+ for item in self.ramanscanitems:
+ item.setHighLight(False)
+ self.ramanscanitems[index].setHighLight(True)
+
+ def centerOnRamanIndex(self, index, centerOn=True, highlightContour=True):
+ if centerOn:
+ self.centerOn(self.ramanscanitems[index])
+
+# if highlightContour:
+# self.contouritem.selectedContours = []
+# else:
+# self.ensureVisible(self.ramanscanitems[index])
+
+
+ def clearItems(self):
+ for item in self.fititems:
+ self.scene().removeItem(item)
+ self.fititems = []
+ for item in self.scanitems:
+ self.scene().removeItem(item)
+ edges, nodes = self.boundaryitems
+ for item in edges:
+ self.scene().removeItem(item)
+ for item in nodes:
+ self.scene().removeItem(item)
+ self.scanitems = []
+ self.boundaryitems = [], []
+ for item in self.ramanscanitems:
+ self.scene().removeItem(item)
+ self.ramanscanitems = []
-
- def prepareAnalysis(self):
- self.clearItems()
- if self.dataset.ramanscansortindex is not None and len(self.dataset.ramanscansortindex)>0:
- data = []
- for i in self.dataset.ramanscansortindex:
-# data.append(list(self.dataset.ramanpoints[i])+list(self.dataset.particlestats[i]))
- data.append(list(self.dataset.ramanpoints[i])) #particlestats are not needed here. Plus, they dont need to match spectra indices anymore..
- for i in range(len(data)):
- item = RamanScanIndicator(self, i+1, 20, (data[i][0],data[i][1]))
- self.scene().addItem(item)
- self.ramanscanitems.append(item)
-
- def highLightRamanIndex(self, index):
- if index < len(self.ramanscanitems):
- for item in self.ramanscanitems:
- item.setHighLight(False)
- self.ramanscanitems[index].setHighLight(True)
-
- def centerOnRamanIndex(self, index, centerOn=True, highlightContour=True):
- if centerOn:
- self.centerOn(self.ramanscanitems[index])
-
-# if highlightContour:
-# self.contouritem.selectedContours = []
-# else:
-# self.ensureVisible(self.ramanscanitems[index])
-
-
- def clearItems(self):
- for item in self.fititems:
- self.scene().removeItem(item)
- self.fititems = []
- for item in self.scanitems:
- self.scene().removeItem(item)
- edges, nodes = self.boundaryitems
- for item in edges:
- self.scene().removeItem(item)
- for item in nodes:
- self.scene().removeItem(item)
- self.scanitems = []
- self.boundaryitems = [], []
- for item in self.ramanscanitems:
- self.scene().removeItem(item)
- self.ramanscanitems = []
-
\ No newline at end of file
diff --git a/viewitems.py b/viewitems.py
index cc9aecbfca8482a7bccf14006e447db1daef15a4..6e709f03b899fe9e33187ea2afb01c3c2c6df223 100644
--- a/viewitems.py
+++ b/viewitems.py
@@ -22,7 +22,7 @@ import numpy as np
from PyQt5 import QtCore, QtWidgets, QtGui
class SegmentationContours(QtWidgets.QGraphicsItem):
- def __init__(self, parent=None, contours=[], pos=(0,0)):
+ def __init__(self, parent, contours=[], pos=(0,0)):
super().__init__()
self.parent = parent
self.setPos(pos[0], pos[1])
@@ -122,14 +122,14 @@ class SegmentationContours(QtWidgets.QGraphicsItem):
for index in self.selectedContours:
# partIndex = int(np.where(self.parent.dataset.ramanscansortindex == index)[0])
partIndex = index
- assignments.append(self.parent.analysiswidget.particleResults[partIndex])
+ assignments.append(self.analysiswidget.datastats.particleResults[partIndex])
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.uniquePolymers:
+ for polymer in self.analysiswidget.datastats.getUniquePolymers():
reassignActs.append(reassignMenu.addAction(polymer))
reassignActs.append(reassignMenu.addAction("other"))
@@ -156,7 +156,7 @@ class SegmentationContours(QtWidgets.QGraphicsItem):
# QtWidgets.QMessageBox.about(self.parent, "Not yet implemented", "we are getting there...")
# return
- self.parent.analysiswidget.editor.combineParticles(self.selectedContours, newAssignment)
+ self.analysiswidget.editor.combineParticles(self.selectedContours, newAssignment)
elif action in reassignActs:
newAssignment = action.text()
@@ -164,7 +164,7 @@ class SegmentationContours(QtWidgets.QGraphicsItem):
# QtWidgets.QMessageBox.about(self.parent, "Not yet implemented", "we are getting there...")
# return
- self.parent.analysiswidget.editor.reassignParticles(self.selectedContours, newAssignment)
+ self.analysiswidget.editor.reassignParticles(self.selectedContours, newAssignment)
class FitPosIndicator(QtWidgets.QGraphicsItem):