96 lines
3.3 KiB
Python
96 lines
3.3 KiB
Python
# 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
|