diff --git a/v2/crates/wifi-densepose-signal/src/ruvsense/cir.rs b/v2/crates/wifi-densepose-signal/src/ruvsense/cir.rs index 38ae6035..79a3dc86 100644 --- a/v2/crates/wifi-densepose-signal/src/ruvsense/cir.rs +++ b/v2/crates/wifi-densepose-signal/src/ruvsense/cir.rs @@ -452,7 +452,11 @@ impl CirEstimator { let active_tap_count = x.iter().filter(|c| c.norm() >= cutoff).count(); // RMS delay spread: √(Σ τ²P(τ)/ΣP(τ) − τ̄²), with P(τ) = |tap|². - let power: Vec = x.iter().map(|c| (c.norm() as f64).powi(2)).collect(); + // Only causal delays [0, G/2) contribute: the ISTA delay grid is circular + // (Φ is DFT-like), so bins ≥ G/2 are aliased *negative* (non-causal) delays — + // an alias of the near-zero dominant tap otherwise inflates the spread (ADR-134 P2). + let causal_bins = x.len() / 2; + let power: Vec = x[..causal_bins].iter().map(|c| (c.norm() as f64).powi(2)).collect(); let p_sum: f64 = power.iter().sum(); let rms_delay_spread_s = if p_sum > 1e-24 { let mean_tau: f64 = power diff --git a/v2/crates/wifi-densepose-signal/tests/cir_synthetic.rs b/v2/crates/wifi-densepose-signal/tests/cir_synthetic.rs index b72af04c..a4ce8d1b 100644 --- a/v2/crates/wifi-densepose-signal/tests/cir_synthetic.rs +++ b/v2/crates/wifi-densepose-signal/tests/cir_synthetic.rs @@ -155,6 +155,7 @@ fn save_fixture(path: &str, k_active: usize, csi: &[Complex64], expected_dominan // --------------------------------------------------------------------------- + // Shared test logic: inject 3-tap channel, run estimator, assert // --------------------------------------------------------------------------- @@ -341,7 +342,6 @@ fn should_return_tof_at_40mhz() { // --------------------------------------------------------------------------- #[test] -#[ignore = "ADR-134 P2 (remaining): ISTA emits a spurious ~15-20%-of-dominant tap at an implausible far delay (~bin 150, ~3us) that inflates rms_delay_spread to ~390ns. Too close to tap2 (~30%) for a safe magnitude cutoff; needs ISTA recovery-quality work (grid de-aliasing / stronger far-tap suppression), not a band-aid. Dominant-ratio tuning landed separately."] fn should_produce_positive_rms_delay_spread() { let cfg = CirConfig::for_bandwidth_mhz(20); let k_active = cfg.delay_bins / 3;