Source code for biobss.edatools.eda_signalfeatures

from copy import copy

import numpy as np
from numpy.typing import ArrayLike

SIGNAL_FEATURES = {
    "rms": lambda x: _calculate_rms(x),
    "acr_length": lambda x: _calculate_arc_length(x),
    "integral": lambda x: _calculate_integral(x),
    "average_power": lambda x: _calculate_avg_pow(x),
}


[docs]def get_feature_names(): return SIGNAL_FEATURES.keys()
[docs]def eda_signal_features(signal: ArrayLike, prefix="signal") -> dict: """Calculates EDA features. rms : Root mean square of the signal acr_length : Arc length of the signal integral : Integral of the signal average_power: Normalized average power of the signal Args: signal (ArrayLike): EDA signal. prefix (str, optional): Prefix for the feature. Defaults to "eda". Returns: dict: Dictionary of calculated features. """ signal = np.array(signal) signal = signal.flatten() s_features = {} for k, f in SIGNAL_FEATURES.items(): try: s_features["_".join([prefix, k])] = f(signal) except: s_features["_".join([prefix, k])] = np.nan return s_features
def _calculate_rms(sig: ArrayLike) -> float: def rms_(x): return x ** 2 rms_func = np.vectorize(rms_) sig_ = rms_func(sig) tot = sig_.sum() tot = tot / len(sig) tot = np.sqrt(tot) return tot def _calculate_arc_length(sig: ArrayLike) -> float: # This is the arc length of the signal sig = np.array(sig) sig1 = copy(sig[1:]) sig2 = copy(sig[:-1]) def alsc_(x): return np.sqrt(1 + x ** 2) alsc_func = np.vectorize(alsc_) tot = alsc_func(sig1 - sig2) tot = tot.sum() return tot def _calculate_integral(sig: ArrayLike) -> float: # This is the integral of the signal return np.abs(sig).sum() def _calculate_avg_pow(sig: ArrayLike) -> float: # This is the normalized average power of the signal def rms_(x): return x ** 2 rms_func = np.vectorize(rms_) sig_ = rms_func(sig) apsc = sig_.sum() apsc = apsc / len(sig) return apsc