Wave Detector#
Wave detection#
WaveDetector finds waves (a negative half-wave followed by a positive
half-wave) inside a chosen frequency band and reports morphological features of
those waves – amplitude, peak-to-peak, duration and slope.
It is a general half-wave detector: with fband=(0.5, 4) it detects delta waves,
with (0.5, 0.9) slow oscillations, and any other band works too. The interface
mirrors brainmaze_eeg.features.feature_extraction.SleepSpectralFeatureExtractor
and brainmaze_eeg.features.time_domain_features.TimeDomainFeatureExtractor:
calling the detector returns (values, names) so wave features can be concatenated
with spectral / time-domain features for the same epochs.
Two ways to use it#
Windowed feature extraction (__call__):
from brainmaze_eeg.features.wave_detector import WaveDetector
det = WaveDetector(fs=200, fband=(0.5, 4.0), segm_size=30)
values, names = det(x) # x: 1-D or (n_signals, n_samples)
Raw detections, for plotting or custom analysis (detect):
det = WaveDetector(fs=200, fband=(0.5, 4.0))
waves = det.detect(x) # dict (1-D) or list of dicts (2-D)
plt.plot(x)
plt.plot(waves['min_pos'], waves['min_val'], 'v')
plt.plot(waves['max_pos'], waves['max_val'], '^')
Slope conventions#
slope='upslope'Trough -> peak rate,
(max_val - min_val) / (t_peak - t_trough). This is the historical behaviour of this class.slope='downslope'Zero-crossing -> negative-trough rate,
|min_val| / (t_trough - t_zero_cross). This is the slow-wave downslope used by Carvalho et al. 2024, who measure it on a broadband trace (pass that trace viameasure_on=) after detecting on the narrow band, and apply an amplitude threshold on the negative peak (amplitude_threshold).
References
Carvalho D.Z. et al. (2024), Non-rapid eye movement sleep slow-wave activity features are associated with amyloid accumulation in older adults with obstructive sleep apnoea, Brain Communications 6(5): fcae354. https://doi.org/10.1093/braincomms/fcae354
Lineage: this detector is the successor of the SlowWaveDetect routine used in the
study above, generalised to an arbitrary band; the slope='downslope' +
amplitude_threshold + measure_on options reproduce that original feature.
- class brainmaze_eeg.features.wave_detector.WaveDetector(fs, fband=(0.5, 4.0), segm_size=None, overlap=0.0, slope='downslope', amplitude_threshold=None, datarate=False, n_processes=1, cutoff_low=None, cutoff_high=None)#
Band-limited wave detector and windowed feature extractor.
- Parameters:
fs (float) – Sampling frequency (Hz).
fband ((float, float)) – Single
(low, high)band in Hz. One detector detects in one band; run several detectors for several bands. Default(0.5, 4.0)(delta).segm_size (float, optional) – Feature window length in seconds.
None(default) treats the whole signal as one window.overlap (float) – Feature window overlap in seconds. Default
0.0.slope ({'downslope', 'upslope'}) – Which slope
WAVE_SLOPE_MEANreports (see module docstring). Default'downslope'.amplitude_threshold (float, optional) – Keep only waves whose negative trough is at least this deep (
-min_val >= amplitude_threshold), measured on the amplitude signal.None(default) keeps all waves. Carvalho et al. use5(µV).datarate (bool) – If True, prepend a
DATA_RATEfeature (fraction of non-NaN samples per window).n_processes (int) – Parallelise detection across signals for 2-D / list input. Default
1.
- property cutoff_high#
- property cutoff_low#
- detect(x, measure_on=None)#
Raw per-signal detections.
- Parameters:
x (np.ndarray or list) – 1-D
(n_samples,), 2-D(n_signals, n_samples), or list of 1-D arrays.measure_on (np.ndarray or list, optional) – Amplitude signal(s), same shape as
x.
- Returns:
A single detection dict for 1-D input, otherwise one dict per signal. Signals are detected independently – positions index into that signal.
- Return type:
dict or list of dict
- brainmaze_eeg.features.wave_detector.detect_waves(x, fs, fband=(0.5, 4.0), measure_on=None)#
Detect waves in a single 1-D signal and return their positions and morphology.
- Parameters:
x (np.ndarray) – 1-D signal.
fs (float) – Sampling frequency (Hz).
fband ((float, float)) – (low, high) band in Hz that defines the waves to detect.
measure_on (np.ndarray, optional) – Signal the amplitudes/slopes are read from (same length as
x). Detection always runs onx; whenmeasure_onis given, morphology is measured on it (e.g. detect on a narrow band, measure on a 0.5-35 Hz broadband trace). Defaults to the drift-removedx.
- Returns:
Keys:
min_pos, min_val, max_pos, max_val, zero_pos(arrays over waves) and the derived per-wave arrayspk2pk, delta_t, upslope, down_dur, downslope.- Return type:
dict