[med-svn] [python-mne] 07/353: ENH : Sign flip computation for robust label average of signed values
Yaroslav Halchenko
debian at onerussian.com
Fri Nov 27 17:24:24 UTC 2015
This is an automated email from the git hooks/post-receive script.
yoh pushed a commit to tag 0.4
in repository python-mne.
commit 11ca75b38a22b7dfa2d48886401b61b2d2af6162
Author: Alexandre Gramfort <alexandre.gramfort at inria.fr>
Date: Tue Nov 8 22:57:17 2011 -0500
ENH : Sign flip computation for robust label average of signed values
---
doc/source/whats_new.rst | 8 +++++
.../plot_compute_mne_inverse_epochs_in_label.py | 13 +++++++-
mne/__init__.py | 2 +-
mne/label.py | 39 ++++++++++++++++++++++
mne/minimum_norm/tests/test_inverse.py | 21 ++++++++----
5 files changed, 74 insertions(+), 9 deletions(-)
diff --git a/doc/source/whats_new.rst b/doc/source/whats_new.rst
index 35650f3..2ef2950 100644
--- a/doc/source/whats_new.rst
+++ b/doc/source/whats_new.rst
@@ -3,6 +3,14 @@ What's new
.. _changes_0_2:
+Current
+-----------
+
+Changelog
+~~~~~~~~~
+
+ - Sign flip computation for robust label average of signed values by `Alex Gramfort`_.
+
Version 0.2
-----------
diff --git a/examples/inverse/plot_compute_mne_inverse_epochs_in_label.py b/examples/inverse/plot_compute_mne_inverse_epochs_in_label.py
index 3975282..473c64e 100644
--- a/examples/inverse/plot_compute_mne_inverse_epochs_in_label.py
+++ b/examples/inverse/plot_compute_mne_inverse_epochs_in_label.py
@@ -14,6 +14,7 @@ to a brain label.
print __doc__
+import numpy as np
import pylab as pl
import mne
from mne.datasets import sample
@@ -57,9 +58,19 @@ stcs = apply_inverse_epochs(epochs, inverse_operator, lambda2, dSPM, label,
data = sum(stc.data for stc in stcs) / len(stcs)
+# compute sign flip to avoid signal cancelation when averaging signed values
+flip = mne.label_sign_flip(label, inverse_operator['src'])
+
+label_mean = np.mean(data, axis=0)
+label_mean_flip = np.mean(flip[:, np.newaxis] * data, axis=0)
+
###############################################################################
# View activation time-series
-pl.plot(1e3 * stcs[0].times, data.T)
+h0 = pl.plot(1e3 * stcs[0].times, data.T, 'k')
+h1 = pl.plot(1e3 * stcs[0].times, label_mean, 'r', linewidth=3)
+h2 = pl.plot(1e3 * stcs[0].times, label_mean_flip, 'g', linewidth=3)
+pl.legend((h0[0], h1, h2), ('all dipoles in label', 'mean',
+ 'mean with sign flip'))
pl.xlabel('time (ms)')
pl.ylabel('dSPM value')
pl.show()
diff --git a/mne/__init__.py b/mne/__init__.py
index 750bf56..45ee7fb 100644
--- a/mne/__init__.py
+++ b/mne/__init__.py
@@ -11,7 +11,7 @@ from .source_estimate import read_stc, write_stc, SourceEstimate, morph_data, \
from .surface import read_bem_surfaces, read_surface
from .source_space import read_source_spaces
from .epochs import Epochs
-from .label import label_time_courses, read_label
+from .label import label_time_courses, read_label, label_sign_flip
from .misc import parse_config, read_reject_parameters
from .transforms import transform_coordinates
from .proj import read_proj
diff --git a/mne/label.py b/mne/label.py
index da5fcad..13320fe 100644
--- a/mne/label.py
+++ b/mne/label.py
@@ -1,4 +1,5 @@
import numpy as np
+from scipy import linalg
from .source_estimate import read_stc
@@ -80,3 +81,41 @@ def label_time_courses(labelfile, stcfile):
times = stc['tmin'] + stc['tstep'] * np.arange(stc['data'].shape[1])
return values, times, vertices
+
+
+def label_sign_flip(label, src):
+ """Compute sign for label averaging
+
+ Parameters
+ ----------
+ label : dict
+ A label read with the read_label function
+ src : list of dict
+ The source space over which is defined the label
+
+ Returns
+ -------
+ flip : array
+ Sign flip vector (contains 1 or -1)
+ """
+ if len(src) != 2:
+ raise ValueError('Only source spaces with 2 hemisphers are accepted')
+
+ lh_vertno = src[0]['vertno']
+ rh_vertno = src[1]['vertno']
+
+ # get source orientations
+ if label['hemi'] == 'lh':
+ vertno_sel = np.intersect1d(lh_vertno, label['vertices'])
+ ori = src[0]['nn'][vertno_sel]
+ elif label['hemi'] == 'rh':
+ vertno_sel = np.intersect1d(rh_vertno, label['vertices'])
+ ori = src[1]['nn'][vertno_sel]
+ else:
+ raise Exception("Unknown hemisphere type")
+
+ _, _, Vh = linalg.svd(ori, full_matrices=False)
+
+ # Comparing to the direction of the first right singular vector
+ flip = np.sign(np.dot(ori, Vh[:, 0]))
+ return flip
diff --git a/mne/minimum_norm/tests/test_inverse.py b/mne/minimum_norm/tests/test_inverse.py
index d5fe27d..1fdde52 100644
--- a/mne/minimum_norm/tests/test_inverse.py
+++ b/mne/minimum_norm/tests/test_inverse.py
@@ -4,7 +4,7 @@ from numpy.testing import assert_array_almost_equal, assert_equal
from nose.tools import assert_true
from ...datasets import sample
-from ...label import read_label
+from ...label import read_label, label_sign_flip
from ...event import read_events
from ...epochs import Epochs
from ...source_estimate import SourceEstimate
@@ -48,7 +48,6 @@ def test_inverse_operator():
With and without precomputed inverse operator.
"""
evoked = fiff.Evoked(fname_data, setno=0, baseline=(None, 0))
- from copy import deepcopy
stc = apply_inverse(evoked, inverse_operator, lambda2, dSPM=False)
@@ -113,12 +112,20 @@ def test_apply_mne_inverse_epochs():
reject = dict(grad=4000e-13, mag=4e-12, eog=150e-6)
flat = dict(grad=1e-15, mag=1e-15)
- events = read_events(fname_event)[:3]
+ events = read_events(fname_event)[:15]
epochs = Epochs(raw, events, event_id, tmin, tmax, picks=picks,
baseline=(None, 0), reject=reject, flat=flat)
stcs = apply_inverse_epochs(epochs, inverse_operator, lambda2, dSPM,
- label=label)
+ label=label, pick_normal=True)
- assert_true(len(stcs) == 1)
- assert_true(np.all(stcs[0].data > 0))
- assert_true(np.all(stcs[0].data < 42))
+ assert_true(len(stcs) == 4)
+ assert_true(3 < stcs[0].data.max() < 10)
+
+
+ data = sum(stc.data for stc in stcs) / len(stcs)
+ flip = label_sign_flip(label, inverse_operator['src'])
+
+ label_mean = np.mean(data, axis=0)
+ label_mean_flip = np.mean(flip[:, np.newaxis] * data, axis=0)
+
+ assert_true(label_mean.max() < label_mean_flip.max())
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-mne.git
More information about the debian-med-commit
mailing list