# How PhaseSanitizer Removes Hardware-Specific Phase Offsets in WiFi-DensePose

> Learn how PhaseSanitizer removes hardware-specific phase offsets by unwrapping raw CSI phase data, detecting outliers, and interpolating for a clean, hardware-independent signal.

- Repository: [rUv/wifi-densepose](https://github.com/ruvnet/wifi-densepose)
- Tags: internals
- Published: 2026-02-19

---

**The PhaseSanitizer eliminates hardware-specific phase offsets by unwrapping raw CSI phase data, detecting systematic deviations as statistical outliers, and interpolating over them to produce a clean, hardware-independent signal.**

The **PhaseSanitizer** class in the `ruvnet/wifi-densepose` repository processes raw Channel State Information (CSI) to remove hardware-specific phase offsets before pose estimation. Located in [`v1/src/core/phase_sanitizer.py`](https://github.com/ruvnet/wifi-densepose/blob/main/v1/src/core/phase_sanitizer.py), this component implements a deterministic pipeline that converts discontinuous, hardware-biased phase measurements into stable signals suitable for downstream machine learning models.

## PhaseSanitizer Configuration and Initialization

When instantiated, the sanitizer receives a configuration dictionary that controls how each processing stage behaves. The three critical parameters for offset removal are `unwrapping_method`, `outlier_threshold`, and `smoothing_window`.

```python
self.unwrapping_method = config['unwrapping_method']                # line 34

self.outlier_threshold = config['outlier_threshold']                # line 35

self.smoothing_window = config['smoothing_window']                  # line 36

self.enable_outlier_removal = config.get('enable_outlier_removal', True)  # line 39

```

The `outlier_threshold` value is particularly crucial because hardware-specific offsets appear as consistent statistical deviations that exceed normal phase variation.

## Step 1: Phase Unwrapping

Raw CSI phase values are wrapped to the interval \([-\pi,\pi]\), creating artificial discontinuities. The sanitizer first **unwraps** the signal to produce a continuous phase timeline that eliminates hardware-induced \(2\pi\) jumps.

```python
def unwrap_phase(self, phase_data: np.ndarray) -> np.ndarray:
    try:
        if self.unwrapping_method == 'numpy':
            return self._unwrap_numpy(phase_data)                         # line 90-91

        elif self.unwrapping_method == 'scipy':
            return self._unwrap_scipy(phase_data)                         # line 92-93

        elif self.unwrapping_method == 'custom':
            return self._unwrap_custom(phase_data)                         # line 94-95

        else:
            raise ValueError(...)
    except Exception as e:
        raise PhaseSanitizationError(f"Failed to unwrap phase: {e}")      # line 99-100

```

This unwrapping preserves the underlying **hardware-specific bias** while removing wrapping artifacts, preparing the data for offset detection.

## Step 2: Detecting Hardware-Specific Offsets

After unwrapping, the sanitizer scans the phase array for values that deviate beyond the configured statistical threshold. The detection logic resides in `_detect_outliers`:

```python
def _detect_outliers(self, phase_data: np.ndarray) -> np.ndarray:
    # Internal logic uses the configured threshold to build a boolean mask

```

Hardware-specific offsets manifest as **consistent spikes or plateaus** across the measurement window. Because these systematic errors exceed the normal variation defined by `outlier_threshold`, they are flagged as outliers in the boolean mask.

## Step 3: Interpolation and Offset Removal

Once outliers are identified, the sanitizer replaces them by linearly interpolating between the nearest valid samples. This interpolation effectively subtracts the systematic hardware bias without distorting the true temporal dynamics.

```python
def _interpolate_outliers(self, phase_data: np.ndarray,
                          outlier_mask: np.ndarray) -> np.ndarray:
    # Interpolates over the masked positions

```

The public `remove_outliers` method orchestrates this process:

```python
def remove_outliers(self, phase_data: np.ndarray) -> np.ndarray:
    if not self.enable_outlier_removal:
        return phase_data
    outlier_mask = self._detect_outliers(phase_data)          # line 124-125

    return self._interpolate_outliers(phase_data, outlier_mask)  # line 126-127

```

By interpolating over the flagged hardware-induced spikes, the sanitizer removes the systematic offset while preserving legitimate phase variations caused by human movement.

## Step 4: Smoothing and Noise Filtering

After outlier correction, optional stages refine the signal quality. The `smooth_phase` method applies a moving average to reduce high-frequency jitter:

```python
def smooth_phase(self, phase_data):
    if self.enable_smoothing:
        return self._apply_moving_average(phase_data, self.smoothing_window)  # line 181-184

    return phase_data

```

Additionally, `filter_noise` applies a low-pass filter to suppress residual high-frequency noise:

```python
def filter_noise(self, phase_data):
    if self.enable_noise_filtering:
        return self._apply_low_pass_filter(phase_data, self.noise_threshold)  # line 221-224

    return phase_data

```

These refinements ensure the final phase vector is continuous, bias-free, and optimized for pose estimation.

## Complete Sanitization Pipeline

The high-level `sanitize_phase` method executes the full sequence in order:

```python
def sanitize_phase(self, phase_data: np.ndarray) -> np.ndarray:
    self.validate_phase_data(phase_data)                     # line 266-267

    phase = self.unwrap_phase(phase_data)                     # line 269-270

    phase = self.remove_outliers(phase)                       # line 271-272

    phase = self.smooth_phase(phase)                          # line 273-274

    phase = self.filter_noise(phase)                          # line 275-276

    return phase

```

The hardware-specific phase offset is eliminated during the outlier detection and interpolation stage, after the initial unwrapping prepares the continuous signal.

## Summary

- **PhaseSanitizer** uses a three-stage pipeline to clean CSI data: unwrapping, outlier removal, and smoothing.
- Hardware-specific offsets are detected as statistical outliers using the configurable `outlier_threshold` parameter.
- Linear interpolation over flagged outliers effectively subtracts systematic hardware bias while preserving movement-induced phase variations.
- The implementation in [`v1/src/core/phase_sanitizer.py`](https://github.com/ruvnet/wifi-densepose/blob/main/v1/src/core/phase_sanitizer.py) provides deterministic, unit-tested processing suitable for real-time pose estimation pipelines.

## Frequently Asked Questions

### What causes hardware-specific phase offsets in WiFi CSI data?

Hardware-specific phase offsets originate from imperfections in radio frequency (RF) components such as oscillators, mixers, and antennas. These imperfections introduce systematic biases and \(2\pi\) wrapping discontinuities that remain consistent across measurements but vary between different WiFi chipsets and hardware configurations.

### How does PhaseSanitizer distinguish hardware offsets from valid human movement?

The sanitizer relies on the statistical distribution of phase values over time. Hardware offsets appear as **consistent spikes or plateaus** that exceed the `outlier_threshold`, whereas human movement produces gradual, continuous phase shifts. The `_detect_outliers` method flags only extreme deviations, ensuring legitimate motion signals pass through to the interpolation stage.

### Can the outlier detection sensitivity be adjusted for different WiFi chipsets?

Yes, the `outlier_threshold` parameter in the configuration dictionary allows per-hardware calibration. Chipsets with known phase instability issues can use a lower threshold to catch subtle offsets, while stable hardware can use higher thresholds to avoid over-filtering. This configuration is set during instantiation at lines 34-39 of [`v1/src/core/phase_sanitizer.py`](https://github.com/ruvnet/wifi-densepose/blob/main/v1/src/core/phase_sanitizer.py).

### Where does PhaseSanitizer fit within the WiFi-DensePose processing pipeline?

According to [`v1/src/services/pose_service.py`](https://github.com/ruvnet/wifi-densepose/blob/main/v1/src/services/pose_service.py), the PhaseSanitizer is instantiated immediately after raw CSI extraction and before feature extraction. It sanitizes phase data early in the pipeline to ensure that downstream pose estimation models receive hardware-independent inputs, preventing device-specific biases from affecting accuracy.