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.3.tar.gz (70.3 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.3-py3-none-any.whl (27.0 kB view details)

Uploaded Python 3

File details

Details for the file gri_sigsim-0.2.3.tar.gz.

File metadata

  • Download URL: gri_sigsim-0.2.3.tar.gz
  • Upload date:
  • Size: 70.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","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.3.tar.gz
Algorithm Hash digest
SHA256 240b70dc003a7b20358c437eb45e622cf404211913e5321cdeda57964c1a9828
MD5 7bf2f93784431630012406a148da8c00
BLAKE2b-256 5125700c4200a08489476c3f539bc4f745216d61e6163952a2425873b587b34a

See more details on using hashes here.

File details

Details for the file gri_sigsim-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: gri_sigsim-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 7b9444ef13a8292c1045fefe8f8c331b56682f2d2e262acc066e06d308e7d7a3
MD5 86663ccb0dc2956395eb448712ed13b7
BLAKE2b-256 138afa67fd39c526243978671f19c9eff37b791a9f43f1df13267bb8b6267124

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