Skip to content

Commit

Permalink
UPDATE mne 0.20
Browse files Browse the repository at this point in the history
  • Loading branch information
christianbrodbeck committed May 2, 2020
1 parent d6b0326 commit 216cca5
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 99 deletions.
98 changes: 2 additions & 96 deletions eelbrain/mne_fixes/_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,19 @@
import logging

import numpy as np
from numpy.polynomial.legendre import legval
from scipy import linalg

import mne
from mne.bem import _fit_sphere
from mne.channels.interpolation import _make_interpolation_matrix
from mne.forward import _map_meg_channels
from mne.io.pick import pick_types, pick_channels
from mne.surface import _normalize_vectors


# mne 0.10 function
def map_meg_channels(inst, picks_good, picks_bad, mode):
info_from = mne.pick_info(inst.info, picks_good, copy=True)
info_to = mne.pick_info(inst.info, picks_bad, copy=True)
return _map_meg_channels(info_from, info_to, mode=mode)
return _map_meg_channels(info_from, info_to, mode=mode, origin='auto')


# private in 0.9.0 (Epochs method)
Expand All @@ -42,98 +40,6 @@ def get_channel_positions(self, picks=None):
return pos


def _calc_g(cosang, stiffness=4, num_lterms=50):
"""Calculate spherical spline g function between points on a sphere.
Parameters
----------
cosang : array-like of float, shape(n_channels, n_channels)
cosine of angles between pairs of points on a spherical surface. This
is equivalent to the dot product of unit vectors.
stiffness : float
stiffness of the spline.
num_lterms : int
number of Legendre terms to evaluate.
Returns
-------
G : np.ndrarray of float, shape(n_channels, n_channels)
The G matrix.
"""
factors = [(2 * n + 1) / (n ** stiffness * (n + 1) ** stiffness *
4 * np.pi) for n in range(1, num_lterms + 1)]
return legval(cosang, [0] + factors)


def _calc_h(cosang, stiffness=4, num_lterms=50):
"""Calculate spherical spline h function between points on a sphere.
Parameters
----------
cosang : array-like of float, shape(n_channels, n_channels)
cosine of angles between pairs of points on a spherical surface. This
is equivalent to the dot product of unit vectors.
stiffness : float
stiffness of the spline. Also referred to as `m`.
num_lterms : int
number of Legendre terms to evaluate.
H : np.ndrarray of float, shape(n_channels, n_channels)
The H matrix.
"""
factors = [(2 * n + 1) /
(n ** (stiffness - 1) * (n + 1) ** (stiffness - 1) * 4 * np.pi)
for n in range(1, num_lterms + 1)]
return legval(cosang, [0] + factors)


def _make_interpolation_matrix(pos_from, pos_to, alpha=1e-5):
"""Compute interpolation matrix based on spherical splines
Implementation based on [1]
Parameters
----------
pos_from : np.ndarray of float, shape(n_good_sensors, 3)
The positions to interpoloate from.
pos_to : np.ndarray of float, shape(n_bad_sensors, 3)
The positions to interpoloate.
alpha : float
Regularization parameter. Defaults to 1e-5.
Returns
-------
interpolation : np.ndarray of float, shape(len(pos_from), len(pos_to))
The interpolation matrix that maps good signals to the location
of bad signals.
References
----------
[1] Perrin, F., Pernier, J., Bertrand, O. and Echallier, JF. (1989).
Spherical splines for scalp potential and current density mapping.
Electroencephalography Clinical Neurophysiology, Feb; 72(2):184-7.
"""

pos_from = pos_from.copy()
pos_to = pos_to.copy()

# normalize sensor positions to sphere
_normalize_vectors(pos_from)
_normalize_vectors(pos_to)

# cosine angles between source positions
cosang_from = pos_from.dot(pos_from.T)
cosang_to_from = pos_to.dot(pos_from.T)
G_from = _calc_g(cosang_from)
G_to_from, H_to_from = (f(cosang_to_from) for f in (_calc_g, _calc_h))

if alpha is not None:
G_from.flat[::len(G_from) + 1] += alpha

C_inv = linalg.pinv(G_from)
interpolation = G_to_from.dot(C_inv)
return interpolation


def _make_interpolator(inst, bad_channels):
"""Find indexes and interpolation matrix to interpolate bad channels
Expand Down
2 changes: 1 addition & 1 deletion eelbrain/mne_fixes/_label.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
@verbose
def write_labels_to_annot(labels, subject=None, parc=None, overwrite=False,
subjects_dir=None, annot_fname=None,
colormap='hsv', hemi='both'):
colormap='hsv', hemi='both', verbose=None):
"""Create a FreeSurfer annotation from a list of labels
FIX: always write both hemispheres
Expand Down
6 changes: 4 additions & 2 deletions eelbrain/mne_fixes/tests/test_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ def test_interpolation():
bads3 = ['MEG 0531', 'MEG 2231']
bads_list = [[], bads1, [], bads3]
test_epochs = ds['epochs']
index_0531 = test_epochs.ch_names.index('MEG 0531')
test_epochs._data[1, index_0531] = 0
epochs1 = test_epochs.copy()
epochs3 = test_epochs.copy()

_interpolate_bads_meg(test_epochs, bads_list, {})
assert_array_equal(test_epochs._data[0], epochs1._data[0])
assert_array_equal(test_epochs._data[2], epochs1._data[2])
epochs1.info['bads'] = bads1
epochs1.interpolate_bads(mode='accurate')
epochs1.interpolate_bads(mode='accurate', origin='auto')
assert_array_almost_equal(test_epochs._data[1], epochs1._data[1], 25)
epochs3.info['bads'] = bads3
epochs3.interpolate_bads(mode='accurate')
epochs3.interpolate_bads(mode='accurate', origin='auto')
assert_array_almost_equal(test_epochs._data[3], epochs3._data[3], 25)

0 comments on commit 216cca5

Please sign in to comment.