59 lines
2.5 KiB
Python
59 lines
2.5 KiB
Python
import numpy as np
|
|
|
|
from galileo_rx.signal_profiles import galileo_e1_profile
|
|
from galileo_rx.signals.boc import boc_subcarrier, sample_primary_code
|
|
from galileo_rx.signals.code_provider import SyntheticCodeProvider
|
|
from galileo_rx.signals.signal_generator import ChannelModelConfig, SatelliteSignalConfig, SyntheticSignalGenerator
|
|
|
|
|
|
def test_code_sampling_wrap_and_noninteger_rate() -> None:
|
|
code = np.array([1, -1, 1, 1], dtype=np.int8)
|
|
sampled, phase = sample_primary_code(code, 11, 2.5, 1.0, 3.5)
|
|
assert sampled.shape == (11,)
|
|
assert 0 <= phase < 4
|
|
assert set(sampled) == {-1.0, 1.0}
|
|
|
|
|
|
def test_boc_phase_continuity_between_blocks() -> None:
|
|
whole, _ = boc_subcarrier(31, 7.3e6, 1.023e6, 0.17)
|
|
first, phase = boc_subcarrier(13, 7.3e6, 1.023e6, 0.17)
|
|
second, _ = boc_subcarrier(18, 7.3e6, 1.023e6, phase)
|
|
np.testing.assert_array_equal(whole, np.concatenate([first, second]))
|
|
|
|
|
|
def test_synthetic_provider_is_deterministic_and_component_specific() -> None:
|
|
profile = galileo_e1_profile()
|
|
provider = SyntheticCodeProvider()
|
|
a = provider.primary_code(profile, "E1C", 1)
|
|
np.testing.assert_array_equal(a, provider.primary_code(profile, "E1C", 1))
|
|
assert not np.array_equal(a, provider.primary_code(profile, "E1B", 1))
|
|
|
|
|
|
def test_generator_streaming_matches_single_block_without_noise() -> None:
|
|
profile = galileo_e1_profile()
|
|
provider = SyntheticCodeProvider()
|
|
satellite = SatelliteSignalConfig(prn=3, doppler_hz=1234.0, code_delay_chips=17.25)
|
|
channel = ChannelModelConfig(add_awgn=False)
|
|
whole_generator = SyntheticSignalGenerator(profile, provider, 4.5e6, satellites=[satellite], channel=channel)
|
|
block_generator = SyntheticSignalGenerator(profile, provider, 4.5e6, satellites=[satellite], channel=channel)
|
|
whole, _ = whole_generator.generate(1001)
|
|
a, _ = block_generator.generate(317)
|
|
b, _ = block_generator.generate(684)
|
|
np.testing.assert_allclose(whole, np.concatenate([a, b]), atol=2e-6)
|
|
|
|
|
|
def test_real_if_and_truth_metadata() -> None:
|
|
profile = galileo_e1_profile()
|
|
generator = SyntheticSignalGenerator(
|
|
profile,
|
|
SyntheticCodeProvider(),
|
|
8.0e6,
|
|
2.0e6,
|
|
True,
|
|
[SatelliteSignalConfig(prn=7, component="E1B", code_delay_chips=2.5)],
|
|
ChannelModelConfig(add_awgn=False),
|
|
)
|
|
samples, truth = generator.generate(80)
|
|
assert samples.dtype == np.float64 and not np.iscomplexobj(samples)
|
|
assert truth.satellites[0].initial_code_delay_samples == 2.5 * 8.0e6 / 1.023e6
|