def test_bandpass_h(self): f_low = -0.4 f_high = -0.3 bw = 0.01 f_shift = (f_low + f_high) / 2 f_c = (f_high - f_low) / 2 N = Filter.get_filter_length_from_bandwidth(bw) h = Filter.design_windowed_sinc_lpf(f_c, bw=bw) * np.exp(np.complex(0,1) * np.pi * 2 * f_shift * np.arange(0, N, dtype=complex)) #h = Filter.design_windowed_sinc_bandpass(f_low=f_low, f_high=f_high, bw=bw) #h = Filter.design_windowed_sinc_lpf(0.42, bw=0.08) impulse = np.exp(1j * np.linspace(0, 1, 50)) plt.subplot("221") plt.title("f_low={} f_high={} bw={}".format(f_low, f_high, bw)) plt.plot(np.fft.fftfreq(1024), np.fft.fft(h, 1024)) plt.subplot("222") plt.plot(h) plt.show()
def test_fft_convolution(self): x = np.array([1, 2, 3]) h = np.array([0, 1, 0.5]) expected_result = np.array([1., 2.5, 4.]) result_np = np.convolve(x, h, 'same') self.assertTrue(np.array_equal(result_np, expected_result)) result_fft = Filter.fft_convolve_1d(x, h) self.assertTrue(np.array_equal(result_fft, expected_result)) x = np.linspace(0, 1, num=10**3).astype(np.complex64) h = Filter.design_windowed_sinc_bandpass(0.1, 0.4, 0.01) # fft convolve is faster if IR is round about 400 samples or windowed sinc has bandwidth of 0.01 print(len(h)) t_np = time.time() result_np = np.convolve(x, h, mode="same") t_np = time.time() - t_np t_fft = time.time() result_fft = Filter.fft_convolve_1d(x, h) t_fft = time.time() - t_fft np.testing.assert_array_almost_equal(result_np, result_fft) print("fft convolve time", t_fft, "np convolve time", t_np)
def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_DialogFilterBandwidth() self.ui.setupUi(self) self.setWindowFlags(Qt.Window) bw_type = constants.SETTINGS.value("bandpass_filter_bw_type", "Medium", str) custom_bw = constants.SETTINGS.value("bandpass_filter_custom_bw", 0.1, float) for item in dir(self.ui): item = getattr(self.ui, item) if isinstance(item, QLabel): name = item.objectName().replace("label", "") key = next((key for key in Filter.BANDWIDTHS.keys() if name.startswith(key.replace(" ", ""))), None) if key is not None and name.endswith("Bandwidth"): item.setText("{0:n}".format(Filter.BANDWIDTHS[key])) elif key is not None and name.endswith("KernelLength"): item.setText(str(Filter.get_filter_length_from_bandwidth(Filter.BANDWIDTHS[key]))) elif isinstance(item, QRadioButton): item.setChecked(bw_type.replace(" ", "_") == item.objectName().replace("radioButton", "")) self.ui.doubleSpinBoxCustomBandwidth.setValue(custom_bw) self.ui.spinBoxCustomKernelLength.setValue(Filter.get_filter_length_from_bandwidth(custom_bw)) self.create_connects()
def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_DialogFilterBandwidth() self.ui.setupUi(self) bw_type = constants.SETTINGS.value("bandpass_filter_bw_type", "Medium", str) custom_bw = constants.SETTINGS.value("bandpass_filter_custom_bw", 0.1, float) for item in dir(self.ui): item = getattr(self.ui, item) if isinstance(item, QLabel): name = item.objectName().replace("label", "") key = next((key for key in Filter.BANDWIDTHS.keys() if name.startswith(key.replace(" ", ""))), None) if key is not None and name.endswith("Bandwidth"): item.setText("{0:n}".format(Filter.BANDWIDTHS[key])) elif key is not None and name.endswith("KernelLength"): item.setText( str( Filter.get_filter_length_from_bandwidth( Filter.BANDWIDTHS[key]))) elif isinstance(item, QRadioButton): item.setChecked( bw_type.replace(" ", "_") == item.objectName().replace( "radioButton", "")) self.ui.doubleSpinBoxCustomBandwidth.setValue(custom_bw) self.ui.spinBoxCustomKernelLength.setValue( Filter.get_filter_length_from_bandwidth(custom_bw)) self.create_connects()
def test_bandpass_h(self): f_low = -0.4 f_high = -0.3 bw = 0.01 f_shift = (f_low + f_high) / 2 f_c = (f_high - f_low) / 2 N = Filter.get_filter_length_from_bandwidth(bw) h = Filter.design_windowed_sinc_lpf(f_c, bw=bw) * np.exp( np.complex(0, 1) * np.pi * 2 * f_shift * np.arange(0, N, dtype=complex)) #h = Filter.design_windowed_sinc_bandpass(f_low=f_low, f_high=f_high, bw=bw) #h = Filter.design_windowed_sinc_lpf(0.42, bw=0.08) impulse = np.exp(1j * np.linspace(0, 1, 50)) plt.subplot("221") plt.title("f_low={} f_high={} bw={}".format(f_low, f_high, bw)) plt.plot(np.fft.fftfreq(1024), np.fft.fft(h, 1024)) plt.subplot("222") plt.plot(h) plt.show()
def test_channels(self): sample_rate = 10**6 channel1_freq = 40 * 10**3 channel2_freq = 240 * 10**3 channel1_data = array.array("B", [1, 0, 1, 0, 1, 0, 0, 1]) channel2_data = array.array("B", [1, 1, 0, 0, 1, 1, 0, 1]) channel3_data = array.array("B", [1, 0, 0, 1, 0, 1, 1, 1]) filter_bw = 0.1 filter_freq1_high = 1.5 * channel1_freq filter_freq1_low = 0.5 * channel1_freq filter_freq2_high = 1.5 * channel2_freq filter_freq2_low = 0.5 * channel2_freq modulator1, modulator2, modulator3 = Modulator("test"), Modulator( "test2"), Modulator("test3") modulator1.carrier_freq_hz = channel1_freq modulator2.carrier_freq_hz = channel2_freq modulator3.carrier_freq_hz = -channel2_freq modulator1.sample_rate = modulator2.sample_rate = modulator3.sample_rate = sample_rate data1 = modulator1.modulate(channel1_data) data2 = modulator2.modulate(channel2_data) data3 = modulator3.modulate(channel3_data) mixed_signal = data1 + data2 + data3 mixed_signal.tofile("/tmp/three_channels.complex") plt.subplot("221") plt.title("Signal") plt.plot(mixed_signal) spectrogram = Spectrogram(mixed_signal) plt.subplot("222") plt.title("Spectrogram") plt.imshow(np.transpose(spectrogram.data), aspect="auto", cmap="magma") plt.ylim(0, spectrogram.freq_bins) chann1_filtered = Filter.apply_bandpass_filter( mixed_signal, filter_freq1_low / sample_rate, filter_freq1_high / sample_rate, filter_bw) plt.subplot("223") plt.title("Channel 1 Filtered ({})".format("".join( map(str, channel1_data)))) plt.plot(chann1_filtered) chann2_filtered = Filter.apply_bandpass_filter( mixed_signal, filter_freq2_low / sample_rate, filter_freq2_high / sample_rate, filter_bw) plt.subplot("224") plt.title("Channel 2 Filtered ({})".format("".join( map(str, channel2_data)))) plt.plot(chann2_filtered) plt.show()
def test_bandpass_filter(self): # GUI tests for bandpass filter are in test_spectrogram.py sig1 = np.sin(2 * np.pi * 0.2 * np.arange(0, 100)) sig2 = np.sin(2 * np.pi * 0.3 * np.arange(0, 100)) sig = sig1 + sig2 filtered1 = Filter.apply_bandpass_filter(sig, 0.1, 0.2) filtered2 = Filter.apply_bandpass_filter(sig, 0.2, 0.1) self.assertTrue(np.array_equal(filtered1, filtered2))
def on_bandpass_filter_triggered(self, f_low: float, f_high: float): self.setCursor(Qt.WaitCursor) filter_bw = Filter.read_configured_filter_bw() filtered = Filter.apply_bandpass_filter(self.signal.data, f_low, f_high, filter_bw=filter_bw) signal = self.signal.create_new(new_data=filtered.astype(np.complex64)) signal.name = self.signal.name + " filtered with f_low={0:.4n} f_high={1:.4n} bw={2:.4n}".format(f_low, f_high, filter_bw) self.signal_created.emit(signal) self.unsetCursor()
def test_fir_filter(self): input_signal = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 42], dtype=np.complex64) filter_taps = [0.25, 0.25, 0.25, 0.25] fir_filter = Filter(filter_taps) filtered_signal = fir_filter.apply_fir_filter(input_signal) expected_filtered_signal = np.array([0.25, 0.75, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 16.5], dtype=np.complex64) self.assertTrue(np.array_equal(filtered_signal, expected_filtered_signal))
def test_change_custom_bw(self): bw = 0.3 N = Filter.get_filter_length_from_bandwidth(bw) self.dialog.ui.doubleSpinBoxCustomBandwidth.setValue(bw) self.assertEqual(N, self.dialog.ui.spinBoxCustomKernelLength.value()) N = 401 bw = Filter.get_bandwidth_from_filter_length(N) self.dialog.ui.spinBoxCustomKernelLength.setValue(N) self.assertAlmostEqual(bw, self.dialog.ui.doubleSpinBoxCustomBandwidth.value(), places=self.dialog.ui.doubleSpinBoxCustomBandwidth.decimals())
def test_channels(self): sample_rate = 10 ** 6 channel1_freq = 40 * 10 ** 3 channel2_freq = 240 * 10 ** 3 channel1_data = array.array("B", [1, 0, 1, 0, 1, 0, 0, 1]) channel2_data = array.array("B", [1, 1, 0, 0, 1, 1, 0, 1]) channel3_data = array.array("B", [1, 0, 0, 1, 0, 1, 1, 1]) filter_bw = 0.1 filter_freq1_high = 1.5 * channel1_freq filter_freq1_low = 0.5 * channel1_freq filter_freq2_high = 1.5*channel2_freq filter_freq2_low = 0.5 * channel2_freq modulator1, modulator2, modulator3 = Modulator("test"), Modulator("test2"), Modulator("test3") modulator1.carrier_freq_hz = channel1_freq modulator2.carrier_freq_hz = channel2_freq modulator3.carrier_freq_hz = -channel2_freq modulator1.sample_rate = modulator2.sample_rate = modulator3.sample_rate = sample_rate data1 = modulator1.modulate(channel1_data) data2 = modulator2.modulate(channel2_data) data3 = modulator3.modulate(channel3_data) mixed_signal = data1 + data2 + data3 mixed_signal.tofile("/tmp/three_channels.complex") plt.subplot("221") plt.title("Signal") plt.plot(mixed_signal) spectrogram = Spectrogram(mixed_signal) plt.subplot("222") plt.title("Spectrogram") plt.imshow(np.transpose(spectrogram.data), aspect="auto", cmap="magma") plt.ylim(0, spectrogram.freq_bins) chann1_filtered = Filter.apply_bandpass_filter(mixed_signal, filter_freq1_low / sample_rate, filter_freq1_high / sample_rate, filter_bw) plt.subplot("223") plt.title("Channel 1 Filtered ({})".format("".join(map(str, channel1_data)))) plt.plot(chann1_filtered) chann2_filtered = Filter.apply_bandpass_filter(mixed_signal, filter_freq2_low / sample_rate, filter_freq2_high / sample_rate, filter_bw) plt.subplot("224") plt.title("Channel 2 Filtered ({})".format("".join(map(str, channel2_data)))) plt.plot(chann2_filtered) plt.show()
def create_context_menu(self): menu = QMenu() menu.setToolTipsVisible(True) self._add_zoom_actions_to_menu(menu) if self.something_is_selected: filter_bw = Filter.read_configured_filter_bw() text = self.tr( "Apply bandpass filter (filter bw={0:n})".format(filter_bw)) create_from_frequency_selection = menu.addAction(text) create_from_frequency_selection.triggered.connect( self.on_create_from_frequency_selection_triggered) create_from_frequency_selection.setIcon( QIcon.fromTheme("view-filter")) try: cancel_button = " or ".join( k.toString() for k in QKeySequence.keyBindings(QKeySequence.Cancel)) except Exception as e: logger.debug("Error reading cancel button: " + str(e)) cancel_button = "Esc" create_from_frequency_selection.setToolTip( "You can abort filtering with <b>{}</b>.".format( cancel_button)) configure_filter_bw = menu.addAction( self.tr("Configure filter bandwidth...")) configure_filter_bw.triggered.connect( self.on_configure_filter_bw_triggered) configure_filter_bw.setIcon(QIcon.fromTheme("configure")) return menu
def test_bandpass(self): # Generate a noisy signal fs = 2000 T = 0.1 nsamples = T * fs t = np.linspace(0, T, nsamples, endpoint=False) a = 0.02 f0 = 600 x = 0.25 * np.sin(2 * np.pi * 0.25 * f0 * t) x += 0.25 * np.sin(2 * np.pi * f0 * t) x += 0.25 * np.sin(2 * np.pi * 2 * f0 * t) x += 0.25 * np.sin(2 * np.pi * 3 * f0 * t) import time lowcut = f0 - 200 highcut = f0 + 200 # Define the parameters fc = f0 / fs b = 0.05 data = x y = Filter.apply_bandpass_filter(data, lowcut / fs, highcut / fs, filter_bw=b) plt.plot(y, label='Filtered signal (%g Hz)' % f0) plt.plot(data, label='Noisy signal') plt.legend(loc='upper left') plt.show()
def filter_range(self, start: int, end: int, fir_filter: Filter): self.iq_array[start:end] = fir_filter.work(self.iq_array[start:end]) self._qad[start:end] = signal_functions.afp_demod( self.iq_array[start:end], self.noise_threshold, self.modulation_type, self.modulation_order, self.costas_loop_bandwidth) self.__invalidate_after_edit()
def create_context_menu(self): menu = QMenu() menu.setToolTipsVisible(True) self._add_zoom_actions_to_menu(menu) if self.something_is_selected: filter_bw = Filter.read_configured_filter_bw() text = self.tr("Apply bandpass filter (filter bw={0:n})".format(filter_bw)) create_from_frequency_selection = menu.addAction(text) create_from_frequency_selection.triggered.connect(self.on_create_from_frequency_selection_triggered) create_from_frequency_selection.setIcon(QIcon.fromTheme("view-filter")) try: cancel_button = " or ".join(k.toString() for k in QKeySequence.keyBindings(QKeySequence.Cancel)) except Exception as e: logger.debug("Error reading cancel button: " + str(e)) cancel_button = "Esc" create_from_frequency_selection.setToolTip("You can abort filtering with <b>{}</b>.".format(cancel_button)) configure_filter_bw = menu.addAction(self.tr("Configure filter bandwidth...")) configure_filter_bw.triggered.connect(self.on_configure_filter_bw_triggered) configure_filter_bw.setIcon(QIcon.fromTheme("configure")) menu.addSeparator() export_fta_action = menu.addAction("Export spectrogram...") export_fta_action.triggered.connect(self.on_export_fta_action_triggered) return menu
def test_bandpass(self): # Generate a noisy signal fs = 2000 T = 0.1 nsamples = T * fs t = np.linspace(0, T, nsamples, endpoint=False) a = 0.02 f0 = 600 x = 0.25 * np.sin(2 * np.pi * 0.25*f0 * t) x += 0.25 * np.sin(2 * np.pi * f0 * t) x += 0.25 * np.sin(2 * np.pi * 2*f0 * t) x += 0.25 * np.sin(2 * np.pi * 3*f0 * t) import time lowcut = f0 - 200 highcut = f0 + 200 # Define the parameters fc = f0 / fs b = 0.05 data = x y = Filter.apply_bandpass_filter(data, lowcut / fs, highcut / fs, filter_bw=b) plt.plot(y, label='Filtered signal (%g Hz)' % f0) plt.plot(data, label='Noisy signal') plt.legend(loc='upper left') plt.show()
def test_fsk_live_capture(self): data = Signal(get_path_for_data_file("fsk_live.coco"), "").data n = 10 moving_average_filter = Filter([1 / n for _ in range(n)], filter_type=FilterType.moving_average) filtered_data = moving_average_filter.apply_fir_filter(data) rect = afp_demod(filtered_data, 0.0175, 1) center = detect_center(rect) self.assertGreaterEqual(center, -0.0148, msg="Filtered") self.assertLessEqual(center, 0.01, msg="Filtered") rect = afp_demod(data, 0.0175, 1) center = detect_center(rect) self.assertGreaterEqual(center, -0.02, msg="Original") self.assertLessEqual(center, 0.01, msg="Original")
def build_filter(self) -> Filter: if self.ui.radioButtonMovingAverage.isChecked(): n = self.ui.spinBoxNumTaps.value() return Filter([1/n for _ in range(n)], filter_type=FilterType.moving_average) else: # custom filter try: taps = eval(self.ui.lineEditCustomTaps.text()) try: taps = list(map(float, taps)) self.error_message = "" return Filter(taps) except (ValueError, TypeError) as e: self.error_message = "Error casting taps:\n" + str(e) return None except SyntaxError as e: self.error_message = "Error parsing taps:\n" + str(e) return None
def test_fsk_live_capture(self): data = Signal(get_path_for_data_file("fsk_live.coco"), "").iq_array.data n = 10 moving_average_filter = Filter([1 / n for _ in range(n)], filter_type=FilterType.moving_average) filtered_data = moving_average_filter.apply_fir_filter( data.flatten()).view(np.float32) filtered_data = filtered_data.reshape((len(filtered_data) // 2, 2)) rect = afp_demod(filtered_data, 0.0175, "FSK", 2) center = detect_center(rect) self.assertGreaterEqual(center, -0.0148, msg="Filtered") self.assertLessEqual(center, 0.01, msg="Filtered") rect = afp_demod(data, 0.0175, "FSK", 2) center = detect_center(rect) self.assertGreaterEqual(center, -0.02, msg="Original") self.assertLessEqual(center, 0.01, msg="Original")
def test_fft_convolution(self): x = np.array([1, 2, 3]) h = np.array([0, 1, 0.5]) expected_result = np.array([1., 2.5, 4.]) result_np = np.convolve(x, h, 'same') self.assertTrue(np.array_equal(result_np, expected_result)) result_fft = Filter.fft_convolve_1d(x, h) self.assertEqual(len(expected_result), len(result_fft)) for i in range(len(expected_result)): self.assertAlmostEqual(expected_result[i], result_fft[i], places=8, msg=str(i)) x = np.linspace(0, 1, num=10 ** 3).astype(np.complex64) h = Filter.design_windowed_sinc_bandpass(0.1, 0.4, 0.01) # fft convolve is faster if IR is round about 400 samples or windowed sinc has bandwidth of 0.01 result_np = np.convolve(x, h, mode="same") result_fft = Filter.fft_convolve_1d(x, h) np.testing.assert_array_almost_equal(result_np, result_fft)
def test_bandpass_h(self): f_low = 0.31 f_high = 0.44 bw = 0.01 h = Filter.design_windowed_sinc_bandpass(f_low=f_low, f_high=f_high, bw=bw) #h = Filter.design_windowed_sinc_lpf(0.42, bw=0.08) impulse = np.exp(1j * np.linspace(0, 1, 50)) plt.subplot("221") plt.title("f_low={} f_high={} bw=0.05".format(f_low, f_high, bw)) plt.plot(np.fft.rfft(h)) plt.subplot("222") plt.plot(h) plt.show()
def create_context_menu(self): menu = QMenu() self._add_zoom_actions_to_menu(menu) if self.something_is_selected: filter_bw = Filter.read_configured_filter_bw() text = self.tr( "Create signal from frequency selection (filter bw={0:n})". format(filter_bw)) create_from_frequency_selection = menu.addAction(text) create_from_frequency_selection.triggered.connect( self.on_create_from_frequency_selection_triggered) create_from_frequency_selection.setIcon( QIcon.fromTheme("view-filter")) configure_filter_bw = menu.addAction( self.tr("Configure filter bandwidth...")) configure_filter_bw.triggered.connect( self.on_configure_filter_bw_triggered) configure_filter_bw.setIcon(QIcon.fromTheme("configure")) return menu
def filter_range(self, start: int, end: int, fir_filter: Filter): self._fulldata[start:end] = fir_filter.work(self._fulldata[start:end]) self._qad[start:end] = signal_functions.afp_demod(self.data[start:end], self.noise_threshold, self.modulation_type) self.__invalidate_after_edit()
def on_spin_box_custom_bandwidth_value_changed(self, bw: float): self.ui.spinBoxCustomKernelLength.blockSignals(True) self.ui.spinBoxCustomKernelLength.setValue(Filter.get_filter_length_from_bandwidth(bw)) self.ui.spinBoxCustomKernelLength.blockSignals(False)
def on_spin_box_custom_kernel_length_value_changed(self, filter_len: int): self.ui.doubleSpinBoxCustomBandwidth.blockSignals(True) self.ui.doubleSpinBoxCustomBandwidth.setValue(Filter.get_bandwidth_from_filter_length(filter_len)) self.ui.doubleSpinBoxCustomBandwidth.blockSignals(False)
def __init__(self, proto_analyzer: ProtocolAnalyzer, undo_stack: QUndoStack, project_manager, proto_bits=None, parent=None): super().__init__(parent) self.undo_stack = undo_stack self.ui = Ui_SignalFrame() self.ui.setupUi(self) fixed_font = QFontDatabase.systemFont(QFontDatabase.FixedFont) fixed_font.setPointSize(QApplication.instance().font().pointSize()) self.ui.txtEdProto.setFont(fixed_font) self.ui.txtEdProto.participants = project_manager.participants self.ui.txtEdProto.messages = proto_analyzer.messages self.ui.gvSignal.participants = project_manager.participants self.setAttribute(Qt.WA_DeleteOnClose) self.project_manager = project_manager self.proto_analyzer = proto_analyzer self.signal = proto_analyzer.signal if self.proto_analyzer is not None else None # type: Signal self.dsp_filter = Filter([0.1] * 10, FilterType.moving_average) self.set_filter_button_caption() self.filter_dialog = FilterDialogController(self.dsp_filter, parent=self) self.proto_selection_timer = QTimer( ) # For Update Proto Selection from ROI self.proto_selection_timer.setSingleShot(True) self.proto_selection_timer.setInterval(1) # Disabled because never used (see also set_protocol_visibilty()) self.ui.chkBoxSyncSelection.hide() if self.signal is not None: self.filter_menu = QMenu() self.apply_filter_to_selection_only = self.filter_menu.addAction( self.tr("Apply only to selection")) self.apply_filter_to_selection_only.setCheckable(True) self.apply_filter_to_selection_only.setChecked(False) self.configure_filter_action = self.filter_menu.addAction( "Configure filter...") self.configure_filter_action.setIcon(QIcon.fromTheme("configure")) self.configure_filter_action.triggered.connect( self.on_configure_filter_action_triggered) self.ui.btnFilter.setMenu(self.filter_menu) if self.signal.qad_demod_file_loaded: self.ui.lSignalTyp.setText("Quad-Demod Signal (*.wav)") elif self.signal.wav_mode: self.ui.lSignalTyp.setText("Realpart Signal (*.wav)") else: self.ui.lSignalTyp.setText("Complex Signal") self.ui.gvLegend.hide() self.ui.lineEditSignalName.setText(self.signal.name) self.ui.lSamplesInView.setText("{0:,}".format( self.signal.num_samples)) self.ui.lSamplesTotal.setText("{0:,}".format( self.signal.num_samples)) self.sync_protocol = self.ui.chkBoxSyncSelection.isChecked() self.ui.chkBoxSyncSelection.hide() self.ui.splitter.setSizes([self.ui.splitter.height(), 0]) self.protocol_selection_is_updateable = True self.scene_manager = SignalSceneManager(self.signal, self) self.ui.gvSignal.scene_manager = self.scene_manager self.ui.gvSignal.setScene(self.scene_manager.scene) self.jump_sync = True self.on_btn_show_hide_start_end_clicked() self.refresh_signal_information(block=True) self.create_connects() self.set_protocol_visibility() self.ui.chkBoxShowProtocol.setChecked(True) self.set_qad_tooltip(self.signal.noise_threshold) self.ui.btnSaveSignal.hide() self.show_protocol(refresh=False) else: self.ui.btnFilter.setDisabled(True) suffix = "" if not proto_analyzer.filename: suffix = "" elif proto_analyzer.filename.endswith(".proto"): suffix = " (*.proto)" elif proto_analyzer.filename.endswith(".txt"): suffix = " (*.txt)" self.ui.lSignalTyp.setText("Protocol" + suffix) scene, nsamples = SignalSceneManager.create_rectangle(proto_bits) self.ui.lSamplesInView.setText("{0:n}".format(int(nsamples))) self.ui.lSamplesTotal.setText("{0:n}".format(int(nsamples))) self.ui.gvSignal.setScene(scene) self.ui.spinBoxSelectionStart.setMaximum(nsamples) self.ui.spinBoxSelectionEnd.setMaximum(nsamples) self.ui.btnReplay.hide() self.create_connects() self.ui.gvSignal.sel_area_active = True self.ui.btnSaveSignal.hide()
def filter_range(self, start: int, end: int, fir_filter: Filter): self._fulldata[start:end] = fir_filter.apply_fir_filter(self._fulldata[start:end]) self._qad[start:end] = signal_functions.afp_demod(self.data[start:end], self.noise_threshold, self.modulation_type) self.__invalidate_after_edit()