[med-svn] [python-mne] 291/376: ENH : factoring code for baseline correction

Yaroslav Halchenko debian at onerussian.com
Fri Nov 27 17:23:08 UTC 2015


This is an automated email from the git hooks/post-receive script.

yoh pushed a commit to annotated tag v0.1
in repository python-mne.

commit 7d4a8c01cef56658a52eefab0370f4f94f7900d2
Author: Alexandre Gramfort <alexandre.gramfort at inria.fr>
Date:   Mon Jun 6 13:19:57 2011 -0400

    ENH : factoring code for baseline correction
---
 mne/baseline.py                    | 80 ++++++++++++++++++++++++++++++++++++++
 mne/epochs.py                      | 21 ++--------
 mne/fiff/evoked.py                 | 18 ++-------
 mne/minimum_norm/time_frequency.py | 26 ++-----------
 mne/time_frequency/tfr.py          | 26 ++-----------
 5 files changed, 93 insertions(+), 78 deletions(-)

diff --git a/mne/baseline.py b/mne/baseline.py
new file mode 100644
index 0000000..6cb7c11
--- /dev/null
+++ b/mne/baseline.py
@@ -0,0 +1,80 @@
+"""Util function to baseline correct data
+"""
+
+# Authors: Alexandre Gramfort <gramfort at nmr.mgh.harvard.edu>
+#
+# License: BSD (3-clause)
+
+import numpy as np
+
+
+def rescale(data, times, baseline, mode, verbose=True, copy=True):
+    """Rescale aka baseline correct data
+
+    Parameters
+    ----------
+    data: array
+        It can be of any shape. The only constraint is that the last
+        dimension should be time.
+
+    times: 1D array
+        Time instants is seconds
+
+    baseline: tuple or list of length 2
+        The time interval to apply rescaling / baseline correction.
+        If None do not apply it. If baseline is (a, b)
+        the interval is between "a (s)" and "b (s)".
+        If a is None the beginning of the data is used
+        and if b is None then b is set to the end of the interval.
+        If baseline is equal ot (None, None) all the time
+        interval is used.
+
+    mode: 'logratio' | 'ratio' | 'zscore' | 'mean'
+        Do baseline correction with ratio (power is divided by mean
+        power during baseline) or zscore (power is divided by standard
+        deviatio of power during baseline after substracting the mean,
+        power = [power - mean(power_baseline)] / std(power_baseline))
+
+    Returns
+    -------
+    data_scaled: array
+        Array of same shape as data after rescaling
+
+    """
+    if copy:
+        data = data.copy()
+
+    valid_modes = ['logratio', 'ratio', 'zscore', 'mean']
+    if mode not in valid_modes:
+        raise Exception('mode should be any of : %s' % valid_modes)
+
+    if baseline is not None:
+        if verbose:
+            print "Applying baseline correction ... (mode: %s)" % mode
+        bmin, bmax = baseline
+        if bmin is None:
+            imin = 0
+        else:
+            imin = int(np.where(times >= bmin)[0][0])
+        if bmax is None:
+            imax = len(times)
+        else:
+            imax = int(np.where(times <= bmax)[0][-1]) + 1
+
+        mean = np.mean(data[..., imin:imax], axis=-1)[..., None]
+        if mode == 'mean':
+            data -= mean
+        if mode == 'logratio':
+            data /= mean
+            data = np.log10(data)  # a value of 1 means 10 times bigger
+        if mode == 'ratio':
+            data /= mean
+        elif mode == 'zscore':
+            std = np.std(data[..., imin:imax], axis=-1)[..., None]
+            data -= mean
+            data /= std
+
+    elif verbose:
+        print "No baseline correction applied..."
+
+    return data
diff --git a/mne/epochs.py b/mne/epochs.py
index 68dab67..1f16abe 100644
--- a/mne/epochs.py
+++ b/mne/epochs.py
@@ -8,6 +8,7 @@ import numpy as np
 import fiff
 from .fiff import Evoked
 from .fiff.pick import pick_types, channel_indices_by_type
+from .baseline import rescale
 
 
 class Epochs(object):
@@ -222,24 +223,8 @@ class Epochs(object):
             epoch = np.dot(self.proj, epoch)
 
         # Run baseline correction
-        times = self.times
-        baseline = self.baseline
-        if baseline is not None:
-            print "Applying baseline correction ..."
-            bmin = baseline[0]
-            bmax = baseline[1]
-            if bmin is None:
-                imin = 0
-            else:
-                imin = int(np.where(times >= bmin)[0][0])
-            if bmax is None:
-                imax = len(times)
-            else:
-                imax = int(np.where(times <= bmax)[0][-1]) + 1
-            epoch -= np.mean(epoch[:, imin:imax], axis=1)[:, None]
-        else:
-            print "No baseline correction applied..."
-
+        epoch = rescale(epoch, self.times, self.baseline, 'mean', verbose=True,
+                        copy=False)
         return epoch
 
     def _get_data_from_disk(self):
