def test_interval(): """Tests if the interval functionality of the LinearSweep class works""" sweep1 = sumpf.LinearSweep(interval=(200, 800), length=2**10) sweep2 = sumpf.LinearSweep(length=600) assert sweep1[:, 200:800].channels() == pytest.approx(sweep2.channels()) sweep3 = sumpf.LinearSweep(interval=(0.1, -0.1), length=2**10) sweep4 = sumpf.LinearSweep( length=int(round(2**10 * 0.9) - round(2**10 * 0.1))) assert sweep3[:, 0.1:-0.1].channels() == pytest.approx(sweep4.channels())
def test_spectrogram(): """Checks the linear frequency increase by finding the maximums in the spectrogram.""" pytest.importorskip("scipy") sweep = sumpf.LinearSweep() spectrogram = sweep.short_time_fourier_transform(window=2048) frequencies = sweep.instantaneous_frequency(spectrogram.time_samples()) for c in spectrogram.magnitude(): maximums = numpy.multiply(c.argmax(axis=0), spectrogram.resolution()) diff = numpy.abs(frequencies - maximums) assert (diff[1:-1] <= spectrogram.resolution() * 1.2).all()
def test_compare_with_numpy_implementation(start_frequency, stop_frequency, phase, sampling_rate, length): """Compares the current implementation with a sweep, that is created with a pure numpy implementation.""" sweep1 = sumpf.LinearSweep(start_frequency=start_frequency, stop_frequency=stop_frequency, phase=phase, sampling_rate=sampling_rate, length=length) sweep2 = numpy_sweep(start_frequency=start_frequency, stop_frequency=stop_frequency, phase=phase, sampling_rate=sampling_rate, length=length) assert sweep1.channels() == pytest.approx(sweep2.channels(), abs=1e-7)
def test_instantaneous_frequency(start_frequency, stop_frequency, sampling_rate, length, interval_start, interval_stop): """Tests the instantaneous_frequency method of the LinearSweep class""" sweep = sumpf.LinearSweep(start_frequency=start_frequency, stop_frequency=stop_frequency, interval=(interval_start, interval_stop), sampling_rate=sampling_rate, length=length) assert sweep.instantaneous_frequency(0.0) == sweep.minimum_frequency() assert sweep.instantaneous_frequency(round(interval_start * length) / sampling_rate) == pytest.approx(start_frequency) # pylint: disable=line-too-long assert sweep.instantaneous_frequency(round(interval_stop * length) / sampling_rate) == pytest.approx(stop_frequency) # pylint: disable=line-too-long assert sweep.instantaneous_frequency( sweep.duration()) == sweep.maximum_frequency() diff = numpy.diff(sweep.instantaneous_frequency(sweep.time_samples())) assert (diff > 0).all() # the frequency should increase monotonically
def test_min_and_max_frequencies(start_frequency, stop_frequency, sampling_rate, length, interval_start, interval_stop): """Tests if the methods for computing the minimum and the maximum frequencies work as expected""" interval = (interval_start, interval_stop) start, stop = sumpf_internal.index(interval, length) sweep_length = stop - start frequency_range = stop_frequency - start_frequency sweep = sumpf.LinearSweep(start_frequency=start_frequency, stop_frequency=stop_frequency, interval=interval, sampling_rate=sampling_rate, length=length) assert sweep.minimum_frequency() == pytest.approx(start_frequency + frequency_range * (-start / sweep_length)) assert sweep.maximum_frequency() == pytest.approx(stop_frequency + frequency_range * ((length - stop) / sweep_length)) # pylint: disable=line-too-long; nothing complicated here, only long variable names
def test_min_and_max_frequencies_inversed(start_frequency, stop_frequency, sampling_rate, length, interval_start, interval_stop): """Tests if the methods for computing the minimum and the maximum frequencies work as expected""" start, stop = sumpf_internal.index((interval_start, interval_stop), length) sweep = sumpf.LinearSweep(start_frequency=start_frequency, stop_frequency=stop_frequency, interval=(start, stop), sampling_rate=sampling_rate, length=length) isweep = sumpf.InverseLinearSweep(start_frequency=start_frequency, stop_frequency=stop_frequency, interval=(length - stop, length - start), sampling_rate=sampling_rate, length=length) assert isweep.minimum_frequency() == pytest.approx( sweep.minimum_frequency()) assert isweep.maximum_frequency() == pytest.approx( sweep.maximum_frequency())
def test_convolution_with_sweep(): """Tests if the convolution with the respective sweep results in a unit impulse""" for kwargs in ({ "start_frequency": 300.0, "length": 1024 }, { "stop_frequency": 12747.0, "length": 8192 }, { "phase": 2.4, "length": 8192 }, { "interval": (0.15, 0.9), "length": 8192 }, { "stop_frequency": 5000.0, "sampling_rate": 18312.7, "length": 4096 }): a, b = kwargs.get("interval", (0, 1.0)) sweep = sumpf.LinearSweep(**kwargs) isweep = sumpf.InverseLinearSweep(**kwargs) impulse = sweep[:, a:b].convolve(isweep[:, a:b]) peak = max(impulse.channels()[0]) peak_index = impulse.channels()[0].argmax() other = max( max(abs(impulse.channels()[0, 0:-impulse.offset() - 1]) ), # the maximum of the absolute values of the impulse except max(abs(impulse.channels()[ 0, -impulse.offset() + 2:]))) # for the sample at t=0 and the two neighboring samples assert abs(peak - 1.0 ) < 0.005 # the highest peak should be one (unit impulse) assert peak_index == -impulse.offset( ) # the highest peak should be at time value 0 assert peak > 5 * abs( other ) # other peaks and notches should be much smaller than the impulse
from lad import lad_training from lad import lad_testing import numpy as np import sumpf import sumpf_staging import utilities signal = sumpf.LinearSweep(length=2**18) spectrogram = signal.short_time_fourier_transform() lad_training(spectrogram.magnitude()) result = lad_testing(spectrogram.magnitude()) result_spectrogram = sumpf.Spectrogram( channels=result, resolution=spectrogram.resolution(), sampling_rate=spectrogram.sampling_rate()) plot = utilities.plot(result_spectrogram, log_frequency=False, log_magnitude=False) plot = plot.plot(spectrogram) plot.show()