Example #1
0
def test_merge_spectrums_manually():
    """Tests the merging behavior with manually generated spectrums."""
    spectrum1 = sumpf.Spectrum(channels=numpy.array([(1.1j, 1.2, 1.3j)]),
                               resolution=1.0,
                               labels=("s1c1",))
    spectrum2 = sumpf.Spectrum(channels=numpy.array([(2.1, 2.2j, 2.3, 2.4j), (3.1, 3.2j, 3.3, 3.4j)]),
                               resolution=2.0,
                               labels=("s2c1", "s2c2"))
    spectrum12 = sumpf.Spectrum(channels=numpy.array([(1.1j, 1.2, 1.3j, 0.0),
                                                      (2.1, 2.2j, 2.3, 2.4j),
                                                      (3.1, 3.2j, 3.3, 3.4j)]),
                                resolution=1.0,
                                labels=("s1c1", "s2c1", "s2c2"))
    spectrum21 = sumpf.Spectrum(channels=numpy.array([(2.1, 2.2j, 2.3, 2.4j),
                                                      (3.1, 3.2j, 3.3, 3.4j),
                                                      (1.1j, 1.2, 1.3j, 0.0)]),
                                resolution=2.0,
                                labels=("s2c1", "s2c2", "s1c1"))
    spectrum21c = sumpf.Spectrum(channels=numpy.array([(2.1, 2.2j, 2.3, 2.4j),
                                                       (1.1j, 1.2, 1.3j, 0.0),
                                                       (3.1, 3.2j, 3.3, 3.4j)]),
                                 resolution=2.0,
                                 labels=("s2c1", "s1c1", "s2c2"))
    FIRST_CHANNELS_FIRST = sumpf.Merge.modes.FIRST_CHANNELS_FIRST
    assert sumpf.Merge([spectrum1, spectrum2]).output() == spectrum12
    assert sumpf.Merge([spectrum2, spectrum1]).output() == spectrum21
    assert sumpf.Merge([spectrum1, spectrum2], mode=FIRST_CHANNELS_FIRST).output() == spectrum12
    assert sumpf.Merge([spectrum2, spectrum1], mode=FIRST_CHANNELS_FIRST).output() == spectrum21c
Example #2
0
def test_subtract():
    """Tests the overload of the ``-`` operator."""
    spectrum1 = sumpf.Spectrum(channels=numpy.array([(1.0, 0.0, 0.0),
                                                     (0.0, 2.0, 0.0)]),
                               labels=("one1", "two1"))
    spectrum2 = sumpf.Spectrum(channels=numpy.array([(1.0, 0.0, 0.0),
                                                     (0.0, 2.0, 0.0),
                                                     (0.0, 0.0, 3.0)]),
                               labels=("one2", "two2", "three2"))
    # test subtracting a number
    difference = spectrum1 - 3.7
    assert difference.resolution() == spectrum1.resolution()
    assert difference.labels() == spectrum1.labels()
    assert (difference.channels() == numpy.subtract(spectrum1.channels(),
                                                    3.7)).all()
    assert ((3.7 - spectrum1).channels() == numpy.subtract(
        3.7, spectrum1.channels())).all()
    # test subtracting an array
    difference = spectrum1 - (1.9, -3.8, 5.5)
    assert difference.resolution() == spectrum1.resolution()
    assert difference.labels() == spectrum1.labels()
    assert (difference.channels() == numpy.subtract(spectrum1.channels(),
                                                    (1.9, -3.8, 5.5))).all()
    assert (((1.9, -3.8, 5.5) - spectrum1).channels() == numpy.subtract(
        (1.9, -3.8, 5.5), spectrum1.channels())).all()
    # test subtracting a Spectrum with the same number of channels
    difference = spectrum1 - spectrum1
    assert difference.resolution() == spectrum1.resolution()
    assert difference.labels() == ("Difference", ) * 2
    assert (difference.channels() == numpy.zeros(
        shape=spectrum1.shape())).all()
    # test subtracting a Spectrum with a higher number of channels
    difference = spectrum1 - spectrum2
    assert difference.resolution() == spectrum1.resolution()
    assert difference.labels() == ("Difference", ) * 3
    assert (difference.channels() == [
        numpy.subtract(spectrum1.channels()[0],
                       spectrum2.channels()[0]),
        numpy.subtract(spectrum1.channels()[1],
                       spectrum2.channels()[1]),
        numpy.subtract(0.0,
                       spectrum2.channels()[2])
    ]).all()
    assert ((spectrum2 - spectrum1).channels() == [
        numpy.subtract(spectrum2.channels()[0],
                       spectrum1.channels()[0]),
        numpy.subtract(spectrum2.channels()[1],
                       spectrum1.channels()[1]),
        spectrum2.channels()[2]
    ]).all()
    # test subtracting a single channel Spectrum
    difference = spectrum1 - spectrum2[2]
    assert difference.resolution() == spectrum1.resolution()
    assert difference.labels() == ("Difference", ) * 2
    assert (difference.channels() == numpy.subtract(
        spectrum1.channels(),
        spectrum2.channels()[2])).all()
    assert ((spectrum2[2] - spectrum1).channels() == numpy.subtract(
        spectrum2.channels()[2], spectrum1.channels())).all()
