87 lines
2.8 KiB
Python
87 lines
2.8 KiB
Python
"""Compute resolution matrix for beamformers."""
|
|
|
|
# Authors: The MNE-Python contributors.
|
|
# License: BSD-3-Clause
|
|
# Copyright the MNE-Python contributors.
|
|
|
|
import numpy as np
|
|
|
|
from .._fiff.pick import pick_channels, pick_channels_forward, pick_info
|
|
from ..evoked import EvokedArray
|
|
from ..utils import fill_doc, logger
|
|
from ._lcmv import apply_lcmv
|
|
|
|
|
|
@fill_doc
|
|
def make_lcmv_resolution_matrix(filters, forward, info):
|
|
"""Compute resolution matrix for LCMV beamformer.
|
|
|
|
Parameters
|
|
----------
|
|
filters : instance of Beamformer
|
|
Dictionary containing filter weights from LCMV beamformer
|
|
(see mne.beamformer.make_lcmv).
|
|
forward : instance of Forward
|
|
Forward Solution with leadfield matrix.
|
|
%(info_not_none)s Used to compute LCMV filters.
|
|
|
|
Returns
|
|
-------
|
|
resmat : array, shape (n_dipoles_lcmv, n_dipoles_fwd)
|
|
Resolution matrix (filter matrix multiplied to leadfield from
|
|
forward solution). Numbers of rows (n_dipoles_lcmv) and columns
|
|
(n_dipoles_fwd) may differ by a factor depending on orientation
|
|
constraints of filter and forward solution, respectively (e.g. factor 3
|
|
for free dipole orientation versus factor 1 for scalar beamformers).
|
|
"""
|
|
# don't include bad channels from noise covariance matrix
|
|
bads_filt = filters["noise_cov"]["bads"]
|
|
ch_names = filters["noise_cov"]["names"]
|
|
|
|
# good channels
|
|
ch_names = [c for c in ch_names if (c not in bads_filt)]
|
|
|
|
# adjust channels in forward solution
|
|
forward = pick_channels_forward(forward, ch_names, ordered=True)
|
|
|
|
# get leadfield matrix from forward solution
|
|
leadfield = forward["sol"]["data"]
|
|
|
|
# get the filter weights for beamformer as matrix
|
|
filtmat = _get_matrix_from_lcmv(filters, forward, info)
|
|
|
|
# compute resolution matrix
|
|
resmat = filtmat.dot(leadfield)
|
|
|
|
logger.info(f"Dimensions of LCMV resolution matrix: {resmat.shape}.")
|
|
|
|
return resmat
|
|
|
|
|
|
def _get_matrix_from_lcmv(filters, forward, info, verbose=None):
|
|
"""Get inverse matrix for LCMV beamformer.
|
|
|
|
Returns
|
|
-------
|
|
invmat : array, shape (n_dipoles, n_channels)
|
|
Inverse matrix associated with LCMV beamformer filters.
|
|
"""
|
|
# number of channels for identity matrix
|
|
info = pick_info(info, pick_channels(info["ch_names"], filters["ch_names"]))
|
|
n_chs = len(info["ch_names"])
|
|
|
|
# create identity matrix as input for inverse operator
|
|
# set elements to zero for non-selected channels
|
|
id_mat = np.eye(n_chs)
|
|
|
|
# convert identity matrix to evoked data type (pretending it's an epochs
|
|
evo_ident = EvokedArray(id_mat, info=info, tmin=0.0)
|
|
|
|
# apply beamformer to identity matrix
|
|
stc_lcmv = apply_lcmv(evo_ident, filters, verbose=verbose)
|
|
|
|
# turn source estimate into numpsy array
|
|
invmat = stc_lcmv.data
|
|
|
|
return invmat
|