[med-svn] [python-mne] 67/353: ENH: include pick_normal into _assemble_kernel to avoid computation of non-normal components when pick_normal=True

Yaroslav Halchenko debian at onerussian.com
Fri Nov 27 17:24:32 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 aa342f294327618b414d4f3332d8bd75e0baa72c
Author: Martin Luessi <mluessi at nmr.mgh.harvard.edu>
Date:   Mon Jan 30 12:42:58 2012 -0500

    ENH: include pick_normal into _assemble_kernel to avoid computation of non-normal components when pick_normal=True
---
 mne/minimum_norm/inverse.py        | 69 ++++++++++++++++++++++----------------
 mne/minimum_norm/time_frequency.py |  4 +--
 2 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/mne/minimum_norm/inverse.py b/mne/minimum_norm/inverse.py
index 54301b5..7e33dc0 100644
--- a/mne/minimum_norm/inverse.py
+++ b/mne/minimum_norm/inverse.py
@@ -288,19 +288,6 @@ def combine_xyz(vec, square=False):
     return comb
 
 
-def _combine_ori(sol, inverse_operator, pick_normal):
-    if inverse_operator['source_ori'] == FIFF.FIFFV_MNE_FREE_ORI:
-        if pick_normal:
-            is_loose = 0 < inverse_operator['orient_prior']['data'][0] < 1
-            if not is_loose:
-                raise ValueError('The pick_normal parameter is only valid '
-                                 'when working with loose orientations.')
-            sol = sol[2::3]  # take one every 3 sources ie. only the normal
-        else:
-            sol = combine_xyz(sol)
-    return sol
-
-
 def _chech_ch_names(inv, info):
     """Check that channels in inverse operator are measurements"""
 
@@ -440,10 +427,10 @@ def prepare_inverse_operator(orig, nave, lambda2, dSPM):
     return inv
 
 
-def _assemble_kernel(inv, label, dSPM):
+def _assemble_kernel(inv, label, dSPM, pick_normal):
     #
     #   Simple matrix multiplication followed by combination of the
-    #   three current components
+    #   current components
     #
     #   This does all the data transformations to compute the weights for the
     #   eigenleads
@@ -470,6 +457,20 @@ def _assemble_kernel(inv, label, dSPM):
         eigen_leads = eigen_leads[src_sel]
         source_cov = source_cov[src_sel]
 
