def init_device(self, device_presets): device_name = device_presets['StreamName'] device_type = device_presets['DeviceType'] if device_name not in self.device_workers.keys( ) and device_type == 'OpenBCI': try: openBCI_lsl_presets, OpenBCILSLInterface = process_preset_create_openBCI_interface( device_presets) except AssertionError as e: dialog_popup(str(e)) return None self.lslStream_presets_dict[device_name] = openBCI_lsl_presets self.device_workers[device_name] = workers.DeviceWorker( OpenBCILSLInterface) worker_thread = pg.QtCore.QThread(self) self.worker_threads[device_name] = worker_thread self.device_workers[device_name].moveToThread( self.worker_threads[device_name]) worker_thread.start() self.init_lsl(openBCI_lsl_presets) else: dialog_popup( 'We are not supporting this Device or the Device has been added' ) return None
def add_preset_experiment_clicked(self): selected_text = str(self.experiment_combo_box.currentText()) if selected_text in self.experiment_presets_dict.keys(): streams_for_experiment = self.experiment_presets_dict[ selected_text] try: assert np.all([ x in self.lslStream_presets_dict.keys() or x in self.device_presets_dict.keys() for x in streams_for_experiment ]) except AssertionError: dialog_popup( msg= "One or more stream name(s) in the experiment preset is not defined in LSLPreset or DevicePreset", title="Error") return loading_dlg = dialog_popup( msg="Please wait while streams are being added...", title="Info") for stream_name in streams_for_experiment: isLSL = stream_name in self.lslStream_presets_dict.keys() if isLSL: index = self.preset_LSLStream_combo_box.findText( stream_name, pg.QtCore.Qt.MatchFixedString) self.preset_LSLStream_combo_box.setCurrentIndex(index) self.add_preset_lslStream_clicked() else: index = self.device_combo_box.findText( stream_name, pg.QtCore.Qt.MatchFixedString) self.device_combo_box.setCurrentIndex(index) self.add_preset_device_clicked() loading_dlg.close()
def add_preset_device_clicked(self): if self.recordingTab.is_recording: dialog_popup(msg='Cannot add device while recording.') return selected_text = str(self.device_combo_box.currentText()) if selected_text in self.device_presets_dict.keys(): print('device found in device preset') device_lsl_preset = self.init_device( self.device_presets_dict[selected_text])
def start_stream(self): try: self._lslInlet_interface.start_sensor() except AttributeError as e: dialog_popup(e) return self.is_streaming = True self.num_samples = 0 self.start_time = time.time()
def stop_recording_btn_pressed(self): self.is_recording = False self.StopRecordingBtn.setEnabled(False) self.StartRecordingBtn.setEnabled(True) self.evict_buffer() self.timer.stop() self.recording_byte_count = 0 self.update_file_size_label() dialog_popup('Saved to {0}'.format(self.save_path), title='Info')
def remove_cam(): if self.recordingTab.is_recording: dialog_popup(msg='Cannot remove stream while recording.') return False worker_thread.exit() self.cam_workers.pop(cam_id) self.cam_displays.pop(cam_id) self.sensorTabSensorsHorizontalLayout.removeWidget( camera_widget) sip.delete(camera_widget) return True
def start_recording_btn_ressed(self): if not (len(self.parent.LSL_data_buffer_dicts.keys()) >= 1 or len(self.parent.cam_workers) >= 1): dialog_popup('You need at least one LSL Stream or Capture opened to start recording!') return self.save_path = self.generate_save_path() # get a new save path self.save_stream = RNStream(self.save_path) self.recording_buffer = {} # clear buffer self.is_recording = True self.StartRecordingBtn.setEnabled(False) self.StopRecordingBtn.setEnabled(True) self.recording_byte_count = 0 self.timer.start()
def add_preset_lslStream_clicked(self): if self.recordingTab.is_recording: dialog_popup(msg='Cannot add stream while recording.') return selected_text = str(self.preset_LSLStream_combo_box.currentText()) if selected_text in self.lslStream_presets_dict.keys(): self.init_lsl(self.lslStream_presets_dict[selected_text]) else: sensor_type = config_ui.sensor_ui_name_type_dict[selected_text] if sensor_type not in self.sensor_workers.keys(): self.init_sensor( sensor_type=config_ui.sensor_ui_name_type_dict[str( self.preset_LSLStream_combo_box.currentText())]) else: msg = 'Sensor type ' + sensor_type + ' is already added.' dialog_popup(msg)
def reload_all_presets(self): if len(self.lsl_workers) > 0 or len(self.device_workers) > 0: dialog_popup('Remove all streams before reloading presets!', title='Warning') return False else: try: self.lslStream_presets_dict = load_all_lslStream_presets() self.device_presets_dict = load_all_Device_presets() self.experiment_presets_dict = load_all_experiment_presets() except KeyError as e: dialog_popup( msg= 'Unknown preset specifier, {0}\n Please check the example presets for list of valid specifiers: ' .format(e), title='Error') return False return True
def init_camera(self, cam_id): if cam_id not in self.cam_workers.keys(): camera_widget_name = ('Webcam ' if cam_id.isnumeric() else 'Screen Capture ') + str(cam_id) camera_widget, camera_layout, remove_cam_btn, camera_img_label = init_camera_widget( parent=self.camWidgetVerticalLayout, label_string=camera_widget_name, insert_position=self.camWidgetVerticalLayout.count() - 1) camera_widget.setObjectName(camera_widget_name) # create camera worker thread worker_thread = pg.QtCore.QThread(self) self.worker_threads[cam_id] = worker_thread wkr = workers.WebcamWorker(cam_id=cam_id) if cam_id.isnumeric( ) else workers.ScreenCaptureWorker(cam_id) self.cam_workers[cam_id] = wkr self.cam_displays[cam_id] = camera_img_label wkr.change_pixmap_signal.connect(self.visualize_cam) def remove_cam(): if self.recordingTab.is_recording: dialog_popup(msg='Cannot remove stream while recording.') return False worker_thread.exit() self.cam_workers.pop(cam_id) self.cam_displays.pop(cam_id) self.sensorTabSensorsHorizontalLayout.removeWidget( camera_widget) sip.delete(camera_widget) return True remove_cam_btn.clicked.connect(remove_cam) self.cam_workers[cam_id].moveToThread(self.worker_threads[cam_id]) worker_thread.start() else: dialog_popup('Webcam with ID ' + cam_id + ' is already added.')
def remove_stream(): if self.recordingTab.is_recording: dialog_popup(msg='Cannot remove stream while recording.') return False stop_stream_btn.click() # fire stop streaming first worker_thread.exit() self.lsl_workers.pop(lsl_stream_name) self.worker_threads.pop(lsl_stream_name) # if this lsl connect to a device: if lsl_stream_name in self.device_workers.keys(): self.device_workers[lsl_stream_name].stop_stream() self.device_workers.pop(lsl_stream_name) self.stream_ui_elements.pop(lsl_stream_name) self.sensorTabSensorsHorizontalLayout.removeWidget(lsl_widget) # close window if popped if lsl_stream_name in self.pop_windows.keys(): self.pop_windows[lsl_stream_name].hide() self.pop_windows.pop(lsl_stream_name) else: # use recursive delete if docked sip.delete(lsl_widget) self.LSL_data_buffer_dicts.pop(lsl_stream_name) return True
def relaod_all_presets_btn_clicked(self): if self.reload_all_presets(): self.update_presets_combo_box() dialog_popup('Reloaded all presets', title='Info')
def init_lsl(self, preset): lsl_stream_name = preset['StreamName'] if lsl_stream_name not in self.lsl_workers.keys( ): # if this inlet hasn't been already added try: preset, interface = process_preset_create_lsl_interface(preset) except AssertionError as e: dialog_popup(str(e)) return None lsl_num_chan, lsl_chan_names, plot_group_slices = preset['NumChannels'], \ preset['ChannelNames'], \ preset['PlotGroupSlices'] if lsl_stream_name.lower().endswith('simulation'): self.lsl_workers[lsl_stream_name] = workers.DEAPWorker( interface) elif lsl_stream_name.lower() == 'aiyvoice': self.lsl_workers[lsl_stream_name] = workers.AIYWorker( interface) elif lsl_stream_name.lower() == 'pubsub': self.lsl_workers[lsl_stream_name] = workers.PubSubWorker( interface) else: self.lsl_workers[lsl_stream_name] = workers.LSLInletWorker( interface) lsl_widget_name = lsl_stream_name + '_widget' lsl_widget, lsl_layout, start_stream_btn, stop_stream_btn, pop_window_btn, signal_settings_btn = init_sensor_or_lsl_widget( parent=self.sensorTabSensorsHorizontalLayout, label_string=lsl_stream_name, insert_position=self.sensorTabSensorsHorizontalLayout.count() - 1) lsl_widget.setObjectName(lsl_widget_name) worker_thread = pg.QtCore.QThread(self) self.worker_threads[lsl_stream_name] = worker_thread stop_stream_btn.clicked.connect( self.lsl_workers[lsl_stream_name].stop_stream) self.LSL_plots_fs_label_dict[ lsl_stream_name] = self.init_visualize_LSLStream_data( parent=lsl_layout, num_chan=lsl_num_chan, chan_names=lsl_chan_names, plot_group_slices=plot_group_slices) self.lsl_workers[lsl_stream_name].signal_data.connect( self.process_LSLStream_data) self.LSL_data_buffer_dicts[lsl_stream_name] = np.empty( shape=(lsl_num_chan, 0)) preset["num_samples_to_plot"] = int(preset["NominalSamplingRate"] * config.PLOT_RETAIN_HISTORY) preset["ActualSamplingRate"] = preset[ "NominalSamplingRate"] # actual sampling rate is updated during runtime preset["timevector"] = np.linspace(0., config.PLOT_RETAIN_HISTORY, preset["num_samples_to_plot"]) def signal_settings_window(): print("signal settings btn clicked") signal_settings_window = SignalSettingsTab() if signal_settings_window.exec_(): print("signal setting window open") else: print("Cancel!") signal_settings_btn.clicked.connect(signal_settings_window) #### TODO: signal processing button (hidded before finishing) signal_settings_btn.hide() ##### # pop window actions # pop window actions def dock_window(): self.sensorTabSensorsHorizontalLayout.insertWidget( self.sensorTabSensorsHorizontalLayout.count() - 1, lsl_widget) pop_window_btn.clicked.disconnect() pop_window_btn.clicked.connect(pop_window) pop_window_btn.setText('Pop Window') self.pop_windows[lsl_stream_name].hide() # tetentive measures self.pop_windows.pop(lsl_stream_name) def pop_window(): w = AnotherWindow(lsl_widget, remove_stream) self.pop_windows[lsl_stream_name] = w w.setWindowTitle(lsl_stream_name) pop_window_btn.setText('Dock Window') w.show() pop_window_btn.clicked.disconnect() pop_window_btn.clicked.connect(dock_window) pop_window_btn.clicked.connect(pop_window) def remove_stream(): if self.recordingTab.is_recording: dialog_popup(msg='Cannot remove stream while recording.') return False stop_stream_btn.click() # fire stop streaming first worker_thread.exit() self.lsl_workers.pop(lsl_stream_name) self.worker_threads.pop(lsl_stream_name) # if this lsl connect to a device: if lsl_stream_name in self.device_workers.keys(): self.device_workers[lsl_stream_name].stop_stream() self.device_workers.pop(lsl_stream_name) self.stream_ui_elements.pop(lsl_stream_name) self.sensorTabSensorsHorizontalLayout.removeWidget(lsl_widget) # close window if popped if lsl_stream_name in self.pop_windows.keys(): self.pop_windows[lsl_stream_name].hide() self.pop_windows.pop(lsl_stream_name) else: # use recursive delete if docked sip.delete(lsl_widget) self.LSL_data_buffer_dicts.pop(lsl_stream_name) return True # worker_thread remove_stream_btn = init_button( parent=lsl_layout, label='Remove Stream', function=remove_stream ) # add delete sensor button after adding visualization self.stream_ui_elements[lsl_stream_name] = { 'lsl_widget': lsl_widget, 'start_stream_btn': start_stream_btn, 'stop_stream_btn': stop_stream_btn, 'remove_stream_btn': remove_stream_btn } self.lsl_workers[lsl_stream_name].moveToThread( self.worker_threads[lsl_stream_name]) start_stream_btn.clicked.connect( self.lsl_workers[lsl_stream_name].start_stream) worker_thread.start() return preset else: dialog_popup('LSL Stream with data type ' + lsl_stream_name + ' is already added.') return None
def add_camera_clicked(self): if self.recordingTab.is_recording: dialog_popup(msg='Cannot add capture while recording.') return selected_camera_id = self.camera_combo_box.currentText() self.init_camera(selected_camera_id)