Example #3
0
def test_divide():
    """Tests the overload of the ``/`` operator."""
    spectrum1 = sumpf.Spectrum(channels=numpy.array([(1.5, 1.0, 1.0),
                                                     (1.0, 1.2, 1.0)]),
                               labels=("one1", "two1"))
    spectrum2 = sumpf.Spectrum(channels=numpy.array([(2.0, 1.0, 1.0),
                                                     (1.0, 0.5, 1.0),
                                                     (1.0, 1.0, 0.2)]),
                               labels=("one2", "two2", "three2"))
    # test dividing by a number
    quotient = spectrum1 / 3.7
    assert quotient.resolution() == spectrum1.resolution()
    assert quotient.labels() == spectrum1.labels()
    assert (quotient.channels() == numpy.divide(spectrum1.channels(),
                                                3.7)).all()
    assert ((3.7 / spectrum1).channels() == numpy.divide(
        3.7, spectrum1.channels())).all()
    # test dividing by an array
    quotient = spectrum1 / (1.9, -3.8, 5.5)
    assert quotient.resolution() == spectrum1.resolution()
    assert quotient.labels() == spectrum1.labels()
    assert (quotient.channels() == numpy.divide(spectrum1.channels(),
                                                (1.9, -3.8, 5.5))).all()
    assert (((1.9, -3.8, 5.5) / spectrum1).channels() == numpy.divide(
        (1.9, -3.8, 5.5), spectrum1.channels())).all()
    # test dividing by a Spectrum with the same number of channels
    quotient = spectrum1 / spectrum1
    assert quotient.resolution() == spectrum1.resolution()
    assert quotient.labels() == ("Quotient", ) * 2
    assert (quotient.channels() == numpy.ones(shape=spectrum1.shape())).all()
    # test dividing by a Spectrum with a higher number of channels
    quotient = spectrum1 / spectrum2
    assert quotient.resolution() == spectrum1.resolution()
    assert quotient.labels() == ("Quotient", ) * 3
    assert (quotient.channels() == [
        numpy.divide(spectrum1.channels()[0],
                     spectrum2.channels()[0]),
        numpy.divide(spectrum1.channels()[1],
                     spectrum2.channels()[1]),
        numpy.divide(1.0,
                     spectrum2.channels()[2])
    ]).all()
    assert ((spectrum2 / spectrum1).channels() == [
        numpy.divide(spectrum2.channels()[0],
                     spectrum1.channels()[0]),
        numpy.divide(spectrum2.channels()[1],
                     spectrum1.channels()[1]),
        spectrum2.channels()[2]
    ]).all()
    # test dividing by a single channel Spectrum
    quotient = spectrum1 / spectrum2[2]
    assert quotient.resolution() == spectrum1.resolution()
    assert quotient.labels() == ("Quotient", ) * 2
    assert (quotient.channels() == numpy.divide(
        spectrum1.channels(),
        spectrum2.channels()[2])).all()
    assert ((spectrum2[2] / spectrum1).channels() == numpy.divide(
        spectrum2.channels()[2], spectrum1.channels())).all()
