예제 #1
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        #f = open('/dev/null', 'w')
        #sys.stdout = f

        self.tabWidget.setCurrentIndex(0)

        # Set pyqtgraph to use white background, black foreground
        pg.setConfigOption('background', 'w')
        pg.setConfigOption('foreground', 'k')
        pg.setConfigOption('imageAxisOrder', 'row-major')
        #pg.setConfigOption('useOpenGL', True)
        #pg.setConfigOption('useWeave', True)

        # Spectrum display

        self.win_spectrum = pg.GraphicsWindow(title="Quad Channel Spectrum")

        self.export_spectrum = pg.exporters.ImageExporter(
            self.win_spectrum.scene())

        self.plotWidget_spectrum_ch1 = self.win_spectrum.addPlot(
            title="Channel 1")
        self.plotWidget_spectrum_ch2 = self.win_spectrum.addPlot(
            title="Channel 2")
        self.win_spectrum.nextRow()
        self.plotWidget_spectrum_ch3 = self.win_spectrum.addPlot(
            title="Channel 3")
        self.plotWidget_spectrum_ch4 = self.win_spectrum.addPlot(
            title="Channel 4")

        self.gridLayout_spectrum.addWidget(self.win_spectrum, 1, 1, 1, 1)

        x = np.arange(1000)
        y = np.random.normal(size=(4, 1000))

        self.spectrum_ch1_curve = self.plotWidget_spectrum_ch1.plot(x,
                                                                    y[0],
                                                                    clear=True,
                                                                    pen='b')
        self.spectrum_ch2_curve = self.plotWidget_spectrum_ch2.plot(x,
                                                                    y[1],
                                                                    clear=True,
                                                                    pen='r')
        self.spectrum_ch3_curve = self.plotWidget_spectrum_ch3.plot(x,
                                                                    y[2],
                                                                    clear=True,
                                                                    pen='g')
        self.spectrum_ch4_curve = self.plotWidget_spectrum_ch4.plot(x,
                                                                    y[3],
                                                                    clear=True,
                                                                    pen='c')

        self.plotWidget_spectrum_ch1.setLabel("bottom", "Frequency [MHz]")
        self.plotWidget_spectrum_ch1.setLabel("left", "Amplitude [dBm]")
        self.plotWidget_spectrum_ch2.setLabel("bottom", "Frequency [MHz]")
        self.plotWidget_spectrum_ch2.setLabel("left", "Amplitude [dBm]")
        self.plotWidget_spectrum_ch3.setLabel("bottom", "Frequency [MHz]")
        self.plotWidget_spectrum_ch3.setLabel("left", "Amplitude [dBm]")
        self.plotWidget_spectrum_ch4.setLabel("bottom", "Frequency [MHz]")
        self.plotWidget_spectrum_ch4.setLabel("left", "Amplitude [dBm]")

        #---> Sync display <---
        # --> Delay

        self.win_sync = pg.GraphicsWindow(title="Receiver Sync")

        self.export_sync = pg.exporters.ImageExporter(self.win_sync.scene())

        self.plotWidget_sync_absx = self.win_sync.addPlot(title="ABS X Corr")
        #self.plotWidget_sync_absx.setDownsampling(ds=4, mode='subsample')
        #self.plotWidget_sync_normph = self.win_sync.addPlot(title="Normalized Phasors")
        self.win_sync.nextRow()
        self.plotWidget_sync_sampd = self.win_sync.addPlot(
            title="Sample Delay History")
        self.plotWidget_sync_phasediff = self.win_sync.addPlot(
            title="Phase Diff History")

        self.gridLayout_sync.addWidget(self.win_sync, 1, 1, 1, 1)

        x = np.arange(1000)
        y = np.random.normal(size=(4, 1000))

        #---> DOA results display <---

        self.win_DOA = pg.GraphicsWindow(title="DOA Plot")
        #Set up image exporter for web display
        self.export_DOA = pg.exporters.ImageExporter(self.win_DOA.scene())

        self.plotWidget_DOA = self.win_DOA.addPlot(
            title="Direction of Arrival Estimation")
        self.plotWidget_DOA.setLabel("bottom", "Incident Angle [deg]")
        self.plotWidget_DOA.setLabel("left", "Amplitude [dB]")
        self.plotWidget_DOA.showGrid(x=True, alpha=0.25)
        self.gridLayout_DOA.addWidget(self.win_DOA, 1, 1, 1, 1)

        self.DOA_res_fd = open("/ram/DOA_value.html",
                               "w")  # DOA estimation result file descriptor

        # Junk data to just init plot legends
        x = np.arange(1000)
        y = np.random.normal(size=(4, 1000))

        self.plotWidget_DOA.addLegend()

        self.plotWidget_DOA.plot(x,
                                 y[0],
                                 pen=pg.mkPen('b', width=2),
                                 name="Bartlett")
        self.plotWidget_DOA.plot(x,
                                 y[1],
                                 pen=pg.mkPen('g', width=2),
                                 name="Capon")
        self.plotWidget_DOA.plot(x,
                                 y[2],
                                 pen=pg.mkPen('r', width=2),
                                 name="MEM")
        self.plotWidget_DOA.plot(x,
                                 y[3],
                                 pen=pg.mkPen('c', width=2),
                                 name="MUSIC")

        #---> Passive radar results display <---

        self.win_PR = pg.GraphicsWindow(title="Passive Radar")

        self.export_PR = pg.exporters.ImageExporter(self.win_PR.scene())

        self.plt_PR = self.win_PR.addPlot(Title="Range-Doppler Matrix")
        self.plt_PR.setLabel("bottom", "Range")
        self.plt_PR.setLabel("left", "Doppler (Speed)")

        self.PR_interp_factor = 4

        self.plt_PR.getAxis("bottom").setScale(1.0 / self.PR_interp_factor)
        self.plt_PR.getAxis("left").setScale(1.0 / self.PR_interp_factor)

        rand_mat = np.random.rand(50, 50)
        self.img_PR = pg.ImageView()

        self.plt_PR.addItem(self.img_PR.imageItem)

        self.img_PR.setImage(rand_mat)
        self.img_PR.autoLevels()
        self.img_PR.autoRange()

        # Take the color map from matplotlib because it's nicer than pyqtgraph's
        colormap = cm.get_cmap("jet")
        colormap._init()
        lut = (colormap._lut * 255).view(np.ndarray)
        self.img_PR.imageItem.setLookupTable(lut)

        #self.img_PR.setPredefinedGradient('spectrum')

        self.gridLayout_RD.addWidget(self.win_PR, 1, 1, 1, 1)

        # Connect pushbutton signals
        self.pushButton_close.clicked.connect(self.pb_close_clicked)
        self.pushButton_proc_control.clicked.connect(
            self.pb_proc_control_clicked)
        self.pushButton_sync.clicked.connect(self.pb_sync_clicked)
        self.pushButton_iq_calib.clicked.connect(self.pb_calibrate_iq_clicked)
        self.pushButton_del_sync_history.clicked.connect(
            self.pb_del_sync_history_clicked)
        self.pushButton_DOA_cal_90.clicked.connect(
            self.pb_calibrate_DOA_90_clicked)
        self.pushButton_set_receiver_config.clicked.connect(
            self.pb_rec_reconfig_clicked)
        self.stream_state = False

        # Status and configuration tab control
        self.tabWidget.currentChanged.connect(self.tab_changed)

        # Connect checkbox signals
        self.checkBox_en_sync_display.stateChanged.connect(
            self.set_sync_params)
        self.checkBox_en_spectrum.stateChanged.connect(
            self.set_spectrum_params)
        self.checkBox_en_DOA.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_Bartlett.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_Capon.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_MEM.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_MUSIC.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_FB_avg.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_dc_compensation.stateChanged.connect(
            self.set_iq_preprocessing_params)
        self.checkBox_en_passive_radar.stateChanged.connect(self.set_PR_params)
        self.checkBox_en_td_filter.stateChanged.connect(self.set_PR_params)
        self.checkBox_en_autodet.stateChanged.connect(self.set_PR_params)
        self.checkBox_en_noise_source.stateChanged.connect(
            self.switch_noise_source)

        # Connect spinbox signals
        self.doubleSpinBox_filterbw.valueChanged.connect(
            self.set_iq_preprocessing_params)
        self.spinBox_fir_tap_size.valueChanged.connect(
            self.set_iq_preprocessing_params)
        self.spinBox_decimation.valueChanged.connect(
            self.set_iq_preprocessing_params)

        self.doubleSpinBox_DOA_d.valueChanged.connect(self.set_DOA_params)
        self.spinBox_DOA_sample_size.valueChanged.connect(self.set_DOA_params)

        self.spinBox_td_filter_dimension.valueChanged.connect(
            self.set_PR_params)
        self.doubleSpinBox_cc_det_max_range.valueChanged.connect(
            self.set_PR_params)
        self.doubleSpinBox_cc_det_max_Doppler.valueChanged.connect(
            self.set_PR_params)
        self.spinBox_ref_ch_select.valueChanged.connect(self.set_PR_params)
        self.spinBox_surv_ch_select.valueChanged.connect(self.set_PR_params)
        self.spinBox_cfar_est_win.valueChanged.connect(self.set_PR_params)
        self.spinBox_cfar_guard_win.valueChanged.connect(self.set_PR_params)
        self.doubleSpinBox_cfar_threshold.valueChanged.connect(
            self.set_PR_params)

        self.spinBox_resync_time.valueChanged.connect(self.set_resync_time)

        # Connect combobox signals
        self.comboBox_antenna_alignment.currentIndexChanged.connect(
            self.set_DOA_params)
        self.comboBox_cc_det_windowing.currentIndexChanged.connect(
            self.set_windowing_mode)

        # Instantiate and configura Hydra modules
        self.module_receiver = ReceiverRTLSDR()

        self.module_receiver.block_size = int(sys.argv[1]) * 1024

        self.module_signal_processor = SignalProcessor(
            module_receiver=self.module_receiver)

        self.module_signal_processor.signal_overdrive.connect(
            self.power_level_update)
        self.module_signal_processor.signal_period.connect(
            self.period_time_update)
        self.module_signal_processor.signal_spectrum_ready.connect(
            self.spectrum_plot)
        self.module_signal_processor.signal_sync_ready.connect(self.delay_plot)
        self.module_signal_processor.signal_DOA_ready.connect(self.DOA_plot)
        self.module_signal_processor.signal_PR_ready.connect(self.RD_plot)
        # -> Set default confiration for the signal processing module
        self.set_spectrum_params()
        self.set_sync_params()
        self.set_DOA_params()
        self.set_windowing_mode()

        self.DOA_time = time.time()
        self.PR_time = time.time()
        self.sync_time = time.time()
        self.spectrum_time = time.time()

        #self.spectrum_plot()
        #self.delay_plot()
        #self.DOA_plot()
        #self.RD_plot()

        # Set default confiuration for the GUI components
        self.set_default_configuration()

        self.ip_addr = sys.argv[2]
        threading.Thread(target=run,
                         kwargs=dict(host=self.ip_addr,
                                     port=8080,
                                     quiet=True,
                                     debug=False,
                                     server='paste')).start()
