def __new__(cls, clear_cache = False): if not cls._instance: cls._instance = super(Settings, cls).__new__(cls) cls._instance.signals = Settings.signals() QSettings.setDefaultFormat(QSettings.IniFormat) log.DEBUG("saving settings in file %s" %(QSettings().fileName())); cls._instance._settings = QSettings() cls._defaults = { Settings.DOTA_PATH_KEY: dota_path_default, Settings.STEAM_PATH_KEY: steam_path_default, } if clear_cache: cls._instance._cache = {} return cls._instance
def closeEvent(self, QCloseEvent): settings = QSettings() settings.setValue('width', QVariant(self.settings['width'])) settings.setValue('color', QVariant(self.settings['color'])) settings.setValue('x_grid', QVariant(self.settings['x_grid'])) settings.setValue('y_grid', QVariant(self.settings['y_grid'])) settings.setValue('grid_opacity', QVariant(self.settings['grid_opacity']))
def read_settings(self): logging.debug('Reading settings') settings = QSettings() read_settings = self.defaults.copy() keys = settings.allKeys() for k in keys: setting_type = QTouTvSettings._settings_types[k] read_settings[k] = settings.value(k, type=setting_type) self.apply_settings(read_settings)
def steam_path_default(): path = "" if os.name == "nt": path = str(QSettings("HKEY_CURRENT_USER\\Software\\Valve\\Steam", QSettings.NativeFormat).value("SteamPath", "").toString()) elif sys.platform == "darwin": path = expanduser("~/Library/Application Support/Steam") else: path = expanduser("~/.steam/steam") if not exists(path): log.CRITICAL("No Steam folder found! Please install it or adjust the settings!") Settings.steam_missing = True return normpath(path)
def write_settings(self): logging.debug('Writing settings') settings = QSettings() settings.clear() for k in self._settings_dict: if k in self.defaults: if self._settings_dict[k] != self.defaults[k]: settings.setValue(k, self._settings_dict[k]) else: msg = 'Setting key {} not found in defaults'.format(k) logging.warning(msg) settings.setValue(k, self._settings_dict[k])
def load_save_settings(self): self.settings = { 'width': 2, 'color': 'blue', 'x_grid': True, 'y_grid': True, 'grid_opacity': 0.5 } settings = QSettings() self.settings['width'] = settings.value( 'width', self.settings.get('width')).toInt()[0] self.settings['color'] = settings.value( 'color', self.settings.get('color')).toString() self.settings['x_grid'] = settings.value( 'x_grid', self.settings.get('x_grid')).toBool() self.settings['y_grid'] = settings.value( 'y_grid', self.settings.get('y_grid')).toBool() self.settings['grid_opacity'] = settings.value( 'grid_opacity', self.settings.get('grid_opacity')).toFloat()[0]
def __init__(self, organization, product): self.config = QSettings(organization, product)
class FileSelectionDialog(QtGui.QDialog): """ """ fileChanged = pyqtSignal() settings = QSettings("CIBR", "Eggie") def __init__(self, parent): """ Dialog for setting the raw file and environment variables. """ QtGui.QDialog.__init__(self, parent) self.parent = parent self.ui = Ui_FileSelectDialog() self.ui.setupUi(self) mneRoot = os.environ.get('MNE_ROOT', '') if mneRoot == "": mneRoot = self.settings.value("MNE_ROOT", "").toString() self.ui.lineEditMneRoot.setText(mneRoot) self.show() def on_pushButtonConvertEdf_clicked(self, checked=None): """ Opens a dialog for converting files to fif. """ if checked is None: return self.mneRoot = self.ui.lineEditMneRoot.text() if str(self.mneRoot) is '': QtGui.QMessageBox.critical( self, "Cannot convert", "MNE_ROOT must be set before conversion", "Ok") return self.edfToFifDialog = EdfToFifDialog(self.mneRoot) self.edfToFifDialog.edfConverted.connect(self.edfConverted) self.edfToFifDialog.updateUi.connect(self.parent.updateUi) self.edfToFifDialog.show() def on_pushButtonBrowse_clicked(self, checked=None): """ Opens a dialog for selecting a raw file. """ if checked is None: return self.fname = str( QtGui.QFileDialog.getOpenFileName( self, 'Open file', '/home/', "Fif-files (*.fif);;All files (*.*)")) if self.fname != '': self.ui.lineEditRawFile.setText(self.fname) def on_pushButtonShowInfo_clicked(self, checked=None): """ Opens a dialog for showing file info. Called when show info button is clicked. """ if checked is None: return QtGui.QApplication.setOverrideCursor(QtGui.QCursor(Qt.WaitCursor)) print str(self.ui.lineEditRawFile.text()) try: raw = mne.io.Raw(str(self.ui.lineEditRawFile.text())) except Exception as e: messageBox = QtGui.QMessageBox() messageBox.setText(str(e)) QtGui.QApplication.restoreOverrideCursor() messageBox.exec_() info = Ui_infoDialog() infoDialog = InfoDialog(raw, info, True) QtGui.QApplication.restoreOverrideCursor() infoDialog.exec_() @pyqtSlot(str) def edfConverted(self, fifName): """ Slot for setting the file name to the line edit. Parameters: fifName - The name of the file. """ self.ui.lineEditRawFile.setText(fifName) def accept(self, *args, **kwargs): """ Called when ok button is clicked. If raw file is successfully loaded, a fileChanged -signal is emitted. """ QtGui.QApplication.setOverrideCursor(QtGui.QCursor(Qt.WaitCursor)) mneRoot = self.ui.lineEditMneRoot.text() if str(mneRoot) is '': messageBox = QtGui.QMessageBox() messageBox.setText("Environment variables MNE_ROOT " + "must be set!") messageBox.exec_() QtGui.QApplication.restoreOverrideCursor() return else: self.settings.setValue("MNE_ROOT", mneRoot) caller = Caller.Instance() preload = self.ui.checkBoxPreload.isChecked() try: caller.setRaw(str(self.ui.lineEditRawFile.text()), self.parent, preload) self.fileChanged.emit() except Exception as e: messageBox = QtGui.QMessageBox() messageBox.setText("Cannot open file. ") messageBox.setInformativeText(str(e)) messageBox.exec_() QtGui.QApplication.restoreOverrideCursor() QtGui.QDialog.accept(self, *args, **kwargs) QtGui.QApplication.restoreOverrideCursor()
class SaveDialog(QtGui.QDialog): caller = Caller.Instance() e = Event() error = False # Boolean to notify error in worker thread. settings = QSettings("CIBR", "Eggie") def __init__(self, parent): """ """ QtGui.QDialog.__init__(self) self.ui = Ui_SaveDialog() self.ui.setupUi(self) self.parent = parent #self.ui.buttonBox.button(QtGui.QDialogButtonBox.Save).clicked.\ # connect(self.on_SaveClicked) #fName = self.caller.raw.info['filename'] # Remove file-extension and add -pre.fif self.ui.lineEditPath.setText(self.settings.value("SaveFolder", "").\ toString()) fullPath = self.caller.raw.info['filename'].\ rsplit('.', 1)[0] + '-pre.fif' fName = fullPath.rsplit('/', 1) if len(fName) == 2: self.ui.lineEditFileName.setText(fName[1]) if self.ui.lineEditPath.text() == "": self.ui.lineEditPath.setText(fName[0]) #self.caller.raw.save(fName, preload=True) def on_pushButtonBrowse_clicked(self, checked=None): """ Called when browse button is clicked. Opens a dialog for choosing a directory. """ if checked is None: return path = str( QtGui.QFileDialog.getExistingDirectory( self, 'Select path', self.ui.lineEditPath.text())) if path != '': self.ui.lineEditPath.setText(path) def saveFile(self): """ Method for saving the file. """ fName = str(self.ui.lineEditPath.text()) + '/' + \ str(self.ui.lineEditFileName.text()) try: self.caller.raw.save(fName) self.caller.setRaw(fName, self.parent) except IOError as e: self.error = True sys.stderr.write("Could not save!\n") sys.stderr.write(str(e)) finally: self.e.set() def accept(self, *args, **kwargs): """ Saves the raw object to a file. """ QtGui.QApplication.setOverrideCursor(QtGui.\ QCursor(QtCore.Qt.WaitCursor)) self.thread = Thread(target=self.saveFile) self.thread.start() while not (self.e.is_set()): sleep(0.5) self.parent.updateUi() if self.e.is_set(): break QtGui.QApplication.restoreOverrideCursor() self.e.clear() if self.error: messageBox = QtGui.QMessageBox() messageBox.setText("Error while saving data.") messageBox.exec_() self.error = False self.settings.setValue("SaveFolder", self.ui.lineEditPath.text()) return QtGui.QDialog.accept(self, *args, **kwargs)
class GroupSpectrumDialog(QtGui.QDialog): fileChanged = QtCore.pyqtSignal() caller = Caller.Instance() conditions = [] tmax = 1000 settings = QSettings("CIBR", "Eggie") def __init__(self, parent, conditions, fmin, fmax, nfft, logarithm, lout, tmax): """ Init method for the dialog. Constructs a set of time series from the given parameters. Parameters: parent - The parent window for this dialog. conditions - A list of PowerSpectrumWidgets. The data from these widgets are copied to this dialog. fmin - Starting frequency of interest. fmax - Ending frequency of interest. nfft - The length of the tapers ie. the windows. The smaller it is the smoother are the PSDs. logarithm - A boolean that determines if a logarithmic scale is used. lout - A layout file name. """ QtGui.QDialog.__init__(self) self.conditions = [] self.ui = Ui_GroupSpectrumDialog() self.ui.setupUi(self) self.installEventFilters() self.parent = parent self.tmax = tmax if conditions == []: widget = PowerSpectrumWidget(tmax, self) widget.setStartTime(5) widget.setEndTime(tmax) self.conditions.append(widget) widget.index = 0 widget.removeWidget.connect(self.on_RemoveWidget_clicked) widget.channelCopy.connect(self.copyChannels) self.ui.verticalLayoutConditions.addWidget(widget) else: i = 0 for condition in conditions: widget = PowerSpectrumWidget(tmax, self) widget.setStartTime(condition.getStartTime()) widget.setEndTime(condition.getEndTime()) widget.setColor(condition.getColor()) widget.setChannelColor(condition.getChannelColor()) widget.on_ChannelsChanged(condition.getChannels()) self.conditions.append(widget) widget.index = i widget.removeWidget.connect(self.on_RemoveWidget_clicked) widget.channelCopy.connect(self.copyChannels) self.ui.verticalLayoutConditions.addWidget(widget) i+=1 self.ui.spinBoxFmin.setValue(fmin) self.ui.spinBoxFmax.setValue(fmax) self.ui.spinBoxNfft.setValue(nfft) self.ui.checkBoxLogarithm.setChecked(logarithm) self.ui.lineEditLayout.setText(lout) self.ui.buttonBox.addButton("Start", QtGui.QDialogButtonBox.AcceptRole) self.ui.buttonBox.addButton(QtGui.QDialogButtonBox.Close) self.ui.lineEditPath.editingFinished.connect(self.on_PathChanged) @QtCore.pyqtSlot(int) def on_RemoveWidget_clicked(self, index): """ Called when a condition widget sends a remove signal. Removes a condition from the list. """ widget = self.conditions.pop(index) self.ui.verticalLayoutConditions.removeWidget(widget) widget.deleteLater() widget = None # Restore order of indices: for i in xrange(len(self.conditions)): self.conditions[i].index = i @QtCore.pyqtSlot(int) def copyChannels(self, index): """ """ channels = self.conditions[index].getChannels() for widget in self.conditions: widget.on_ChannelsChanged(channels) @QtCore.pyqtSlot() def on_PathChanged(self): """ Called when source path field loses focus. Loads the first fif file in the folder and uses it as a template for configuring the parameters. """ QtGui.QApplication.setOverrideCursor(QtGui.\ QCursor(QtCore.Qt.WaitCursor)) data_path = str(self.ui.lineEditPath.text()) try: fifFiles = [ f for f in listdir(data_path)\ if isfile(join(data_path,f)) and f.endswith('.fif') ] except Exception as e: messageBox = QtGui.QMessageBox() messageBox.setText("Cannot open folder.") messageBox.setInformativeText(str(e)) messageBox.exec_() QtGui.QApplication.restoreOverrideCursor() return if len(fifFiles) == 0: QtGui.QApplication.restoreOverrideCursor() return else: fName = data_path + '/' + fifFiles[0] try: #raw = mne.io.Raw(fName, preload=True) self.caller.setRaw(fName, self, False) except Exception as e: messageBox = QtGui.QMessageBox() messageBox.setText("Cannot open file " + fName) messageBox.setInformativeText(str(e)) messageBox.exec_() QtGui.QApplication.restoreOverrideCursor() return self.tmax = np.floor(self.caller.raw.index_as_time\ (self.caller.raw.n_times)) for condition in self.conditions: condition.setMaxTime(self.tmax) triggers = [] try: triggers = find_events(self.caller.raw, stim_channel='STI 014') for trigger in triggers: self.ui.comboBoxStart.addItem(str(trigger[2])) self.ui.comboBoxEnd.addItem(str(trigger[2])) except Exception as e: print 'Could not find triggers from STI 014.' print str(e) self.fileChanged.emit() messageBox = QtGui.QMessageBox() messageBox.setText("Working file changed to " + fName) QtGui.QApplication.restoreOverrideCursor() messageBox.exec_() def on_pushButtonBrowseLayout_clicked(self, checked=None): """ Called when browse layout button is clicked. Opens a file dialog for selecting a file. """ if checked is None: return fname = str(QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home/', "Layout-files (*.lout *.lay);;All files (*.*)")) self.ui.lineEditLayout.setText(fname) self.settings.setValue("Layout", fname) def on_pushButtonBrowseDest_clicked(self, checked=None): """ Called when browse destination path button is clicked. Opens a file dialog for selecting a directory. """ if checked is None: return dest = str(QtGui.QFileDialog.getExistingDirectory(self, 'Set destination path', '/home/')) self.ui.lineEditDestPath.setText(dest) def on_pushButtonBrowsePath_clicked(self, checked=None): """ Called when browse path button is clicked. Opens a file dialog for selecting a directory. """ if checked is None: return path = str(QtGui.QFileDialog.getExistingDirectory(self, 'Set source path', '/home/')) self.ui.lineEditPath.setText(path) self.on_PathChanged() def on_pushButtonAddTimeSeries_clicked(self, checked=None): """ Called when the add condition button is clicked. Adds a new condition to the list. """ if checked is None: return index = len(self.conditions) channels = self.conditions[0].getChannels() widget = PowerSpectrumWidget(self.tmax, self) widget.index = index widget.on_ChannelsChanged(channels) self.conditions.append(widget) self.ui.verticalLayoutConditions.addWidget(widget) widget.removeWidget.connect(self.on_RemoveWidget_clicked) widget.channelCopy.connect(self.copyChannels) def accept(self, *args, **kwargs): """ Begins the plotting of power spectral densities to files. """ self.caller.clearGroups() destPath = str(self.ui.lineEditDestPath.text()) if destPath == "": messageBox = QtGui.QMessageBox() messageBox.setText("You must set a destination "\ + "path for the images.") messageBox.exec_() return QtGui.QApplication.setOverrideCursor(QtGui.\ QCursor(QtCore.Qt.WaitCursor)) colors = [] times = [] # Array for start and end times. channelColors = dict() i = 0 for condition in self.conditions: start = condition.getStartTime() end = condition.getEndTime() if end < start: messageBox = QtGui.QMessageBox() messageBox.setText\ ("End time must be higher than the start time.") messageBox.exec_() QtGui.QApplication.restoreOverrideCursor() return times.append((start, end)) colors.append(condition.getColor()) channels = condition.getChannels() channelColors[i] = (condition.getChannelColor(), channels) i += 1 if len(times) == 0: messageBox = QtGui.QMessageBox() messageBox.setText("Could not find data. Check parameters!") messageBox.exec_() QtGui.QApplication.restoreOverrideCursor() return params = dict() params['times'] = times params['fmin'] = self.ui.spinBoxFmin.value() params['fmax'] = self.ui.spinBoxFmax.value() params['nfft'] = self.ui.spinBoxNfft.value() params['log'] = self.ui.checkBoxLogarithm.isChecked() params['lout'] = str(self.ui.lineEditLayout.text()) params['dpi'] = self.ui.spinBoxResolution.value() params['format'] = str(self.ui.comboBoxFormat.currentText()) params['groupAverage'] = self.ui.checkBoxGroupAverage.isChecked() params['plotChannels'] = self.ui.checkBoxPlotChannels.isChecked() origRaw = self.caller.raw.info['filename'] data_path = str(self.ui.lineEditPath.text()) try: fifFiles = [ f for f in listdir(data_path)\ if isfile(join(data_path,f)) and f.endswith('.fif') ] except OSError as e: messageBox = QtGui.QMessageBox() messageBox.setText("Error reading files.") messageBox.setInformativeText(str(e)) messageBox.exec_() QtGui.QApplication.restoreOverrideCursor() return print "Found {!s} fif-files.\n".format(len(fifFiles)) self.parent.ui.progressBar.setVisible(True) if params['groupAverage']: self.parent.ui.progressBar.setRange(0, len(fifFiles) + 1) else: self.parent.ui.progressBar.setRange(0, len(fifFiles)) self.parent.ui.progressBar.setValue(0) counter = 0 for fName in fifFiles: print "Working on {!s}...\n".format(fName) raw = data_path + '/' + fName try: self.caller.setRaw(raw, self) except Exception as e: messageBox = QtGui.QMessageBox() messageBox.setText("Cannot open file " + raw) messageBox.setInformativeText(str(e)) messageBox.exec_() break self.parent.updateUi() if self.ui.checkBoxTriggers.isChecked(): times = [] try: events = find_events(self.caller.raw, 'STI 014') except Exception as e: print "Could not find events from STI 014. Aborting..." print str(e) continue triggerStart, _ = self.ui.comboBoxStart.currentText().toInt() #triggerStart = int(triggerStart) triggerEnd, _ = self.ui.comboBoxEnd.currentText().toInt() #triggerEnd = int(triggerEnd)) tmin = np.where(events[:,2]==triggerStart)[0][0] tmax = np.where(events[:,2]==triggerEnd)[0][0] tmin = self.caller.raw.index_as_time(events[tmin][0]) tmax = self.caller.raw.index_as_time(events[tmax][0]) times.append((int(tmin[0]), int(tmax[0]))) print times params['times'] = times try: self.caller.plotSpectrum(self, params, colors, channelColors, destPath) except IOError as e: messageBox = QtGui.QMessageBox() messageBox.setText("IO error occurred:") messageBox.setInformativeText(str(e)) messageBox.exec_() break except RuntimeError as e: messageBox = QtGui.QMessageBox() messageBox.setText("Runtime error occurred:") messageBox.setInformativeText(str(e)) messageBox.exec_() break except Exception as e: messageBox = QtGui.QMessageBox() messageBox.setText("Error occurred:") messageBox.setInformativeText(str(e)) messageBox.exec_() break counter = counter + 1 self.parent.ui.progressBar.setValue(counter) if params['groupAverage']: print "Calculating group averages..." self.updateUi() self.caller.createGroupAverage(destPath, colors, channelColors, params['format'], params['dpi'], params['log'], params['lout']) counter = counter + 1 self.parent.ui.progressBar.setValue(counter) self.updateUi() self.caller.setRaw(origRaw, self) self.parent.ui.progressBar.setVisible(False) QtGui.QApplication.restoreOverrideCursor() @QtCore.pyqtSlot(int) def on_comboBoxStart_currentIndexChanged(self, index): """ Method for setting time on the start time spinbox after trigger selection has changed. Parameters: index - Index of the selection in combobox. """ if not self.ui.checkBoxTriggers.isChecked(): return triggers = find_events(self.caller.raw, stim_channel='STI 014') triggerStart, _ = self.ui.comboBoxStart.currentText().toInt() tmin = np.where(triggers[:,2]==triggerStart)[0][0] tmin = self.caller.raw.index_as_time(triggers[tmin][0]) tmin = int(tmin[0]) self.conditions[0].setStartTime(tmin) @QtCore.pyqtSlot(int) def on_comboBoxEnd_currentIndexChanged(self, index): """ Method for setting time on the end time spinbox after trigger selection has changed. Parameters: index - Index of the selection in combobox. """ if not self.ui.checkBoxTriggers.isChecked(): return triggers = find_events(self.caller.raw, stim_channel='STI 014') triggerEnd, _ = self.ui.comboBoxEnd.currentText().toInt() tmax = np.where(triggers[:,2]==triggerEnd)[0][0] tmax = self.caller.raw.index_as_time(triggers[tmax][0]) tmax = int(tmax[0]) self.conditions[0].setEndTime(tmax) @QtCore.pyqtSlot(bool) def on_checkBoxTriggers_toggled(self, toggled): """ A slot for setting the powerspectrumwidgets according to trigger settings. Called when trigger check box is toggled. Parameters: toggled - A boolean that determines if check box is ticked. """ if toggled: for condition in reversed(self.conditions): index = condition.index if index != 0: self.on_RemoveWidget_clicked(index) else: condition.disableSpinBoxes(toggled) self.ui.pushButtonAddTimeSeries.setEnabled(False) index = self.ui.comboBoxStart.currentIndex() self.on_comboBoxStart_currentIndexChanged(index) index = self.ui.comboBoxEnd.currentIndex() self.on_comboBoxEnd_currentIndexChanged(index) else: self.conditions[0].disableSpinBoxes(False) self.ui.pushButtonAddTimeSeries.setEnabled(True) def on_pushButtonSeriesFromTriggers_clicked(self, checked=None): """ Opens a TimeSeriesDialog. Called when construct time series from triggers -button is clicked. """ if checked is None or self.caller.raw is None: return dialog = TimeSeriesDialog() dialog.timeSeriesChanged.connect(self.on_TimeSeriesChanged) dialog.exec_() @QtCore.pyqtSlot(list) def on_TimeSeriesChanged(self, conditions): """ Slot for adding a set of PowerSpectrumWidgets to this dialog. Called from TimeSeriesDialog. Parameters: conditions - A list of PowerSpectrumWidgets. """ if conditions == []: return for widget in self.conditions: self.on_RemoveWidget_clicked(widget.index) i = 0 tmax = np.floor(self.caller.raw.index_as_time(self.caller.raw.n_times)) for condition in conditions: widget = PowerSpectrumWidget(tmax, self) widget.setStartTime(condition.getStartTime()) widget.setEndTime(condition.getEndTime()) widget.setColor(condition.getColor()) widget.setChannelColor(condition.getChannelColor()) widget.on_ChannelsChanged(condition.getChannels()) self.conditions.append(widget) widget.index = i widget.removeWidget.connect(self.on_RemoveWidget_clicked) widget.channelCopy.connect(self.copyChannels) self.ui.verticalLayoutConditions.addWidget(widget) i+=1 self.ui.scrollAreaConditions.updateGeometry() def updateUi(self): self.parent.updateUi() def keyPressEvent(self, qKeyEvent): """ Overrided method to prevent enter or return from starting the plotting. Parameters: qKeyEvent - Qt key event. """ key = qKeyEvent.key() if key == QtCore.Qt.Key_Return or key == QtCore.Qt.Key_Enter: return return QtGui.QDialog.keyPressEvent(self, qKeyEvent) def installEventFilters(self): """ Helper method for disabling wheel events on all widgets. """ self.ui.spinBoxFmin.installEventFilter(self) self.ui.spinBoxFmax.installEventFilter(self) self.ui.comboBoxFormat.installEventFilter(self) self.ui.spinBoxNfft.installEventFilter(self) self.ui.spinBoxResolution.installEventFilter(self) def eventFilter(self, source, event): """ Event filter for disabling wheel events on spin boxes and such. """ if (event.type() == QtCore.QEvent.Wheel): return True return QtGui.QWidget.eventFilter(self, source, event)
class PreprocessDialog(QtGui.QMainWindow): """ """ e = Event() filterFinished = pyqtSignal() caller = Caller.Instance() conditions = [] settings = QSettings("CIBR", "Eggie") def __init__(self): """ Init method for the preprocessing dialog. Redirects stdout to dialog's console. """ QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.progressBar.setVisible(False) self.installEventFilters() self.ui.tableWidgetEvents.setSortingEnabled(False) #Signals self.ui.tableWidgetEvents.currentItemChanged.connect(self.\ on_currentChanged) self.ui.checkBoxLowCutOff.stateChanged.connect(self.on_StateChanged) self.ui.checkBoxHighCutOff.stateChanged.connect(self.on_StateChanged) self.ui.checkBoxNotch.stateChanged.connect(self.on_StateChanged) self.ui.doubleSpinBoxLowCutOff.valueChanged.connect(self.\ ui.pushButtonFilter.setEnabled) self.ui.doubleSpinBoxHighCutOff.valueChanged.connect(self.\ ui.pushButtonFilter.setEnabled) self.ui.doubleSpinBoxNotchFilter.valueChanged.connect(self.\ ui.pushButtonFilter.setEnabled) self.ui.actionDirectOutput.triggered.connect(self.directOutput) self.ui.actionOpen.triggered.connect(self.on_actionOpen) self.ui.actionExit.triggered.connect(self.on_actionExit) sys.stdout = EmittingStream(textWritten=self.normalOutputWritten) sys.stderr = EmittingStream(textWritten=self.errorOutputWritten) self.on_actionOpen() self.ui.lineEditLayout.setText(self.settings.value("Layout", "").\ toString()) def initialize(self): """ Method for initializing the dialog. """ if not self.caller.raw: return self.ui.labelRaw.setText(self.caller.raw.info.get('filename')) self.ui.comboBoxChannelSelect.addItems(self.caller.raw.info.\ get('ch_names')) index = self.ui.comboBoxChannelSelect.findText('17') self.ui.comboBoxChannelSelect.setCurrentIndex(index) self.ui.pushButtonFilter.setEnabled(True) self.ui.tableWidgetEvents.setSelectionBehavior(1) self.ui.tableWidgetEvents.setColumnCount(4) self.ui.tableWidgetEvents.setHorizontalHeaderLabels( ["Time (s)", "Sample", "Prev. id", "Current id"]) tmax = np.floor(self.caller.raw.index_as_time( self.caller.raw.n_times)) # / 1000.0)) if len(self.conditions) == 0: spectrumWidget = PowerSpectrumWidget(tmax, self) spectrumWidget.index = 0 spectrumWidget.removeWidget.connect(self.on_RemoveWidget_clicked) spectrumWidget.channelCopy.connect(self.copyChannels) self.ui.verticalLayoutConditions.addWidget(spectrumWidget) self.conditions.append(spectrumWidget) def directOutput(self): """ Method for directing stdout to the console and back. """ if self.ui.actionDirectOutput.isChecked(): sys.stdout = EmittingStream(textWritten=self.normalOutputWritten) sys.stderr = EmittingStream(textWritten=self.errorOutputWritten) else: sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ def on_actionOpen(self): """ Opens a dialog for selecting a file. """ fileDialog = FileSelectionDialog(self) fileDialog.fileChanged.connect(self.on_FileChanged) fileDialog.show() def on_actionExit(self): """ Closes the main window. """ self.close() def on_pushButtonFilter_clicked(self, checked=None): """ Called when filter button is clicked. """ if checked is None or not self.caller.raw: return self.ui.pushButtonFilter.setEnabled(False) QtGui.QApplication.setOverrideCursor(QtGui.\ QCursor(QtCore.Qt.WaitCursor)) self.e.clear() self.thread = Thread(target=self.callFilter) self.thread.start() #while (self.thread.is_alive()): # time.sleep(1) #self.e.wait() self.on_FilterFinished() QtGui.QApplication.restoreOverrideCursor() def callFilter(self): """ A function for calling filtering function in mne. Performed in a worker thread. """ if self.ui.checkBoxHighCutOff.isChecked(): highCutOff = self.ui.doubleSpinBoxHighCutOff.value() else: highCutOff = None if self.ui.checkBoxLowCutOff.isChecked(): lowCutOff = self.ui.doubleSpinBoxLowCutOff.value() else: lowCutOff = None try: self.caller.raw.filter(l_freq=lowCutOff, h_freq=highCutOff, n_jobs=2) except Exception as e: print str(e) self.e.set() return print self.caller.raw.info['bads'] if self.ui.checkBoxNotch.isChecked(): print "Applying notch filter...\n" notchFreq = self.ui.doubleSpinBoxNotchFilter.value() try: self.caller.raw.notch_filter(freqs=notchFreq) except Exception as e: print str(e) self.e.set() return print self.caller.raw.info['bads'] print "Launching mne_browse_raw...\n" self.e.set() def on_FilterFinished(self): """ Function for adding bad channels via mne_browse_raw. """ while not (self.e.is_set()): sleep(0.5) self.updateUi() if self.e.is_set(): break self.caller.raw.plot(scalings=dict(eeg=40e-6)) plt.show() self.ui.listWidgetBads.clear() self.ui.listWidgetBads.addItems(self.caller.raw.info['bads']) self.e.clear() print "Finished\n" self.ui.pushButtonSave.setEnabled(True) def on_pushButtonAddBads_clicked(self, checked=None): """ Called as the add-button is clicked. Opens a dialog for adding bad channels by hand. """ if checked is None or not self.caller.raw: return badsDialog = ChannelSelectionDialog(self.caller.raw.info['bads'], "Select bad channels:") badsDialog.channelsChanged.connect(self.on_BadsChanged) badsDialog.exec_() def on_pushButtonFindEogEvents_clicked(self, checked=None): """ Finds EOG-events from the raw data. Called when find eog events -button is clicked. """ if checked is None or not self.caller.raw: return QtGui.QApplication.setOverrideCursor(QtGui.\ QCursor(QtCore.Qt.WaitCursor)) params = dict() event_id = int(self.ui.labelBlinkId.text()) params['event_id'] = event_id params['ch_name'] = str(self.ui.comboBoxChannelSelect.currentText()) params['l_freq'] = float(self.ui.doubleSpinBoxLowPass.value()) params['h_freq'] = float(self.ui.doubleSpinBoxHighPass.value()) params['filter_length'] = str( self.ui.spinBoxFilterLength.value()) + 's' params['tstart'] = float(self.ui.doubleSpinBoxStart.value()) try: #sfreq = self.caller.raw.info['sfreq'] eog_events = self.caller.findEogEvents(params) #eog_events = self.caller.raw.index_as_time(eog_events) self.ui.tableWidgetEvents.clear() self.ui.tableWidgetEvents.setRowCount(0) for i in range(0, len(eog_events)): self.ui.tableWidgetEvents.insertRow(i) self.ui.tableWidgetEvents.setItem(i,0,QtGui.\ QTableWidgetItem(str(self.caller.raw.index_as_time(eog_events[i][0])[0]))) self.ui.tableWidgetEvents.setItem(i,1,QtGui.\ QTableWidgetItem(str(int(eog_events[i][0])))) self.ui.tableWidgetEvents.setItem(i,2,QtGui.\ QTableWidgetItem(str(eog_events[i][1]))) self.ui.tableWidgetEvents.setItem(i,3,QtGui.\ QTableWidgetItem(str(eog_events[i][2]))) except Exception as e: print str(e) finally: self.ui.tableWidgetEvents.setHorizontalHeaderLabels( ["Time (s)", "Sample", "Prev. id", "Current id"]) QtGui.QApplication.restoreOverrideCursor() @QtCore.pyqtSlot(int) def on_StateChanged(self, checked): """ Slot for activating filter button. """ if checked == 2: self.ui.pushButtonFilter.setEnabled(True) @QtCore.pyqtSlot() def on_FileChanged(self): """ Called when raw file has changed. """ self.ui.listWidgetBads.clear() self.ui.listWidgetBads.addItems(self.caller.raw.info['bads']) self.ui.tableWidgetEvents.clear() self.ui.tableWidgetEvents.setRowCount(0) for condition in reversed(self.conditions): index = condition.index self.on_RemoveWidget_clicked(index) self.initialize() @QtCore.pyqtSlot() def on_currentChanged(self): """ Called when tableWidgetEvent row selection is changed. """ index = self.ui.tableWidgetEvents.currentIndex().row() if index < 0: self.ui.pushButtonDelete.setEnabled(False) else: self.ui.pushButtonDelete.setEnabled(True) @QtCore.pyqtSlot(list) def on_BadsChanged(self, bads): """ Called when bad channels are changed by hand Parameters: bads - The list of bad channels. """ self.ui.listWidgetBads.clear() self.caller.raw.info['bads'] = bads self.ui.listWidgetBads.addItems(self.caller.raw.info['bads']) @QtCore.pyqtSlot(int) def on_EventsChanged(self, index): """ Slot removing an event from the table. Parameters: index - Index of the item on the table. """ self.ui.tableWidgetEvents.removeRow(index) def on_pushButtonDelete_clicked(self, checked=None): """ Called when delete button of eventlist is clicked. """ if checked is None: return index = self.ui.tableWidgetEvents.currentRow() self.ui.tableWidgetEvents.removeRow(index) def on_pushButtonCalculateSSP_clicked(self, checked=None): """ Called when calculate SSP projections -button is clicked. """ if checked is None or not self.caller.raw: return events = [] rowCount = self.ui.tableWidgetEvents.rowCount() for i in xrange(0, rowCount): time, _ = self.ui.tableWidgetEvents.item(i, 1).text().toFloat() prev, _ = self.ui.tableWidgetEvents.item(i, 2).text().toFloat() curr, _ = self.ui.tableWidgetEvents.item(i, 3).text().toFloat() events.append([time, prev, curr]) if events == []: print "Cannot remove blinks without events!" return projectionDialog = ProjectionDialog(np.array(events), curr, self) projectionDialog.badsChanged.connect(self.on_BadsChanged) projectionDialog.eventsChanged.connect(self.on_EventsChanged) projectionDialog.exec_() def on_pushButtonSave_clicked(self, checked=None): """ Called when save button is clicked. """ if checked is None or not self.caller.raw: return saveDialog = SaveDialog(self) saveDialog.exec_() self.ui.labelRaw.setText(self.caller.raw.info.get('filename')) def on_pushButtonSeriesFromTriggers_clicked(self, checked=None): """ Opens a dialog for constructing a set of time series for PSDs from triggers. """ if checked is None or self.caller.raw is None: return dialog = TimeSeriesDialog() dialog.timeSeriesChanged.connect(self.on_TimeSeriesChanged) dialog.exec_() @QtCore.pyqtSlot(list) def on_TimeSeriesChanged(self, conditions): """ Slot for adding a set of time series for PSDs. Parameters: conditions - A list of PowerSpectrumWidgets. """ if conditions == []: return for widget in self.conditions: self.on_RemoveWidget_clicked(widget.index) i = 0 tmax = np.floor(self.caller.raw.index_as_time(self.caller.raw.n_times)) for condition in conditions: widget = PowerSpectrumWidget(tmax, self) widget.setStartTime(condition.getStartTime()) widget.setEndTime(condition.getEndTime()) widget.setColor(condition.getColor()) widget.setChannelColor(condition.getChannelColor()) widget.on_ChannelsChanged(condition.getChannels()) self.conditions.append(widget) widget.index = i widget.removeWidget.connect(self.on_RemoveWidget_clicked) widget.channelCopy.connect(self.copyChannels) self.ui.verticalLayoutConditions.addWidget(widget) i += 1 self.ui.scrollAreaConditions.updateGeometry() def on_pushButtonAddTimeSeries_clicked(self, checked=None): """ Called when condition add button is clicked. """ if checked is None or not self.caller.raw: return tmax = np.floor(self.caller.raw.index_as_time( self.caller.raw.n_times)) # ms to s index = len(self.conditions) channels = self.conditions[0].getChannels() widget = PowerSpectrumWidget(tmax, self) widget.index = index widget.on_ChannelsChanged(channels) self.conditions.append(widget) self.ui.verticalLayoutConditions.addWidget(widget) widget.removeWidget.connect(self.on_RemoveWidget_clicked) widget.channelCopy.connect(self.copyChannels) def on_pushButtonFileInfo_clicked(self, checked=None): """ Opens the info dialog. """ if checked is None or not self.caller.raw: return info = Ui_infoDialog() infoDialog = InfoDialog(self.caller.raw, info, True) infoDialog.exec_() @QtCore.pyqtSlot(int) def on_RemoveWidget_clicked(self, index): """ Called when a condition widget sends a remove signal. Removes a condition from the list. Parameters: index - The index of the widget. """ widget = self.conditions.pop(index) self.ui.verticalLayoutConditions.removeWidget(widget) widget.deleteLater() widget = None # Restore order of indices: for i in xrange(len(self.conditions)): self.conditions[i].index = i @QtCore.pyqtSlot(int) def copyChannels(self, index): """ """ channels = self.conditions[index].getChannels() for widget in self.conditions: widget.on_ChannelsChanged(channels) def on_pushButtonPlot_clicked(self, checked=None): """ Called when plot spectrum button is clicked. """ if checked is None or not self.caller.raw: return QtGui.QApplication.setOverrideCursor(QtGui.\ QCursor(QtCore.Qt.WaitCursor)) colors = [] times = [] # Array for start and end times. channelColors = dict() i = 0 for condition in self.conditions: start = condition.getStartTime() end = condition.getEndTime() if end < start: messageBox = QtGui.QMessageBox() messageBox.setText("End time must be higher than the " + \ "start time.") QtGui.QApplication.restoreOverrideCursor() messageBox.exec_() return times.append((start, end)) colors.append(condition.getColor()) channels = condition.getChannels() channelColors[i] = (condition.getChannelColor(), channels) i += 1 if len(times) == 0: messageBox = QtGui.QMessageBox() messageBox.setText("Could not find data. Check parameters!") QtGui.QApplication.restoreOverrideCursor() messageBox.exec_() return fmin = self.ui.spinBoxFmin.value() fmax = self.ui.spinBoxFmax.value() if fmin >= fmax: messageBox = QtGui.QMessageBox() messageBox.setText("End frequency must be higher than the " + \ "starting frequency.") QtGui.QApplication.restoreOverrideCursor() messageBox.exec_() params = dict() params['times'] = times params['fmin'] = fmin params['fmax'] = fmax params['nfft'] = self.ui.spinBoxNfft.value() params['log'] = self.ui.checkBoxLogarithm.isChecked() params['lout'] = str(self.ui.lineEditLayout.text()) try: self.caller.plotSpectrum(self, params, colors, channelColors) except Exception as e: messageBox = QtGui.QMessageBox() messageBox.setText(str(e)) QtGui.QApplication.restoreOverrideCursor() messageBox.exec_() return QtGui.QApplication.restoreOverrideCursor() def on_pushButtonBrowseLayout_clicked(self, checked=None): """ Opens a dialog for selecting a layout file. """ if checked is None: return fname = str( QtGui.QFileDialog.getOpenFileName( self, 'Open file', '/home/', "Layout-files (*.lout *.lay);;All files (*.*)")) self.ui.lineEditLayout.setText(fname) self.settings.setValue("Layout", fname) def on_pushButtonGroupPlot_clicked(self, checked=None): """ Opens a dialog for plotting power spectrums as a group. """ if checked is None: return fmin = self.ui.spinBoxFmin.value() fmax = self.ui.spinBoxFmax.value() nfft = self.ui.spinBoxNfft.value() logarithm = self.ui.checkBoxLogarithm.isChecked() lout = self.ui.lineEditLayout.text() tmax = 10000 if self.caller.raw: tmax = np.floor( self.caller.raw.index_as_time(self.caller.raw.n_times)) groupSpectrumDialog = GroupSpectrumDialog(self, self.conditions, fmin, fmax, nfft, logarithm, lout, tmax) groupSpectrumDialog.fileChanged.connect(self.on_FileChanged) groupSpectrumDialog.exec_() def keyPressEvent(self, event): key = event.key() if key == QtCore.Qt.Key_Delete: if self.ui.tabWidget.currentIndex() == 0: self.on_pushButtonDelete_clicked(1) def installEventFilters(self): """ Helper method for disabling wheel events on all widgets. """ #Preprocess tab: self.ui.doubleSpinBoxLowCutOff.installEventFilter(self) self.ui.doubleSpinBoxHighCutOff.installEventFilter(self) self.ui.doubleSpinBoxNotchFilter.installEventFilter(self) self.ui.comboBoxChannelSelect.installEventFilter(self) self.ui.doubleSpinBoxLowPass.installEventFilter(self) self.ui.doubleSpinBoxHighPass.installEventFilter(self) self.ui.spinBoxFilterLength.installEventFilter(self) self.ui.doubleSpinBoxStart.installEventFilter(self) #Power spectrum tab: self.ui.spinBoxFmin.installEventFilter(self) self.ui.spinBoxFmax.installEventFilter(self) self.ui.spinBoxNfft.installEventFilter(self) def eventFilter(self, source, event): """ Event filter for disabling wheel events on spin boxes and such. """ if (event.type() == QtCore.QEvent.Wheel): return True return QtGui.QWidget.eventFilter(self, source, event) @QtCore.pyqtSlot() def updateUi(self): """ Method for updating the UI. """ QApplication.processEvents() def __del__(self): """ Restores stdout at the end. """ sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ def normalOutputWritten(self, text): """ Appends text to 'console' at the bottom of the dialog. Used for redirecting stdout. Parameters: text - Text to write to the console. """ cursor = self.ui.textEdit.textCursor() cursor.movePosition(QtGui.QTextCursor.End) cursor.insertText(text) self.ui.textEdit.setTextCursor(cursor) self.ui.textEdit.ensureCursorVisible() def errorOutputWritten(self, text): """ Appends text to 'console' at the bottom of the dialog. Used for redirecting stderr. Parameters: text - Text to write to the console. """ cursor = self.ui.textEdit.textCursor() cursor.movePosition(QtGui.QTextCursor.End) cursor.insertText(text) self.ui.textEdit.setTextCursor(cursor) self.ui.textEdit.ensureCursorVisible()