Time Domain Features#

Time-domain feature extraction#

Windowed time-domain features for EEG/iEEG. Mirrors the call contract of brainmaze_eeg.features.feature_extraction.SleepSpectralFeatureExtractorextractor(x) -> (values, names) – so time-domain and spectral features can be concatenated for the same epochs.

Features#

LINE_LENGTH

Sum of absolute sample-to-sample differences within a window. Scales with window length; divide by DATA_RATE * segm_size * fs to obtain a per-sample rate.

TKEO_MEAN

Mean Teager-Kaiser energy within a window.

Example

import numpy as np
from brainmaze_eeg.features.time_domain_features import TimeDomainFeatureExtractor

fs = 200
x = np.random.randn(2, 60 * fs)          # (n_channels, n_samples)

extractor = TimeDomainFeatureExtractor(fs=fs, segm_size=30, datarate=True)
values, names = extractor(x)             # values: list of (n_channels, n_windows)
class brainmaze_eeg.features.time_domain_features.TimeDomainFeatureExtractor(fs: float, segm_size: float, overlap: float = 0.0, features: tuple = ('LINE_LENGTH', 'TKEO_MEAN'), datarate: bool = False)#

Windowed time-domain feature extractor.

Each feature is computed from the samples inside its window: line length sums the n-1 increments between consecutive in-window samples, and TKEO averages the n-2 values it can define without reaching outside. Values are therefore identical to a straightforward per-window computation – this class does not change the definitions, only how fast they are evaluated.

The speed comes from evaluating each per-sample operator once across the whole signal and then aggregating it with a strided window view, so there is no Python-level loop over windows or channels and no copy of the signal. Cost is O(n_samples) per channel. Clean (NaN-free) input takes a branch with no masking and no nan-aware reductions, which is roughly 2x faster again.

Parameters:
  • fs (float) – Sampling frequency in Hz.

  • segm_size (float) – Window length in seconds.

  • overlap (float) – Window overlap in seconds. Must be in [0, segm_size). Default 0.0.

  • features (tuple of str) – Which features to compute. Any of 'LINE_LENGTH', 'TKEO_MEAN'.

  • datarate (bool) – If True, prepend a DATA_RATE feature: the fraction of non-NaN samples in each window. Default False.

Notes

NaNs propagate as missing data, not as zeros: they are excluded from each window’s aggregate rather than being counted as flat signal. A window that is entirely NaN yields NaN. Pair with datarate=True to know how much of each window was real.

AVAILABLE_FEATURES = ('LINE_LENGTH', 'TKEO_MEAN')#
brainmaze_eeg.features.time_domain_features.line_length(x: ndarray, axis: int = -1) ndarray#

Per-sample line-length increments.

\[L[n] = |x[n] - x[n-1]|\]

Summing these within a window gives the classic line-length feature, a cheap proxy for signal complexity and amplitude that is widely used for seizure onset detection.

Parameters:
  • x (np.ndarray) – Input signal. May be of any dimensionality.

  • axis (int) – Axis along which the increments are computed. Default is the last axis.

Returns:

Same shape as x. The first sample along axis is undefined and set to NaN, so the result stays sample-aligned with the input.

Return type:

np.ndarray

brainmaze_eeg.features.time_domain_features.tkeo(x: ndarray, axis: int = -1) ndarray#

Teager-Kaiser Energy Operator.

\[\Psi[n] = x[n]^2 - x[n-1] \cdot x[n+1]\]

Tracks the instantaneous energy of a quasi-sinusoidal signal, being jointly proportional to the square of its amplitude and frequency. Sensitive to sharp transients, which makes it useful for spike and artefact detection.

Parameters:
  • x (np.ndarray) – Input signal. May be of any dimensionality.

  • axis (int) – Axis along which the operator is applied. Default is the last axis.

Returns:

Same shape as x. The first and last samples along axis are undefined and set to NaN, so the result stays sample-aligned with the input.

Return type:

np.ndarray