예제 #2
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        #f = open('/dev/null', 'w')
        #sys.stdout = f

        self.tabWidget.setCurrentIndex(0)

        # Set pyqtgraph to use white background, black foreground
        pg.setConfigOption('background', 'w')
        pg.setConfigOption('foreground', 'k')
        pg.setConfigOption('imageAxisOrder', 'row-major')
        #pg.setConfigOption('useOpenGL', True)
        #pg.setConfigOption('useWeave', True)

        # Spectrum display

        self.win_spectrum = pg.GraphicsWindow(title="Quad Channel Spectrum")

        self.export_spectrum = pg.exporters.ImageExporter(
            self.win_spectrum.scene())

        self.plotWidget_spectrum_ch1 = self.win_spectrum.addPlot(
            title="Channel 1")
        self.plotWidget_spectrum_ch2 = self.win_spectrum.addPlot(
            title="Channel 2")
        self.win_spectrum.nextRow()
        self.plotWidget_spectrum_ch3 = self.win_spectrum.addPlot(
            title="Channel 3")
        self.plotWidget_spectrum_ch4 = self.win_spectrum.addPlot(
            title="Channel 4")

        self.gridLayout_spectrum.addWidget(self.win_spectrum, 1, 1, 1, 1)

        x = np.arange(1000)
        y = np.random.normal(size=(4, 1000))

        self.spectrum_ch1_curve = self.plotWidget_spectrum_ch1.plot(x,
                                                                    y[0],
                                                                    clear=True,
                                                                    pen='b')
        self.spectrum_ch2_curve = self.plotWidget_spectrum_ch2.plot(x,
                                                                    y[1],
                                                                    clear=True,
                                                                    pen='r')
        self.spectrum_ch3_curve = self.plotWidget_spectrum_ch3.plot(x,
                                                                    y[2],
                                                                    clear=True,
                                                                    pen='g')
        self.spectrum_ch4_curve = self.plotWidget_spectrum_ch4.plot(x,
                                                                    y[3],
                                                                    clear=True,
                                                                    pen='c')

        self.plotWidget_spectrum_ch1.setLabel("bottom", "Frequency [MHz]")
        self.plotWidget_spectrum_ch1.setLabel("left", "Amplitude [dBm]")
        self.plotWidget_spectrum_ch2.setLabel("bottom", "Frequency [MHz]")
        self.plotWidget_spectrum_ch2.setLabel("left", "Amplitude [dBm]")
        self.plotWidget_spectrum_ch3.setLabel("bottom", "Frequency [MHz]")
        self.plotWidget_spectrum_ch3.setLabel("left", "Amplitude [dBm]")
        self.plotWidget_spectrum_ch4.setLabel("bottom", "Frequency [MHz]")
        self.plotWidget_spectrum_ch4.setLabel("left", "Amplitude [dBm]")

        #---> Sync display <---
        # --> Delay

        self.win_sync = pg.GraphicsWindow(title="Receiver Sync")

        self.export_sync = pg.exporters.ImageExporter(self.win_sync.scene())

        self.plotWidget_sync_absx = self.win_sync.addPlot(title="ABS X Corr")
        #self.plotWidget_sync_absx.setDownsampling(ds=4, mode='subsample')
        #self.plotWidget_sync_normph = self.win_sync.addPlot(title="Normalized Phasors")
        self.win_sync.nextRow()
        self.plotWidget_sync_sampd = self.win_sync.addPlot(
            title="Sample Delay History")
        self.plotWidget_sync_phasediff = self.win_sync.addPlot(
            title="Phase Diff History")

        self.gridLayout_sync.addWidget(self.win_sync, 1, 1, 1, 1)

        x = np.arange(1000)
        y = np.random.normal(size=(4, 1000))

        #---> DOA results display <---

        self.win_DOA = pg.GraphicsWindow(title="DOA Plot")
        #Set up image exporter for web display
        self.export_DOA = pg.exporters.ImageExporter(self.win_DOA.scene())

        self.plotWidget_DOA = self.win_DOA.addPlot(
            title="Direction of Arrival Estimation")
        self.plotWidget_DOA.setLabel("bottom", "Incident Angle [deg]")
        self.plotWidget_DOA.setLabel("left", "Amplitude [dB]")
        self.plotWidget_DOA.showGrid(x=True, alpha=0.25)
        self.gridLayout_DOA.addWidget(self.win_DOA, 1, 1, 1, 1)

        self.DOA_res_fd = open("/ram/DOA_value.html",
                               "w")  # DOA estimation result file descriptor

        # Junk data to just init plot legends
        x = np.arange(1000)
        y = np.random.normal(size=(4, 1000))

        self.plotWidget_DOA.addLegend()

        self.plotWidget_DOA.plot(x,
                                 y[0],
                                 pen=pg.mkPen('b', width=2),
                                 name="Bartlett")
        self.plotWidget_DOA.plot(x,
                                 y[1],
                                 pen=pg.mkPen('g', width=2),
                                 name="Capon")
        self.plotWidget_DOA.plot(x,
                                 y[2],
                                 pen=pg.mkPen('r', width=2),
                                 name="MEM")
        self.plotWidget_DOA.plot(x,
                                 y[3],
                                 pen=pg.mkPen('c', width=2),
                                 name="MUSIC")

        #---> Passive radar results display <---

        self.win_PR = pg.GraphicsWindow(title="Passive Radar")

        self.export_PR = pg.exporters.ImageExporter(self.win_PR.scene())

        self.plt_PR = self.win_PR.addPlot(Title="Range-Doppler Matrix")
        self.plt_PR.setLabel("bottom", "Range")
        self.plt_PR.setLabel("left", "Doppler (Speed)")

        self.PR_interp_factor = 4

        self.plt_PR.getAxis("bottom").setScale(1.0 / self.PR_interp_factor)
        self.plt_PR.getAxis("left").setScale(1.0 / self.PR_interp_factor)

        rand_mat = np.random.rand(50, 50)
        self.img_PR = pg.ImageView()

        self.plt_PR.addItem(self.img_PR.imageItem)

        self.img_PR.setImage(rand_mat)
        self.img_PR.autoLevels()
        self.img_PR.autoRange()

        # Take the color map from matplotlib because it's nicer than pyqtgraph's
        colormap = cm.get_cmap("jet")
        colormap._init()
        lut = (colormap._lut * 255).view(np.ndarray)
        self.img_PR.imageItem.setLookupTable(lut)

        #self.img_PR.setPredefinedGradient('spectrum')

        self.gridLayout_RD.addWidget(self.win_PR, 1, 1, 1, 1)

        # Connect pushbutton signals
        self.pushButton_close.clicked.connect(self.pb_close_clicked)
        self.pushButton_proc_control.clicked.connect(
            self.pb_proc_control_clicked)
        self.pushButton_sync.clicked.connect(self.pb_sync_clicked)
        self.pushButton_iq_calib.clicked.connect(self.pb_calibrate_iq_clicked)
        self.pushButton_del_sync_history.clicked.connect(
            self.pb_del_sync_history_clicked)
        self.pushButton_DOA_cal_90.clicked.connect(
            self.pb_calibrate_DOA_90_clicked)
        self.pushButton_set_receiver_config.clicked.connect(
            self.pb_rec_reconfig_clicked)
        self.stream_state = False

        # Status and configuration tab control
        self.tabWidget.currentChanged.connect(self.tab_changed)

        # Connect checkbox signals
        self.checkBox_en_sync_display.stateChanged.connect(
            self.set_sync_params)
        self.checkBox_en_spectrum.stateChanged.connect(
            self.set_spectrum_params)
        self.checkBox_en_DOA.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_Bartlett.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_Capon.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_MEM.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_MUSIC.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_DOA_FB_avg.stateChanged.connect(self.set_DOA_params)
        self.checkBox_en_dc_compensation.stateChanged.connect(
            self.set_iq_preprocessing_params)
        self.checkBox_en_passive_radar.stateChanged.connect(self.set_PR_params)
        self.checkBox_en_td_filter.stateChanged.connect(self.set_PR_params)
        self.checkBox_en_autodet.stateChanged.connect(self.set_PR_params)
        self.checkBox_en_noise_source.stateChanged.connect(
            self.switch_noise_source)

        # Connect spinbox signals
        self.doubleSpinBox_filterbw.valueChanged.connect(
            self.set_iq_preprocessing_params)
        self.spinBox_fir_tap_size.valueChanged.connect(
            self.set_iq_preprocessing_params)
        self.spinBox_decimation.valueChanged.connect(
            self.set_iq_preprocessing_params)

        self.doubleSpinBox_DOA_d.valueChanged.connect(self.set_DOA_params)
        self.spinBox_DOA_sample_size.valueChanged.connect(self.set_DOA_params)

        self.spinBox_td_filter_dimension.valueChanged.connect(
            self.set_PR_params)
        self.doubleSpinBox_cc_det_max_range.valueChanged.connect(
            self.set_PR_params)
        self.doubleSpinBox_cc_det_max_Doppler.valueChanged.connect(
            self.set_PR_params)
        self.spinBox_ref_ch_select.valueChanged.connect(self.set_PR_params)
        self.spinBox_surv_ch_select.valueChanged.connect(self.set_PR_params)
        self.spinBox_cfar_est_win.valueChanged.connect(self.set_PR_params)
        self.spinBox_cfar_guard_win.valueChanged.connect(self.set_PR_params)
        self.doubleSpinBox_cfar_threshold.valueChanged.connect(
            self.set_PR_params)

        self.spinBox_resync_time.valueChanged.connect(self.set_resync_time)

        # Connect combobox signals
        self.comboBox_antenna_alignment.currentIndexChanged.connect(
            self.set_DOA_params)
        self.comboBox_cc_det_windowing.currentIndexChanged.connect(
            self.set_windowing_mode)

        # Instantiate and configura Hydra modules
        self.module_receiver = ReceiverRTLSDR()

        self.module_receiver.block_size = int(sys.argv[1]) * 1024

        self.module_signal_processor = SignalProcessor(
            module_receiver=self.module_receiver)

        self.module_signal_processor.signal_overdrive.connect(
            self.power_level_update)
        self.module_signal_processor.signal_period.connect(
            self.period_time_update)
        self.module_signal_processor.signal_spectrum_ready.connect(
            self.spectrum_plot)
        self.module_signal_processor.signal_sync_ready.connect(self.delay_plot)
        self.module_signal_processor.signal_DOA_ready.connect(self.DOA_plot)
        self.module_signal_processor.signal_PR_ready.connect(self.RD_plot)
        # -> Set default confiration for the signal processing module
        self.set_spectrum_params()
        self.set_sync_params()
        self.set_DOA_params()
        self.set_windowing_mode()

        self.DOA_time = time.time()
        self.PR_time = time.time()
        self.sync_time = time.time()
        self.spectrum_time = time.time()

        #self.spectrum_plot()
        #self.delay_plot()
        #self.DOA_plot()
        #self.RD_plot()

        # Set default confiuration for the GUI components
        self.set_default_configuration()

        self.ip_addr = sys.argv[2]
        threading.Thread(target=run,
                         kwargs=dict(host=self.ip_addr,
                                     port=8080,
                                     quiet=True,
                                     debug=False,
                                     server='paste')).start()

    #-----------------------------------------------------------------
    #
    #-----------------------------------------------------------------

    def set_default_configuration(self):

        self.power_level_update(0)
        self.checkBox_en_spectrum.setChecked(False)
        self.checkBox_en_DOA.setChecked(False)

    def tab_changed(self):
        tab_index = self.tabWidget.currentIndex()

        if tab_index == 0:  # Spectrum tab
            self.stackedWidget_config.setCurrentIndex(0)
        elif tab_index == 1:  # Sync tab
            self.stackedWidget_config.setCurrentIndex(1)
        elif tab_index == 2:  # DOA tab
            self.stackedWidget_config.setCurrentIndex(2)
        elif tab_index == 3:  # PR tab
            self.stackedWidget_config.setCurrentIndex(3)

    def set_sync_params(self):
        if self.checkBox_en_sync_display.checkState():
            self.module_signal_processor.en_sync = True
        else:
            self.module_signal_processor.en_sync = False

    def set_spectrum_params(self):
        if self.checkBox_en_spectrum.checkState():
            self.module_signal_processor.en_spectrum = True
        else:
            self.module_signal_processor.en_spectrum = False

    def pb_rec_reconfig_clicked(self):
        center_freq = self.doubleSpinBox_center_freq.value() * 10**6
        sample_rate = float(self.comboBox_sampling_freq.currentText(
        )) * 10**6  #self.doubleSpinBox_sampling_freq.value()*10**6
        gain = [0, 0, 0, 0]
        gain[0] = 10 * float(self.comboBox_gain.currentText())
        gain[1] = 10 * float(self.comboBox_gain_2.currentText())
        gain[2] = 10 * float(self.comboBox_gain_3.currentText())
        gain[3] = 10 * float(self.comboBox_gain_4.currentText())

        self.module_receiver.receiver_gain = 10 * float(
            self.comboBox_gain.currentText())
        self.module_receiver.receiver_gain_2 = 10 * float(
            self.comboBox_gain_2.currentText())
        self.module_receiver.receiver_gain_3 = 10 * float(
            self.comboBox_gain_3.currentText())
        self.module_receiver.receiver_gain_4 = 10 * float(
            self.comboBox_gain_4.currentText())

        self.module_receiver.fs = float(
            self.comboBox_sampling_freq.currentText(
            )) * 10**6  #self.doubleSpinBox_sampling_freq.value()*10**6
        self.module_signal_processor.fs = self.module_receiver.fs / self.module_receiver.decimation_ratio

        self.module_signal_processor.center_freq = self.doubleSpinBox_center_freq.value(
        ) * 10**6
        self.module_receiver.reconfigure_tuner(center_freq, sample_rate, gain)

    def switch_noise_source(self):
        if self.checkBox_en_noise_source.checkState():
            self.module_signal_processor.noise_checked = True
            self.module_receiver.switch_noise_source(1)
        else:
            self.module_signal_processor.noise_checked = False
            self.module_receiver.switch_noise_source(0)

    def set_iq_preprocessing_params(self):
        """
            Update IQ preprocessing parameters
            
            Callback function of:
                -
                
        """
        # Set DC compensations
        if self.checkBox_en_dc_compensation.checkState():
            self.module_receiver.en_dc_compensation = True
        else:
            self.module_receiver.en_dc_compensation = False

        # Set FIR filter parameters
        tap_size = self.spinBox_fir_tap_size.value()
        bw = self.doubleSpinBox_filterbw.value() * 10**3  # ->[kHz]
        self.module_receiver.set_fir_coeffs(tap_size, bw)

        # Set Decimation
        self.module_receiver.decimation_ratio = self.spinBox_decimation.value()
        self.module_signal_processor.fs = self.module_receiver.fs / self.module_receiver.decimation_ratio

    def set_windowing_mode(self):
        self.module_signal_processor.windowing_mode = int(
            self.comboBox_cc_det_windowing.currentIndex())

    def set_DOA_params(self):
        """
            Update DOA processing parameters
            
            Callback function of:
                -
            
        """
        #  Set DOA processing option
        if self.checkBox_en_DOA.checkState():
            self.module_signal_processor.en_DOA_estimation = True
        else:
            self.module_signal_processor.en_DOA_estimation = False

        if self.checkBox_en_DOA_Bartlett.checkState():
            self.module_signal_processor.en_DOA_Bartlett = True
        else:
            self.module_signal_processor.en_DOA_Bartlett = False

        if self.checkBox_en_DOA_Capon.checkState():
            self.module_signal_processor.en_DOA_Capon = True
        else:
            self.module_signal_processor.en_DOA_Capon = False

        if self.checkBox_en_DOA_MEM.checkState():
            self.module_signal_processor.en_DOA_MEM = True
        else:
            self.module_signal_processor.en_DOA_MEM = False

        if self.checkBox_en_DOA_MUSIC.checkState():
            self.module_signal_processor.en_DOA_MUSIC = True
        else:
            self.module_signal_processor.en_DOA_MUSIC = False

        if self.checkBox_en_DOA_FB_avg.checkState():
            self.module_signal_processor.en_DOA_FB_avg = True
        else:
            self.module_signal_processor.en_DOA_FB_avg = False

        self.module_signal_processor.DOA_inter_elem_space = self.doubleSpinBox_DOA_d.value(
        )
        self.module_signal_processor.DOA_ant_alignment = self.comboBox_antenna_alignment.currentText(
        )

        if self.module_signal_processor.DOA_ant_alignment == "UCA":
            self.checkBox_en_DOA_FB_avg.setEnabled(False)
            self.checkBox_en_DOA_FB_avg.setCheckState(False)
        else:
            self.checkBox_en_DOA_FB_avg.setEnabled(True)

        self.module_signal_processor.DOA_sample_size = 2**self.spinBox_DOA_sample_size.value(
        )

    def set_PR_params(self):
        if self.checkBox_en_passive_radar.checkState():
            self.module_signal_processor.en_PR_processing = True
        else:
            self.module_signal_processor.en_PR_processing = False

        if self.checkBox_en_td_filter.checkState():
            self.module_signal_processor.en_td_filtering = True
        else:
            self.module_signal_processor.en_td_filtering = False

        if self.checkBox_en_autodet.checkState():
            self.module_signal_processor.en_PR_autodet = True
        else:
            self.module_signal_processor.en_PR_autodet = False

        # Set CFAR parameters
        self.module_signal_processor.cfar_win_params = [
            self.spinBox_cfar_est_win.value(),
            self.spinBox_cfar_est_win.value(),
            self.spinBox_cfar_guard_win.value(),
            self.spinBox_cfar_guard_win.value()
        ]

        self.module_signal_processor.cfar_threshold = self.doubleSpinBox_cfar_threshold.value(
        )

        # Set Time-domain clutter fitler parameters
        self.module_signal_processor.td_filter_dimension = self.spinBox_td_filter_dimension.value(
        )

        # Set Cross-Correlation detector parameters
        self.module_signal_processor.max_range = int(
            self.doubleSpinBox_cc_det_max_range.value())
        self.module_signal_processor.max_Doppler = int(
            self.doubleSpinBox_cc_det_max_Doppler.value())

        # General channel settings
        self.module_signal_processor.ref_ch_id = self.spinBox_ref_ch_select.value(
        )
        self.module_signal_processor.surv_ch_id = self.spinBox_surv_ch_select.value(
        )

    def set_resync_time(self):
        self.module_signal_processor.resync_time = self.spinBox_resync_time.value(
        )

    def pb_close_clicked(self):
        #self.stop_streaming()
        #self.module_receiver.module_state = "EXIT"
        self.module_receiver.close()
        self.DOA_res_fd.close()
        self.close()

    def pb_proc_control_clicked(self):
        if self.pushButton_proc_control.text() == "Start processing":
            self.pushButton_proc_control.setText("Stop processing")

            self.module_signal_processor.start()

        elif self.pushButton_proc_control.text() == "Stop processing":
            self.pushButton_proc_control.setText("Start processing")

            self.module_signal_processor.stop()

    def pb_sync_clicked(self):
        #print("[ INFO ] Sync requested")
        self.module_signal_processor.en_sample_offset_sync = True

    def pb_calibrate_iq_clicked(self):
        #print("[ INFO ] IQ calibration requested")
        self.module_signal_processor.en_calib_iq = True

    def pb_calibrate_DOA_90_clicked(self):
        #print("[ INFO ] DOA IQ calibration requested")
        self.module_signal_processor.en_calib_DOA_90 = True

    def pb_del_sync_history_clicked(self):
        self.module_signal_processor.delete_sync_history()

    def power_level_update(self, over_drive_flag):
        if over_drive_flag:
            red_text = "<span style=\" font-size:8pt; font-weight:600; color:#ff0000;\" >"
            red_text += "OVERDRIVE"
            red_text += ("</span>")
            self.label_power_level.setText(red_text)
        else:
            green_text = "<span style=\" font-size:8pt; font-weight:600; color:#01df01;\" >"
            green_text += "OK"
            green_text += ("</span>")
            self.label_power_level.setText(green_text)

    def period_time_update(self, update_period):
        if update_period > 1:
            self.label_update_rate.setText("%.1f s" % update_period)
        else:
            self.label_update_rate.setText("%.1f ms" % (update_period * 1000))

    def spectrum_plot(self):
        xw1 = self.module_signal_processor.spectrum[1, :]
        xw2 = self.module_signal_processor.spectrum[2, :]
        xw3 = self.module_signal_processor.spectrum[3, :]
        xw4 = self.module_signal_processor.spectrum[4, :]
        freqs = self.module_signal_processor.spectrum[0, :]
        spectrum_dynamic_range = 10

        self.spectrum_ch1_curve.setData(freqs, xw1)
        self.spectrum_ch2_curve.setData(freqs, xw2)
        self.spectrum_ch3_curve.setData(freqs, xw3)
        self.spectrum_ch4_curve.setData(freqs, xw4)

        currentTime = time.time()
        if ((currentTime - self.spectrum_time) > 0.5):
            self.spectrum_time = currentTime
            self.export_spectrum.export('/ram/spectrum.jpg')

    def delay_plot(self):

        xcorr12 = 10 * np.log10(
            np.abs(self.module_signal_processor.xcorr[0, :]))
        xcorr13 = 10 * np.log10(
            np.abs(self.module_signal_processor.xcorr[1, :]))
        xcorr14 = 10 * np.log10(
            np.abs(self.module_signal_processor.xcorr[2, :]))

        phasor12 = self.module_signal_processor.phasors[0, :]
        phasor13 = self.module_signal_processor.phasors[1, :]
        phasor14 = self.module_signal_processor.phasors[2, :]

        N = np.size(xcorr12) // 2

        xcorr12 -= np.max(xcorr12)
        xcorr13 -= np.max(xcorr13)
        xcorr14 -= np.max(xcorr14)

        #phasor12 /= np.max(np.abs(phasor12))
        #phasor13 /= np.max(np.abs(phasor13))
        #phasor14 /= np.max(np.abs(phasor14))

        M = 500
        max_delay = np.max(
            np.abs(self.module_signal_processor.delay_log[:, -1]))
        if max_delay + 50 > M:
            M = max_delay + 50

        delay_label = np.arange(-M, M + 1, 1)

        #        if(xcorr12[0] != 0 and xcorr13[0] != 0 and xcorr14[0] != 0):
        self.plotWidget_sync_absx.clear()

        self.plotWidget_sync_absx.plot(delay_label,
                                       xcorr12[N - M:N + M + 1],
                                       pen='b')
        self.plotWidget_sync_absx.plot(delay_label,
                                       xcorr13[N - M:N + M + 1],
                                       pen='r')
        self.plotWidget_sync_absx.plot(delay_label,
                                       xcorr14[N - M:N + M + 1],
                                       pen='g')

        # Plot delay history

        self.plotWidget_sync_sampd.clear()

        self.plotWidget_sync_sampd.plot(
            self.module_signal_processor.delay_log[0, :], pen='b')
        self.plotWidget_sync_sampd.plot(
            self.module_signal_processor.delay_log[1, :], pen='r')
        self.plotWidget_sync_sampd.plot(
            self.module_signal_processor.delay_log[2, :], pen='g')

        # Plot phasors
        # For averaged phasors
        #self.plotWidget_sync_normph.clear()
        #self.plotWidget_sync_normph.plot(np.cos(np.deg2rad(self.module_signal_processor.phase_log[0,:])), np.sin(np.deg2rad(self.module_signal_processor.phase_log[0,:])), pen=None, symbol='o', symbolBrush=(100,100,255,50))
        #self.plotWidget_sync_normph.plot(np.cos(np.deg2rad(self.module_signal_processor.phase_log[0,:])), np.sin(np.deg2rad(self.module_signal_processor.phase_log[0,:])), pen=None, symbol='o', symbolBrush=(150,150,150,50))
        #self.plotWidget_sync_normph.plot(np.cos(np.deg2rad(self.module_signal_processor.phase_log[0,:])), np.sin(np.deg2rad(self.module_signal_processor.phase_log[0,:])), pen=None, symbol='o', symbolBrush=(50,50,50,50))

        # Plot phase history

        self.plotWidget_sync_phasediff.clear()

        self.plotWidget_sync_phasediff.plot(
            self.module_signal_processor.phase_log[0, :], pen='b')
        self.plotWidget_sync_phasediff.plot(
            self.module_signal_processor.phase_log[1, :], pen='r')
        self.plotWidget_sync_phasediff.plot(
            self.module_signal_processor.phase_log[2, :], pen='g')

        currentTime = time.time()
        if ((currentTime - self.sync_time) > 0.5):
            self.sync_time = currentTime
            self.export_sync.export('/ram/sync.jpg')

    def DOA_plot_helper(self,
                        DOA_data,
                        incident_angles,
                        log_scale_min=None,
                        color='b',
                        legend=None):

        DOA_data = np.divide(np.abs(DOA_data),
                             np.max(np.abs(DOA_data)))  # normalization
        if (log_scale_min != None):
            DOA_data = 10 * np.log10(DOA_data)
            theta_index = 0
            for theta in incident_angles:
                if DOA_data[theta_index] < log_scale_min:
                    DOA_data[theta_index] = log_scale_min
                theta_index += 1

        plot = self.plotWidget_DOA.plot(incident_angles,
                                        DOA_data,
                                        pen=pg.mkPen(color, width=2))
        return DOA_data

    def DOA_plot(self):

        thetas = self.module_signal_processor.DOA_theta
        Bartlett = self.module_signal_processor.DOA_Bartlett_res
        Capon = self.module_signal_processor.DOA_Capon_res
        MEM = self.module_signal_processor.DOA_MEM_res
        MUSIC = self.module_signal_processor.DOA_MUSIC_res

        DOA = 0
        DOA_results = []
        COMBINED = np.zeros_like(thetas, dtype=np.complex)

        self.plotWidget_DOA.clear()

        if self.module_signal_processor.en_DOA_Bartlett:

            plt = self.DOA_plot_helper(Bartlett,
                                       thetas,
                                       log_scale_min=-50,
                                       color='b')
            COMBINED += np.divide(np.abs(Bartlett), np.max(np.abs(Bartlett)))
            #de.DOA_plot(Bartlett, thetas, log_scale_min = -50, axes=self.axes_DOA)
            DOA_results.append(thetas[np.argmax(Bartlett)])

        if self.module_signal_processor.en_DOA_Capon:

            self.DOA_plot_helper(Capon, thetas, log_scale_min=-50, color='g')
            COMBINED += np.divide(np.abs(Capon), np.max(np.abs(Capon)))
            #de.DOA_plot(Capon, thetas, log_scale_min = -50, axes=self.axes_DOA)
            DOA_results.append(thetas[np.argmax(Capon)])

        if self.module_signal_processor.en_DOA_MEM:

            self.DOA_plot_helper(MEM, thetas, log_scale_min=-50, color='r')
            COMBINED += np.divide(np.abs(MEM), np.max(np.abs(MEM)))
            #de.DOA_plot(MEM, thetas, log_scale_min = -50, axes=self.axes_DOA)
            DOA_results.append(thetas[np.argmax(MEM)])

        if self.module_signal_processor.en_DOA_MUSIC:

            self.DOA_plot_helper(MUSIC, thetas, log_scale_min=-50, color='c')
            COMBINED += np.divide(np.abs(MUSIC), np.max(np.abs(MUSIC)))
            #de.DOA_plot(MUSIC, thetas, log_scale_min = -50, axes=self.axes_DOA)
            DOA_results.append(thetas[np.argmax(MUSIC)])

        #COMBINED_LOG = 10*np.log10(COMBINED)

        if len(DOA_results) != 0:

            # Combined Graph (beta)
            COMBINED_LOG = self.DOA_plot_helper(COMBINED,
                                                thetas,
                                                log_scale_min=-50,
                                                color='k')

            confidence = scipy.signal.find_peaks_cwt(
                COMBINED_LOG, np.arange(10, 30), min_snr=1
            )  #np.max(DOA_combined**2) / np.average(DOA_combined**2)
            maxIndex = confidence[np.argmax(COMBINED_LOG[confidence])]
            confidence_sum = 0

            #print("Peaks: " + str(confidence))
            for val in confidence:
                if (val != maxIndex
                        and np.abs(COMBINED_LOG[val] - min(COMBINED_LOG)) >
                        np.abs(min(COMBINED_LOG)) * 0.25):
                    #print("Doing other peaks: " + str(val) + "combined value: " + str(COMBINED_LOG[val]))
                    confidence_sum += 1 / (np.abs(COMBINED_LOG[val]))
                elif val == maxIndex:
                    #print("Doing maxIndex peak: " + str(maxIndex) + "min combined: " + str(min(COMBINED_LOG)))
                    confidence_sum += 1 / np.abs(min(COMBINED_LOG))
            # Get avg power level
            max_power_level = np.max(
                self.module_signal_processor.spectrum[1, :])
            #rms_power_level = np.sqrt(np.mean(self.module_signal_processor.spectrum[1,:]**2))

            confidence_sum = 10 / confidence_sum

            #print("Max Power Level" + str(max_power_level))
            #print("Confidence Sum: " + str(confidence_sum))

            DOA_results = np.array(DOA_results)
            # Convert measured DOAs to complex numbers
            DOA_results_c = np.exp(1j * np.deg2rad(DOA_results))
            # Average measured DOA angles
            DOA_avg_c = np.average(DOA_results_c)
            # Convert back to degree
            DOA = np.rad2deg(np.angle(DOA_avg_c))

            # Update DOA results on the compass display
            #print("[ INFO ] Python GUI: DOA results :",DOA_results)
            if DOA < 0:
                DOA += 360
            #DOA = 360 - DOA
            DOA_str = str(int(DOA))
            html_str = "<DOA>" + DOA_str + "</DOA><CONF>" + str(
                int(confidence_sum)) + "</CONF><PWR>" + str(
                    np.maximum(0, max_power_level)) + "</PWR>"
            self.DOA_res_fd.seek(0)
            self.DOA_res_fd.write(html_str)
            self.DOA_res_fd.truncate()
            #print("[ INFO ] Python GUI: DOA results writen:",html_str)

        #self.DOA_res_fd.close()

        currentTime = time.time()
        if ((currentTime - self.DOA_time) > 0.5):
            self.DOA_time = currentTime
            self.export_DOA.export('/ram/doa.jpg')

    def RD_plot(self):
        """
        Event type: Surveillance processor module has calculated the new range-Doppler matrix
    
        callback description:
        ------------------
            Plot the previously obtained range-Doppler matrix
        """
        # If Automatic detection is disabled the range-Doppler matrix is plotted otherwise the matrix
        if not self.checkBox_en_autodet.checkState():

            # Set colormap TODO: Implement this properly
            colormap = cm.get_cmap("jet")
            colormap._init()
            lut = (colormap._lut * 255).view(np.ndarray)
            self.img_PR.imageItem.setLookupTable(lut)

            CAFMatrix = self.module_signal_processor.RD_matrix
            CAFMatrix = np.abs(CAFMatrix)
            CAFDynRange = self.spinBox_rd_dyn_range.value()

            #print("Max Val" + str(np.amax(CAFMatrix)))
            #print("X-Size" + str(np.shape(CAFMatrix)[0]))
            #print("Y-Size" + str(np.shape(CAFMatrix)[1]))

            CAFMatrix = CAFMatrix / np.amax(
                CAFMatrix)  # Noramlize with the maximum value
            CAFMatrixLog = 20 * np.log10(CAFMatrix)  # Change to logscale

            CAFMatrixLog[CAFMatrixLog < -CAFDynRange] = -CAFDynRange

            #            for i in range(np.shape(CAFMatrix)[0]):  # Remove extreme low values
            #                for j in range(np.shape(CAFMatrix)[1]):
            #                    if CAFMatrixLog[i, j] < -CAFDynRange:
            #                        CAFMatrixLog[i, j] = -CAFDynRange

            # plot
            #CAFPlot = self.axes_RD.imshow(CAFMatrixLog, interpolation='sinc', cmap='jet', origin='lower', aspect='auto')
            plotPRImage = scipy.ndimage.zoom(CAFMatrixLog,
                                             self.PR_interp_factor,
                                             order=3)
            self.img_PR.clear()
            self.img_PR.setImage(plotPRImage)

        else:
            # Set colormap TODO: Implement this properly
            colormap = cm.get_cmap("gray")
            colormap._init()
            lut = (colormap._lut * 255).view(np.ndarray)
            self.img_PR.imageItem.setLookupTable(lut)
            CAFMatrix = self.module_signal_processor.hit_matrix
            plotPRImage = scipy.ndimage.zoom(CAFMatrix,
                                             self.PR_interp_factor,
                                             order=3)
            self.img_PR.clear()
            self.img_PR.setImage(plotPRImage)

        currentTime = time.time()
        if ((currentTime - self.PR_time) > 0.5):
            self.PR_time = currentTime
            self.export_PR.export(toBytes=True).save('/ram/pr.jpg', quality=30)

        # Set doppler speed Y-AXIS
        max_Doppler = int(self.doubleSpinBox_cc_det_max_Doppler.value())
        ay = self.plt_PR.getAxis('left')
        matrix_ySize = np.shape(plotPRImage)[0]
        ay.setTicks([[(0, -max_Doppler),
                      (matrix_ySize * 0.25, -max_Doppler * 0.5),
                      (matrix_ySize / 2, 0),
                      (matrix_ySize * 0.75, max_Doppler * 0.5),
                      (matrix_ySize, max_Doppler)], []])