diff --git a/mne/fiff/evoked.py b/mne/fiff/evoked.py
index 47d8b13..8e939a3 100644
--- a/mne/fiff/evoked.py
+++ b/mne/fiff/evoked.py
@@ -11,6 +11,7 @@ from .tag import read_tag
 from .tree import dir_tree_find
 from .meas_info import read_meas_info, write_meas_info
 from .proj import make_projector_info
+from ..baseline import rescale
 
 from .write import start_file, start_block, end_file, end_block, \
                    write_int, write_string, write_float_matrix, \
@@ -237,21 +238,8 @@ class Evoked(object):
             all_data = np.dot(self.proj, all_data)
 
         # Run baseline correction
-        if baseline is not None:
-            print "Applying baseline correction ..."
-            bmin = baseline[0]
-            bmax = baseline[1]
-            if bmin is None:
-                imin = 0
-            else:
-                imin = int(np.where(times >= bmin)[0][0])
-            if bmax is None:
-                imax = len(times)
-            else:
-                imax = int(np.where(times <= bmax)[0][-1]) + 1
-            all_data -= np.mean(all_data[:, imin:imax], axis=1)[:, None]
-        else:
-            print "No baseline correction applied..."
+        all_data = rescale(all_data, times, baseline, 'mean', verbose=True,
+                        copy=False)
 
         # Put it all together
         self.info = info
diff --git a/mne/minimum_norm/time_frequency.py b/mne/minimum_norm/time_frequency.py
index 8acb3d4..1262669 100644
--- a/mne/minimum_norm/time_frequency.py
+++ b/mne/minimum_norm/time_frequency.py
@@ -8,6 +8,7 @@ from scipy import linalg
 from ..fiff.constants import FIFF
 from ..source_estimate import SourceEstimate
 from ..time_frequency.tfr import cwt, morlet
+from ..baseline import rescale
 from .inverse import combine_xyz, prepare_inverse_operator
 
 
@@ -137,7 +138,7 @@ def source_induced_power(epochs, inverse_operator, bands, lambda2=1.0 / 9.0,
 
     if pca:
         U, s, Vh = linalg.svd(K)
-        rank = np.sum(s > 1e-8*s[0])
+        rank = np.sum(s > 1e-8 * s[0])
         K = s[:rank] * U[:, :rank]
         Vh = Vh[:rank]
         print 'Reducing data rank to %d' % rank
@@ -186,27 +187,8 @@ def source_induced_power(epochs, inverse_operator, bands, lambda2=1.0 / 9.0,
         power /= len(epochs_data) * len(freqs)
 
         # Run baseline correction
-        if baseline is not None:
-            print "Applying baseline correction ..."
-            times = epochs.times
-            bmin, bmax = baseline
-            if bmin is None:
-                imin = 0
-            else:
-                imin = int(np.where(times >= bmin)[0][0])
-            if bmax is None:
-                imax = len(times)
-            else:
-                imax = int(np.where(times <= bmax)[0][-1]) + 1
-            mean_baseline_power = np.mean(power[:, imin:imax], axis=1)
-            if baseline_mode is 'logratio':
-                power /= mean_baseline_power[:, None]
-                power = np.log(power)
-            elif baseline_mode is 'zscore':
-                power -= mean_baseline_power[:, None]
-                power /= np.std(power[:, imin:imax], axis=1)[:, None]
-        else:
-            print "No baseline correction applied..."
+        power = rescale(power, epochs.times, baseline, baseline_mode,
+                        verbose=True, copy=False)
 
         stc = SourceEstimate(None)
         stc.data = power
diff --git a/mne/time_frequency/tfr.py b/mne/time_frequency/tfr.py
index 063f051..ff97ed4 100644
--- a/mne/time_frequency/tfr.py
+++ b/mne/time_frequency/tfr.py
@@ -11,6 +11,7 @@ from math import sqrt
 import numpy as np
 from scipy import linalg
 from scipy.fftpack import fftn, ifftn
+from ..baseline import rescale
 
 
 def morlet(Fs, freqs, n_cycles=7, sigma=None):
@@ -299,29 +300,8 @@ def single_trial_power(epochs, Fs, frequencies, use_fft=True, n_cycles=7,
             power[k] = np.abs(tfr) ** 2
 
     # Run baseline correction
-    if baseline is not None:
-        if times is None:
-            raise ValueError('times parameter is required to define baseline')
-        print "Applying baseline correction ..."
-        bmin = baseline[0]
-        bmax = baseline[1]
-        if bmin is None:
-            imin = 0
-        else:
-            imin = int(np.where(times >= bmin)[0][0])
-        if bmax is None:
-            imax = len(times)
-        else:
-            imax = int(np.where(times <= bmax)[0][-1]) + 1
-        mean_baseline_power = np.mean(power[:, :, :, imin:imax], axis=3)
-        if baseline_mode is 'ratio':
-            power /= mean_baseline_power[:, :, :, None]
-        elif baseline_mode is 'zscore':
-            power -= mean_baseline_power[:, :, :, None]
-            power /= np.std(power[:, :, :, imin:imax], axis=3)[:, :, :, None]
-    else:
-        print "No baseline correction applied..."
-
+    power = rescale(power, times, baseline, baseline_mode,
+                    verbose=True, copy=False)
     return power
 
 

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