Skip to main content

Object-oriented RF signal simulation with chainable methods and encapsulated state

Project description

GeoSol Research Logo

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gri_sigsim-0.2.2.tar.gz (67.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gri_sigsim-0.2.2-py3-none-any.whl (27.0 kB view details)

Uploaded Python 3

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

Hashes for gri_sigsim-0.2.2.tar.gz
Algorithm Hash digest
SHA256 512be5d6bb595306d67db6c66548661ab70ef02209872be14ee06c9a0bc0608f
MD5 3f2778e0395d2ec92b3a450071bca56f
BLAKE2b-256 c7fada1e622467df319a318afd7ce42f7fad4ba0ac39ebeadf6f3da720bc7534

See more details on using hashes here.

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

Hashes for gri_sigsim-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e95f968916683e34b2b3e6be0b6a2c137f209563316ed7f18ca1d2c68b1a449b
MD5 e9141cccdc0572f2abf31a70d57163f0
BLAKE2b-256 f73f42c87671e0459c313d85b545489c2ac3107257b76eea9e6b051ff6b19ed3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page