Implement CSI processing and phase sanitization modules; add unit tests for DensePose and modality translation networks
This commit is contained in:
0
src/core/__init__.py
Normal file
0
src/core/__init__.py
Normal file
46
src/core/csi_processor.py
Normal file
46
src/core/csi_processor.py
Normal file
@@ -0,0 +1,46 @@
|
||||
"""CSI (Channel State Information) processor for WiFi-DensePose system."""
|
||||
|
||||
import numpy as np
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
|
||||
class CSIProcessor:
|
||||
"""Processes raw CSI data for neural network input."""
|
||||
|
||||
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
||||
"""Initialize CSI processor with configuration.
|
||||
|
||||
Args:
|
||||
config: Configuration dictionary with processing parameters
|
||||
"""
|
||||
self.config = config or {}
|
||||
self.sample_rate = self.config.get('sample_rate', 1000)
|
||||
self.num_subcarriers = self.config.get('num_subcarriers', 56)
|
||||
self.num_antennas = self.config.get('num_antennas', 3)
|
||||
|
||||
def process_raw_csi(self, raw_data: np.ndarray) -> np.ndarray:
|
||||
"""Process raw CSI data into normalized format.
|
||||
|
||||
Args:
|
||||
raw_data: Raw CSI data array
|
||||
|
||||
Returns:
|
||||
Processed CSI data ready for neural network input
|
||||
"""
|
||||
if raw_data.size == 0:
|
||||
raise ValueError("Raw CSI data cannot be empty")
|
||||
|
||||
# Basic processing: normalize and reshape
|
||||
processed = raw_data.astype(np.float32)
|
||||
|
||||
# Handle NaN values by replacing with mean of non-NaN values
|
||||
if np.isnan(processed).any():
|
||||
nan_mask = np.isnan(processed)
|
||||
non_nan_mean = np.nanmean(processed)
|
||||
processed[nan_mask] = non_nan_mean
|
||||
|
||||
# Simple normalization
|
||||
if processed.std() > 0:
|
||||
processed = (processed - processed.mean()) / processed.std()
|
||||
|
||||
return processed
|
||||
108
src/core/phase_sanitizer.py
Normal file
108
src/core/phase_sanitizer.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""Phase sanitizer for WiFi-DensePose CSI phase data processing."""
|
||||
|
||||
import numpy as np
|
||||
from typing import Optional
|
||||
from scipy import signal
|
||||
|
||||
|
||||
class PhaseSanitizer:
|
||||
"""Sanitizes phase data by unwrapping, removing outliers, and smoothing."""
|
||||
|
||||
def __init__(self, outlier_threshold: float = 3.0, smoothing_window: int = 5):
|
||||
"""Initialize phase sanitizer with configuration.
|
||||
|
||||
Args:
|
||||
outlier_threshold: Standard deviations for outlier detection
|
||||
smoothing_window: Window size for smoothing filter
|
||||
"""
|
||||
self.outlier_threshold = outlier_threshold
|
||||
self.smoothing_window = smoothing_window
|
||||
|
||||
def unwrap_phase(self, phase_data: np.ndarray) -> np.ndarray:
|
||||
"""Unwrap phase data to remove 2π discontinuities.
|
||||
|
||||
Args:
|
||||
phase_data: Raw phase data array
|
||||
|
||||
Returns:
|
||||
Unwrapped phase data
|
||||
"""
|
||||
if phase_data.size == 0:
|
||||
raise ValueError("Phase data cannot be empty")
|
||||
|
||||
# Apply unwrapping along the last axis (temporal dimension)
|
||||
unwrapped = np.unwrap(phase_data, axis=-1)
|
||||
return unwrapped.astype(np.float32)
|
||||
|
||||
def remove_outliers(self, phase_data: np.ndarray) -> np.ndarray:
|
||||
"""Remove outliers from phase data using statistical thresholding.
|
||||
|
||||
Args:
|
||||
phase_data: Phase data array
|
||||
|
||||
Returns:
|
||||
Phase data with outliers replaced
|
||||
"""
|
||||
if phase_data.size == 0:
|
||||
raise ValueError("Phase data cannot be empty")
|
||||
|
||||
result = phase_data.copy().astype(np.float32)
|
||||
|
||||
# Calculate statistics for outlier detection
|
||||
mean_val = np.mean(result)
|
||||
std_val = np.std(result)
|
||||
|
||||
# Identify outliers
|
||||
outlier_mask = np.abs(result - mean_val) > (self.outlier_threshold * std_val)
|
||||
|
||||
# Replace outliers with mean value
|
||||
result[outlier_mask] = mean_val
|
||||
|
||||
return result
|
||||
|
||||
def smooth_phase(self, phase_data: np.ndarray) -> np.ndarray:
|
||||
"""Apply smoothing filter to reduce noise in phase data.
|
||||
|
||||
Args:
|
||||
phase_data: Phase data array
|
||||
|
||||
Returns:
|
||||
Smoothed phase data
|
||||
"""
|
||||
if phase_data.size == 0:
|
||||
raise ValueError("Phase data cannot be empty")
|
||||
|
||||
result = phase_data.copy().astype(np.float32)
|
||||
|
||||
# Apply simple moving average filter along temporal dimension
|
||||
if result.ndim > 1:
|
||||
for i in range(result.shape[0]):
|
||||
if result.shape[-1] >= self.smoothing_window:
|
||||
# Apply 1D smoothing along the last axis
|
||||
kernel = np.ones(self.smoothing_window) / self.smoothing_window
|
||||
result[i] = np.convolve(result[i], kernel, mode='same')
|
||||
else:
|
||||
if result.shape[0] >= self.smoothing_window:
|
||||
kernel = np.ones(self.smoothing_window) / self.smoothing_window
|
||||
result = np.convolve(result, kernel, mode='same')
|
||||
|
||||
return result
|
||||
|
||||
def sanitize(self, phase_data: np.ndarray) -> np.ndarray:
|
||||
"""Apply full sanitization pipeline to phase data.
|
||||
|
||||
Args:
|
||||
phase_data: Raw phase data array
|
||||
|
||||
Returns:
|
||||
Fully sanitized phase data
|
||||
"""
|
||||
if phase_data.size == 0:
|
||||
raise ValueError("Phase data cannot be empty")
|
||||
|
||||
# Apply sanitization pipeline
|
||||
result = self.unwrap_phase(phase_data)
|
||||
result = self.remove_outliers(result)
|
||||
result = self.smooth_phase(result)
|
||||
|
||||
return result
|
||||
Reference in New Issue
Block a user