# gaitsetpy.features.harup_features

HAR-UP Feature Extractor. Maintainer: @aharshit123456

This file contains the HAR-UP feature extractor class that inherits from BaseFeatureExtractor. It implements the feature extraction methods used in the HAR-UP project.

Reference:

- Website: https://sites.google.com/up.edu.mx/har-up/
- GitHub: https://github.com/jpnm561/HAR-UP

View Source

      1'''
      2HAR-UP Feature Extractor.
      3Maintainer: @aharshit123456
      4
      5This file contains the HAR-UP feature extractor class that inherits from BaseFeatureExtractor.
      6It implements the feature extraction methods used in the HAR-UP project.
      7
      8Reference:
      9- Website: https://sites.google.com/up.edu.mx/har-up/
     10- GitHub: https://github.com/jpnm561/HAR-UP
     11'''
     12
     13import numpy as np
     14from typing import List, Dict, Any
     15from scipy.stats import kurtosis, skew
     16from scipy.fftpack import rfft
     17from ..core.base_classes import BaseFeatureExtractor
     18
     19
     20class HARUPFeatureExtractor(BaseFeatureExtractor):
     21    """
     22    HAR-UP feature extractor class.
     23
     24    This class implements the feature extraction methods used in the HAR-UP project.
     25    It extracts both time-domain and frequency-domain features from sensor data.
     26    """
     27
     28    def __init__(self, verbose: bool = False):
     29        """
     30        Initialize the HAR-UP feature extractor.
     31
     32        Args:
     33            verbose: Whether to print progress information
     34        """
     35        super().__init__(
     36            name="harup",
     37            description="HAR-UP Feature Extractor - Extracts features used in the HAR-UP project"
     38        )
     39        self.config = {
     40            'time_domain': True,
     41            'frequency_domain': True,
     42            'verbose': verbose
     43        }
     44
     45        # Define the features to extract
     46        self.time_domain_features = [
     47            'mean', 'std', 'rms', 'max_amp', 'min_amp', 'median',
     48            'zero_crossings', 'skewness', 'kurtosis', 'q1', 'q3', 'autocorr'
     49        ]
     50
     51        self.freq_domain_features = [
     52            'energy'
     53        ]
     54
     55    def extract_features(self, windows: List[Dict], fs: int, **kwargs) -> List[Dict]:
     56        """
     57        Extract features from sliding windows.
     58
     59        Args:
     60            windows: List of sliding window dictionaries
     61            fs: Sampling frequency
     62            **kwargs: Additional arguments for feature extraction
     63
     64        Returns:
     65            List of feature dictionaries
     66        """
     67        # Update config with kwargs
     68        self.config.update(kwargs)
     69
     70        all_features = []
     71
     72        # Skip label and activity_id windows
     73        sensor_windows = [w for w in windows if w["name"] not in ["labels", "activity_id"]]
     74
     75        if self.config['verbose']:
     76            print(f"Extracting features from {len(sensor_windows)} sensor windows")
     77
     78        # Process each sensor window
     79        for window in sensor_windows:
     80            sensor_name = window["name"]
     81            sensor_data = window["data"]
     82
     83            if self.config['verbose']:
     84                print(f"Processing {sensor_name} with {len(sensor_data)} windows")
     85
     86            # For each window of this sensor
     87            for i, window_data in enumerate(sensor_data):
     88                features = {}
     89                features["sensor"] = sensor_name
     90
     91                # Time domain features
     92                if self.config['time_domain']:
     93                    self._extract_time_domain_features(window_data, features)
     94
     95                # Frequency domain features
     96                if self.config['frequency_domain']:
     97                    self._extract_freq_domain_features(window_data, features)
     98
     99                all_features.append(features)
    100
    101        return all_features
    102
    103    def _extract_time_domain_features(self, window_data: np.ndarray, features: Dict[str, Any]):
    104        """
    105        Extract time domain features from a window.
    106
    107        Args:
    108            window_data: Window data
    109            features: Dictionary to store the extracted features
    110        """
    111        # Basic statistical features
    112        features["mean"] = np.mean(window_data)
    113        features["std"] = np.std(window_data)
    114        features["rms"] = np.sqrt(np.mean(window_data**2))
    115        features["max_amp"] = np.max(np.abs(window_data))
    116        features["min_amp"] = np.min(np.abs(window_data))
    117        features["median"] = np.median(window_data)
    118
    119        # Zero crossings
    120        zero_crossings = np.where(np.diff(np.signbit(window_data)))[0]
    121        features["zero_crossings"] = len(zero_crossings)
    122
    123        # Higher-order statistics
    124        features["skewness"] = skew(window_data)
    125        features["kurtosis"] = kurtosis(window_data)
    126
    127        # Quartiles
    128        features["q1"] = np.percentile(window_data, 25)
    129        features["q3"] = np.percentile(window_data, 75)
    130
    131        # Autocorrelation
    132        autocorr = np.correlate(window_data, window_data, mode='full')
    133        features["autocorr"] = np.median(autocorr)
    134
    135    def _extract_freq_domain_features(self, window_data: np.ndarray, features: Dict[str, Any]):
    136        """
    137        Extract frequency domain features from a window.
    138
    139        Args:
    140            window_data: Window data
    141            features: Dictionary to store the extracted features
    142        """
    143        # FFT
    144        fft_values = abs(rfft(np.asarray(window_data)))
    145
    146        # Energy
    147        features["energy"] = np.sum(fft_values**2)
    148
    149    def get_feature_names(self) -> List[str]:
    150        """
    151        Get names of features extracted by this extractor.
    152
    153        Returns:
    154            List of feature names
    155        """
    156        feature_names = []
    157
    158        if self.config['time_domain']:
    159            feature_names.extend(self.time_domain_features)
    160
    161        if self.config['frequency_domain']:
    162            feature_names.extend(self.freq_domain_features)
    163
    164        return feature_names
    165
    166
    167# Legacy function wrapper for backward compatibility
    168def extract_harup_features(windows: List[Dict], fs: int = 100,
    169                         time_domain: bool = True, freq_domain: bool = True,
    170                         verbose: bool = False) -> List[Dict]:
    171    """
    172    Legacy function for extracting HAR-UP features.
    173
    174    Args:
    175        windows: List of sliding window dictionaries
    176        fs: Sampling frequency (default: 100Hz)
    177        time_domain: Whether to extract time domain features
    178        freq_domain: Whether to extract frequency domain features
    179        verbose: Whether to print progress information
    180
    181    Returns:
    182        List of feature dictionaries
    183    """
    184    extractor = HARUPFeatureExtractor(verbose=verbose)
    185    return extractor.extract_features(
    186        windows,
    187        fs=fs,
    188        time_domain=time_domain,
    189        frequency_domain=freq_domain
    190    )

