Commit 15c7be2e authored by Lars Bittrich's avatar Lars Bittrich
Browse files

further restructuring of code in respect to analysisview; pixelscale modes are...

further restructuring of code in respect to analysisview; pixelscale modes are now handled in dataset; dataset object are now able to be compared for consistency checks later;
parent 58e2489c
Loading
Loading
Loading
Loading
+48 −4
Original line number Diff line number Diff line
@@ -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()
@@ -490,6 +491,48 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
        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()
        self.particleSelector.setMaximum(len(self.datastats.indices[self.polymerIndex]))
@@ -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
            
+27 −3
Original line number Diff line number Diff line
@@ -21,6 +21,19 @@ If not, see <https://www.gnu.org/licenses/>.
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
+55 −5
Original line number Diff line number Diff line
@@ -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
                
+527 −568
Original line number Diff line number Diff line
@@ -355,7 +355,7 @@ class SampleView(QtWidgets.QGraphicsView):
        self.announceScaling()
        
    def announceScaling(self):
        pixelscale = (self.dataset.pixelscale_df if self.microscopeMode == 'df' else self.dataset.pixelscale_bf)
        pixelscale = self.dataset.getPixelScale(self.microscopeMode)
        if self.dataset is None or pixelscale is None:
            self.ScalingChanged.emit(-1.0)
        else:
@@ -453,10 +453,8 @@ class SampleView(QtWidgets.QGraphicsView):
        if len(p2)<len(p1):
            p1 = [[pi[1],pi[0]] for pi in p2]
        self.dataset.grid = p1
        if self.microscopeMode == 'df':
            wxs, wys = width/self.dataset.pixelscale_df, height/self.dataset.pixelscale_df
        else:
            wxs, wys = width/self.dataset.pixelscale_bf, height/self.dataset.pixelscale_bf
        pixelscale = self.dataset.getPixelScale(self.microscopeMode)
        wxs, wys = width/pixelscale, height/pixelscale
        
        self.scanitems = []
        for i, p in enumerate(p1):
@@ -489,46 +487,7 @@ class SampleView(QtWidgets.QGraphicsView):
    @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
                
                selectedPolymer = self.analysiswidget.currentPolymers[specIndex]
                try:
                    self.analysiswidget.polymerIndex = self.analysiswidget.uniquePolymers.index(selectedPolymer)
                except:
                    print(selectedPolymer)
                    raise
                
                #subparticleIndex
                partIndicesOfThatPolymer = self.analysiswidget.indices[self.analysiswidget.polymerIndex]
                subPartInd = partIndicesOfThatPolymer.index(index)
                
                #disconnect analysis widgets:
                self.analysiswidget.particleSelector.valueChanged.disconnect()
                self.analysiswidget.spectrumSelector.valueChanged.disconnect()
                self.analysiswidget.polymerComboBox.currentIndexChanged.disconnect()
                
                #set widgets...
                self.analysiswidget.particleSelector.setValue(subPartInd+1)
                self.analysiswidget.particleSelector.setMaximum(len(partIndicesOfThatPolymer))
                
                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)
                
                self.analysiswidget.updateSpecPlot(centerOn=centerOn)

            self.analysiswidget.selectContour(index, centerOn)
    
    def prepareAnalysis(self):
        self.clearItems()
+5 −5
Original line number Diff line number Diff line
@@ -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):