Example #4
0
def test_power():
    """Tests the overload of the ``**`` operator."""
    spectrum1 = sumpf.Spectrum(channels=numpy.array([(1.5 + 4.0j, 1.0,
                                                      0.0 + 0.1j),
                                                     (1.0, -1.2, 1.0 + 1.0j)]),
                               labels=("one1", "two1"))
    spectrum2 = sumpf.Spectrum(channels=numpy.array([(2.0 + 1.0j, 0.0, -1.0),
                                                     (1.0 - 0.6j, -0.5, 1.0),
                                                     (1.0, 1.0, 0.2 - 2.0j)]),
                               labels=("one2", "two2", "three2"))
    # test computing the power with a number
    power = spectrum1**3.7
    assert power.resolution() == spectrum1.resolution()
    assert power.labels() == spectrum1.labels()
    assert (power.channels() == numpy.power(spectrum1.channels(), 3.7)).all()
    assert ((3.7**spectrum1).channels() == numpy.power(
        3.7, spectrum1.channels())).all()
    # test computing the power with an array
    power = spectrum1**(1.9, -3.8, 5.5)
    assert power.resolution() == spectrum1.resolution()
    assert power.labels() == spectrum1.labels()
    assert (power.channels() == numpy.power(spectrum1.channels(),
                                            (1.9, -3.8, 5.5))).all()
    assert (((1.9, -3.8, 5.5)**spectrum1).channels() == numpy.power(
        (1.9, -3.8, 5.5), spectrum1.channels())).all()
    # test computing the power with a Spectrum with the same number of channels
    power = spectrum1**spectrum1
    assert power.resolution() == spectrum1.resolution()
    assert power.labels() == ("Power", ) * 2
    assert (power.channels() == numpy.power(spectrum1.channels(),
                                            spectrum1.channels())).all()
    # test computing the power with a Spectrum with a higher number of channels
    power = spectrum1**spectrum2
    assert power.resolution() == spectrum1.resolution()
    assert power.labels() == ("Power", ) * 3
    assert (power.channels() == [
        numpy.power(spectrum1.channels()[0],
                    spectrum2.channels()[0]),
        numpy.power(spectrum1.channels()[1],
                    spectrum2.channels()[1]),
        spectrum2.channels()[2]
    ]).all()
    assert ((spectrum2**spectrum1).channels() == [
        numpy.power(spectrum2.channels()[0],
                    spectrum1.channels()[0]),
        numpy.power(spectrum2.channels()[1],
                    spectrum1.channels()[1]),
        spectrum2.channels()[2]
    ]).all()
    # test computing the power with a single channel Spectrum
    power = spectrum1**spectrum2[2]
    assert power.resolution() == spectrum1.resolution()
    assert power.labels() == ("Power", ) * 2
    assert (power.channels() == numpy.power(spectrum1.channels(),
                                            spectrum2.channels()[2])).all()
    assert ((spectrum2[2]**spectrum1).channels() == numpy.power(
        spectrum2.channels()[2], spectrum1.channels())).all()
Example #5
0
def test_eq(parameters):
    """Tests the operator overloads for ``==`` and ``!=``."""
    spectrum1 = sumpf.Spectrum(**parameters)
    spectrum2 = sumpf.Spectrum(**parameters)
    assert spectrum1 is not spectrum2
    assert spectrum1 == spectrum2
    if spectrum2.length() > 1:
        assert spectrum1 != spectrum2[:, 0:
                                      -1]  # test for a case, where the NumPy comparison of the channels returns a boolean rather than an array of booleans
    assert spectrum1 != (spectrum2 + spectrum2) * spectrum2
    assert spectrum1 != spectrum1.channels()
Example #6
0
def test_hash(parameters):
    """Tests the operator overload for hashing a spectrum with the builtin :func:`hash` function."""
    parameters2 = copy.copy(parameters)
    parameters2["channels"] = numpy.empty(shape=parameters["channels"].shape,
                                          dtype=numpy.complex128)
    parameters2["channels"][:] = parameters["channels"][:]
    spectrum1 = sumpf.Spectrum(**parameters)
    spectrum2 = sumpf.Spectrum(**parameters2)
    spectrum3 = (spectrum2 + spectrum2) * spectrum2
    assert spectrum1.channels() is not spectrum2.channels()
    assert hash(spectrum1) == hash(spectrum2)
    assert hash(spectrum1) != hash(spectrum3)