class HARUPFeatureExtractor(gaitsetpy.core.base_classes.BaseFeatureExtractor): View Source

     21class HARUPFeatureExtractor(BaseFeatureExtractor):
     22    """
     23    HAR-UP feature extractor class.
     24
     25    This class implements the feature extraction methods used in the HAR-UP project.
     26    It extracts both time-domain and frequency-domain features from sensor data.
     27    """
     28
     29    def __init__(self, verbose: bool = False):
     30        """
     31        Initialize the HAR-UP feature extractor.
     32
     33        Args:
     34            verbose: Whether to print progress information
     35        """
     36        super().__init__(
     37            name="harup",
     38            description="HAR-UP Feature Extractor - Extracts features used in the HAR-UP project"
     39        )
     40        self.config = {
     41            'time_domain': True,
     42            'frequency_domain': True,
     43            'verbose': verbose
     44        }
     45
     46        # Define the features to extract
     47        self.time_domain_features = [
     48            'mean', 'std', 'rms', 'max_amp', 'min_amp', 'median',
     49            'zero_crossings', 'skewness', 'kurtosis', 'q1', 'q3', 'autocorr'
     50        ]
     51
     52        self.freq_domain_features = [
     53            'energy'
     54        ]
     55
     56    def extract_features(self, windows: List[Dict], fs: int, **kwargs) -> List[Dict]:
     57        """
     58        Extract features from sliding windows.
     59
     60        Args:
     61            windows: List of sliding window dictionaries
     62            fs: Sampling frequency
     63            **kwargs: Additional arguments for feature extraction
     64
     65        Returns:
     66            List of feature dictionaries
     67        """
     68        # Update config with kwargs
     69        self.config.update(kwargs)
     70
     71        all_features = []
     72
     73        # Skip label and activity_id windows
     74        sensor_windows = [w for w in windows if w["name"] not in ["labels", "activity_id"]]
     75
     76        if self.config['verbose']:
     77            print(f"Extracting features from {len(sensor_windows)} sensor windows")
     78
     79        # Process each sensor window
     80        for window in sensor_windows:
     81            sensor_name = window["name"]
     82            sensor_data = window["data"]
     83
     84            if self.config['verbose']:
     85                print(f"Processing {sensor_name} with {len(sensor_data)} windows")
     86
     87            # For each window of this sensor
     88            for i, window_data in enumerate(sensor_data):
     89                features = {}
     90                features["sensor"] = sensor_name
     91
     92                # Time domain features
     93                if self.config['time_domain']:
     94                    self._extract_time_domain_features(window_data, features)
     95
     96                # Frequency domain features
     97                if self.config['frequency_domain']:
     98                    self._extract_freq_domain_features(window_data, features)
     99
    100                all_features.append(features)
    101
    102        return all_features
    103
    104    def _extract_time_domain_features(self, window_data: np.ndarray, features: Dict[str, Any]):
    105        """
    106        Extract time domain features from a window.
    107
    108        Args:
    109            window_data: Window data
    110            features: Dictionary to store the extracted features
    111        """
    112        # Basic statistical features
    113        features["mean"] = np.mean(window_data)
    114        features["std"] = np.std(window_data)
    115        features["rms"] = np.sqrt(np.mean(window_data**2))
    116        features["max_amp"] = np.max(np.abs(window_data))
    117        features["min_amp"] = np.min(np.abs(window_data))
    118        features["median"] = np.median(window_data)
    119
    120        # Zero crossings
    121        zero_crossings = np.where(np.diff(np.signbit(window_data)))[0]
    122        features["zero_crossings"] = len(zero_crossings)
    123
    124        # Higher-order statistics
    125        features["skewness"] = skew(window_data)
    126        features["kurtosis"] = kurtosis(window_data)
    127
    128        # Quartiles
    129        features["q1"] = np.percentile(window_data, 25)
    130        features["q3"] = np.percentile(window_data, 75)
    131
    132        # Autocorrelation
    133        autocorr = np.correlate(window_data, window_data, mode='full')
    134        features["autocorr"] = np.median(autocorr)
    135
    136    def _extract_freq_domain_features(self, window_data: np.ndarray, features: Dict[str, Any]):
    137        """
    138        Extract frequency domain features from a window.
    139
    140        Args:
    141            window_data: Window data
    142            features: Dictionary to store the extracted features
    143        """
    144        # FFT
    145        fft_values = abs(rfft(np.asarray(window_data)))
    146
    147        # Energy
    148        features["energy"] = np.sum(fft_values**2)
    149
    150    def get_feature_names(self) -> List[str]:
    151        """
    152        Get names of features extracted by this extractor.
    153
    154        Returns:
    155            List of feature names
    156        """
    157        feature_names = []
    158
    159        if self.config['time_domain']:
    160            feature_names.extend(self.time_domain_features)
    161
    162        if self.config['frequency_domain']:
    163            feature_names.extend(self.freq_domain_features)
    164
    165        return feature_names

