#!/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. 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 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): 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 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_axis = 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) def loadSpectraAndInitializeSpecPlot(self): self.spectra = self.dataset.particleContainer.getSpectraFromDisk() self.canvas.draw() def updateParticleSpectrum(self, specIndex, assignment, 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) if self.spectra is not None: specInfo = f'ScanPoint Number {specIndex+1}, with assignment {assignment} (hqi = {hqi})' self.spec_axis.plot(self.spectra[:, 0], self.spectra[:, specIndex+1]) self.spec_axis.set_title(specInfo, fontsize=13) 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()