Example #7
0
def from_rows(frequency_column, data_rows, labels):     # pylint: disable=too-many-branches; the branches are not too complicated in this one
    """Deserializes a spectrum from tabular data.

    :param frequency_column: a vector with frequency values, that correspond to
                             the rows in the data_rows matrix with the same index.
    :param data_rows: a matrix, where the rows contain a complex sample for each
                      channel of the spectrum.
    :param labels: the labels for the channels or an empty tuple.
    :returns: the deserialized spectrum
    """
    if len(data_rows) and len(data_rows[0]):    # pylint: disable=len-as-condition; data_rows can be a NumPy array
        # determine the resolution
        sorted_frequency_row = sorted(frequency_column)
        minimum_frequency = sorted_frequency_row[0]
        maximum_frequency = sorted_frequency_row[-1]
        if len(sorted_frequency_row) <= 1:
            resolution = 0.0
        else:
            resolution = (maximum_frequency - minimum_frequency) / (len(sorted_frequency_row) - 1)
        # determine the offset, that must be either cropped or filled with zero samples
        if resolution == 0.0:
            offset = 0
        else:
            offset = int(round(minimum_frequency / resolution))
        # sort the data rows by their corresponding value in the frequency column
        if numpy.array_equal(frequency_column, sorted_frequency_row):
            sorted_data_rows = data_rows
        else:
            sorted_data_rows = [[e for _, e in sorted(zip(frequency_column, data_row))] for data_row in data_rows]
        # create the channels
        if offset == 0:
            channels = allocate_array(shape=numpy.shape(sorted_data_rows), dtype=numpy.complex128)
            channels[:] = sorted_data_rows
        elif offset < 0:
            channels = allocate_array(shape=numpy.subtract(numpy.shape(sorted_data_rows), (0, offset)),
                                      dtype=numpy.complex128)
            channels[:] = sorted_data_rows[:, offset:]
        else:
            channels = allocate_array(shape=numpy.add(numpy.shape(sorted_data_rows), (0, offset)),
                                      dtype=numpy.complex128)
            channels[:, 0:offset] = 0.0 + 0j
            channels[:, offset:] = sorted_data_rows[:]
        # extend the labels if necessary
        if len(labels) < len(channels):
            labels = tuple(labels) + ("",) * (len(channels) - len(labels))
        elif len(labels) > len(channels):
            labels = labels[0:len(channels)]
        # create the Spectrum instance
        return sumpf.Spectrum(channels=channels, resolution=resolution, labels=labels)
    else:
        return sumpf.Spectrum()
Example #8
0
def test_multiply():
    """Tests the overload of the ``*`` operator."""
    spectrum1 = sumpf.Spectrum(channels=numpy.array([(1.1, 1.0, 1.0),
                                                     (1.0, 1.2, 1.0)]),
                               labels=("one1", "two1"))
    spectrum2 = sumpf.Spectrum(channels=numpy.array([(2.0, 1.0, 1.0),
                                                     (1.0, 3.0, 1.0),
                                                     (1.0, 1.0, 4.0)]),
                               labels=("one2", "two2", "three2"))
    # test multiplying with a number
    product = spectrum1 * 3.7
    assert product.resolution() == spectrum1.resolution()
    assert product.labels() == spectrum1.labels()
    assert (product.channels() == numpy.multiply(spectrum1.channels(),
                                                 3.7)).all()
    assert ((3.7 * spectrum1).channels() == product.channels()).all()
    # test multiplying with an array
    product = spectrum1 * (1.9, -3.8, 5.5)
    assert product.resolution() == spectrum1.resolution()
    assert product.labels() == spectrum1.labels()
    assert (product.channels() == numpy.multiply(spectrum1.channels(),
                                                 (1.9, -3.8, 5.5))).all()
    assert (((1.9, -3.8, 5.5) *
             spectrum1).channels() == product.channels()).all()
    # test multiplying with a Spectrum with the same number of channels
    product = spectrum1 * spectrum1
    assert product.resolution() == spectrum1.resolution()
    assert product.labels() == ("Product", ) * 2
    assert (product.channels() == numpy.square(spectrum1.channels())).all()
    # test multiplying with a Spectrum with a higher number of channels
    product = spectrum1 * spectrum2
    assert product.resolution() == spectrum1.resolution()
    assert product.labels() == ("Product", ) * 3
    assert (product.channels() == [
        numpy.multiply(spectrum1.channels()[0],
                       spectrum2.channels()[0]),
        numpy.multiply(spectrum1.channels()[1],
                       spectrum2.channels()[1]),
        spectrum2.channels()[2]
    ]).all()
    assert ((spectrum2 * spectrum1).channels() == product.channels()).all()
    # test multiplying with a single channel Spectrum
    product = spectrum1 * spectrum2[2]
    assert product.resolution() == spectrum1.resolution()
    assert product.labels() == ("Product", ) * 2
    assert (product.channels() == numpy.multiply(
        spectrum1.channels(),
        spectrum2.channels()[2])).all()
    assert ((spectrum2[2] * spectrum1).channels() == product.channels()).all()
