initial commit
This commit is contained in:
95
mne/preprocessing/_css.py
Normal file
95
mne/preprocessing/_css.py
Normal file
@@ -0,0 +1,95 @@
|
||||
# Authors: The MNE-Python contributors.
|
||||
# License: BSD-3-Clause
|
||||
# Copyright the MNE-Python contributors.
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .._fiff.pick import _picks_to_idx
|
||||
from ..evoked import Evoked
|
||||
from ..utils import _ensure_int, _validate_type, verbose
|
||||
|
||||
|
||||
def _temp_proj(ref_2, ref_1, raw_data, n_proj=6):
|
||||
# Orthonormalize gradiometer and magnetometer data by a QR decomposition
|
||||
ref_1_orth = np.linalg.qr(ref_1.T)[0]
|
||||
ref_2_orth = np.linalg.qr(ref_2.T)[0]
|
||||
|
||||
# Calculate cross-correlation
|
||||
cross_corr = np.dot(ref_1_orth.T, ref_2_orth)
|
||||
|
||||
# Channel weights for common temporal subspace by SVD of cross-correlation
|
||||
ref_1_ch_weights, _, _ = np.linalg.svd(cross_corr)
|
||||
|
||||
# Get temporal signals from channel weights
|
||||
proj_mat = ref_1_orth @ ref_1_ch_weights
|
||||
|
||||
# Project out common subspace
|
||||
filtered_data = raw_data
|
||||
proj_vec = proj_mat[:, :n_proj]
|
||||
weights = filtered_data @ proj_vec
|
||||
filtered_data -= weights @ proj_vec.T
|
||||
|
||||
|
||||
@verbose
|
||||
def cortical_signal_suppression(
|
||||
evoked, picks=None, mag_picks=None, grad_picks=None, n_proj=6, *, verbose=None
|
||||
):
|
||||
"""Apply cortical signal suppression (CSS) to evoked data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
evoked : instance of Evoked
|
||||
The evoked object to use for CSS. Must contain magnetometer,
|
||||
gradiometer, and EEG channels.
|
||||
%(picks_good_data)s
|
||||
mag_picks : array-like of int
|
||||
Array of the first set of channel indices that will be used to find
|
||||
the common temporal subspace. If None (default), all magnetometers will
|
||||
be used.
|
||||
grad_picks : array-like of int
|
||||
Array of the second set of channel indices that will be used to find
|
||||
the common temporal subspace. If None (default), all gradiometers will
|
||||
be used.
|
||||
n_proj : int
|
||||
The number of projection vectors.
|
||||
%(verbose)s
|
||||
|
||||
Returns
|
||||
-------
|
||||
evoked_subcortical : instance of Evoked
|
||||
The evoked object with contributions from the ``mag_picks`` and ``grad_picks``
|
||||
channels removed from the ``picks`` channels.
|
||||
|
||||
Notes
|
||||
-----
|
||||
This method removes the common signal subspace between two sets of
|
||||
channels (``mag_picks`` and ``grad_picks``) from a set of channels
|
||||
(``picks``) via a temporal projection using ``n_proj`` number of
|
||||
projection vectors. In the reference publication :footcite:`Samuelsson2019`,
|
||||
the joint subspace between magnetometers and gradiometers is used to
|
||||
suppress the cortical signal in the EEG data. In principle, other
|
||||
combinations of sensor types (or channels) could be used to suppress
|
||||
signals from other sources.
|
||||
|
||||
References
|
||||
----------
|
||||
.. footbibliography::
|
||||
"""
|
||||
_validate_type(evoked, Evoked, "evoked")
|
||||
n_proj = _ensure_int(n_proj, "n_proj")
|
||||
picks = _picks_to_idx(evoked.info, picks, none="data", exclude="bads")
|
||||
mag_picks = _picks_to_idx(evoked.info, mag_picks, none="mag", exclude="bads")
|
||||
grad_picks = _picks_to_idx(evoked.info, grad_picks, none="grad", exclude="bads")
|
||||
evoked_subcortical = evoked.copy()
|
||||
|
||||
# Get data
|
||||
all_data = evoked.data
|
||||
mag_data = all_data[mag_picks]
|
||||
grad_data = all_data[grad_picks]
|
||||
|
||||
# Process data with temporal projection algorithm
|
||||
data = all_data[picks]
|
||||
_temp_proj(mag_data, grad_data, data, n_proj=n_proj)
|
||||
evoked_subcortical.data[picks, :] = data
|
||||
|
||||
return evoked_subcortical
|
||||
Reference in New Issue
Block a user