+    if pick_normal:
+        if not inv['source_ori'] == FIFF.FIFFV_MNE_FREE_ORI:
+            raise ValueError('Pick normal can only be used with a free '
+                             'orientation inverse operator.')
+
+        is_loose = 0 < inv['orient_prior']['data'][0] < 1
+        if not is_loose:
+            raise ValueError('The pick_normal parameter is only valid '
+                             'when working with loose orientations.')
+
+        # keep only the normal components
+        eigen_leads = eigen_leads[2::3]
+        source_cov = source_cov[2::3]
+
     trans = inv['reginv'][:, None] * reduce(np.dot,
                                             [inv['eigen_fields']['data'],
                                             inv['whitener'],
@@ -574,10 +575,15 @@ def apply_inverse(evoked, inverse_operator, lambda2, dSPM=True,
     print 'Picked %d channels from the data' % len(sel)
 
     print 'Computing inverse...',
-    K, noise_norm, _ = _assemble_kernel(inv, None, dSPM)
+    K, noise_norm, _ = _assemble_kernel(inv, None, dSPM, pick_normal)
     sol = np.dot(K, evoked.data[sel])  # apply imaging kernel
-    print 'combining the current components...',
-    sol = _combine_ori(sol, inv, pick_normal)
+
+    is_free_ori = (inverse_operator['source_ori'] == FIFF.FIFFV_MNE_FREE_ORI
+                   and not pick_normal)
+
+    if is_free_ori:
+        print 'combining the current components...',
+        sol = combine_xyz(sol)
 
     if noise_norm is not None:
         print '(dSPM)...',
@@ -658,11 +664,12 @@ def apply_inverse_raw(raw, inverse_operator, lambda2, dSPM=True,
     if time_func is not None:
         data = time_func(data)
 
-    K, noise_norm, vertno = _assemble_kernel(inv, label, dSPM)
+    K, noise_norm, vertno = _assemble_kernel(inv, label, dSPM, pick_normal)
 
-    inv_free_ori = inverse_operator['source_ori'] == FIFF.FIFFV_MNE_FREE_ORI
+    is_free_ori = (inverse_operator['source_ori'] == FIFF.FIFFV_MNE_FREE_ORI
+                   and not pick_normal)
 
-    if buffer_size is not None and inv_free_ori:
+    if buffer_size is not None and is_free_ori:
         # Process the data in segments to conserve memory
         n_seg = int(np.ceil(data.shape[1] / float(buffer_size)))
         print 'computing inverse and combining the current components'\
@@ -675,13 +682,14 @@ def apply_inverse_raw(raw, inverse_operator, lambda2, dSPM=True,
 
         for pos in xrange(0, n_times, buffer_size):
             sol[:, pos:pos + buffer_size] = \
-                _combine_ori(np.dot(K, data[:, pos:pos + buffer_size]),
-                             inv, pick_normal)
+                combine_xyz(np.dot(K, data[:, pos:pos + buffer_size]))
+
             print 'segment %d / %d done..' % (pos / buffer_size + 1, n_seg)
     else:
         sol = np.dot(K, data)
-        print 'combining the current components...',
-        sol = _combine_ori(sol, inv, pick_normal)
+        if is_free_ori:
+            print 'combining the current components...',
+            sol = combine_xyz(sol)
 
     if noise_norm is not None:
         sol *= noise_norm
@@ -739,17 +747,22 @@ def apply_inverse_epochs(epochs, inverse_operator, lambda2, dSPM=True,
     print 'Picked %d channels from the data' % len(sel)
 
     print 'Computing inverse...',
-    K, noise_norm, vertno = _assemble_kernel(inv, label, dSPM)
+    K, noise_norm, vertno = _assemble_kernel(inv, label, dSPM, pick_normal)
 
     stcs = list()
     tstep = 1.0 / epochs.info['sfreq']
     tmin = epochs.times[0]
 
+    is_free_ori = (inverse_operator['source_ori'] == FIFF.FIFFV_MNE_FREE_ORI
+                   and not pick_normal)
+
     for k, e in enumerate(epochs):
         print "Processing epoch : %d" % (k + 1)
         sol = np.dot(K, e[sel])  # apply imaging kernel
-        print 'combining the current components...',
-        sol = _combine_ori(sol, inv, pick_normal)
+
+        if is_free_ori:
+            print 'combining the current components...',
+            sol = combine_xyz(sol)
 
         if noise_norm is not None:
             sol *= noise_norm
diff --git a/mne/minimum_norm/time_frequency.py b/mne/minimum_norm/time_frequency.py
index 8b049ba..95f2667 100644
--- a/mne/minimum_norm/time_frequency.py
+++ b/mne/minimum_norm/time_frequency.py
@@ -102,7 +102,7 @@ def _compute_pow_plv(data, K, sel, Ws, source_ori, use_fft, Vh, with_plv,
     n_freqs = len(Ws)
     n_sources = K.shape[0]
     is_free_ori = False
-    if source_ori == FIFF.FIFFV_MNE_FREE_ORI:
+    if (source_ori == FIFF.FIFFV_MNE_FREE_ORI and not pick_normal):
         is_free_ori = True
         n_sources /= 3
 
@@ -190,7 +190,7 @@ def _source_induced_power(epochs, inverse_operator, frequencies, label=None,
     #   This does all the data transformations to compute the weights for the
     #   eigenleads
     #
-    K, noise_norm, vertno = _assemble_kernel(inv, label, dSPM)
+    K, noise_norm, vertno = _assemble_kernel(inv, label, dSPM, pick_normal)
 
     if pca:
         U, s, Vh = linalg.svd(K, full_matrices=False)

-- 
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