class EEGViewer(QThread): """docstring for EEGViewer""" StoppedState = 0 PausedState = 1 RunningState = 2 def __init__(self, mode='single', rows=4): super(EEGViewer, self).__init__() self.mode = mode self.rows = rows self.view = GraphicsLayoutWidget() self.view.setAntialiasing(True) self.view.setWindowTitle('EEG Viewer') self.state = self.StoppedState self.position = 0 self.maxPosition = 0 self.plotItem = list() self.plotTrace = dict() # Holders self.wait = 0 self.wsize = 0 self.hsize = 0 self.color = dict() self.window = list([0, 0]) self.channel = list() def widget(self): return self.view def show(self): self.view.show() def hide(self): self.view.hide() def getState(self): return self.state def isVisible(self): return self.view.isVisible() def setSize(self, width, height): self.view.resize(width, height) def configure(self, channel, color, wsize, fs=0): # Link params nCh = len(channel) self.wait = 1 / (fs * nCh) if fs > 0 else 0 self.wsize = wsize self.hsize = wsize / 2 self.color = color self.channel = channel self.window = np.array([0, wsize]) # Remove previous items and traces self.view.clear() self.plotItem.clear() self.plotTrace.clear() # Create new canvas if self.mode == 'single': self.singleLayout() else: self.multipleLayout() def singleLayout(self): canvas = self.view.addPlot(0, 0) canvas.disableAutoRange() canvas.setClipToView(True) canvas.setLimits(yMin=0, yMax=1) canvas.setDownsampling(mode='subsample') canvas.showGrid(x=True, y=True, alpha=0.25) for ch in self.channel: pen = mkPen(color=self.color[ch], width=2) self.plotTrace[ch] = canvas.plot(pen=pen) self.plotItem.append(canvas) def multipleLayout(self): col = 0 rowLimit = self.rows for i, ch in enumerate(self.channel): pen = mkPen(color=self.color[ch], width=2) canvas = self.view.addPlot(i % rowLimit, col) canvas.disableAutoRange() canvas.setClipToView(True) canvas.setLimits(yMin=0, yMax=1) canvas.setDownsampling(mode='subsample') canvas.showGrid(x=True, y=True, alpha=0.25) self.plotItem.append(canvas) self.plotTrace[ch] = canvas.plot(pen=pen) if (i + 1) % rowLimit == 0: col += 1 def plotData(self, D): for ch in self.channel: self.plotTrace[ch].setData(D[ch].values) self.position = 0 self.maxPosition = D.index.size def addMark(self, position, label=None): for canvas in self.plotItem: pen = mkPen(color='g', width=2.5, style=Qt.DashLine) hpen = mkPen(color='r', width=2.5, style=Qt.DashLine) mark = canvas.addLine(x=position, pen=pen, label=label, labelOpts={'position': 0.9}, movable=True, hoverPen=hpen) return mark def setPosition(self, position): self.window[0] = position - self.hsize self.window[1] = position + self.hsize self.position = position self.update() def update(self): for plot in self.plotItem: plot.setRange(xRange=self.window) self.position += 1 if self.position < self.maxPosition else 0 def play(self): self.state = self.RunningState self.start() def pause(self): self.state = self.PausedState def toggle(self): self.state = self.PausedState if self.state == self.RunningState else self.RunningState def stop(self): self.state = self.StoppedState self.quit() self.setPosition(0) def run(self): while True: if self.state == self.RunningState: self.setPosition(self.position) elif self.state == self.PausedState: pass else: break sleep(self.wait)
class mainWindow(QMainWindow): # Metodo constructor de la clase def __init__(self): #Inicia el objeto QMainWindow QMainWindow.__init__(self) #carga la configuracion del archivo .ui en el objeto loadUi("mainWindowPPG.ui", self) # Loads everything about mainWindowPPG configuration self.setupUI() # Shared variables, initial values self.queue = Queue(N_SAMPLES) self.dataR = deque([], maxlen=N_SAMPLES) self.dataIR = deque([], maxlen=N_SAMPLES) self.TIME = deque([], maxlen=N_SAMPLES) self._plt = None self._timer_plot = None self.plot_colors = ['#0072bd', '#d95319'] # configures self._configure_plot() self._configure_timers() self._configure_signals() # Loads everything about mainWindowPPG configuration def setupUI(self): """ Configures everything about the mainWindow """ self.plt = GraphicsLayoutWidget( self.centralwidget) # Bringing my plot wiindow as plt self.plt.setAutoFillBackground(False) self.plt.setStyleSheet("border: 0px;") self.plt.setFrameShape(QtWidgets.QFrame.StyledPanel) self.plt.setFrameShadow(QtWidgets.QFrame.Plain) self.plt.setLineWidth(0) self.Layout_graphs.addWidget(self.plt, 0, 0, 1, 1) # Set the plotting squared graph def _configure_plot(self): """ Configures specific elements of the PyQtGraph plots. :return: """ self.plt.setBackground(background=None) self.plt.setAntialiasing(True) self._plt = self.plt.addPlot(row=1, col=1) self._plt.setLabel('bottom', "Time", "s") pass def _configure_timers(self): """ Configures specific elements of the QTimers. :return: """ self._timer_plot = QtCore.QTimer( self) # gives _timer_plot the attribute of QtCore.QTimer self._timer_plot.timeout.connect( self._update_plot) # connects with _update_plot method pass def _update_plot(self): """ Updates and redraws the graphics in the plot. This function us connected to the timeout signal of a QTimer. :return: """ # Spo2 signal parameters f = 2 amp1 = 0.5 # amplitud for Sine signal zeroDes1 = 0.5413 # Desplacement from zero for Sine signal amp2 = 0.5 # amplitud for Cosine signal zeroDes2 = 1.5413 # Desplacement from zero for Cosine signal # generate the time tsignal = time() - self.timestamp # Sine signal function sR = zeroDes1 + amp1 * 0.8 * np.sin(2 * np.pi * tsignal * 3 * f) # Cosine signal function sIR = zeroDes2 + amp2 * 0.8 * np.cos(2 * np.pi * tsignal * 3 * f) # put the data generate (time & signal) into queue self.queue.put([tsignal, sR, sIR]) # get the data generate into queue data = self.queue.get(True, 1) # store data into variables self.TIME.append(data[0]) self.dataR.append(data[1]) self.dataIR.append(data[2]) # Draw new data self._plt.clear() self._plt.plot(x=list(self.TIME)[-PLOT_UPDATE_POINTS:], y=list(self.dataR)[-PLOT_UPDATE_POINTS:], pen=self.plot_colors[1]) self._plt.plot(x=list(self.TIME)[-PLOT_UPDATE_POINTS:], y=list(self.dataIR)[-PLOT_UPDATE_POINTS:], pen=self.plot_colors[0]) def _configure_signals(self): """ Configures the connections between signals and UI elements. :return: """ self.startButton.clicked.connect(self.start) self.stopButton.clicked.connect(self.stop) def start(self): """ Starts the acquisition of the selected serial port. This function is connected to the clicked signal of the Start button. :return: """ self.timestamp = time() self._timer_plot.start(16) def stop(self): """ Stops the acquisition of the selected serial port. This function is connected to the clicked signal of the Stop button. :return: """ self._timer_plot.stop() # stop the Qt timer self.reset_buffers() # Go to reset the vector containing values def reset_buffers(self): self.dataR.clear() self.dataIR.clear() self.TIME.clear()
class CustomGraphicsLayoutWidget(GraphicsLayoutWidget): def __init__(self, nName: tuple = ("Temperature", "Heater Power"), nUnit: tuple = ("degC", "%P"), parent=None): assert len(nName) == len(nUnit) pyqtgraph.setConfigOption('background', 'w') pyqtgraph.setConfigOption('foreground', 'k') super(CustomGraphicsLayoutWidget, self).__init__(parent) self.nName = nName self.nUnit = nUnit self.curves = [] self.graphs = [] self.legends = [] self._samples = DEFAULT_SAMPLES self._plt = GraphicsLayoutWidget() def set_mode(self, mode): if mode == "Manual": self.is_manmode = True else: self.is_manmode = False self._clear_plot() self._configure_plot() def _clear_plot(self): self.clear() #this is crucial fiuhh self.curves = [] self.graphs = [] def _configure_plot(self): n = len(self.nName) npos = np.linspace(1, n, n) if self.is_manmode: self.nLine = 1 self.legend = MANUAL_LEGEND else: self.nLine = 2 self.legend = PID_LEGEND for name, ypos, unit in zip(self.nName, npos, self.nUnit): self._plt.setBackground(background=None) self._plt.setAntialiasing(True) if name == self.nName[-1]: graph = self.addPlot(labels={ 'right': name, 'bottom': "Waktu (detik)" }) else: graph = self.addPlot(labels={'right': name}) for i in range(self.nLine): curve = [graph.plot()] self.curves.extend(curve) graph.setLabel('right', name, unit) self.graphs.append(graph) self.nextRow() def get_curves(self): print("original curves: {}".format(self.curves)) return self.curves def get_graphs(self): print("original graphs: {}".format(self.graphs)) return self.graphs def get_legend(self): return self.legends
class Aditi(QMainWindow): def __init__(self): QMainWindow.__init__(self) # title self.setWindowTitle("Aditi") self.setDockOptions(QMainWindow.VerticalTabs | QMainWindow.AnimatedDocks) #self.showMaximized() # model self.rawfiles_by_short_path = {} self.xic_by_rawfile_short_path = {} self.tic_by_rawfile_short_path = {} self.spec_by_rawfile_short_path = {} self.inf_line_tic_item = None self.curr_scan_id_by_short_path = {} # menu self.file_menu = self.menuBar().addMenu('&File') #self.file_menu.setTearOffEnabled(False) open_action = QAction("&Open...", self) open_action.setToolTip("Open a rawfile") open_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O)) self.file_menu.addAction(open_action) open_action.triggered.connect(self.show_open_dialog) exit_action = QAction("&Exit", self) exit_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q)) self.file_menu.addAction(exit_action) exit_action.triggered.connect(self.quit) self.tab_widget = QTabWidget(self) # spectrum plot Widget self.graphics_layout_widget = GraphicsLayoutWidget(parent=self.tab_widget) self.graphics_layout_widget.keyPressEvent = self.handle_key_press_event self.graphics_layout_widget.useOpenGL(False) self.graphics_layout_widget.setAntialiasing(False) self.plot_widget_tic = self.graphics_layout_widget.addPlot(title="TIC(s)", labels={'left': "Intensity", 'bottom': "Retention Time (sec)"}) self.plot_widget_tic.showGrid(x=True, y=True) self.graphics_layout_widget.nextRow() self.plot_widget_spectrum = self.graphics_layout_widget.addPlot(title="Spectrum", labels={'left': "Intensity", 'bottom': "m/z"}) self.plot_widget_spectrum.showGrid(x=True, y=True) # finally add tab self.tab_widget.addTab(self.graphics_layout_widget, "Spectrum") # Xic plotWidget self.plot_widget_xic = PlotWidget(name="MainPlot", labels={'left': "Intensity", 'bottom': "Retention Time (sec)"}) self.plot_widget_xic.showGrid(x=True, y=True) self.tab_widget.addTab(self.plot_widget_xic, "Xic extraction") self.setCentralWidget(self.tab_widget) self.statusBar().showMessage("Ready") # dock 1 self.rawfile_dock_widget = QDockWidget("Rawfiles") self.rawfile_table_view = QTableView() self.rawfile_table_view.horizontalHeader().setVisible(False) self.rawfile_table_view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) self.rawfile_dock_widget.setWidget(self.rawfile_table_view) self.rawfile_model = QStandardItemModel() self.rawfile_model.setHorizontalHeaderLabels(["Rawfiles"]) self.rawfile_table_view.setModel(self.rawfile_model) self.rawfile_model.itemChanged.connect(self.item_changed) self.addDockWidget(0x2, self.rawfile_dock_widget) # xic dock widget extraction parameter self.xic_dock_widget = QDockWidget("Xic extraction") self.xic_widget = XicWidget() self.xic_widget.plotButton.clicked.connect(self.plot) self.xic_dock_widget.setWidget(self.xic_widget) self.addDockWidget(0x2, self.xic_dock_widget) def handle_key_press_event(self, evt): if self.inf_line_tic_item is None: return times = [] if evt.key() == Qt.Key_Left: for rawfile in self.rawfiles_by_short_path.values()[:1]: if not rawfile.is_checked: continue curr_scan_id = self.curr_scan_id_by_short_path[rawfile.short_path] scan_ids = rawfile.reader.rt_by_scan_id_by_ms_level[1].keys() idx = scan_ids.index(curr_scan_id) times.append(rawfile.reader.rt_by_scan_id_by_ms_level[1][scan_ids[idx - 1]]) self.curr_scan_id_by_short_path[rawfile.short_path] = scan_ids[idx - 1] elif evt.key() == Qt.Key_Right: for rawfile in self.rawfiles_by_short_path.values()[:1]: if not rawfile.is_checked: continue curr_scan_id = self.curr_scan_id_by_short_path[rawfile.short_path] scan_ids = rawfile.reader.rt_by_scan_id_by_ms_level[1].keys() idx = scan_ids.index(curr_scan_id) times.append(rawfile.reader.rt_by_scan_id_by_ms_level[1][scan_ids[idx + 1]]) self.curr_scan_id_by_short_path[rawfile.short_path] = scan_ids[idx + 1] self._plot_spectrum() if times: self.inf_line_tic_item.setPos(sum(times) / float(len(times))) def _plot_spectrum(self): self.plot_widget_spectrum.clear() min_mz, max_mz = 1e9, 0 min_int, max_int = 1e10, 0 for rawfile in self.rawfiles_by_short_path.values(): if not rawfile.is_checked: continue scan_id, mzs, intensities = rawfile.reader.get_scan(self.curr_scan_id_by_short_path[rawfile.short_path]) min_mz = min(min_mz, mzs[0]) max_mz = max(max_mz, mzs[-1]) min_int = min(min_int, min(intensities)) max_int = max(max_int, max(intensities)) item = BarGraphItem(x=mzs, height=intensities, width=0.01, pen=rawfile.qcolor, brush=rawfile.qcolor) self.plot_widget_spectrum.addItem(item) self.plot_widget_spectrum.setLimits(xMin=min_mz, xMax=max_mz, yMin=min_int, yMax=max_int) def plot_spectrum(self, ev): #clear if ev.button() == Qt.RightButton: return self.plot_widget_spectrum.clear() vb = self.plot_widget_tic.vb mouse_point = vb.mapSceneToView(ev.scenePos()) t = mouse_point.x() if self.inf_line_tic_item is None: self.inf_line_tic_item = InfiniteLine(pos=t, angle=90) self.plot_widget_tic.addItem(self.inf_line_tic_item) self.inf_line_tic_item.setMovable(True) else: self.inf_line_tic_item.setPos(t) min_mz, max_mz = 1e9, 0 min_int, max_int = 1e10, 0 for rawfile in self.rawfiles_by_short_path.values(): if not rawfile.is_checked: continue scan_id, mzs, intensities = rawfile.reader.get_scan_for_time(t) self.curr_scan_id_by_short_path[rawfile.short_path] = scan_id min_mz = min(min_mz, mzs[0]) max_mz = max(max_mz, mzs[-1]) min_int = min(min_int, min(intensities)) max_int = max(max_int, max(intensities)) item = BarGraphItem(x=mzs, height=intensities, width=0.01, pen=rawfile.qcolor, brush=rawfile.qcolor) self.plot_widget_spectrum.addItem(item) self.plot_widget_spectrum.setLimits(xMin=min_mz, xMax=max_mz, yMin=min_int, yMax=max_int) def item_changed(self, item): print "item changed", item.text() s = item.text() if item.checkState(): self.rawfiles_by_short_path[s].is_checked = True else: self.rawfiles_by_short_path[s].is_checked = False #self.qApp.emit(SIGNAL('redraw()')) self.update_plot_() def show_open_dialog(self): files = QFileDialog(self).getOpenFileNames() if files: preload = Preloader(files, self) preload.loaded.connect(self.update_rawfile_model) preload.start() def update_rawfile_model(self, obj): files, r = obj[0], obj[1] n = len(files) not_database = [] min_time, max_time = 1e9, 0 min_int, max_int = 1e9, 0 for i, f in enumerate(files): i_f = float(i) c = WithoutBlank.get_color(i_f / n, asQColor=True) c_ = WithoutBlank.get_color(i_f / n, asQColor=True) filename = f.split("\\")[-1] abs_path = str(f.replace("\\", "\\\\")) if r[i]: rawfile = Rawfile(abs_path, c, filename) self.rawfiles_by_short_path[filename] = rawfile #[MzDBReader(abs_path), c, True] self.rawfile_model.appendRow(Aditi.get_coloured_root_item(filename, c, c_)) times, intensities = rawfile.reader.get_tic() min_time = min(min_time, min(times)) max_time = max(max_time, max(times)) min_int = min(min_int, min(intensities)) max_int = max(max_int, max(intensities)) self.plot_widget_tic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=1.3)) else: not_database.append(str(filename)) self.plot_widget_tic.setLimits(xMin=min_time, xMax=max_time, yMin=min_int, yMax=max_int) self.plot_widget_tic.scene().sigMouseClicked.connect(self.plot_spectrum) if not_database: v = "\n".join(not_database) QMessageBox.information(self, "Error", "The following files are not valid sqlite database:\n" + v) @staticmethod def get_coloured_root_item(filepath, color, colorr): root = QStandardItem(filepath) gradient = QLinearGradient(-100, -100, 100, 100) gradient.setColorAt(0.7, colorr) gradient.setColorAt(1, color) root.setBackground(QBrush(gradient)) root.setEditable(False) root.setCheckState(Qt.Checked) root.setCheckable(True) return root def quit(self): res = QMessageBox.warning(self, "Exiting...", "Are you sure ?", QMessageBox.Ok | QMessageBox.Cancel) if res == QMessageBox.Cancel: return QtGui.qApp.quit() def plot(self): #clear pw self.plot_widget_xic.clear() # check sample checked checked_files = [rawfile for rawfile in self.rawfiles_by_short_path.values() if rawfile.is_checked] mz = self.xic_widget.mzSpinBox.value() mz_tol = self.xic_widget.mzTolSpinBox.value() mz_diff = mz * mz_tol / 1e6 min_mz, max_mz = mz - mz_diff, mz + mz_diff #Thread implementation not as fast # args = [(data[0], min_mz, max_mz, data[2]) for data in checked_files] # extractor_thread = Extractor(args, self) # extractor_thread.extracted.connect(self._plot) # extractor_thread.start() min_time_val, max_time_val = 10000, 0 min_int_val, max_int_val = 1e9, 0 for rawfile in checked_files: t1 = time.clock() times, intensities = rawfile.reader.get_xic(min_mz, max_mz) print "elapsed: ", time.clock() - t1 # min_time_val = min(min_time_val, times[0]) # max_time_val = max(max_time_val, times[-1]) # min_int_val = min(min_int_val, min(intensities)) # max_int_val = max(max_int_val, max(intensities)) item = self.plot_widget_xic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=1.3)) item.curve.setClickable(True) def on_curve_clicked(): if not rawfile.is_highlighted: item.setPen(mkPen(color=rawfile.qcolor, width=4)) rawfile.is_highlighted = True else: item.setPen(mkPen(color=rawfile.qcolor, width=2)) rawfile.is_highlighted = False item.sigClicked.connect(on_curve_clicked) #item.sigHovered = on_curve_clicked self.xic_by_rawfile_short_path[rawfile.short_path] = item self.plot_widget_xic.setTitle(title="Xic@" + str(mz)) #self.plot_widget_xic.setLimits(xMin=min_time_val, xMax=max_time_val, yMin=min_int_val, yMax=max_int_val) def update_plot_(self): for rawfile in self.rawfiles_by_short_path.viewvalues(): if rawfile.is_checked: try: self.plot_widget_xic.addItem(self.xic_by_rawfile_short_path[rawfile.short_path]) except KeyError: mz = self.xic_widget.mzSpinBox.value() mz_tol = self.xic_widget.mzTolSpinBox.value() mz_diff = mz * mz_tol / 1e6 min_mz, max_mz = mz - mz_diff, mz + mz_diff times, intensities = rawfile.reader.get_xic(min_mz, max_mz) item = self.plot_widget_xic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=2)) self.xic_by_rawfile_short_path[rawfile.short_path] = item else: try: #self.plot_widget_xic.removeItem(self.xic_by_rawfile_short_path[rawfile.short_path]) self.xic_by_rawfile_short_path[rawfile.short_path].hide() except KeyError: pass