Correlation and Detection¶
What you're seeing¶
Left — Corr coherent integration. BPSK PN reference, lag=17,
SNR ≈ −6 dB. With a single frame the peak/mean ratio is ~4.0 —
barely distinguishable from noise. After 8 coherent dwells
(dwell=8) it rises to ~7.0, pulling the lag-17 peak cleanly above
the noise floor. Coherent integration improves SNR by 10 log₁₀(M)
dB.
Centre — Corr2D 2-D template match. An 8×8 complex template
shifted by (row=3, col=5) is recovered in a single FFT2 call. The
surface peak lands exactly on the injected shift.
Right — Detector.push() stream. Four signal dwells fire above
threshold=5; noise-only dwells stay below it. Each dot is one
dwell's test statistic: peak magnitude divided by local noise
estimate.
How it works¶
execute() accumulates frames and returns output only on the
dwell-th call; all other calls return None.
from doppler.spectral import Corr
import numpy as np
rng = np.random.default_rng(42)
N, LAG, DWELL = 64, 17, 8
SNR = 10 ** (-6 / 20) # −6 dB amplitude SNR
ref = rng.choice(
np.array([-1., 1.], dtype=np.float32), size=N
).astype(np.complex64)
def frame():
sig = np.roll(ref, LAG) * np.float32(SNR)
re = rng.standard_normal(N).astype(np.float32)
im = rng.standard_normal(N).astype(np.float32)
return (
sig
+ (re + 1j * im).astype(np.complex64) * np.float32(1 / np.sqrt(2))
)
with Corr(ref, dwell=DWELL) as c:
output = None
for _ in range(DWELL):
output = c.execute(frame())
peak_lag = int(np.argmax(np.abs(output)))
Detector wraps this loop and applies a CFAR threshold so you get
(lag, peak_mag, noise_est, test_stat) tuples directly from
det.push(block) without managing the dwell counter yourself.
See Corr / Detector API walkthrough
for Detector, Corr2D, and Detector2D in full detail.
