def plot_pixel_sums(self, axis, label): plot = PlotWindow(f'{self.spec.id} {label} Sum') plt.sca(plot.axis) science = self.spec.science.sum(axis=axis) contamination = self.spec.contamination.sum(axis=axis) plt.plot(contamination, alpha=0.6, label='Contamination') plt.plot(science + contamination, alpha=0.6, label='Original') plt.plot(science, label='Decontaminated') plt.title(f'Object ID: {self.spec.id}') plt.xlabel(f'Pixel {label}') plt.ylabel(f'{label} Sum') plt.legend() plt.draw() plot.show() plot.adjustSize() plt.close()
def show_spec_layer(self, title, data): plot = PlotWindow(title) plt.sca(plot.axis) plt.imshow(data, origin='lower') plt.subplots_adjust(top=0.975, bottom=0.025, left=0.025, right=0.975) plt.draw() plot.setWindowFlag(Qt.WindowStaysOnTopHint, False) plot.show() padding = 32 display = QApplication.desktop() current_screen = display.screenNumber(self.view) geom = display.screenGeometry(current_screen) width = geom.width() - 2 * padding height = geom.height() - 2 * padding plot.setGeometry(geom.left() + padding, geom.top() + padding, width, height) plt.close()
def plotResults(directory): np.set_printoptions(linewidth=150) plt.rc('text', usetex=True) plt.rc('font', family='serif') global xtitles, vtitles, etitles, imu_titles, colors, data, pw, plotCov xtitles = ['$p_x$', '$p_y$', '$p_z$', '$q_w$', '$q_x$', '$q_y$', '$q_z$'] vtitles = ['$v_x$', '$v_y$', '$v_z$'] etitles = ['$\phi$', r'$\theta$', '$\psi$'] imu_titles = [ r"$acc_x$", r"$acc_y$", r"$acc_z$", r"$\omega_x$", r"$\omega_y$", r"$\omega_z$" ] colors = [ '#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf' ] plotCov = True data = Log(directory) pw = PlotWindow() plotPosition() plotPosition2d() plotVelocity() plotAttitude() plotEuler() plotLla() plotIMU() plotImuBias() plotZVRes() plotBaroRes() plotRangeRes() plotGnssRes() pw.show()
class ViewPSD(QObject): # view_finished = pyqtSignal() plot_ready = pyqtSignal(list) def __init__(self, config, out_file_name, parent=None): super(ViewPSD, self).__init__(parent) self.config = config self.out_file_name = out_file_name self.plot_window = PlotWindow() self.plot_window.closed.connect(self.stop_view_psd) self.plot_window.show() self.plot_flg = False self.plot_ready[list].connect(self.plot) def __del__(self): self.plot_window.close() def update_config(self, config): self.config = config def plot(self, data): print("-- plot --") self.plot_window.fc = self.config.fc self.plot_window.fs = self.config.fs self.plot_window.sig = data # if not self.plot_window.t.isActive(): if self.plot_flg: self.plot_window.t.start(50) def plot_psd_process(self): self.plot_flg = True bat = pjoin(self.config.gnu_radio_path, "run_gr.bat") rx_py = pjoin(self.config.gnu_radio_path, "uhd_rx_cfile.py") output_path = pjoin(self.config.save_path, self.out_file_name) print( f"{bat} {rx_py} {output_path} -s -f {self.config.fc} -r {self.config.fs} -N {self.config.sample_nums}" ) print("查看频谱模式") while self.plot_flg: print("=========================") os.spawnl( os.P_WAIT, bat, f"{bat} {rx_py} {output_path} -s -f {self.config.fc} -r {self.config.fs} -N {self.config.sample_nums}" ) with open(output_path, "rb") as f: buff = f.read() tmp = np.frombuffer(buff, np.int16) / 32768 d_i, d_q = np.reshape(tmp, (-1, 2)).T data = d_i + 1j * d_q # if not self.plot_flg: # break self.plot_ready.emit(list(data)) def stop_view_psd(self): print("-- stop_view_psd --") self.plot_flg = False self.view_finished.emit()
def show_all_layers(self): title = f'All Layers of {self.spec.id}' horizontal = self.rect().width() > self.rect().height() subplot_grid_shape = (7, 1) if horizontal else (1, 7) plot = PlotWindow(title, shape=subplot_grid_shape) plt.sca(plot.axis[0]) plt.imshow(self.spec.contamination + self.spec.science, origin='lower') plt.title('Original') plt.draw() plt.sca(plot.axis[1]) plt.imshow(self.spec.contamination, origin='lower') plt.title('Contamination') plt.draw() plt.sca(plot.axis[2]) plt.imshow(self.spec.science, origin='lower') plt.title('Decontaminated') plt.draw() plt.sca(plot.axis[3]) if self.model is not None: plt.imshow(self.model, origin='lower') plt.title('Model') else: plt.title('N/A') plt.draw() plt.sca(plot.axis[4]) if self.model is not None: plt.imshow(self.spec.science - self.model, origin='lower') plt.title('Residual') else: plt.title('N/A') plt.draw() plt.sca(plot.axis[5]) plt.imshow(self.spec.variance, origin='lower') plt.title('Variance') plt.draw() plt.sca(plot.axis[6]) data = (flag['ZERO'] & self.spec.mask) == flag['ZERO'] plt.imshow(data, origin='lower') plt.title('Zeroth Orders') plt.draw() if horizontal: plt.subplots_adjust(top=0.97, bottom=0.025, left=0.025, right=0.975, hspace=0, wspace=0) else: plt.subplots_adjust(top=0.9, bottom=0.03, left=0.025, right=0.975, hspace=0, wspace=0) plt.draw() plot.setWindowFlag(Qt.WindowStaysOnTopHint, False) plot.show() padding = 50 display = QApplication.desktop() current_screen = display.screenNumber(self.view) geom = display.screenGeometry(current_screen) width = geom.width() - 2 * padding height = geom.height() - 2 * padding plot.setGeometry(geom.left() + padding, geom.top() + padding, width, height) plt.close()
class MainWindow(QMainWindow, Ui_MainWindow): config_changed = pyqtSignal() def __init__(self): super(MainWindow, self).__init__() self.setupUi(self) self.setWindowTitle("USRP B210 信号采样") self.setWindowIcon(QIcon("signal_app_24.png")) self.resize(1280, 720) self.plot_win = PlotWindow() # qss = "QWidget#MainWindow{background-color:red;}" # qss = "QWidget#MainWindow{border-image:url(signal_app_24.png);}" # self.setStyleSheet(qss) self.home_dir = pjoin(os.path.expanduser("~"), ".uhd_ui") self.config_path = pjoin(self.home_dir, "config.json") self.CONFIG = {} self.config = Config() self.config_keys = [ "gnu_radio_path", "save_path", "fc", "fs", "stop_fc", "sample_interval", "sample_nums", "sample_times" ] self.view_spec_config = Config() self.view_spec_config.save_path = self.home_dir self.view_spec_config.sample_times = 1 self.view_spec_config.sample_nums = 1 * 1024 * 1024 self.sample_thread = None # SampleThread() self.initial() self.save_path_btn.clicked.connect(self.open_folder) self.gnu_radio_btn.clicked.connect(self.open_gnu_folder) self.ok_btn.clicked.connect(self.sample_thread_start) self.ok_btn.setToolTip("开始采集信号") self.plot_btn.clicked.connect(self.plot_psd_start) self.plot_win.closed.connect(self.plot_psd_stop) self.stop_btn.setEnabled(False) self.stop_btn.setToolTip("停止当前信号采样") self.stop_btn.clicked.connect(self.stop_current_sampling) self.advance_groupBox.hide() self.advance_mode = False self.advance_mode_btn.setText("打开高级模式") self.advance_mode_btn.clicked.connect(self.set_advance_mode) self.gnu_radio_path_edit.textChanged[str].connect( self.new_gnu_radio_path) self.save_path_edit.textChanged[str].connect(self.new_save_path) self.fc_spinBox.valueChanged[int].connect(self.new_fc_val) self.fc_comboBox.currentIndexChanged[int].connect(self.new_fc_cbox) self.stop_fc_spinBox.valueChanged[int].connect(self.new_stop_fc_val) self.stop_fc_comboBox.currentIndexChanged[int].connect( self.new_stop_fc_cbox) self.fs_spinBox.valueChanged[int].connect(self.new_fs_val) self.fs_comboBox.currentIndexChanged[int].connect(self.new_fs_cbox) self.sample_interval_spinBox.valueChanged[int].connect( self.new_sample_interval_val) self.sample_interval_comboBox.currentIndexChanged[int].connect( self.new_sample_interval_cbox) self.sample_nums_spinBox.valueChanged[int].connect( self.new_n_sample_val) self.sample_nums_comboBox.currentIndexChanged[int].connect( self.new_n_sample_cbox) self.sample_times_spinBox.valueChanged[int].connect( self.new_sample_times) self.config_changed.connect(self.update_config) def resizeEvent(self, event): print(f"new_window_size: [{self.width()}, {self.height()}]") def closeEvent(self, event): self.plot_win.close() self.sample_thread.stop() self.sample_thread.quit() self.sample_thread.wait() def initial(self): def _get(s_cfg, index=0): s_cfg = s_cfg.split() if len(s_cfg) == 2: try: index = self.config.u2ix_dict[s_cfg[1]] return s_cfg[0], index except: raise ValueError("配置出错!") elif len(s_cfg) == 1: return s_cfg[0], index else: raise ValueError("配置出错!") initial_config = _config() if not os.path.exists(self.home_dir): os.makedirs(self.home_dir) if not os.path.exists(self.config_path): # self.CONFIG["gnu_radio_path"] = initial_config.gnu_radio_path # self.CONFIG["save_path"] = initial_config.save_path # self.CONFIG["FC"] = initial_config.fc # self.CONFIG["FS"] = initial_config.fs # self.CONFIG["stop_FC"] = initial_config.stop_fc # self.CONFIG["sample_interval"] = initial_config.sample_interval # self.CONFIG["sample_nums"] = initial_config.sample_nums # self.CONFIG["sample_times"] = initial_config.sample_times for key in self.config_keys: self.CONFIG[key] = initial_config.__getattribute__(key) self.save_config() self.gnu_radio_path_edit.setText(self.CONFIG["gnu_radio_path"]) self.save_path_edit.setText(self.CONFIG["save_path"]) _fc, _fc_index = _get(self.CONFIG["fc"]) self.fc_spinBox.setValue(int(_fc)) self.fc_comboBox.setCurrentIndex(_fc_index) _fs, _fs_index = _get(self.CONFIG["fs"]) self.fs_spinBox.setValue(int(_fs)) self.fs_comboBox.setCurrentIndex(_fs_index) _stop_fc, _stop_fc_index = _get(self.CONFIG["stop_fc"]) self.stop_fc_spinBox.setValue(int(_stop_fc)) self.stop_fc_comboBox.setCurrentIndex(_stop_fc_index) _interval, _interval_index = _get(self.CONFIG["sample_interval"]) self.sample_interval_spinBox.setValue(int(_interval)) self.sample_interval_comboBox.setCurrentIndex(_interval_index) _n_sample, _n_index = _get(self.CONFIG["sample_nums"]) self.sample_nums_spinBox.setValue(int(_n_sample)) self.sample_nums_comboBox.setCurrentIndex(_n_index) self.sample_times_spinBox.setValue(int( self.CONFIG["sample_times"])) else: with open(self.config_path, "r") as f: self.CONFIG = json.load(f) self.config_changed.emit() for key in self.config_keys: if key not in self.CONFIG: self.CONFIG[key] = initial_config.__getattribute__(key) self.gnu_radio_path_edit.setText(self.CONFIG["gnu_radio_path"]) self.save_path_edit.setText(self.CONFIG["save_path"]) _fc, _fc_index = _get(self.CONFIG["fc"]) self.fc_spinBox.setValue(int(_fc)) self.fc_comboBox.setCurrentIndex(_fc_index) _fs, _fs_index = _get(self.CONFIG["fs"]) self.fs_spinBox.setValue(int(_fs)) self.fs_comboBox.setCurrentIndex(_fs_index) _stop_fc, _stop_fc_index = _get(self.CONFIG["stop_fc"]) self.stop_fc_spinBox.setValue(int(_stop_fc)) self.stop_fc_comboBox.setCurrentIndex(_stop_fc_index) _interval, _interval_index = _get( self.CONFIG["sample_interval"]) self.sample_interval_spinBox.setValue(int(_interval)) self.sample_interval_comboBox.setCurrentIndex(_interval_index) _n_sample, _n_index = _get(self.CONFIG["sample_nums"]) self.sample_nums_spinBox.setValue(int(_n_sample)) self.sample_nums_comboBox.setCurrentIndex(_n_index) self.sample_times_spinBox.setValue( int(self.CONFIG["sample_times"])) self.update_config() def save_config(self): with open(self.config_path, "w") as f: json.dump(self.CONFIG, f) self.config_changed.emit() def update_config(self): def get_value(cfg, u=1000): val, unit = cfg.split() if len(cfg.split()) > 1 else [ cfg.split()[0], "" ] val = int(int(val) * u**self.config.u2ix_dict[unit]) return val self.config.gnu_radio_path = self.CONFIG["gnu_radio_path"] self.config.save_path = self.CONFIG["save_path"] self.config.fc = get_value(self.CONFIG["fc"]) self.config.fs = get_value(self.CONFIG["fs"]) self.config.stop_fc = get_value(self.CONFIG["stop_fc"]) self.config.sample_interval = get_value(self.CONFIG["sample_interval"]) self.config.sample_nums = get_value(self.CONFIG["sample_nums"], 1024) self.config.sample_times = int(self.CONFIG["sample_times"]) self.view_spec_config.gnu_radio_path = self.config.gnu_radio_path self.view_spec_config.fc = self.config.fc self.view_spec_config.fs = self.config.fs print(f"---- config changed ----\n\ GNU Radio 安装目录:\t{self.config.gnu_radio_path} \n\ 文件保存路径:\t{self.config.save_path} \n\ 中心频率:\t\t{self.config.fc} \n\ 采样带宽:\t\t{self.config.fs} \n\ 结束频率:\t\t{self.config.stop_fc} \n\ 采样间隔:\t\t{self.config.sample_interval} \n\ 采样点数:\t\t{self.config.sample_nums} \n\ 采样次数:\t\t{self.config.sample_times} \n") def sample_thread_start(self): self.textEdit.append("---- 开始采样 ----\n") self.sample_thread = SampleThread() self.sample_thread.one_sample_end[int, str].connect(self.one_sample_end) self.sample_thread.all_sample_end.connect(self.sample_thread_end) self.sample_thread.config = self.config # self.sample_thread.mode = 2 # test_mode self.sample_thread.mode = 1 # test_mode self.sample_thread.start_sample = True self.sample_thread.start() self.plot_btn.setEnabled(False) self.plot_btn.setToolTip("正在采集信号, 无法查看当前频谱") self.stop_btn.setEnabled(True) self.ok_btn.setEnabled(False) def one_sample_end(self, ix, output_path): self.textEdit.append( f"第 {ix} 次采样完成,共 {self.config.sample_times} 次,文件保存路径:{output_path}" ) def sample_thread_end(self): self.textEdit.append("---- 采样结束 ----\n") # self.sample_thread.terminate() self.sample_thread.stop() self.sample_thread.wait() self.sample_thread = None self.ok_btn.setEnabled(True) self.plot_btn.setEnabled(True) self.plot_btn.setToolTip("查看当前频谱") self.stop_btn.setEnabled(False) def stop_current_sampling(self): self.textEdit.append("---- 停止采样 ----\n") self.stop_btn.setEnabled(False) # self.sample_thread.terminate() self.sample_thread.stop() self.sample_thread.wait() self.sample_thread = None self.plot_btn.setEnabled(True) self.plot_btn.setToolTip("查看当前频谱") def plot_psd_start(self): self.textEdit.append("---- 查看频谱 ----\n") self.sample_thread = SampleThread() self.sample_thread.spec_data_get[list].connect(self.plot_psd) self.sample_thread.out_file_name = "usrp_tmp.bin" self.sample_thread.config = self.view_spec_config self.sample_thread.mode = 0 self.sample_thread.start_sample = True self.sample_thread.start() self.ok_btn.setEnabled(False) @pyqtSlot(list) def plot_psd(self, data): print("-- plot spec --") self.plot_win.show() self.plot_win.fc = self.config.fc self.plot_win.fs = self.config.fs self.plot_win.sig = data self.plot_win.t.start(50) @pyqtSlot() def plot_psd_stop(self): self.textEdit.append("---- 查看频谱 ----\n") self.sample_thread.start_plot = False # self.sample_thread.terminate() self.sample_thread.stop() self.sample_thread.wait() self.sample_thread = None self.ok_btn.setEnabled(True) def set_advance_mode(self): self.advance_mode = not self.advance_mode if self.advance_mode: self.advance_groupBox.show() self.advance_mode_btn.setText("退出高级模式") self.textEdit.setText("-- 退出高级模式 --") else: self.advance_groupBox.hide() self.advance_mode_btn.setText("打开高级模式") self.textEdit.setText("-- 打开高级模式 --") def open_folder(self): dataPath = QtWidgets.QFileDialog.getExistingDirectory( self, "选择文件保存路径", self.CONFIG["save_path"], QtWidgets.QFileDialog.ShowDirsOnly) if dataPath == "": return else: self.save_path_edit.setText(dataPath) def open_gnu_folder(self): dataPath = QtWidgets.QFileDialog.getExistingDirectory( self, "打开GNU Radio/bin目录", self.CONFIG["gnu_radio_path"], QtWidgets.QFileDialog.ShowDirsOnly) if dataPath == "": return else: self.gnu_radio_path_edit.setText(dataPath) @pyqtSlot(str) def new_gnu_radio_path(self, path): self.textEdit.append("gnu_path_changed: " + path) self.CONFIG["gnu_radio_path"] = path self.save_config() @pyqtSlot(str) def new_save_path(self, path): self.textEdit.append("save_path_changed: " + path) self.CONFIG["save_path"] = path self.save_config() @pyqtSlot(int) def new_fc_val(self, val): unit = self.config.ix2u_dict[self.fc_comboBox.currentIndex()] new_fc = f"{int(val)} {unit}" self.textEdit.append("FC: " + new_fc + "Hz") self.CONFIG["fc"] = new_fc self.save_config() @pyqtSlot(int) def new_fc_cbox(self, ix): try: unit = self.config.ix2u_dict[ix] except KeyError: raise ValueError("设置出错") new_fc = f"{self.fc_spinBox.value()} {unit}" self.textEdit.append("FC: " + new_fc + "Hz") self.CONFIG["fc"] = new_fc self.save_config() @pyqtSlot(int) def new_stop_fc_val(self, val): unit = self.config.ix2u_dict[self.stop_fc_comboBox.currentIndex()] new_stop_fc = f"{int(val)} {unit}" self.textEdit.append("stop_FC: " + new_stop_fc + "Hz") self.CONFIG["stop_fc"] = new_stop_fc self.save_config() @pyqtSlot(int) def new_stop_fc_cbox(self, ix): try: unit = self.config.ix2u_dict[ix] except KeyError: raise ValueError("设置出错") new_stop_fc = f"{self.stop_fc_spinBox.value()} {unit}" self.textEdit.append("stop_FC: " + new_stop_fc + "Hz") self.CONFIG["stop_fc"] = new_stop_fc self.save_config() @pyqtSlot(int) def new_fs_val(self, val): unit = self.config.ix2u_dict[self.fs_comboBox.currentIndex()] new_fs = f"{int(val)} {unit}" self.textEdit.append("FS: " + new_fs + "Hz") self.CONFIG["fs"] = new_fs self.save_config() @pyqtSlot(int) def new_fs_cbox(self, ix): try: unit = self.config.ix2u_dict[ix] except KeyError: raise ValueError("设置出错") new_fs = f"{self.fs_spinBox.value()} {unit}" self.textEdit.append("FS: " + new_fs + "Hz") self.CONFIG["fs"] = new_fs self.save_config() @pyqtSlot(int) def new_sample_interval_val(self, val): unit = self.config.ix2u_dict[ self.sample_interval_comboBox.currentIndex()] new_sample_interval = f"{int(val)} {unit}" self.textEdit.append("sample_interval: " + new_sample_interval + "Hz") self.CONFIG["sample_interval"] = new_sample_interval self.save_config() @pyqtSlot(int) def new_sample_interval_cbox(self, ix): try: unit = self.config.ix2u_dict[ix] except KeyError: raise ValueError("设置出错") new_sample_interval = f"{self.sample_interval_spinBox.value()} {unit}" self.textEdit.append("sample_interval: " + new_sample_interval + "Hz") self.CONFIG["sample_interval"] = new_sample_interval self.save_config() @pyqtSlot(int) def new_n_sample_val(self, val): unit = self.config.ix2u_dict[self.sample_nums_comboBox.currentIndex()] new_n_sample = f"{int(val)} {unit}" # new_n_sample = f"{int(val)} {_d[self.sample_nums_comboBox.currentIndex()]}" self.textEdit.append("sample_num: " + new_n_sample) self.CONFIG["sample_nums"] = new_n_sample self.save_config() @pyqtSlot(int) def new_n_sample_cbox(self, ix): try: unit = self.config.ix2u_dict[ix] except KeyError: raise ValueError("设置出错") new_n_sample = f"{self.sample_nums_spinBox.value()} {unit}" self.textEdit.append("sample_num: " + new_n_sample) self.CONFIG["sample_nums"] = new_n_sample self.save_config() @pyqtSlot(int) def new_sample_times(self, val): new_times = str(val) self.textEdit.append("sample_times: " + new_times) self.CONFIG["sample_times"] = new_times self.save_config()