Source code for torchsig.signals.builders.test

"""Test Signal Builder and Modulator
"""
# TorchSig
from torchsig.signals.builder import SignalBuilder
from torchsig.datasets.dataset_metadata import DatasetMetadata
from torchsig.utils.dsp import (
    low_pass_iterative_design,
    convolve
)

# Third Party
import numpy as np


# Modulator
[docs] def shaped_noise_modulator ( bandwidth:float, sample_rate:float, num_samples:int, rng=np.random.default_rng() ) -> np.ndarray: """Implements a shaped noise modulator for testing and development. Args: bandwidth (float): the desired 3 dB bandwidth of the signal signal_power_db (float): the desired power of the signal in dB sample_rate (float): the sample rate (must align with CF and BW values) num_samples (float): number of samples of shaped noise to create rng (optional): Seedable random number generator for reproducibility. Returns: np.ndarray: Shaped noise IQ samples with proper bandwidth and center frequency. """ # compute noise ("message") at 0 dB gain noise = rng.normal(0,np.sqrt(1/2),num_samples) + 1j*rng.normal(0,np.sqrt(1/2),num_samples) # apply LPF to get down to bandwidth lpf = low_pass_iterative_design(cutoff=bandwidth/2, transition_bandwidth=bandwidth/16, sample_rate=sample_rate) shaped_noise_iq = convolve(signal=noise,taps=lpf) #return passband_signal return shaped_noise_iq
# Builder
[docs] class TestSignalBuilder(SignalBuilder): """Implements the test signal generator. Implements SignalBuilder() for a test waveform which is shaped noise. The waveform is useful in development but is not a practical signal. Attributes: dataset_metadata (DatasetMetadata): Parameters describing the dataset required for signal generation. supported_classes (List[str]): List of supported signal classes. Set to `["testsignal"]`. """ supported_classes = ["testsignal"]
[docs] def __init__(self, dataset_metadata: DatasetMetadata, class_name:str = 'testsignal', **kwargs): """Initializes Test Signal Builder. Sets `class_name= "testsignal"`. Args: dataset_metadata (DatasetMetadata): Dataset metadata. class_name (str, optional): Class name. """ super().__init__(dataset_metadata=dataset_metadata, class_name=class_name, **kwargs)
def _update_data(self) -> None: """Creates the IQ samples for the test signal waveform based on the signal metadata fields. """ # wideband params sample_rate = self.dataset_metadata.sample_rate # signal params bandwidth = self._signal.metadata.bandwidth num_iq_samples_signal = self._signal.metadata.duration_in_samples # modulate waveform at complex baseband self._signal.data = shaped_noise_modulator( bandwidth, sample_rate, num_iq_samples_signal, self.random_generator ) def _update_metadata(self) -> None: """Performs a signals-specific update of signal metadata. This does nothing because the signal does not need any fields to be updated. This `_update_metadata()` must be implemented but is not required to create or modify any data or fields for this particular signal case. """