Example #9
0
def test_inverse_fourier_transform_results():
    """Tests the inverse Fourier transform of a spectrum with trivial examples."""
    # an empty spectrum
    assert sumpf.Spectrum().inverse_fourier_transform().shape() == (1, 0)
    # a group delay of 1s
    spectrum = sumpf.Spectrum(channels=numpy.array([
        (1.0, numpy.exp(-1j * math.pi), numpy.exp(-2j * math.pi)),
        (2.0, 2.0, 2.0)
    ]),
                              resolution=0.5)
    signal = spectrum.inverse_fourier_transform()
    assert signal.duration() == 2.0
    assert signal.sampling_rate() == 2.0
    assert signal.channels()[0] == pytest.approx((0.0, 0.0, 1.0, 0.0))
    assert (signal[1].channels() == [(2.0, 0.0, 0.0, 0.0)]).all()
Example #10
0
def test_constructor_parameters(parameters):
    """Tests if the constructor parameters are interpreted correctly and have the expected default values."""
    # test an empty Spectrum
    spectrum = sumpf.Spectrum()
    assert (spectrum.channels() == [[]]).all()
    assert spectrum.resolution() == 1.0
    assert spectrum.labels() == ("", )
    # test a Spectrum with all constructor parameters set
    channels = parameters["channels"]
    resolution = parameters["resolution"]
    labels = tuple(parameters["labels"][0:len(channels)]) + ("", ) * (
        len(channels) - len(parameters["labels"]))
    spectrum = sumpf.Spectrum(**parameters)
    assert (spectrum.channels() == channels).all()
    assert spectrum.resolution() == resolution
    assert spectrum.labels() == labels
Example #11
0
def cut_spectrum(input_spectrum, desired_frequency_range):
    """
    Cut the input spectrum to the desired frequency range. It appends zero outside the desired frequency range.

    :param input_spectrum: the input spectrum to which zero has to be appended outside the desired frequency range
    :param desired_frequency_range: the desired freqency range
    :return: the modified spectrum
    """
    channels_ip = []
    for ip in input_spectrum.GetChannels():
        channel_ip = []
        channel_op = []
        for n, i in enumerate(ip):
            if n > desired_frequency_range[0] / input_spectrum.GetResolution() and n < desired_frequency_range[1] / \
                    input_spectrum.GetResolution():
                channel_ip.append(i)
            else:
                channel_ip.append(0.0)
                channel_op.append(0.0)
        channels_ip.append(tuple(channel_ip))
    input_spectrum_modified = sumpf.Spectrum(
        channels=tuple(channels_ip),
        resolution=input_spectrum.GetResolution(),
        labels=input_spectrum.GetLabels())
    return input_spectrum_modified
Example #12
0
def smooth_filter_kernels(kernels=None, window_size=53, polynomial_order=3):
    """
    Smooth the spectrum of the filter kernels, to make it suitable for curve fitting algorithm.

    :param kernels: the input filter kernels
    :type kernels: tuple
    :return: the smoothened output filter kernels
    :rtype: tuple
    """
    kernels_smooth = []
    for kernel in kernels:
        kernel_spec = sumpf.modules.FourierTransform(kernel).GetSpectrum()
        kernel_spec_channel = kernel_spec.GetChannels()[0]
        kernel_spec_channel_smooth = savitzky_golay(kernel_spec_channel,
                                                    window_size,
                                                    polynomial_order)
        kernel_spec_smooth = sumpf.Spectrum(
            channels=[
                kernel_spec_channel_smooth,
            ],
            resolution=kernel_spec.GetResolution(),
            labels=kernel_spec.GetLabels())
        kernel_smooth = sumpf.modules.InverseFourierTransform(
            kernel_spec_smooth).GetSignal()
        kernels_smooth.append(kernel_smooth)
    return kernels_smooth
