[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