HAR-UP feature extractor class.

This class implements the feature extraction methods used in the HAR-UP project. It extracts both time-domain and frequency-domain features from sensor data.

HARUPFeatureExtractor(verbose: bool = False) View Source

    29    def __init__(self, verbose: bool = False):
    30        """
    31        Initialize the HAR-UP feature extractor.
    32
    33        Args:
    34            verbose: Whether to print progress information
    35        """
    36        super().__init__(
    37            name="harup",
    38            description="HAR-UP Feature Extractor - Extracts features used in the HAR-UP project"
    39        )
    40        self.config = {
    41            'time_domain': True,
    42            'frequency_domain': True,
    43            'verbose': verbose
    44        }
    45
    46        # Define the features to extract
    47        self.time_domain_features = [
    48            'mean', 'std', 'rms', 'max_amp', 'min_amp', 'median',
    49            'zero_crossings', 'skewness', 'kurtosis', 'q1', 'q3', 'autocorr'
    50        ]
    51
    52        self.freq_domain_features = [
    53            'energy'
    54        ]

Initialize the HAR-UP feature extractor.

Args: verbose: Whether to print progress information

config
time_domain_features
freq_domain_features
def extract_features(self, windows: List[Dict], fs: int, **kwargs) -> List[Dict]: View Source

     56    def extract_features(self, windows: List[Dict], fs: int, **kwargs) -> List[Dict]:
     57        """
     58        Extract features from sliding windows.
     59
     60        Args:
     61            windows: List of sliding window dictionaries
     62            fs: Sampling frequency
     63            **kwargs: Additional arguments for feature extraction
     64
     65        Returns:
     66            List of feature dictionaries
     67        """
     68        # Update config with kwargs
     69        self.config.update(kwargs)
     70
     71        all_features = []
     72
     73        # Skip label and activity_id windows
     74        sensor_windows = [w for w in windows if w["name"] not in ["labels", "activity_id"]]
     75
     76        if self.config['verbose']:
     77            print(f"Extracting features from {len(sensor_windows)} sensor windows")
     78
     79        # Process each sensor window
     80        for window in sensor_windows:
     81            sensor_name = window["name"]
     82            sensor_data = window["data"]
     83
     84            if self.config['verbose']:
     85                print(f"Processing {sensor_name} with {len(sensor_data)} windows")
     86
     87            # For each window of this sensor
     88            for i, window_data in enumerate(sensor_data):
     89                features = {}
     90                features["sensor"] = sensor_name
     91
     92                # Time domain features
     93                if self.config['time_domain']:
     94                    self._extract_time_domain_features(window_data, features)
     95
     96                # Frequency domain features
     97                if self.config['frequency_domain']:
     98                    self._extract_freq_domain_features(window_data, features)
     99
    100                all_features.append(features)
    101
    102        return all_features