Example #13
0
def linearweighting(input):
    """
    Compute the linearly weighted spectrum.

    :param input: the input signal or spectrum
    :type input: sumpf.Signal or sumpf.Spectrum
    :return: the exponentially weighted sum
    :rtype: tuple
    """
    if isinstance(input, (sumpf.Signal)):
        ip = sumpf.modules.FourierTransform(signal=input).GetSpectrum()
    else:
        ip = input
    dummy = 0.0001
    while True:
        dummy = dummy + 0.0001
        low = 1 * (dummy**1)
        high = 1 * (dummy**(len(input) - 1))
        if low > 1 and high > 10000:
            break
    energy_allchannels = []
    for c in ip.GetChannels():
        energy_singlechannel = []
        c = reversed(c)
        for i, s in enumerate(c):
            energy_singlechannel.append((abs(s)) * (1 * (dummy**i)))
        energy_singlechannel = numpy.asarray(energy_singlechannel)[::-1]
        energy_allchannels.append(energy_singlechannel)
    energy_allchannels = sumpf.Spectrum(channels=tuple(energy_allchannels),
                                        resolution=ip.GetResolution(),
                                        labels=ip.GetLabels())
    return energy_allchannels
Example #14
0
def test_add():
    """Tests the overload of the ``+`` operator."""
    spectrum1 = sumpf.Spectrum(channels=numpy.array([(1.0, 0.0, 0.0),
                                                     (0.0, 2.0, 0.0)]),
                               labels=("one1", "two1"))
    spectrum2 = sumpf.Spectrum(channels=numpy.array([(1.0, 0.0, 0.0),
                                                     (0.0, 2.0, 0.0),
                                                     (0.0, 0.0, 3.0)]),
                               labels=("one2", "two2", "three2"))
    # test adding a number
    sum_ = spectrum1 + 3.7
    assert sum_.resolution() == spectrum1.resolution()
    assert sum_.labels() == spectrum1.labels()
    assert (sum_.channels() == numpy.add(spectrum1.channels(), 3.7)).all()
    assert ((3.7 + spectrum1).channels() == sum_.channels()).all()
    # test adding an array
    sum_ = spectrum1 + (1.9, -3.8, 5.5)
    assert sum_.resolution() == spectrum1.resolution()
    assert sum_.labels() == spectrum1.labels()
    assert (sum_.channels() == numpy.add(spectrum1.channels(),
                                         (1.9, -3.8, 5.5))).all()
    assert (((1.9, -3.8, 5.5) + spectrum1).channels() == sum_.channels()).all()
    # test adding a Spectrum with the same number of channels
    sum_ = spectrum1 + spectrum1
    assert sum_.resolution() == spectrum1.resolution()
    assert sum_.labels() == ("Sum", ) * 2
    assert (sum_.channels() == numpy.multiply(spectrum1.channels(), 2)).all()
    # test adding a Spectrum with a higher number of channels
    sum_ = spectrum1 + spectrum2
    assert sum_.resolution() == spectrum1.resolution()
    assert sum_.labels() == ("Sum", ) * 3
    assert (sum_.channels() == [
        numpy.add(spectrum1.channels()[0],
                  spectrum2.channels()[0]),
        numpy.add(spectrum1.channels()[1],
                  spectrum2.channels()[1]),
        spectrum2.channels()[2]
    ]).all()
    assert ((spectrum2 + spectrum1).channels() == sum_.channels()).all()
    # test adding a single channel Spectrum
    sum_ = spectrum1 + spectrum2[2]
    assert sum_.resolution() == spectrum1.resolution()
    assert sum_.labels() == ("Sum", ) * 2
    assert (sum_.channels() == numpy.add(spectrum1.channels(),
                                         spectrum2.channels()[2])).all()
    assert ((spectrum2[2] + spectrum1).channels() == sum_.channels()).all()
Example #15
0
def _compare_merge_first_spectrum_first(spectrums, merged):
    """tests if the merged spectrum's channels are ordered like the input spectrums"""
    c = 0
    resolution = spectrums[0].resolution()
    for s in spectrums:
        spectrum = sumpf.Spectrum(channels=s.channels(),
                                  resolution=resolution,    # take the resolution from the first spectrum
                                  labels=s.labels())        # the merged spectrum has a label for each channel, which could be empty
        stop = s.length()
        assert merged[c:c + len(spectrum), 0:stop] == spectrum
        c += len(spectrum)
    assert c == len(merged)
Example #16
0
def exponential_weighting(input_spectrum, base=2):
    if isinstance(input_spectrum, (sumpf.Signal)):
        input_spectrum = sumpf.modules.FourierTransform(
            signal=input_spectrum).GetSpectrum()
    else:
        input_spectrum = input_spectrum
    channels_ip = []
    for ip in input_spectrum.GetChannels():
        channel_ip = []
        for n, i in enumerate(ip):
            exp = i * (base)**(1.0 / (n + 1) * input_spectrum.GetResolution())
            channel_ip.append(exp)
        channels_ip.append(tuple(channel_ip))
    output = sumpf.Spectrum(channels=tuple(channels_ip),
                            resolution=input_spectrum.GetResolution(),
                            labels=input_spectrum.GetLabels())
    return output
