Object-oriented RF signal simulation with chainable methods and encapsulated state
Project description
SigSim (Signal Simulation)
Object-oriented RF signal simulation library that wraps gri-signal's functional API. Provides chainable methods, encapsulated state, and self-contained result objects for intuitive simulation workflows. Requires Python 3.12+.
gri-sigsim is to gri-signal what gri-pos is to gri-utils: an OOP layer over functional primitives. The functional API in gri-signal provides composable pure functions for filtering, correlation, and spectral analysis. gri-sigsim wraps these into stateful classes with method chaining, making multi-step simulation workflows more concise and readable.
Key Features
- Signal: Core container with chainable filtering, spectral analysis, and correlation
- Waveforms: PulsedWaveform (PRI), PrnWaveform (noise-like), ToneWaveform
- Channel: Composable propagation model (delay, Doppler, attenuation, multipath, AWGN)
- Receiver: Receive chain with noise figure, ADC quantization, and IQ imbalance
- Results: Self-contained PSD and Correlation objects with query methods
- Estimators: ToaEstimator with PEAK, QINT, THRESHOLD, and CFAR methods
Installation
pip install gri-sigsim
Quick Start
from gri_sigsim import Signal, PulsedWaveform, Channel, Receiver
# Generate a pulsed waveform
waveform = PulsedWaveform(
freq_hz=10e3,
pri_interval_s=1e-3,
pulse_width_s=100e-6,
)
transmitted = waveform.generate(duration_s=0.01, sample_rate_hz=1e6)
# Define channel with builder pattern
channel = (
Channel()
.with_delay(3.33e-6)
.with_doppler(150.0)
.with_attenuation(80.0)
.with_awgn(snr_db=15.0)
)
# Define receiver with impairments
receiver = Receiver(
sample_rate_hz=1e6,
bandwidth_hz=100e3,
noise_figure_db=3.0,
adc_bits=12,
iq_gain_imbalance_db=0.5,
)
# Receive signal through channel
received = receiver.receive(transmitted, channel)
# Spectral analysis
psd = received.psd()
peak_power, peak_freq = psd.peak()
# TOA estimation via correlation
ref = waveform.generate(duration_s=100e-6, sample_rate_hz=1e6)
toa = received.correlate(ref).estimate_toa()
Signal Processing
from gri_sigsim import Signal
from gri_sigsim._enums import FilterMethod
# Create signal from numpy array
sig = Signal(data, sample_rate_hz=1e6, center_freq_hz=100e6)
# Chainable filtering (butter, fir, or fft methods)
filtered = (
sig.lowpass(cutoff_hz=10e3, method=FilterMethod.BUTTER)
.highpass(cutoff_hz=1e3)
.bandpass(low_hz=2e3, high_hz=8e3)
)
# Spectral analysis
psd = sig.psd()
snr = sig.estimate_snr()
bandwidth = sig.effective_bandwidth()
# Correlation
corr = sig.correlate(reference_sig)
delay_s = corr.peak_delay_s
refined_delay = corr.peak_delay_refined_s() # Sub-sample precision
Waveform Generation
from gri_sigsim import PulsedWaveform, PrnWaveform, ToneWaveform
# Pulsed waveform (PRI-based)
pulsed = PulsedWaveform(
freq_hz=10e3,
pri_interval_s=1e-3,
pulse_width_s=100e-6,
)
sig = pulsed.generate(duration_s=0.1, sample_rate_hz=1e6)
# PRN (noise-like) waveform
prn = PrnWaveform(hz_low=1e3, hz_high=10e3)
sig = prn.generate(duration_s=0.1, sample_rate_hz=100e3, seed=42)
# Tone waveform
tone = ToneWaveform(freq_hz=1000.0, amplitude=1.0, phase_rad=0.0)
sig = tone.generate(duration_s=0.1, sample_rate_hz=10e3)
Channel Modeling
from gri_sigsim import Channel
# Builder pattern for channel composition
channel = (
Channel()
.with_delay(1e-3) # Propagation delay
.with_doppler(100.0) # Frequency shift
.with_attenuation(80.0) # Path loss in dB
.with_awgn(snr_db=20.0) # Additive noise
.with_multipath( # Multipath reflections
delays_s=[0, 1e-6, 2e-6],
amplitudes=[1.0, 0.5, 0.25],
)
)
# Factory method for common case
channel = Channel.free_space(
delay_s=1e-3,
doppler_hz=100.0,
attenuation_db=80.0,
)
# Apply to signal
received = channel.apply(transmitted)
TOA Estimation
from gri_sigsim.estimators import ToaEstimator, ToaMethod
# Simple TOA from correlation
corr = signal.correlate(reference)
toa = corr.estimate_toa()
# Advanced estimation with configurable method
estimator = ToaEstimator(
method=ToaMethod.CFAR, # or PEAK, QINT, THRESHOLD
guard_cells=4,
ref_cells=16,
)
toa = estimator.estimate_from_signals(signal, reference)
Future Integration with gri-geosim
gri-sigsim is designed for future integration with gri-geosim for geometry-driven simulations:
# Future implementation in gri-geosim
class RfScenario(Scenario):
def simulate_rf(self, waveform, receiver, time) -> list[Signal]:
for platform, emitter in self._pairs():
geometry = self._compute_geometry(platform, emitter, time)
channel = Channel.free_space(
delay_s=geometry.range_m / C,
doppler_hz=geometry.doppler_hz,
attenuation_db=geometry.path_loss_db,
)
sig = waveform.generate(...)
received = receiver.receive(sig, channel)
results.append(received)
return results
Dependencies
This is a Layer 3 application-level package in the GRI FOSS ecosystem:
Direct dependencies:
- gri-signal: Functional signal processing (filters, FFT, correlation)
- numpy, scipy: Numerical computing
Future integrations:
- gri-geosim: Platform geometry for realistic channel modeling
- gri-tropo: Tropospheric delay effects
- gri-iono: Ionospheric delay effects
Other Projects
Current list of other GRI FOSS Projects we are building and maintaining.
License
MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gri_sigsim-0.2.2.tar.gz.
File metadata
- Download URL: gri_sigsim-0.2.2.tar.gz
- Upload date:
- Size: 67.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
512be5d6bb595306d67db6c66548661ab70ef02209872be14ee06c9a0bc0608f
|
|
| MD5 |
3f2778e0395d2ec92b3a450071bca56f
|
|
| BLAKE2b-256 |
c7fada1e622467df319a318afd7ce42f7fad4ba0ac39ebeadf6f3da720bc7534
|
File details
Details for the file gri_sigsim-0.2.2-py3-none-any.whl.
File metadata
- Download URL: gri_sigsim-0.2.2-py3-none-any.whl
- Upload date:
- Size: 27.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e95f968916683e34b2b3e6be0b6a2c137f209563316ed7f18ca1d2c68b1a449b
|
|
| MD5 |
e9141cccdc0572f2abf31a70d57163f0
|
|
| BLAKE2b-256 |
f73f42c87671e0459c313d85b545489c2ac3107257b76eea9e6b051ff6b19ed3
|