analysisview.py 21 KB
Newer Older
1
# -*- coding: utf-8 -*-
2
#!/usr/bin/env python3
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
"""
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 QtCore, QtGui, QtWidgets

JosefBrandt's avatar
JosefBrandt committed
25
from .excelexport import ExpExcelDialog
26 27
from . import analysisplots
from . import analysiswidgets
JosefBrandt's avatar
 
JosefBrandt committed
28
from .loadresults import LoadTrueMatchResults
29
from .database import DataBaseWindow
JosefBrandt's avatar
 
JosefBrandt committed
30
from .colorlegend import getColorFromNameWithSeed
31
from .particleCharacterization import updateStatsOfParticlesIfNotManuallyEdited
JosefBrandt's avatar
 
JosefBrandt committed
32

Hackmet's avatar
Hackmet committed
33
try:
34
    from .sqlexport import SQLExport
Hackmet's avatar
Hackmet committed
35 36 37
    sqlEnabled = True
except:
    sqlEnabled = False
38 39


Hackmet's avatar
Hackmet committed
40
class ParticleAnalysis(QtWidgets.QMainWindow):
41 42
    def __init__(self, dataset, viewparent=None):
        super(ParticleAnalysis, self).__init__(viewparent)
43 44
        self.setWindowTitle('Results of polymer analysis')
        self.layout = QtWidgets.QHBoxLayout()
Hackmet's avatar
Hackmet committed
45 46 47 48
        self.widget = QtWidgets.QWidget()
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)
        
49
        self.viewparent = viewparent
JosefBrandt's avatar
JosefBrandt committed
50 51
        self.dataset = dataset
        self.particleContainer = dataset.particleContainer
52 53
        
        self.importWindow = None
54
        self.findcoloredParticlesWindow = None
55 56 57 58
        
        self.currentParticleIndex = 0
        self.currentSpectrumIndex = 0
        
59 60 61
        self.typeHistogramPlot = analysisplots.TypeHistogramPlot(self.dataset)
        self.sizeHistogramPlot = analysisplots.SizeHistogramPlot(self.dataset)
        self.specPlot = analysisplots.SpectraPlot(self.dataset)
62 63
        
        splitter1 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
JosefBrandt's avatar
 
JosefBrandt committed
64
        splitter1.addWidget(self.specPlot)
65
        splitter1.addWidget(self.sizeHistogramPlot)
66 67
        splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        splitter2.addWidget(splitter1)
JosefBrandt's avatar
JosefBrandt committed
68
        splitter2.addWidget(self.typeHistogramPlot)
69 70
        splitter2.setSizes([300, 150])
       
JosefBrandt's avatar
 
JosefBrandt committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
        referenceGroup = QtWidgets.QGroupBox('Reference Spectra')
        referenceLayout = QtWidgets.QHBoxLayout()
        
        self.refSelector = QtWidgets.QComboBox()
        self.refSelector.setMinimumWidth(200)
        self.refSelector.setDisabled(True)
        self.dbWin = DataBaseWindow(self)
        self.dbWin.selectDataBase(refreshParent=True)  #this includes updating the refSelector
        
        self.refSelector.currentIndexChanged.connect(self.updateSpecPlot)
        referenceLayout.addWidget(QtWidgets.QLabel('Select Reference'))
        referenceLayout.addWidget(self.refSelector)
        referenceLayout.addStretch()
        referenceGroup.setLayout(referenceLayout)

86 87 88 89
        self.navigationToolbar = analysiswidgets.PolymerNavigationToolbar(self.particleContainer)
        self.navigationToolbar.WidgetsUpdated.connect(self.updateFromNavigationToolbar)
        self.navigationToolbar.JumpToIndicatedSpec.connect(self.jumpToIndicatedSpectrum)
        self.viewparent.ParticleOfIndexSelected.connect(self.navigationToolbar.setWidgetsToNewParticleIndex)
90 91
        
        topLayout = QtWidgets.QHBoxLayout()
92
        topLayout.addWidget(self.navigationToolbar)
Hackmet's avatar
Hackmet committed
93
        topLayout.addWidget(referenceGroup)
94
        
JosefBrandt's avatar
 
JosefBrandt committed
95
        viewLayout = QtWidgets.QVBoxLayout()
96 97 98 99
        viewLayout.addLayout(topLayout)
        viewLayout.addWidget(splitter2)
        viewLayout.setStretch(1, 1)

JosefBrandt's avatar
 
JosefBrandt committed
100
        self.optionsGroup = QtWidgets.QGroupBox('Set HQI Threshold')
101 102 103 104 105
        optionsLayout = QtWidgets.QFormLayout()
        
        self.hqiSpinBox = QtWidgets.QDoubleSpinBox()
        self.hqiSpinBox.setDecimals(1)
        self.hqiSpinBox.setMinimum(0)
JosefBrandt's avatar
JosefBrandt committed
106
        self.hqiSpinBox.setMaximum(100)
JosefBrandt's avatar
 
JosefBrandt committed
107
        self.hqiSpinBox.setMaximumWidth(100)
108 109 110
        minHQI = self.dataset.resultParams['minHQI']
        if minHQI is not None:
            self.hqiSpinBox.setValue(minHQI)
JosefBrandt's avatar
 
JosefBrandt committed
111
        self.hqiSpinBox.valueChanged.connect(self.applyHQIThresholdToResults)
JosefBrandt's avatar
JosefBrandt committed
112 113 114
        minHQI = self.dataset.resultParams['minHQI']
        if minHQI is not None:
            self.hqiSpinBox.setValue(minHQI)
JosefBrandt's avatar
 
JosefBrandt committed
115
        optionsLayout.addRow(QtWidgets.QLabel('minimum HQI:'), self.hqiSpinBox)
116 117 118 119
        
        self.optionsGroup.setLayout(optionsLayout)
        self.optionsGroup.setMinimumWidth(175)
        
120 121
        self.resultCheckBoxes = analysiswidgets.PolymerTypeCheckboxes()
        self.resultCheckBoxes.PolymerCheckBoxToggled.connect(self.updatedPlotsAndContoursSelectively)
JosefBrandt's avatar
 
JosefBrandt committed
122 123
        
        self.menuLayout = QtWidgets.QVBoxLayout()
124
        self.menuLayout.addWidget(self.optionsGroup)
125
        self.menuLayout.addWidget(self.resultCheckBoxes)
126 127 128 129
        
        self.layout.addLayout(self.menuLayout)
        self.layout.addLayout(viewLayout)
         
Hackmet's avatar
Hackmet committed
130 131
        self.createActions()
        self.createMenus()
JosefBrandt's avatar
JosefBrandt committed
132
        self.applyHQIThresholdToResults()
JosefBrandt's avatar
 
JosefBrandt committed
133
        self.initializeSpecPlot()
134
        self.navigationToolbar.updateWidgets()
Hackmet's avatar
Hackmet committed
135 136 137 138 139
    
    def createActions(self):
        self.loadTrueMatchAct = QtWidgets.QAction("Load &TrueMatch Results", self)
        self.loadTrueMatchAct.triggered.connect(self.importTrueMatchResults)
        
JosefBrandt's avatar
JosefBrandt committed
140 141
        self.loadSpectraAct = QtWidgets.QAction("Load &Spectra", self)
        self.loadSpectraAct.triggered.connect(self.initializeSpecPlot)
Hackmet's avatar
Hackmet committed
142
        
143
        self.databaseAct = QtWidgets.QAction("&Manage reference spectra databases", self)
144 145
        self.databaseAct.triggered.connect(self.launchDBManager)
        
146 147 148 149 150 151
        self.findColorParticlesAct = QtWidgets.QAction("Navigate throuch &colored, not unknown particles", self)
        self.findColorParticlesAct.triggered.connect(self.launchColoredParticleWindow)
        
        self.recalculateParticleStatsAct = QtWidgets.QAction("&Recalculated particle stats", self)
        self.recalculateParticleStatsAct.triggered.connect(self.recalculateParticleStats)
        
152 153 154 155 156 157 158 159 160 161 162
        self.expExcelAct= QtWidgets.QAction("Export &Excel List", self)
        self.expExcelAct.setDisabled(True)
        self.expExcelAct.triggered.connect(self.exportToExcel)
        
        self.expSQLAct = QtWidgets.QAction("Export to &SQL Database", self)
        self.expSQLAct.setDisabled(True)
        self.expSQLAct.triggered.connect(self.exportToSQL)
        
        self.getAndActivateActionsFromGepardMain()
    
    def getAndActivateActionsFromGepardMain(self):
163 164 165 166
        """
        For user convenience, the actions from the Gepard main window are also added to the menubar of the analysis window.
        :return:
        """
167 168 169 170 171
        gepard = self.viewparent.imparent
        
        self.noOverlayAct = gepard.noOverlayAct
        self.selOverlayAct = gepard.selOverlayAct
        self.fullOverlayAct = gepard.fullOverlayAct
Hackmet's avatar
Hackmet committed
172
        
173
        self.transpAct = gepard.transpAct
174
        self.transpAct.triggered.connect(self.updateContourColors)
Hackmet's avatar
Hackmet committed
175
            
176
        self.hideLabelAct = gepard.hideLabelAct
177
        self.hideLabelAct.triggered.connect(self.showOrHideSpecNumbers)
Hackmet's avatar
Hackmet committed
178
        
179
        self.darkenAct = gepard.darkenAct
Hackmet's avatar
Hackmet committed
180 181 182 183 184 185
        self.darkenAct.triggered.connect(self.darkenBackground)
        
        for act in [self.noOverlayAct, self.selOverlayAct, self.fullOverlayAct, self.hideLabelAct, self.transpAct, self.darkenAct]:
            act.setCheckable(True)
        self.fullOverlayAct.setChecked(True)
        
186
        self.seedAct = gepard.seedAct
Hackmet's avatar
Hackmet committed
187
        self.seedAct.triggered.connect(self.updateColorSeed)
JosefBrandt's avatar
JosefBrandt committed
188
        
189 190
        for act in [self.noOverlayAct, self.selOverlayAct, self.fullOverlayAct, self.hideLabelAct, self.transpAct, self.darkenAct, self.seedAct]:
            act.setDisabled(False)
191

Hackmet's avatar
Hackmet committed
192
    def createMenus(self):
JosefBrandt's avatar
JosefBrandt committed
193 194
        self.importMenu = QtWidgets.QMenu("&Import Spectra and Results")
        self.importMenu.addActions([self.loadSpectraAct, self.loadTrueMatchAct])
Hackmet's avatar
Hackmet committed
195 196 197 198
        
        self.dispMenu = QtWidgets.QMenu("&Display", self)
        self.overlayActGroup = QtWidgets.QActionGroup(self.dispMenu)
        self.overlayActGroup.setExclusive(True)
199
        self.overlayActGroup.triggered.connect(self.updateContourColors)
200
        self.overlayActGroup.triggered.connect(self.updatePlotsAndContours)
Hackmet's avatar
Hackmet committed
201 202 203 204 205 206 207 208
        
        for act in [self.noOverlayAct, self.selOverlayAct, self.fullOverlayAct]:
            self.dispMenu.addAction(act)
            self.overlayActGroup.addAction(act)
        
        self.dispMenu.addSeparator()
        self.dispMenu.addActions([self.transpAct, self.hideLabelAct, self.darkenAct, self.seedAct])
        
209 210
        self.toolMenu = QtWidgets.QMenu("&Tools")
        self.toolMenu.addAction(self.databaseAct)
211 212
        self.toolMenu.addAction(self.findColorParticlesAct)
        self.toolMenu.addAction(self.recalculateParticleStatsAct)
Hackmet's avatar
Hackmet committed
213 214 215 216 217 218 219
        
        self.exportMenu = QtWidgets.QMenu("&Export", self)
        self.exportMenu.addAction(self.expExcelAct)
        self.exportMenu.addAction(self.expSQLAct)
        
        self.menuBar().addMenu(self.importMenu)
        self.menuBar().addMenu(self.dispMenu)
220
        self.menuBar().addMenu(self.toolMenu)
Hackmet's avatar
Hackmet committed
221
        self.menuBar().addMenu(self.exportMenu)
JosefBrandt's avatar
JosefBrandt committed
222
    
Hackmet's avatar
Hackmet committed
223
    def launchDBManager(self):
224 225 226 227
        """
        The Database Manager is launched for editing and creating databases with reference spectra
        :return:
        """
Hackmet's avatar
Hackmet committed
228 229 230
        if self.dbWin.isHidden():
            self.dbWin.show()
    
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
    def launchColoredParticleWindow(self):
        """
        Likely just a temporary function to find colored particles, as the color classification is still not perfect.
        The module finds not unknown particles that were assigned to a color and the user can confirm or change the respective colors.
        :return:
        """
        if self.findcoloredParticlesWindow is not None:
            del self.findcoloredParticlesWindow 
        self.findcoloredParticlesWindow = analysiswidgets.FindColoredParticleWindow(self)
        self.findcoloredParticlesWindow.ParticleOfIndexSelected.connect(self.navigationToolbar.setWidgetsToNewParticleIndex)
    
    def recalculateParticleStats(self):
        """
        recalculate all particle colors, if not already manually set
        """
        self.setDisabled(True)
        self.viewparent.blockUI()
        reply = QtWidgets.QMessageBox.question(self, 'Recalculate stats',
                                "Do you want recalculate stats of all particles?\nThis might take a while..",
                                QtWidgets.QMessageBox.Yes | 
                                QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
        
        if reply == QtWidgets.QMessageBox.Yes:
            updateStatsOfParticlesIfNotManuallyEdited(self.particleContainer)
            self.updatedPlotsAndContoursSelectively()
            QtWidgets.QMessageBox.about(self, 'Done', 'Recalculation is finished')
        self.viewparent.unblockUI()
        self.setDisabled(False)
    
Hackmet's avatar
Hackmet committed
260
    def populateRefSelector(self):
261 262 263 264
        """
        The Combobox for selecting references is updated to the currently selected database
        :return:
        """
Hackmet's avatar
Hackmet committed
265 266 267 268 269
        self.refSelector.clear()
        
        if self.dbWin.activeDatabase is None:
            self.refSelector.setDisabled(True)
        else:
Hackmet's avatar
Hackmet committed
270
            self.refSelector.addItem('')
Hackmet's avatar
Hackmet committed
271 272 273 274
            self.refSelector.addItems(self.dbWin.activeDatabase.spectraNames)
            self.refSelector.setDisabled(False)
            
    def importTrueMatchResults(self):
JosefBrandt's avatar
JosefBrandt committed
275 276 277
        if self.importWindow is not None:
            del self.importWindow
        
JosefBrandt's avatar
 
JosefBrandt committed
278
        self.importWindow = LoadTrueMatchResults(self.particleContainer, self)
JosefBrandt's avatar
JosefBrandt committed
279
        
280
    @QtCore.pyqtSlot()
JosefBrandt's avatar
JosefBrandt committed
281
    def applyHQIThresholdToResults(self):
282 283 284 285 286
        """
        The in the hqiSpinBox indicated value is applied to all spectra in the dataset.
        All plots are updated, as the assignment of each particle can have changed.
        :return:
        """
JosefBrandt's avatar
 
JosefBrandt committed
287 288 289 290
        hqi = self.hqiSpinBox.value()
        self.particleContainer.applyHQITresholdToParticles(hqi)
        self.dataset.resultParams['minHQI'] = hqi
        self.dataset.save()
291 292 293 294 295 296 297 298
        self.updateWidgetContents()
        self.updatePlotsAndContours()
        
    def updatePlotsAndContours(self):  
        """
        All plots are updated, the colors of the contourItems in the sampleview are updated
        :return:
        """
JosefBrandt's avatar
 
JosefBrandt committed
299 300 301 302
        self.updateTypeHistogram()
        self.updateSizeHistogram()
        self.updateContourColors()
        self.updateLegend()
303

304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
    @QtCore.pyqtSlot()
    def updatedPlotsAndContoursSelectively(self):
        """
        ONLY if a selection of polymers is to be displayed, TypeHistogram, contours and legend are updated.
        Otherwise only the sizeHistogram needs to be updated
        :return:
        """
        self.updateSizeHistogram()
        if self.selOverlayAct.isChecked():
            self.updateTypeHistogram()
            self.updateContourColors()
            self.updateLegend()
        
    def updateWidgetContents(self):
        """
        The content of all child widgets is updated to a new status in the particleContainer
        :return:
        """
JosefBrandt's avatar
JosefBrandt committed
322
        uniquePolymers = self.particleContainer.getUniquePolymers()
323 324
        self.resultCheckBoxes.updatePolymerCheckBoxes(uniquePolymers)
        self.navigationToolbar.updateWidgets()
325
        
Hackmet's avatar
Hackmet committed
326 327 328
        self.expExcelAct.setDisabled(False)
        if sqlEnabled:
            self.expSQLAct.setDisabled(False)
329
        
JosefBrandt's avatar
 
JosefBrandt committed
330 331 332
    def initializeSpecPlot(self):
        self.specPlot.loadSpectraAndInitializeSpecPlot()
        self.updateSpecPlot()
333
    
JosefBrandt's avatar
 
JosefBrandt committed
334
    def updateTypeHistogram(self):
335 336 337 338 339 340 341
        if self.particleContainer.getNumberOfParticles() > 0:
            if self.selOverlayAct.isChecked():
                histogramData = self.getSelectedTypeHistogram()
            else:
                histogramData = self.particleContainer.getTypeHistogram()
                
            self.typeHistogramPlot.updateTypeHistogram(histogramData)
JosefBrandt's avatar
 
JosefBrandt committed
342 343 344
    
    def updateSizeHistogram(self):
        if self.particleContainer.getNumberOfParticles() > 0:
345 346 347 348
            listOfSizeHistograms = []
            if self.resultCheckBoxes.showAllCheckBox.isChecked():
                totalHist = analysisplots.SizeHistogramData('total', self.particleContainer.getSizesOfAllParticles())
                listOfSizeHistograms.append(totalHist)
JosefBrandt's avatar
 
JosefBrandt committed
349
            
350 351 352
            for polymType in self.resultCheckBoxes.getSelectedPolymers(): 
                polymHist = analysisplots.SizeHistogramData(polymType, self.particleContainer.getSizesOfParticleType(polymType))
                listOfSizeHistograms.append(polymHist)
JosefBrandt's avatar
 
JosefBrandt committed
353
                
354
            self.sizeHistogramPlot.drawHistograms(listOfSizeHistograms)
JosefBrandt's avatar
 
JosefBrandt committed
355
    
356
    def updateSpecPlot(self):
JosefBrandt's avatar
 
JosefBrandt committed
357
        hqi = self.particleContainer.getHQIOfSpectrumIndex(self.currentSpectrumIndex)
JosefBrandt's avatar
JosefBrandt committed
358
        assignment = self.particleContainer.getParticleAssignmentByIndex(self.currentParticleIndex)
359
        self.specPlot.updateParticleSpectrum(self.currentSpectrumIndex, assignment, hqi)
JosefBrandt's avatar
 
JosefBrandt committed
360
            
361 362 363 364 365 366 367
        if self.refSelector.isEnabled():
            if self.refSelector.currentText() != '':
                refID = self.dbWin.activeDatabase.spectraNames.index(self.refSelector.currentText())
                ref = self.dbWin.activeDatabase.spectra[refID]
                self.specPlot.updateReferenceSpectrum(ref[:, 0], ref[:, 1])
            else:
                self.specPlot.clearReferenceSpectrum()
JosefBrandt's avatar
 
JosefBrandt committed
368
    
369
    def updateContourColors(self):
370 371 372 373
        """
        Updates the contour colors in the sampleview
        :return:
        """
374
        contours = self.viewparent.contourItems
JosefBrandt's avatar
 
JosefBrandt committed
375
        alpha = (64 if self.transpAct.isChecked() else 255)
376
        selectedPolymers = self.resultCheckBoxes.getSelectedPolymers()
JosefBrandt's avatar
 
JosefBrandt committed
377 378 379 380 381 382 383 384 385 386

        for particleIndex, contour in enumerate(contours):
            assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex)
            hidden = self.noOverlayAct.isChecked() or (not self.fullOverlayAct.isChecked() and assignment not in selectedPolymers)
            color = getColorFromNameWithSeed(assignment, self.dataset.colorSeed)
            color = QtGui.QColor(color[0], color[1], color[2], alpha=alpha)
            
            contour.setHidden(hidden)
            contour.setColor(color)
            contour.update()
387
    
JosefBrandt's avatar
 
JosefBrandt committed
388
    def updateLegend(self):
389 390 391 392
        """
        Updates the color legend in the sampleview
        :return:
        """
JosefBrandt's avatar
 
JosefBrandt committed
393 394
        if not self.noOverlayAct.isChecked():
            legendItems = []
395
            selectedPolymers = self.resultCheckBoxes.getSelectedPolymers()
JosefBrandt's avatar
 
JosefBrandt committed
396 397 398 399 400
            for polymer in self.particleContainer.getUniquePolymers():
                if self.fullOverlayAct.isChecked() or polymer in selectedPolymers:                
                    color = getColorFromNameWithSeed(polymer, self.dataset.colorSeed)
                    color = QtGui.QColor(color[0], color[1], color[2], 255)
                    legendItems.append((polymer, color))
401
            self.viewparent.updateLegend(legendItems)
JosefBrandt's avatar
 
JosefBrandt committed
402

JosefBrandt's avatar
 
JosefBrandt committed
403
        
404 405 406 407 408 409 410 411
    def getSelectedTypeHistogram(self):
        """
        returns the typeHistogram, filtered by the selection of the result CheckBoxes
        :return:
        """
        totalHist = self.particleContainer.getTypeHistogram()
        histogramData = {}
        selectedPolymers = self.resultCheckBoxes.getSelectedPolymers()
JosefBrandt's avatar
 
JosefBrandt committed
412
        
413 414 415 416 417 418 419 420 421 422 423 424 425
        for polymType in totalHist:
            if polymType in selectedPolymers:
                histogramData[polymType] = totalHist[polymType]
        return histogramData
        
    @QtCore.pyqtSlot()
    def updateFromNavigationToolbar(self):
        """
        Retrieves values from the navigation toolbar and updates the SpecPlot accordingly
        :return:
        """
        self.currentParticleIndex = self.navigationToolbar.currentParticleIndex
        self.currentSpectrumIndex = self.navigationToolbar.currentSpectrumIndex
JosefBrandt's avatar
 
JosefBrandt committed
426
        self.updateSpecPlot()
427
    
428
    @QtCore.pyqtSlot()
JosefBrandt's avatar
JosefBrandt committed
429
    def jumpToIndicatedSpectrum(self):
430 431 432 433 434
        """
        Make the sampleView jump to the indicated spectrum number and upates the SpecPlot accordingly
        :return:
        """
        self.currentSpectrumIndex = self.navigationToolbar.specNumberSelector.value()-1
JosefBrandt's avatar
 
JosefBrandt committed
435
        self.currentParticleIndex = self.particleContainer.getParticleIndexContainingSpecIndex(self.currentSpectrumIndex)
JosefBrandt's avatar
JosefBrandt committed
436
        self.viewparent.centerOnRamanIndex(self.currentSpectrumIndex)
JosefBrandt's avatar
JosefBrandt committed
437 438
        self.viewparent.highLightContour(self.currentParticleIndex)
        self.updateSpecPlot()
439 440
    
    def darkenBackground(self):
441 442 443 444
        """
        Darkens the background of the sampleview to make the overlay easier visible
        :return:
        """
445
        self.viewparent.darkenPixmap = self.darkenAct.isChecked()
446
        
Hackmet's avatar
Hackmet committed
447
        if self.darkenAct.isChecked():
448 449
            self.viewparent.scene().setBackgroundBrush(QtGui.QColor(5, 5, 5))
            self.viewparent.item.setOpacity(0.2)
450
        else:
451 452
            self.viewparent.scene().setBackgroundBrush(QtCore.Qt.darkGray)
            self.viewparent.item.setOpacity(1)
453 454

    def updateColorSeed(self):
455 456 457 458
        """
        Updates the color Seed of the dataset, which is used to get randomized colors
        :return:
        """
JosefBrandt's avatar
 
JosefBrandt committed
459
        text, ok = QtWidgets.QInputDialog.getText(self, 'Color Seed', 'Enter New Seed here', text=self.dataset.colorSeed)
460
        if ok:
JosefBrandt's avatar
 
JosefBrandt committed
461
            self.dataset.colorSeed = text
462
            self.updatePlotsAndContours()
463
    
464 465 466 467
    def showOrHideSpecNumbers(self):
        """
        Shows or hides spectraLabels in the sampleview
        """
Hackmet's avatar
Hackmet committed
468
        hidden = self.hideLabelAct.isChecked()
469
        for scanIndicator in self.viewparent.ramanscanitems:
470 471
            scanIndicator.hidden = hidden
            scanIndicator.update()
JosefBrandt's avatar
 
JosefBrandt committed
472 473
    
    def exportToExcel(self):
474 475 476 477
        """
        Opens the Excel Export Window
        :return:
        """
JosefBrandt's avatar
JosefBrandt committed
478
        expWin = ExpExcelDialog(self.dataset)
JosefBrandt's avatar
 
JosefBrandt committed
479 480 481
        expWin.exec()
            
    def exportToSQL(self):
482 483 484 485
        """
        Opens the SQL Export Window
        :return:
        """
486 487 488 489
        def launchSQLWin():
            sqlexp = SQLExport(self.dataset)
            sqlexp.exec()
            
490 491 492 493 494 495
        if len(self.dataset.resultsUploadedToSQL) > 0:
           reply = QtWidgets.QMessageBox.question(self, 'Warning!',
                                "The following results were already uploaded:\n\n{}\n\nContinue?".format('\n'.join(self.dataset.resultsUploadedToSQL)),
                                QtWidgets.QMessageBox.Yes | 
                                QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
           if reply == QtWidgets.QMessageBox.Yes:
496 497 498
                launchSQLWin()
        else:
            launchSQLWin()
499 500
    
    def closeEvent(self, event):
501
        for window in [self.importWindow, self.dbWin, self.findcoloredParticlesWindow]:
JosefBrandt's avatar
JosefBrandt committed
502 503 504
            if window is not None:
                window.close()
                
505
        self.viewparent.imparent.particelAnalysisAct.setChecked(False)
506
        event.accept()