Example #17
0
    def spectrum(self, resolution=48000.0 / 4096, length=2049):
        """Samples the transfer functions with the given resolution and given number
        of samples and returns the result as a spectrum.

        :param resolution: the frequency resolution of the resulting spectrum
        :param length: the number of samples per channel of the resulting spectrum
        :returns: a :class:`~sumpf.Spectrum` instance
        """
        frequencies = numpy.linspace(0.0, (length - 1) * resolution, length)
        s = S(frequencies)
        channels = sumpf_internal.allocate_array(shape=(len(
            self.__transfer_functions), length),
                                                 dtype=numpy.complex128)
        for tf, c in zip(self.__transfer_functions, channels):
            tf(s, out=c)
        return sumpf.Spectrum(channels=channels,
                              resolution=resolution,
                              labels=self.__labels)
Example #18
0
def _compare_merge_spectrums_first_channel_first(spectrums, merged):
    """test if the merged spectrum's channels are ordered in a way that the first
    channels of all input spectrum come first"""
    resolution = spectrums[0].resolution()
    spectrums = list(spectrums)
    c = 0
    d = 0
    while spectrums:
        to_remove = []
        for s in spectrums:
            if d < len(s):
                spectrum = sumpf.Spectrum(channels=s[d].channels(),
                                          resolution=resolution,    # take the resolution from the first spectrum
                                          labels=s[d].labels())     # the merged spectrum has a label for each channel, which could be empty
                stop = spectrum.length()
                assert merged[c, 0:stop] == spectrum
                c += 1
            else:
                to_remove.append(s)
        for s in to_remove:
            spectrums.remove(s)
        d += 1
    assert c == len(merged)
Example #19
0
def test_getitem_samples():
    """Tests the slicing of a spectrum with the ``[]`` overload"""
    spectrum = sumpf.Spectrum(channels=numpy.array([(1.0, 0.0, 0.0),
                                                    (0.0, 2.0, 0.0),
                                                    (0.0, 0.0, 3.0)]),
                              labels=("one", "two", "three"))
    # integer
    sliced = spectrum[1, 1]
    assert (sliced.channels() == [(2.0, )]).all()
    assert sliced.labels() == ("two", )
    # float
    assert spectrum[:, 0.5] == spectrum[:, 1]
    # integer slice
    sliced = spectrum[1:3, 1:3]
    assert (sliced.channels() == [(2.0, 0.0), (0.0, 3.0)]).all()
    assert sliced.labels() == ("two", "three")
    # integer slice with step
    sliced = spectrum[:, 0:3:2]
    assert (sliced.channels() == [(1.0, 0.0), (0.0, 0.0), (0.0, 3.0)]).all()
    assert sliced.labels() == ("one", "two", "three")
    # incomplete slices
    assert spectrum[:, :] == spectrum
    assert spectrum[:2, :1] == spectrum[0:2, 0]
    assert spectrum[1:, 2:] == spectrum[1:3, 2]
    assert spectrum[0::2, 0::2] == spectrum[0:3:2, 0:3:2]
    # float slices
    assert spectrum[0.33:1.0, 0.0:0.66] == spectrum[1:3, 0:2]
    assert spectrum[0:3:0.66, 0.0:1.0:0.66] == spectrum[0:3:2, 0:3:2]
    # negative slices
    assert spectrum[0:-2, 0:-1] == spectrum[0, 0:2]
    assert spectrum[-2:, -1:] == spectrum[1:3, 2]
    sliced = spectrum[::-1, ::-1]
    assert (sliced.channels() == [(3.0, 0.0, 0.0), (0.0, 2.0, 0.0),
                                  (0.0, 0.0, 1.0)]).all()
    assert sliced.labels() == ("three", "two", "one")
    assert spectrum[-0.99:-0.01:-0.66, -0.99:-0.01:-0.66] == spectrum[0:3:-2,
                                                                      0:3:-2]
