Extended artefact detection
The CNN model aims to distinguish artefacts from clean samples. There exist additional artefact detection methods and they can all be combined. This script shows how various artefact detection methods can easily be combined.
Author: Tim Hermans (tim-hermans@hotmail.com).
Link to script: artefacts/extended_artefact_detection.py
import numpy as np
from nnsa import CleanDetectorCnn, detect_anomalous_channels, EegDataset
First, let us demonstrate how to do it using EEG data in array format.
# Simulate random data (looks nothing like EEG, so will all be classified as artefact).
fs = 250
channel_labels = ['EEG Fp1', 'EEG Fp2', 'EEG C3', 'EEG C4', 'EEG T3', 'EEG T4', 'EEG O1', 'EEG O2']
eeg = (np.random.rand(fs*40, len(channel_labels)) - 0.5)*300
Apply the CNN model.
# Initiate the CNN artefact detector.
cnn = CleanDetectorCnn(multi_channel=True)
# Predict/detect clean locations (see also apply_cnn_to_array). Note the options detect_flat and detect_peaks
# which also check for low and high amplitude EEG (especially low amplitudes/flatlines could be missed be the CNN).
clean_mask, _ = cnn.predict(
eeg=eeg, fs=fs, preprocess=True,
detect_flats=True, detect_peaks=True,
verbose=1)
# Clean mask to artefact mask.
af_mask = clean_mask == 0
# The mask should have the same shape as the EEG.
assert af_mask.shape == eeg.shape
We can also detect anomolous channels. See the function documentation for more details.
# Detect anomalous channels based on line length.
anomaly_mask = detect_anomalous_channels(
x=eeg, fs=fs, window=3, std_factor=8, p_trim=0.25, shape_mode='transpose')
# The mask should have the same shape as the EEG.
assert anomaly_mask.shape == eeg.shape
# Use the or operator to update the artefact mask.
af_mask = af_mask | anomaly_mask
If we start from an EegDataset object, we can do all of the above in just one line.
# Convert the array data to an EegDataset (or read the EEG data in EegDataset format immediately from an EDF,
# see EdfReader).
eeg_ds = EegDataset.from_array(eeg=eeg, fs=fs, channel_labels=channel_labels)
# Detect the artefacts with several methods combined (see the docs of the funtion).
af_mask_ds = eeg_ds.detect_artefacts(multi_channel_cnn=True, verbose=1)
# The mask should have the same shape as the EEG.
assert af_mask_ds.shape == eeg_ds.shape