示例#1
0
    def test_pilot_subsymbols_validation(self) -> None:
        """Pilot subsymbol setter should raise ValueErrors on invalid arguments"""

        with self.assertRaises(ValueError):
            self.pilot_section.pilot_elements = Symbols(np.array([[1], [1]]))

        with self.assertRaises(ValueError):
            self.pilot_section.pilot_elements = Symbols()
示例#2
0
    def test_synchronize(self) -> None:
        """Test the proper estimation of delays during Schmidl-Cox synchronization"""

        for d, n in product(self.delays_in_samples, self.num_frames):

            symbols = np.exp(
                2j * pi * self.rng.uniform(0, 1,
                                           (n, self.frame.symbols_per_frame)))
            frames = [
                np.exp(2j * pi * self.rng.uniform(0, 1, (self.num_streams, 1)))
                @ self.frame.modulate(Symbols(symbols[f, :])).samples
                for f in range(n)
            ]

            signal = np.empty((self.num_streams, 0), dtype=complex)
            for frame in frames:

                signal = np.concatenate(
                    (signal, np.zeros(
                        (self.num_streams, d), dtype=complex), frame),
                    axis=1)

            channel_state = ChannelStateInformation.Ideal(
                len(signal), self.num_streams)

            synchronization = self.synchronization.synchronize(
                signal, channel_state)

            self.assertEqual(n, len(synchronization))
            for frame, (synchronized_frame, _) in zip(frames, synchronization):
                assert_array_equal(frame, synchronized_frame)
    def test_synchronization(self) -> None:
        """Synchronization should properly partition signal samples into frame sections."""

        # Generate frame signal models
        num_samples = 2 * self.max_offset + self.num_frames * self.waveform.samples_in_frame
        csi = ChannelStateInformation.Ideal(num_samples)
        samples = np.zeros((1, num_samples), dtype=complex)
        expected_frames = []
        pilot_indices = self.rng.integers(
            0, self.max_offset, self.num_frames) + np.arange(
                self.num_frames) * self.waveform.samples_in_frame

        for p in pilot_indices:

            data_symbols = Symbols(
                self.rng.integers(0, self.waveform.modulation_order,
                                  self.waveform.symbols_per_frame))
            signal_samples = self.waveform.modulate(data_symbols).samples

            samples[:, p:p + self.waveform.samples_in_frame] += signal_samples
            expected_frames.append(samples[:, p:p +
                                           self.waveform.samples_in_frame])

        synchronized_frames = self.synchronization.synchronize(samples, csi)

        if len(synchronized_frames) != len(expected_frames):
            self.fail()

        for expected_frame, (synchronized_frame,
                             _) in zip(expected_frames, synchronized_frames):
            assert_array_equal(expected_frame, synchronized_frame)
示例#4
0
    def test_samples_in_frame(self) -> None:
        """Samples in frame property should compute the correct sample count."""

        symbols = Symbols(
            np.exp(2j *
                   self.rng.uniform(0, pi, self.generator.symbols_per_frame)))
        signal = self.generator.modulate(symbols)

        self.assertEqual(signal.num_samples, self.generator.samples_in_frame)
示例#5
0
    def test_pilot_subsymbols_setget(self) -> None:
        """Pilot subsymbol getter should return setter argument"""

        self.pilot_section.pilot_elements = None
        self.assertIs(None, self.pilot_section.pilot_elements)

        expected_subsymbols = Symbols(np.array([-1., 1.]))
        self.pilot_section.pilot_elements = expected_subsymbols
        self.assertIs(expected_subsymbols, self.pilot_section.pilot_elements)
示例#6
0
    def setUp(self) -> None:

        self.rng = default_rng(42)
        self.subsymbols = Symbols(np.array([1., -1., 1.j, -1.j],
                                           dtype=complex))
        self.frame = WaveformGeneratorOfdm(oversampling_factor=4)

        self.pilot_section = PilotSection(pilot_elements=self.subsymbols,
                                          frame=self.frame)
