mirror of
https://github.com/jopohl/urh.git
synced 2026-03-05 16:04:01 +01:00
* rename signalFunctions -> signal_functions * basic methods for auto interpretation * cythonize k means * reorder tests * remove check and update gitignore * estimate tolerance and implement score for choosing modulation type * use absdiff * remove comment * cythonize messsage segmentation * improve message segementation and add test for xavax * integrate OOK special case * add check if psk is possible * integrate xavax and improve score * improve noise detection * add test for noise detection multiple messages * improve noise detection * homematic fix: use percetange of signal length instead of num flanks * homematic has some trash at start of messages, which counts as flanks * additonally set score to 0 if found only one bit length lower 5 * calculate minimum bit length from tolerance * improve noise noise detection * refactor limit and propose new limit calculation * improve minimum bit length penalty * only increase score for mod_type if bit length surpasses a minimum * this way scoring loop later becomes easier and * score is more accurate as there is no division needed which does not scale well with the length of message vectors * remove demodulated complex files and demod live in tests * remove enocean.coco * add a new check to prevent PSK misclassification * add tolerance unit test * use z=2 for finding outlier free max in tolerance estimation * prevent numpy warnings * adapt threshold of unit test * normalize the score by dividing by plateau vector length * improve OOK segmentation: Use minimum pulse length instead pause length for reference * use 50 percentile for detecting n_digits in plateau rounding * add elektromaten integration test * improve center detection to deal with varying signal power levels * use 10% clustering for rect signal * calculate min and max of each cluster * return max(minima) + min(maxima) / 2 * improve the center aggregation, separate between modulation types * add validity checks if message can be ASK or FSK modulated * use a weighted mean for center estimation: 60/40 for high/low * improve bit length estimation: use decimal deviation for filtering * add scislo test * improve tolerance estimation: use 50 percentile + revert to normal mean for bitlength estimation * add haar wavelet transform * add median filter * rename to Wavelet * add signal generation with configurable snr for lab test * add method for testdata generation * prepare fsk test: generate messages and estimate parameters * improve performance of plateau length filtering * remove unused import * improve robustness * improve robustness * add fsk error plot * only append bit length if it surpasses minimum * fix plot title * improve noise level detection, prevent it from being too low * integrate all modulations to test * increase pause threshold for ook * improve tolerance estimation * improve noise detection: take maximum of all maxima of noise clusters * improve scoring algorithm to prevent PSK misclassify as FSK * use histogram based approach for center detection * modulation detection with wavelets * fix median filter when at end of data * integrate modulation detection with wavelets * improve robustness * improve psk parameters * improve psk threshold * improve robustness * swap psk angles for easier demod * better xticks * add message segmentation test and fix noise generation snr * add error print * update audi test * fix runtime warning * improve accuracy of center detection * avoid warning * remove unused functions * fine tune fsk fft threshold * update esaver test * improve fsk fft threshold * change test order * update enocean test signal * update enocean test signal * enhance bit length estimation: use a threshold divisor histogram * improve noise estimation: round to fourth digit * update enocean signal * consider special case if message pause is 0 * remove unused * improve noise detection * improve center detection * improve center detection * prevent warning * refactor * cythonize get_plateau_lengths * improve syntax * use c++ sort * optimize PSK threshold * optimize coverage * fix buffer types * integrate new auto detection routine * update test * remove unused stuff * fix tests * backward compat * backward compat * update test * add threshold for large signals for performance * update changelog * make algorithm more robust against short bit length outliers * make multi button for selecting auto detect options * update unittest
90 lines
4.5 KiB
Python
90 lines
4.5 KiB
Python
from PyQt5.QtCore import QTimer
|
|
|
|
from tests.QtTestCase import QtTestCase
|
|
from urh import colormaps
|
|
from urh.signalprocessing.Signal import Signal
|
|
from urh.signalprocessing.Spectrogram import Spectrogram
|
|
|
|
|
|
class TestSpectrogram(QtTestCase):
|
|
def setUp(self):
|
|
self.signal = Signal(self.get_path_for_filename("two_participants.coco"), "test")
|
|
self.spectrogram = Spectrogram(self.signal.data)
|
|
|
|
def test_create_spectrogram_image(self):
|
|
image = self.spectrogram.create_spectrogram_image()
|
|
self.assertEqual(image.width(), self.spectrogram.time_bins - 2)
|
|
self.assertEqual(image.height(), self.spectrogram.freq_bins)
|
|
|
|
def test_create_colormap_image(self):
|
|
image = self.spectrogram.create_colormap_image("magma", height=42)
|
|
self.assertEqual(image.height(), 42)
|
|
self.assertEqual(image.width(), len(colormaps.chosen_colormap_numpy_bgra))
|
|
|
|
def test_channel_separation_with_negative_frequency(self):
|
|
super().setUp()
|
|
self.add_signal_to_form("three_channels.complex")
|
|
self.assertEqual(self.form.signal_tab_controller.num_frames, 1)
|
|
|
|
signal_frame = self.form.signal_tab_controller.signal_frames[0]
|
|
self.__prepare_channel_separation(signal_frame)
|
|
|
|
self.__test_extract_channel(signal_frame, freq1=650, freq2=850, bandwidth="195,312kHz", target_bits="11001101", center=0.1)
|
|
self.__test_extract_channel(signal_frame, freq1=500, freq2=620, bandwidth="117,188kHz", target_bits="10101001", center=0.1)
|
|
self.__test_extract_channel(signal_frame, freq1=217, freq2=324, bandwidth="104,492kHz", target_bits="10010111", center=0.1)
|
|
|
|
def test_cancel_filtering(self):
|
|
super().setUp()
|
|
self.add_signal_to_form("two_participants.coco")
|
|
signal_frame = self.form.signal_tab_controller.signal_frames[0]
|
|
signal_frame.ui.cbSignalView.setCurrentIndex(2)
|
|
signal_frame.ui.spinBoxSelectionStart.setValue(100)
|
|
signal_frame.ui.spinBoxSelectionEnd.setValue(200)
|
|
menu = signal_frame.ui.gvSpectrogram.create_context_menu()
|
|
create_action = next(action for action in menu.actions() if "bandpass filter" in action.text())
|
|
timer = QTimer(self.form)
|
|
timer.setSingleShot(True)
|
|
timer.timeout.connect(self.form.cancel_action.trigger)
|
|
timer.start(1)
|
|
|
|
create_action.trigger()
|
|
|
|
self.assertTrue(signal_frame.filter_abort_wanted)
|
|
self.assertEqual(self.form.signal_tab_controller.num_frames, 1)
|
|
|
|
def __prepare_channel_separation(self, signal_frame):
|
|
self.assertEqual(self.form.signal_tab_controller.num_frames, 1)
|
|
signal_frame = self.form.signal_tab_controller.signal_frames[0]
|
|
signal_frame.ui.spinBoxNoiseTreshold.setValue(0)
|
|
signal_frame.ui.spinBoxNoiseTreshold.editingFinished.emit()
|
|
self.assertEqual(signal_frame.signal.num_samples, 800)
|
|
signal_frame.ui.cbSignalView.setCurrentIndex(2)
|
|
self.assertTrue(signal_frame.spectrogram_is_active)
|
|
|
|
def __test_extract_channel(self, signal_frame, freq1, freq2, bandwidth: str, target_bits: str, center=None):
|
|
num_frames = self.form.signal_tab_controller.num_frames
|
|
|
|
signal_frame.ui.spinBoxSelectionStart.setValue(freq1)
|
|
signal_frame.ui.spinBoxSelectionEnd.setValue(freq2 - 1)
|
|
signal_frame.ui.spinBoxSelectionEnd.setValue(freq2)
|
|
|
|
self.assertEqual(signal_frame.ui.lNumSelectedSamples.text(), str(freq2 - freq1))
|
|
self.assertEqual(signal_frame.ui.lDuration.text().replace(".", ","), bandwidth)
|
|
menu = signal_frame.ui.gvSpectrogram.create_context_menu()
|
|
create_action = next(action for action in menu.actions() if "bandpass filter" in action.text())
|
|
create_action.trigger()
|
|
|
|
self.assertEqual(self.form.signal_tab_controller.num_frames, num_frames + 1)
|
|
filtered_frame = self.form.signal_tab_controller.signal_frames[1]
|
|
filtered_frame.ui.cbModulationType.setCurrentText("ASK")
|
|
filtered_frame.ui.spinBoxNoiseTreshold.setValue(0)
|
|
filtered_frame.ui.spinBoxNoiseTreshold.editingFinished.emit()
|
|
filtered_frame.ui.spinBoxInfoLen.setValue(100)
|
|
filtered_frame.ui.spinBoxInfoLen.editingFinished.emit()
|
|
if center is not None:
|
|
filtered_frame.ui.spinBoxCenterOffset.setValue(center)
|
|
filtered_frame.ui.spinBoxCenterOffset.editingFinished.emit()
|
|
|
|
self.assertEqual(len(filtered_frame.proto_analyzer.plain_bits_str), 1)
|
|
self.assertEqual(filtered_frame.proto_analyzer.plain_bits_str[0], target_bits)
|