Signal processing for filtering, spectral analysis, correlation, and beamforming
Project description
Signal Processing Library
Signal processing utilities for signal generation, channel simulation, modulation, sampling, filtering, spectral analysis, correlation, and beamforming. Requires Python 3.12+.
This library provides functional signal processing tools designed to be composable and efficient. All functions support both 1D and multi-channel (row-major: channels x samples) signals where applicable.
Mathematical Background
Filter design tradeoffs. Three filter implementations are provided for each filter type, each with different characteristics:
- Butterworth (IIR): Maximally flat passband response. Uses zero-phase filtering (
sosfiltfilt) for zero phase distortion. Lowest order for a given transition width, but infinite impulse response means feedback. - FIR: Linear phase, no feedback (always stable). Hamming window design. Higher order than IIR for equivalent stopband attenuation, but predictable group delay.
- FFT-domain: Steepest possible cutoff (brick-wall in frequency). Applied via multiplication in the frequency domain with Hann smoothing at transitions. Best rejection but assumes periodic signals.
Power spectral density. PSD estimates the power distribution across frequency, computed via |FFT(x)|^2 / N and reported in dB.
Cross-correlation for delay estimation. The cross-correlation R_xy[k] = sum(x[n] * conj(y[n-k])) peaks at the lag corresponding to the time delay between signals. Quadratic interpolation (qint) refines the peak location to sub-sample precision.
References: Oppenheim & Willsky, "Signals and Systems"; Proakis & Manolakis, "Digital Signal Processing."
Installation
pip install gri-signal
For development:
git clone https://gitlab.com/geosol-foss/python/gri-signal.git
cd gri-signal
. .init_venv.sh
Signal Flow
The library is organized around the standard signal processing pipeline:
sources -> modulation -> channel -> sampling -> [filters/spectral/correlation/beamforming]
Sources
Signal generation functions for creating test signals and waveforms:
tone(fs, freq, ...): Complex sinusoidal tone with optional windowingprn(fs, ...): Pseudorandom noise (white or bandlimited)pri(fs, freq, pri_interval, pulse_width, ...): Pulsed signal with constant PRIzeros(fs, ...): Zero-filled signal arrayula_steering(aoa_deg, d, wavelength, n_elements): ULA steering vector for multi-channel signal generationgenerate_complex_signal(...): Multi-component test signal with tones, chirps, AM, PM
Channel
Propagation effects for simulating signal transmission:
delay(sig, delay_time, fs): Sub-sample precision time delay via FFTawgn(sig, snr_db): Additive white Gaussian noiseattenuation(sig, db): Amplitude scaling (gain or loss)doppler(sig, fs, f_shift, *, f_rate=0.0): Doppler frequency shift with optional linear driftmultipath(sig, fs, delays, amplitudes): Tapped delay line multipath channel
Modulation
Analog modulation schemes:
mod_am(sig, fs, f_carrier, *, mod_index=1.0): Amplitude modulationdemod_am(sig, fs, f_carrier): AM envelope detectionmod_fm(sig, fs, f_carrier, *, freq_deviation): Frequency modulationdemod_fm(sig, fs, f_carrier, *, freq_deviation): FM frequency discriminationmod_pm(sig, fs, f_carrier, *, phase_deviation): Phase modulationdemod_pm(sig, fs, f_carrier, *, phase_deviation): PM phase extraction
Digital modulation schemes (baseband, rectangular pulses):
mod_bpsk(bits, fs, symbol_rate): Binary Phase Shift Keying (1 bit/symbol)demod_bpsk(sig, fs, symbol_rate): BPSK hard decisionmod_qpsk(bits, fs, symbol_rate): Quadrature PSK (2 bits/symbol, Gray coded)demod_qpsk(sig, fs, symbol_rate): QPSK hard decisionmod_qam(bits, fs, symbol_rate, *, order=16): QAM (4/16/64/256, Gray coded)demod_qam(sig, fs, symbol_rate, *, order=16): QAM nearest-neighbor decision
IQ conversion:
passband_to_iq(sig, fs, f_center): Real passband to complex basebandiq_to_passband(sig, fs, f_center): Complex baseband to real passband
Sampling
Digitization and quantization:
adc(sig, n_bits): Simulate n-bit analog-to-digital converter
Filters
Lowpass Filters
Three implementations with different tradeoffs:
lowpass_butter: Butterworth IIR filter (scipy SOS, zero-phase via sosfiltfilt)lowpass_fir: FIR filter (Hamming window design, less phase ringing)lowpass_fft: FFT-domain filter (steepest cutoff, Hann smoothing)
Highpass Filters
highpass_butter: Butterworth highpasshighpass_fir: FIR highpasshighpass_fft: FFT-domain highpass
Bandpass Filters
bandpass_butter: Butterworth bandpassbandpass_fir: FIR bandpassbandpass_fft: FFT-domain bandpass
Notch (Bandstop) Filters
Attenuate a frequency band while passing all others (useful for interference rejection):
notch_butter: Butterworth notch/bandstopnotch_fir: FIR notch/bandstopnotch_fft: FFT-domain notch/bandstop
Analytic Bandpass Filters
Complex-valued bandpass filters returning analytic signals for single-sideband processing:
analytic_bandpass_butter: Butterworth-based analyticanalytic_bandpass_fir: FIR-based analyticanalytic_bandpass_fft: FFT-based analytic (handles negative/positive frequencies)
Spectral Analysis
PSD computation and frequency mapping:
get_psd(fs, sig): Power Spectral Density (dB-scaled, shifted frequency)get_max_power(fs, sig): Find dominant frequency and powerget_psd_power(f, psd, freq): Query PSD at specific frequencyget_freq_idx(f, fs, n): Frequency-to-bin mapping
Signal quality metrics:
estimate_snr(fs, sig, *, signal_bw, signal_center): Estimate SNR in dBestimate_noise_floor(fs, sig, *, percentile): Estimate noise floor in dBsinad(fs, sig, *, fundamental_freq): Signal-to-Noise and Distortion ratiothd(fs, sig, *, fundamental_freq, num_harmonics): Total Harmonic Distortion
Time-frequency analysis:
effective_bandwidth(fs, sig, *, method): RMS or threshold-based bandwidth in Hzeffective_duration(fs, sig, *, method): RMS or threshold-based duration in secondsestimate_tbp(fs, sig, *, method): Time-bandwidth product (dimensionless)
Correlation
xcorr(sig1, sig2, max_lags=None): MATLAB-style cross-correlation with lagsqint(x3p, y3p): Quadratic interpolation for sub-sample peak resolution
Beamforming
Single-section processing:
adaptive_beamform(sig): Adaptive beamforming with spatial covariance and eigenvalue decompositionsteering_angles(steering_vecs): Compute steering angles from eigenvectors
Batch processing (for multiple sections):
batch_adaptive_beamform(sig): Vectorized beamforming for all sectionsbatch_steering_angles(steering_vecs): Batch steering angle computation
Example Usage
from gri_signal import (
# Sources
tone, prn, pri, ula_steering,
# Channel
delay, awgn, attenuation, doppler, multipath,
# Sampling
adc,
# Filters
lowpass_butter, bandpass_fft,
# Analysis
get_psd, xcorr, qint,
)
# Generate a 100 Hz tone
fs = 10e3 # 10 kHz sample rate
sig = tone(fs, 100, duration=1.0)
# Add channel effects
sig = delay(sig, 0.001, fs) # 1ms delay
sig = doppler(sig, fs, 50.0) # 50 Hz Doppler shift
sig = awgn(sig, 20.0) # 20 dB SNR
sig = attenuation(sig, 6.0) # 6 dB loss
# Digitize
sig = adc(sig, 12) # 12-bit ADC
# Filter
filtered = lowpass_butter(fs, 200, sig) # 200 Hz cutoff
# Analyze
freqs, psd_db = get_psd(fs, filtered)
# Generate multi-channel array signal from a source at 30 degrees
wavelength = 3e8 / 915e6 # 915 MHz
steering = ula_steering(30.0, wavelength/2, wavelength, n_elements=4)
array_sig = steering[:, None] * sig # (4, n_samples)
Design Patterns
All functions follow consistent conventions:
- Functional: Pure functions, no classes (composable, testable)
- Signature:
func(fs, params, sig, *, optional_params)for processing functions - Input/Output: Signal arrays with same shape preserved
- Safety: Uses
sig.copy()where needed to avoid modifying original data - Multi-channel: Row-major format (channels as rows)
Dependencies
- numpy: Array operations
- scipy: Filter design and signal processing
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_signal-0.2.2.tar.gz.
File metadata
- Download URL: gri_signal-0.2.2.tar.gz
- Upload date:
- Size: 98.1 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 |
7acb071397d1775add212db2446cb0f6d3b2cc6bea78ebd1e46c57a9599d0292
|
|
| MD5 |
9ed4d3d26399c9a55cbfbcb2510f282d
|
|
| BLAKE2b-256 |
f79f919ae98837ade11a1448a1ceb690cb1bd836736fbf69573ddb552ecad6d5
|
File details
Details for the file gri_signal-0.2.2-py3-none-any.whl.
File metadata
- Download URL: gri_signal-0.2.2-py3-none-any.whl
- Upload date:
- Size: 73.2 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 |
1bf8922a3734cbf2fd24aacfeba40c713544186acca3f4a44eaa39835c67899e
|
|
| MD5 |
26a38386756b607dee3085fe79b0dcd4
|
|
| BLAKE2b-256 |
e7389e80a69280e3075910870496649b48624ed11331db8a91a24d30574a6693
|