示例#7
0
    def test_pilot(self) -> None:
        """Pilot samples should be the inverse Fourier transform of subsymbols"""

        expected_pilot_symbols = np.exp(
            2j * pi * self.rng.uniform(0, 1, self.frame.num_subcarriers))
        self.pilot_section.pilot_elements = Symbols(expected_pilot_symbols)

        pilot = self.pilot_section._pilot()
        pilot_symbols = fft(pilot, norm='ortho')[:self.frame.num_subcarriers]
        assert_array_almost_equal(expected_pilot_symbols, pilot_symbols)
示例#8
0
    def test_symbol_samples_in_frame(self) -> None:
        """Symbol samples in frame property should compute the correct sample count."""

        self.generator.tx_filter = ShapingFilter(ShapingFilter.FilterType.NONE,
                                                 self.oversampling_factor)
        symbols = Symbols(
            np.exp(2j *
                   self.rng.uniform(0, pi, self.generator.symbols_per_frame)))
        signal = self.generator.modulate(symbols)

        self.assertEqual(signal.num_samples,
                         self.generator.symbol_samples_in_frame)
示例#9
0
    def test_configured_pilot_sequence(self) -> None:
        """Specified subsymbols should result in the generation of a valid pilot sequence"""

        self.pilot_section.pilot_elements = Symbols(
            np.array([1., -1., 1.j, -1.j], dtype=complex))
        pilot_sequence = self.pilot_section._pilot_sequence()

        self.assertEqual(1, pilot_sequence.num_streams)
        self.assertEqual(self.frame.num_subcarriers,
                         pilot_sequence.num_symbols)
        assert_array_equal(self.pilot_section.pilot_elements.raw,
                           pilot_sequence.raw[:, :4])
示例#10
0
    def test_modulate(self) -> None:
        """Modulation should return a valid pilot section"""

        expected_pilot_symbols = np.exp(
            2j * pi * self.rng.uniform(0, 1, self.frame.num_subcarriers))
        self.pilot_section.pilot_elements = Symbols(expected_pilot_symbols)

        pilot = self.pilot_section.modulate()
        pilot_symbols = fft(pilot, norm='ortho')[:self.frame.num_subcarriers]
        assert_array_almost_equal(expected_pilot_symbols, pilot_symbols)

        cached_pilot = self.pilot_section.modulate()
        assert_array_equal(pilot, cached_pilot)
示例#11
0
    def test_modulate_demodulate(self) -> None:
        """Modulating and subsequently de-modulating a symbol stream should yield identical symbols."""

        expected_symbols = Symbols(
            np.exp(2j *
                   self.rng.uniform(0, pi, self.generator.symbols_per_frame)))
        # * np.arange(1, 1 + self.rng.symbols_per_frame))

        baseband_signal = self.generator.modulate(expected_symbols)
        channel_state = ChannelStateInformation.Ideal(
            num_samples=baseband_signal.num_samples)
        symbols, _, _ = self.generator.demodulate(
            baseband_signal.samples[0, :], channel_state)

        assert_array_almost_equal(expected_symbols.raw, symbols.raw, decimal=1)
示例#12
0
    def test_modulate_demodulate_no_filter(self) -> None:
        """Modulating and subsequently de-modulating a symbol stream should yield identical symbols."""

        self.generator.rx_filter = ShapingFilter(ShapingFilter.FilterType.NONE,
                                                 self.oversampling_factor)
        self.generator.tx_filter = ShapingFilter(ShapingFilter.FilterType.NONE,
                                                 self.oversampling_factor)

        expected_symbols = Symbols(
            np.exp(2j *
                   self.rng.uniform(0, pi, self.generator.symbols_per_frame)) *
            np.arange(1, 1 + self.generator.symbols_per_frame))

        baseband_signal = self.generator.modulate(expected_symbols)
        channel_state = ChannelStateInformation.Ideal(
            num_samples=baseband_signal.num_samples)
        symbols, _, _ = self.generator.demodulate(
            baseband_signal.samples[0, :], channel_state)

        assert_array_almost_equal(expected_symbols.raw, symbols.raw)