Extract features from sliding windows.

Args: windows: List of sliding window dictionaries fs: Sampling frequency **kwargs: Additional arguments for feature extraction

Returns: List of feature dictionaries

def get_feature_names(self) -> List[str]: View Source

    150    def get_feature_names(self) -> List[str]:
    151        """
    152        Get names of features extracted by this extractor.
    153
    154        Returns:
    155            List of feature names
    156        """
    157        feature_names = []
    158
    159        if self.config['time_domain']:
    160            feature_names.extend(self.time_domain_features)
    161
    162        if self.config['frequency_domain']:
    163            feature_names.extend(self.freq_domain_features)
    164
    165        return feature_names

Get names of features extracted by this extractor.

Returns: List of feature names

##### Inherited Members

gaitsetpy.core.base_classes.BaseFeatureExtractor
  name
  description
  configure
  get_info

def extract_harup_features( windows: List[Dict], fs: int = 100, time_domain: bool = True, freq_domain: bool = True, verbose: bool = False) -> List[Dict]: View Source

    169def extract_harup_features(windows: List[Dict], fs: int = 100,
    170                         time_domain: bool = True, freq_domain: bool = True,
    171                         verbose: bool = False) -> List[Dict]:
    172    """
    173    Legacy function for extracting HAR-UP features.
    174
    175    Args:
    176        windows: List of sliding window dictionaries
    177        fs: Sampling frequency (default: 100Hz)
    178        time_domain: Whether to extract time domain features
    179        freq_domain: Whether to extract frequency domain features
    180        verbose: Whether to print progress information
    181
    182    Returns:
    183        List of feature dictionaries
    184    """
    185    extractor = HARUPFeatureExtractor(verbose=verbose)
    186    return extractor.extract_features(
    187        windows,
    188        fs=fs,
    189        time_domain=time_domain,
    190        frequency_domain=freq_domain
    191    )

Legacy function for extracting HAR-UP features.

Args: windows: List of sliding window dictionaries fs: Sampling frequency (default: 100Hz) time_domain: Whether to extract time domain features freq_domain: Whether to extract frequency domain features verbose: Whether to print progress information

Returns: List of feature dictionaries