analysisplots.py 6.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
#!/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, QtGui, QtCore
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar


class ParticleIndicator(QtWidgets.QPushButton):
    def __init__(self, number, numtotal, color, text, parent=None):
        super().__init__(parent)
        self.number = number
        self.numtotal = numtotal
        self.color = color
        self.text = text
        self.setFixedHeight(30)
        
    def paintEvent(self, event):
        r = self.number/self.numtotal
        width = self.width()
        height = self.height()
        
        qp = QtGui.QPainter()
        qp.begin(self)
        qp.setBrush(QtCore.Qt.white)
        qp.drawRoundedRect(0, 0, width, height, 5. ,5.)
        qp.setPen(self.color)
        qp.setBrush(self.color)
        qp.drawRoundedRect(0, 0, int(width*r), height, 5. ,5.)
        qp.setPen(QtCore.Qt.black)
        qp.setBrush(QtCore.Qt.NoBrush)
        qp.drawRoundedRect(0, 0, width, height, 5. ,5.)
        font = qp.font()
        font.setPointSize(13)
        font.setStyleStrategy(QtGui.QFont.NoAntialias)
        font.setWeight(0)
        qp.setFont(font)
        qp.setCompositionMode(QtGui.QPainter.RasterOp_SourceXorDestination)
        qp.setPen(QtCore.Qt.white)
        qp.drawText(5, 0, width-10, height, QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter, 
                    self.text)
        qp.end()
        
        
class TypeHistogramView(QtWidgets.QScrollArea):
    indexClicked = QtCore.pyqtSignal(int)
    def __init__(self, parent=None):
        super().__init__(parent)
        self.view = QtWidgets.QWidget(self)
        self.view.setCursor(QtGui.QCursor(QtCore.Qt.WhatsThisCursor))
        self.view.setMinimumWidth(250)
        
        group = QtWidgets.QGroupBox('Polymer Type Distribution', self.view)
        self.indicatorbox = QtWidgets.QVBoxLayout()
        self.indicatorbox.setContentsMargins(5,5,5,5)
        group.setLayout(self.indicatorbox)
        
        hbox = QtWidgets.QHBoxLayout()
        hbox.addWidget(group)
        self.view.setLayout(hbox)
        self.setWidgetResizable(True)
        self.setWidget(self.view)
        self.setAlignment(QtCore.Qt.AlignHCenter)
        self.widgets = []
        
    def updateTypeHistogram(self, types):
#        print("Updating polymer type view", flush=True)
        for pi in self.widgets:
            self.indicatorbox.removeWidget(pi)
            pi.setParent(None)
            pi.destroy()
        self.indicatorbox.takeAt(0)
        self.widgets = []
        numtotal = sum([num for num, text, color in types])
        
        def getIndexFunction(index):
            return lambda : self.indexClicked.emit(index)
        
        for index, entry in enumerate(types):
            num, text, color = entry
#            print("num, text, color:", num, text, color, flush=True)
            pi = ParticleIndicator(num, numtotal, color, text)
            self.indicatorbox.addWidget(pi)
            pi.clicked.connect(getIndexFunction(index))
            self.widgets.append(pi)
        self.indicatorbox.addStretch()
        self.view.update()


class SpectraPlot(QtWidgets.QGroupBox):
    def __init__(self, dataset):
        super(SpectraPlot, self).__init__()
        self.dataset = dataset
        self.spectra = None
        
        layout = QtWidgets.QHBoxLayout()
        self.canvas = FigureCanvas(Figure())
        self.spec_axis = self.canvas.figure.subplots()
        self.reference_ax = self.spec_axis.twinx()
        self.canvas.figure.subplots_adjust(left=0.1, top=0.93, bottom=0.15, right=0.9)
        specNavigation = NavigationToolbar(self.canvas, self)
        specNavigation.setOrientation(QtCore.Qt.Vertical)
        specNavigation.setFixedWidth(50)
        
        layout.addWidget(specNavigation)
        layout.addWidget(self.canvas)
        self.setLayout(layout)
        
JosefBrandt's avatar
JosefBrandt committed
128 129
    def loadSpectraAndInitializeSpecPlot(self):
        self.spectra = self.dataset.particleContainer.getSpectraFromDisk()
130 131
        self.canvas.draw()
        
JosefBrandt's avatar
JosefBrandt committed
132 133 134 135 136 137 138 139
    def updateParticleSpectrum(self, specIndex, assignment, particleSize, hqi):
        #draw Sample Spectrum
        self.spec_axis.axis("on")
        self.spec_axis.clear()
        self.spec_axis.tick_params(axis='both', which='both', labelsize=15)
        self.spec_axis.set_xlabel('Wavenumber (cm-1)', fontsize = 15)
        self.spec_axis.set_ylabel('Counts', fontsize = 15)
        
140 141
        if self.spectra is not None:
            self.spec_axis.plot(self.spectra[:, 0], self.spectra[:, specIndex+1])
JosefBrandt's avatar
JosefBrandt committed
142
            self.spec_axis.set_title('{}, ScanPoint Number {}, Size = {} µm, HQI = {}'.format(assignment, specIndex+1, particleSize, hqi))
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
            self.spec_axis.set_xbound(100, (3400 if self.spectra[-1, 0] > 3400 else self.spectra[-1, 0]))
            wavenumber_diff = list(self.spectra[:, 0]-100)
            y_start = wavenumber_diff.index(min(wavenumber_diff))
            y_min = min(self.spectra[y_start:, specIndex+1])
            y_max = max(self.spectra[y_start:, specIndex+1])
            self.spec_axis.set_ybound(0.9*y_min, 1.1*y_max)
            
        self.canvas.draw()
    
    def updateReferenceSpectrum(self, ref_wavenumber, ref_intensity):
        #draw Reference
        self.reference_axis.clear()
        self.reference_axis.tick_params(axis='both', which='both', labelsize=15)
        self.reference_axis.plot(ref_wavenumber, ref_intensity, color = 'r')
        self.reference_axis.set_ylabel('Ref. Intensity', fontsize = 15, color = 'r')
        self.reference_axis.tick_params('y', colors = 'r')
        self.reference_axis.set_xbound(100, (3400 if self.spectra[-1, 0] > 3400 else self.spectra[-1, 0]))
        
        self.canvas.draw()