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 <[email protected]> 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 <[email protected]> +# +# 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 _______________________________________________ debian-med-commit mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit
