<jupyter_start><jupyter_text>Signal Subspace Projections (SSP) for removing artefacts`Authors:<NAME>`License: BSD (3-clause)<jupyter_code>import numpy as np

import mne
from mne.datasets import sample
from mne.utils import set_log_level
# SSP (projection) related functionality
from mne.preprocessing import compute_proj_ecg, compute_proj_eog
from mne.preprocessing import create_ecg_epochs, create_eog_epochs
set_log_level('warning')  # we don't want to see all loging outputs today
# getting some data ready
data_path = sample.data_path()
raw_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw.fif'

raw = mne.io.read_raw_fif(raw_fname, preload=True)

# Let's work only with MEG data with the EOG channel(s)
picks_meg = mne.pick_types(raw.info, meg=True, eeg=False, eog=True,
                           stim=True, exclude='bads')

raw.pick_channels([raw.ch_names[k] for k in picks_meg])  # select MEG channels only
raw.filter(1, 45, n_jobs=2)  # note the n_jobs=2 to run filtering in parallel !<jupyter_output><empty_output><jupyter_text>Before fitting models let's look at what we want to get rid offFirst ECGWhat is the order of magnitude of the average artefact?Do we see different spatial patterns?<jupyter_code>%matplotlib inline 
reject = dict(mag=4e-12, grad=4000e-13)  # don't fit on crazy environmental artefacts
ecg_average = create_ecg_epochs(raw, reject=reject).average()
ecg_average.plot_joint();<jupyter_output><empty_output><jupyter_text>And now EOG<jupyter_code>reject = dict(mag=4e-12, grad=4000e-13)  # don't fit on crazy environmental artefacts
eog_average = create_eog_epochs(raw, reject=reject).average()
eog_average.plot_joint();<jupyter_output><empty_output><jupyter_text>Compute SSP projection vectorsFirst for ECG<jupyter_code>compute_proj_ecg?
projs, events = compute_proj_ecg(raw, n_grad=1, n_mag=1, average=True)
print(projs)
ecg_projs = projs[-2:]
mne.viz.plot_projs_topomap(ecg_projs);<jupyter_output><empty_output><jupyter_text>Now for EOG<jupyter_code>projs, events = compute_proj_eog(raw, n_grad=1, n_mag=1, average=True)
print(projs)
eog_projs = projs[-2:]
mne.viz.plot_projs_topomap(eog_projs);<jupyter_output><empty_output><jupyter_text>Apply projections<jupyter_code>raw.info['projs'] += eog_projs + ecg_projs
events = mne.find_events(raw, stim_channel='STI 014')
reject = dict(grad=4000e-13, mag=4e-12, eog=150e-6)  # this can be highly data dependent
event_id = [1]
epochs_no_proj = mne.Epochs(raw, events, event_id, tmin=-0.2, tmax=0.5, proj=False,
                            baseline=(None, 0), reject=reject)
epochs_no_proj.average().plot(spatial_colors=True);
epochs_proj = mne.Epochs(raw, events, event_id, tmin=-0.2, tmax=0.5, proj=True,
                         baseline=(None, 0), reject=reject)
epochs_proj.average().plot(spatial_colors=True);<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11326746647847566, 'fraction_numerical': 0.02117148906139732, 'mean_word_length': 6.306701030927835, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '198859', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1118, 'n_tokens_neox': 1062, 'n_words': 218, 'path': '2016_05_Halifax/Day1/Preprocessing_SSP.ipynb', 'repo_name': 'mne-tools/mne-workshops', 'size': '2846'}