Source code for biobss.edatools.eda_freqdomain

import numpy as np
from numpy.typing import ArrayLike
from scipy import signal
from scipy.fft import fft

# Frequency-domain features
FREQ_FEATURES = {
    "f1sc": lambda x, freqs: x[np.where(np.logical_and(freqs > 0.1, freqs < 0.2))].mean(),
    "f2sc": lambda x, freqs: x[np.where(np.logical_and(freqs > 0.2, freqs < 0.3))].mean(),
    "f3sc": lambda x, freqs: x[np.where(np.logical_and(freqs > 0.3, freqs < 0.4))].mean(),
    "Energy": lambda x, freqs: np.sum(x ** 2),
    "Entropy": lambda x, freqs: np.sum(x * np.log(x)),
    "max_freq": lambda x, freqs: freqs[np.argmax(x)],
}


[docs]def eda_freq_features(sig: ArrayLike, prefix: str = "eda") -> dict: """Calculates frequency-domain EDA features. f1sc: Spectral power in the range of 0.1 to 0.2 Hz. f2sc: Spectral power in the range of 0.2 to 0.3 Hz. f3sc: Spectral power in the range of 0.3 to 0.4 Hz. Energy: Sum of the signal power Entropy: S sum of the power in the signal times the log of the power in the signal max_freq: Frequency corresponding to highest power in the signal Reference: Zangróniz, R., Martínez-Rodrigo, A., Pastor, J.M., López, M.T. and Fernández-Caballero, A., 2017. Electrodermal activity sensor for classification of calm/distress condition. Sensors, 17(10), p.2324. Args: sig (ArrayLike): EDA signal. prefix (str, optional): Prefix for the feature. Defaults to "eda". Returns: dict: Dictionary of calculated features. """ sig_features = {} sig_fft = fft(np.array(sig)) freqs, psd = signal.welch(sig_fft, return_onesided=False) for k, f in FREQ_FEATURES.items(): try: sig_features["_".join([prefix, k])] = f(psd, freqs) except: sig_features["_".join([prefix, k])] = np.nan return sig_features