gaitsetpy.features.utils
1import numpy as np 2from scipy.stats import skew, kurtosis, entropy 3from scipy.signal import welch, find_peaks 4from scipy.fft import fft 5from statsmodels.tsa.ar_model import AutoReg 6 7 8def calculate_stride_times(signal, fs): 9 """ 10 Calculate stride times from a signal using peak detection. 11 Args: 12 signal (np.array): Input signal. 13 fs (int): Sampling frequency. 14 Returns: 15 avg_stride_time (float): Average stride time. 16 """ 17 peaks, _ = find_peaks(signal) 18 stride_times = np.diff(peaks) / fs 19 avg_stride_time = np.mean(stride_times) if len(stride_times) > 0 else 0 20 return avg_stride_time 21 22def calculate_zero_crossing_rate(signal): 23 """ 24 Calculate the zero-crossing rate of a signal. 25 Args: 26 signal (np.array): Input signal. 27 Returns: 28 zcr (float): Zero-crossing rate. 29 """ 30 n = len(signal) 31 zcr = 1 / (n - 1) * sum(0.5 * abs(np.sign(signal[i + 1]) - np.sign(signal[i])) for i in range(n - 1)) 32 return zcr 33 34def calculate_power(signal, fs, band): 35 """ 36 Calculate the power of a signal in a specific frequency band. 37 Args: 38 signal (np.array): Input signal. 39 fs (int): Sampling frequency. 40 band (tuple): Frequency band (low, high). 41 Returns: 42 band_power (float): Power in the specified frequency band. 43 """ 44 # f, Pxx = welch(signal, fs=fs, nperseg=min(len(signal), 1024)) 45 f, Pxx = welch(signal, fs=fs, nperseg = min(len(signal), 192)) # Ensure nperseg ≤ length) 46 band_power = np.trapz(Pxx[(f >= band[0]) & (f <= band[1])], f[(f >= band[0]) & (f <= band[1])]) 47 return band_power 48 49def calculate_freezing_index(signal, fs): 50 """ 51 Calculate the freezing index of a signal. 52 Args: 53 signal (np.array): Input signal. 54 fs (int): Sampling frequency. 55 Returns: 56 freezing_index (float): Freezing index. 57 """ 58 power_3_8 = calculate_power(signal, fs, (3, 8)) 59 power_0_5_3 = calculate_power(signal, fs, (0.5, 3)) 60 freezing_index = power_3_8 / power_0_5_3 if power_0_5_3 != 0 else 0 61 return freezing_index 62 63def calculate_standard_deviation(signal): 64 """ 65 Calculate the standard deviation of a signal. 66 Args: 67 signal (np.array): Input signal. 68 Returns: 69 std_dev (float): Standard deviation. 70 """ 71 return np.std(signal) 72 73def calculate_entropy(signal): 74 """ 75 Calculate the entropy of a signal. 76 Args: 77 signal (np.array): Input signal. 78 Returns: 79 entropy_value (float): Entropy. 80 """ 81 value, counts = np.unique(signal, return_counts=True) 82 probabilities = counts / len(signal) 83 return entropy(probabilities, base=2) 84 85def calculate_energy(signal): 86 """ 87 Calculate the energy of a signal. 88 Args: 89 signal (np.array): Input signal. 90 Returns: 91 energy (float): Energy. 92 """ 93 return np.sum(signal ** 2) 94 95def calculate_variance(signal): 96 """ 97 Calculate the variance of a signal. 98 Args: 99 signal (np.array): Input signal. 100 Returns: 101 variance (float): Variance. 102 """ 103 return np.var(signal) 104 105def calculate_kurtosis(signal): 106 """ 107 Calculate the kurtosis of a signal. 108 Args: 109 signal (np.array): Input signal. 110 Returns: 111 kurtosis_value (float): Kurtosis. 112 """ 113 try: 114 return kurtosis(signal, fisher=False) 115 except Exception as e: 116 print(f"An error occurred in feature 'kurtosis': {e}") 117 return 0 118 119def calculate_step_time(signal, fs): 120 """ 121 Calculate step times from a signal using peak detection. 122 Args: 123 signal (np.array): Input signal. 124 fs (int): Sampling frequency. 125 Returns: 126 step_times (np.array): Array of step times. 127 """ 128 peaks, _ = find_peaks(signal) 129 step_times = np.diff(peaks) / fs 130 return step_times 131 132def calculate_mean(signal): 133 """Calculate the mean of the signal.""" 134 return np.mean(signal) 135 136def calculate_max(signal): 137 """Calculate the maximum value of the signal.""" 138 return np.max(signal) 139 140def calculate_min(signal): 141 """Calculate the minimum value of the signal.""" 142 return np.min(signal) 143 144def calculate_median(signal): 145 """Calculate the median of the signal.""" 146 return np.median(signal) 147 148def calculate_skewness(signal): 149 """Calculate the skewness of the signal.""" 150 try: 151 return skew(signal) 152 except Exception as e: 153 print(f"An error occurred in skewness: {e}") 154 return 0 155 156def calculate_root_mean_square(signal): 157 """Calculate the root mean square of the signal.""" 158 return np.sqrt(np.mean(np.square(signal))) 159 160def calculate_range(signal): 161 """Calculate the range of the signal.""" 162 return np.max(signal) - np.min(signal) 163 164def calculate_correlation(signal1, signal2): 165 """Calculate the correlation between two signals.""" 166 return np.corrcoef(signal1, signal2)[0, 1] 167 168def calculate_dominant_frequency(signal, fs): 169 """Calculate the dominant frequency of the signal.""" 170 try: 171 fft_values = np.abs(fft(signal)) 172 freqs = np.fft.fftfreq(len(signal), 1 / fs) 173 dominant_freq = freqs[np.argmax(fft_values)] 174 return dominant_freq 175 except Exception as e: 176 print(f"An error occurred: {e}") 177 return 0 178 179def calculate_peak_height(signal): 180 """Calculate the peak height of the signal.""" 181 peaks, _ = find_peaks(signal) 182 return np.max(signal[peaks]) if len(peaks) > 0 else 0 183 184def calculate_interquartile_range(signal): 185 """Calculate the interquartile range of the signal.""" 186 try: 187 q75, q25 = np.percentile(signal, [75, 25]) 188 return q75 - q25 189 except Exception as e: 190 print(f"An error occurred in feature 'interquartile_range': {e}") 191 return 0 192 193def calculate_mode(signal): 194 """Calculate the mode of the signal.""" 195 values, counts = np.unique(signal, return_counts=True) 196 return values[np.argmax(counts)] 197 198def calculate_cadence(signal, fs): 199 """Calculate the cadence (steps per minute) of the signal.""" 200 peaks, _ = find_peaks(signal) 201 step_count = len(peaks) 202 duration = len(signal) / fs 203 return (step_count / duration) * 60 204 205def calculate_mean_absolute_value(signal): 206 """Calculate the mean absolute value of the signal.""" 207 return np.mean(np.abs(signal)) 208 209def calculate_median_absolute_deviation(signal): 210 """Calculate the median absolute deviation of the signal.""" 211 return np.median(np.abs(signal - np.median(signal))) 212 213def calculate_peak_frequency(signal, fs): 214 """Calculate the peak frequency of the signal.""" 215 try: 216 f, Pxx = welch(signal, fs=fs, nperseg=min(len(signal), 192)) # Ensure nperseg ≤ length 217 return f[np.argmax(Pxx)] 218 except Exception as e: 219 print(f"An error occurred in feature 'peak_frequency': {e}") 220 return 0 221 222def calculate_peak_width(signal, fs): 223 """Calculate the peak width of the signal.""" 224 peaks, _ = find_peaks(signal) 225 if len(peaks) == 0: 226 return 0 227 peak_heights = signal[peaks] 228 half_max = np.max(peak_heights) / 2 229 widths = np.diff(np.where(signal > half_max)[0]) 230 return np.mean(widths) / fs if len(widths) > 0 else 0 231 232def calculate_power_spectral_entropy(signal, fs): 233 """Calculate the power spectral entropy of the signal.""" 234 try: 235 f, Pxx = welch(signal, fs=fs, nperseg=min(len(signal), 192)) # Ensure nperseg ≤ length 236 Pxx_norm = Pxx / np.sum(Pxx) 237 return -np.sum(Pxx_norm * np.log2(Pxx_norm + np.finfo(float).eps)) 238 except Exception as e: 239 print(f"An error occurred in feature 'power spectral entropy': {e}") 240 return 0 241 242def calculate_principal_harmonic_frequency(signal, fs): 243 """Calculate the principal harmonic frequency of the signal.""" 244 try: 245 fft_values = np.abs(fft(signal)) 246 freqs = np.fft.fftfreq(len(signal), 1 / fs) 247 return freqs[np.argmax(fft_values)] 248 except Exception as e: 249 print(f"An error occurred in feature 'principal_harmonic_frequency': {e}") 250 return 0 251 252def calculate_auto_regression_coefficients(signal, order=3): 253 """Calculate the auto-regression coefficients of the signal.""" 254 try: 255 model = AutoReg(signal, lags=order) 256 results = model.fit() 257 return results.params 258 except Exception as e: 259 print(f"An error occurred in feature 'auto_regression_coefficients': {e}") 260 return 0
9def calculate_stride_times(signal, fs): 10 """ 11 Calculate stride times from a signal using peak detection. 12 Args: 13 signal (np.array): Input signal. 14 fs (int): Sampling frequency. 15 Returns: 16 avg_stride_time (float): Average stride time. 17 """ 18 peaks, _ = find_peaks(signal) 19 stride_times = np.diff(peaks) / fs 20 avg_stride_time = np.mean(stride_times) if len(stride_times) > 0 else 0 21 return avg_stride_time
Calculate stride times from a signal using peak detection. Args: signal (np.array): Input signal. fs (int): Sampling frequency. Returns: avg_stride_time (float): Average stride time.
23def calculate_zero_crossing_rate(signal): 24 """ 25 Calculate the zero-crossing rate of a signal. 26 Args: 27 signal (np.array): Input signal. 28 Returns: 29 zcr (float): Zero-crossing rate. 30 """ 31 n = len(signal) 32 zcr = 1 / (n - 1) * sum(0.5 * abs(np.sign(signal[i + 1]) - np.sign(signal[i])) for i in range(n - 1)) 33 return zcr
Calculate the zero-crossing rate of a signal. Args: signal (np.array): Input signal. Returns: zcr (float): Zero-crossing rate.
35def calculate_power(signal, fs, band): 36 """ 37 Calculate the power of a signal in a specific frequency band. 38 Args: 39 signal (np.array): Input signal. 40 fs (int): Sampling frequency. 41 band (tuple): Frequency band (low, high). 42 Returns: 43 band_power (float): Power in the specified frequency band. 44 """ 45 # f, Pxx = welch(signal, fs=fs, nperseg=min(len(signal), 1024)) 46 f, Pxx = welch(signal, fs=fs, nperseg = min(len(signal), 192)) # Ensure nperseg ≤ length) 47 band_power = np.trapz(Pxx[(f >= band[0]) & (f <= band[1])], f[(f >= band[0]) & (f <= band[1])]) 48 return band_power
Calculate the power of a signal in a specific frequency band. Args: signal (np.array): Input signal. fs (int): Sampling frequency. band (tuple): Frequency band (low, high). Returns: band_power (float): Power in the specified frequency band.
50def calculate_freezing_index(signal, fs): 51 """ 52 Calculate the freezing index of a signal. 53 Args: 54 signal (np.array): Input signal. 55 fs (int): Sampling frequency. 56 Returns: 57 freezing_index (float): Freezing index. 58 """ 59 power_3_8 = calculate_power(signal, fs, (3, 8)) 60 power_0_5_3 = calculate_power(signal, fs, (0.5, 3)) 61 freezing_index = power_3_8 / power_0_5_3 if power_0_5_3 != 0 else 0 62 return freezing_index
Calculate the freezing index of a signal. Args: signal (np.array): Input signal. fs (int): Sampling frequency. Returns: freezing_index (float): Freezing index.
64def calculate_standard_deviation(signal): 65 """ 66 Calculate the standard deviation of a signal. 67 Args: 68 signal (np.array): Input signal. 69 Returns: 70 std_dev (float): Standard deviation. 71 """ 72 return np.std(signal)
Calculate the standard deviation of a signal. Args: signal (np.array): Input signal. Returns: std_dev (float): Standard deviation.
74def calculate_entropy(signal): 75 """ 76 Calculate the entropy of a signal. 77 Args: 78 signal (np.array): Input signal. 79 Returns: 80 entropy_value (float): Entropy. 81 """ 82 value, counts = np.unique(signal, return_counts=True) 83 probabilities = counts / len(signal) 84 return entropy(probabilities, base=2)
Calculate the entropy of a signal. Args: signal (np.array): Input signal. Returns: entropy_value (float): Entropy.
86def calculate_energy(signal): 87 """ 88 Calculate the energy of a signal. 89 Args: 90 signal (np.array): Input signal. 91 Returns: 92 energy (float): Energy. 93 """ 94 return np.sum(signal ** 2)
Calculate the energy of a signal. Args: signal (np.array): Input signal. Returns: energy (float): Energy.
96def calculate_variance(signal): 97 """ 98 Calculate the variance of a signal. 99 Args: 100 signal (np.array): Input signal. 101 Returns: 102 variance (float): Variance. 103 """ 104 return np.var(signal)
Calculate the variance of a signal. Args: signal (np.array): Input signal. Returns: variance (float): Variance.
106def calculate_kurtosis(signal): 107 """ 108 Calculate the kurtosis of a signal. 109 Args: 110 signal (np.array): Input signal. 111 Returns: 112 kurtosis_value (float): Kurtosis. 113 """ 114 try: 115 return kurtosis(signal, fisher=False) 116 except Exception as e: 117 print(f"An error occurred in feature 'kurtosis': {e}") 118 return 0
Calculate the kurtosis of a signal. Args: signal (np.array): Input signal. Returns: kurtosis_value (float): Kurtosis.
120def calculate_step_time(signal, fs): 121 """ 122 Calculate step times from a signal using peak detection. 123 Args: 124 signal (np.array): Input signal. 125 fs (int): Sampling frequency. 126 Returns: 127 step_times (np.array): Array of step times. 128 """ 129 peaks, _ = find_peaks(signal) 130 step_times = np.diff(peaks) / fs 131 return step_times
Calculate step times from a signal using peak detection. Args: signal (np.array): Input signal. fs (int): Sampling frequency. Returns: step_times (np.array): Array of step times.
133def calculate_mean(signal): 134 """Calculate the mean of the signal.""" 135 return np.mean(signal)
Calculate the mean of the signal.
137def calculate_max(signal): 138 """Calculate the maximum value of the signal.""" 139 return np.max(signal)
Calculate the maximum value of the signal.
141def calculate_min(signal): 142 """Calculate the minimum value of the signal.""" 143 return np.min(signal)
Calculate the minimum value of the signal.
145def calculate_median(signal): 146 """Calculate the median of the signal.""" 147 return np.median(signal)
Calculate the median of the signal.
149def calculate_skewness(signal): 150 """Calculate the skewness of the signal.""" 151 try: 152 return skew(signal) 153 except Exception as e: 154 print(f"An error occurred in skewness: {e}") 155 return 0
Calculate the skewness of the signal.
157def calculate_root_mean_square(signal): 158 """Calculate the root mean square of the signal.""" 159 return np.sqrt(np.mean(np.square(signal)))
Calculate the root mean square of the signal.
161def calculate_range(signal): 162 """Calculate the range of the signal.""" 163 return np.max(signal) - np.min(signal)
Calculate the range of the signal.
165def calculate_correlation(signal1, signal2): 166 """Calculate the correlation between two signals.""" 167 return np.corrcoef(signal1, signal2)[0, 1]
Calculate the correlation between two signals.
169def calculate_dominant_frequency(signal, fs): 170 """Calculate the dominant frequency of the signal.""" 171 try: 172 fft_values = np.abs(fft(signal)) 173 freqs = np.fft.fftfreq(len(signal), 1 / fs) 174 dominant_freq = freqs[np.argmax(fft_values)] 175 return dominant_freq 176 except Exception as e: 177 print(f"An error occurred: {e}") 178 return 0
Calculate the dominant frequency of the signal.
180def calculate_peak_height(signal): 181 """Calculate the peak height of the signal.""" 182 peaks, _ = find_peaks(signal) 183 return np.max(signal[peaks]) if len(peaks) > 0 else 0
Calculate the peak height of the signal.
185def calculate_interquartile_range(signal): 186 """Calculate the interquartile range of the signal.""" 187 try: 188 q75, q25 = np.percentile(signal, [75, 25]) 189 return q75 - q25 190 except Exception as e: 191 print(f"An error occurred in feature 'interquartile_range': {e}") 192 return 0
Calculate the interquartile range of the signal.
194def calculate_mode(signal): 195 """Calculate the mode of the signal.""" 196 values, counts = np.unique(signal, return_counts=True) 197 return values[np.argmax(counts)]
Calculate the mode of the signal.
199def calculate_cadence(signal, fs): 200 """Calculate the cadence (steps per minute) of the signal.""" 201 peaks, _ = find_peaks(signal) 202 step_count = len(peaks) 203 duration = len(signal) / fs 204 return (step_count / duration) * 60
Calculate the cadence (steps per minute) of the signal.
206def calculate_mean_absolute_value(signal): 207 """Calculate the mean absolute value of the signal.""" 208 return np.mean(np.abs(signal))
Calculate the mean absolute value of the signal.
210def calculate_median_absolute_deviation(signal): 211 """Calculate the median absolute deviation of the signal.""" 212 return np.median(np.abs(signal - np.median(signal)))
Calculate the median absolute deviation of the signal.
214def calculate_peak_frequency(signal, fs): 215 """Calculate the peak frequency of the signal.""" 216 try: 217 f, Pxx = welch(signal, fs=fs, nperseg=min(len(signal), 192)) # Ensure nperseg ≤ length 218 return f[np.argmax(Pxx)] 219 except Exception as e: 220 print(f"An error occurred in feature 'peak_frequency': {e}") 221 return 0
Calculate the peak frequency of the signal.
223def calculate_peak_width(signal, fs): 224 """Calculate the peak width of the signal.""" 225 peaks, _ = find_peaks(signal) 226 if len(peaks) == 0: 227 return 0 228 peak_heights = signal[peaks] 229 half_max = np.max(peak_heights) / 2 230 widths = np.diff(np.where(signal > half_max)[0]) 231 return np.mean(widths) / fs if len(widths) > 0 else 0
Calculate the peak width of the signal.
233def calculate_power_spectral_entropy(signal, fs): 234 """Calculate the power spectral entropy of the signal.""" 235 try: 236 f, Pxx = welch(signal, fs=fs, nperseg=min(len(signal), 192)) # Ensure nperseg ≤ length 237 Pxx_norm = Pxx / np.sum(Pxx) 238 return -np.sum(Pxx_norm * np.log2(Pxx_norm + np.finfo(float).eps)) 239 except Exception as e: 240 print(f"An error occurred in feature 'power spectral entropy': {e}") 241 return 0
Calculate the power spectral entropy of the signal.
243def calculate_principal_harmonic_frequency(signal, fs): 244 """Calculate the principal harmonic frequency of the signal.""" 245 try: 246 fft_values = np.abs(fft(signal)) 247 freqs = np.fft.fftfreq(len(signal), 1 / fs) 248 return freqs[np.argmax(fft_values)] 249 except Exception as e: 250 print(f"An error occurred in feature 'principal_harmonic_frequency': {e}") 251 return 0
Calculate the principal harmonic frequency of the signal.
253def calculate_auto_regression_coefficients(signal, order=3): 254 """Calculate the auto-regression coefficients of the signal.""" 255 try: 256 model = AutoReg(signal, lags=order) 257 results = model.fit() 258 return results.params 259 except Exception as e: 260 print(f"An error occurred in feature 'auto_regression_coefficients': {e}") 261 return 0
Calculate the auto-regression coefficients of the signal.