Example #20
0
    def output(self):
        """Computes the merged data set and returns it.

        :returns: a data set, that contains all channels of the added data sets.
        """
        if not self.__data:
            raise RuntimeError("Nothing to merge")
        if len(self.__data) == 1:
            return next(iter(self.__data.values())
                        )  # simply return the first and only data set
        else:
            first = next(iter(self.__data.values()))
            number_of_channels = sum(len(s) for s in self.__data.values())
            labels = [""] * number_of_channels
            if isinstance(first, sumpf.Signal):
                merged_offset = min(s.offset() for s in self.__data.values())
                length = max(s.offset() + s.length()
                             for s in self.__data.values()) - merged_offset
                channels = sumpf_internal.allocate_array(
                    shape=(number_of_channels, length))
                for index, channel, offset, label in zip(
                        self.__indices(),
                    (c for d in self.__data.values() for c in d.channels()),
                    (d.offset() for d in self.__data.values()
                     for l in d.channels()),  # pylint: disable=line-too-long
                    (l for d in self.__data.values() for l in d.labels())):
                    start = offset - merged_offset
                    stop = start + len(channel)
                    channels[index, 0:start] = 0.0
                    channels[index, start:stop] = channel
                    channels[index, stop:] = 0.0
                    labels[index] = label
                return sumpf.Signal(channels=channels,
                                    sampling_rate=first.sampling_rate(),
                                    offset=merged_offset,
                                    labels=labels)
            elif isinstance(first, sumpf.Spectrum):
                length = max(s.length() for s in self.__data.values())
                channels = sumpf_internal.allocate_array(
                    shape=(number_of_channels, length), dtype=numpy.complex128)
                for index, channel, label in zip(
                        self.__indices(), (c for d in self.__data.values()
                                           for c in d.channels()),
                    (l for d in self.__data.values() for l in d.labels())):
                    channels[index, 0:len(channel)] = channel
                    channels[index, len(channel):] = 0.0
                    labels[index] = label
                return sumpf.Spectrum(channels=channels,
                                      resolution=first.resolution(),
                                      labels=labels)
            elif isinstance(first, sumpf.Spectrogram):
                merged_offset = min(s.offset() for s in self.__data.values())
                length = max(s.offset() + s.length()
                             for s in self.__data.values()) - merged_offset
                number_of_frequencies = max(s.number_of_frequencies()
                                            for s in self.__data.values())
                channels = sumpf_internal.allocate_array(
                    shape=(number_of_channels, number_of_frequencies, length),
                    dtype=numpy.complex128)
                channels[:] = 0.0
                for index, channel, offset, label in zip(
                        self.__indices(),
                    (c for d in self.__data.values() for c in d.channels()),
                    (d.offset() for d in self.__data.values()
                     for l in d.channels()),  # pylint: disable=line-too-long
                    (l for d in self.__data.values() for l in d.labels())):
                    channel_frequencies, channel_length = channel.shape
                    start = offset - merged_offset
                    stop = start + channel_length
                    channels[index, 0:channel_frequencies,
                             start:stop] = channel
                    labels[index] = label
                return sumpf.Spectrogram(channels=channels,
                                         resolution=first.resolution(),
                                         sampling_rate=first.sampling_rate(),
                                         offset=merged_offset,
                                         labels=labels)
            elif isinstance(first, sumpf.Filter):
                transfer_functions = [None] * number_of_channels
                for index, transfer_function, label in zip(
                        self.__indices(),
                    (tf for d in self.__data.values()
                     for tf in d.transfer_functions()),  # pylint: disable=line-too-long
                    (l for d in self.__data.values() for l in d.labels())):
                    transfer_functions[index] = transfer_function
                    labels[index] = label
                return sumpf.Filter(transfer_functions=transfer_functions,
                                    labels=labels)
            else:
                raise ValueError(
                    f"Cannot merge data sets of type {type(first)}")
Example #21
0
def test_absolute(spectrum):
    """Tests if computing the magnitude of a spectrum yields the expected result."""
    assert abs(spectrum) == sumpf.Spectrum(channels=numpy.absolute(
        spectrum.channels()),
                                           resolution=spectrum.resolution(),
                                           labels=spectrum.labels())
Example #22
0
def from_dict(channels, dictionary):
    """Deserializes a spectrum from a dictionary."""
    return sumpf.Spectrum(channels=channels,
                          resolution=dictionary.get("resolution", 1.0),
                          labels=dictionary.get("labels", ()))
Example #23
0
def test_negative(spectrum):
    """Tests if inverting the phase of a spectrum yields the expected result."""
    assert -spectrum == sumpf.Spectrum(channels=numpy.subtract(
        0.0, spectrum.channels()),
                                       resolution=spectrum.resolution(),
                                       labels=spectrum.labels())