[med-svn] [python-mne] 99/353: Save memory if n_jobs=1 and dtype stays the same
Yaroslav Halchenko
debian at onerussian.com
Fri Nov 27 17:24:37 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 08fbe22078d52227b0b306b9058c26de6ce2348a
Author: Martin Luessi <mluessi at nmr.mgh.harvard.edu>
Date: Mon Mar 5 11:10:39 2012 -0500
Save memory if n_jobs=1 and dtype stays the same
---
mne/fiff/raw.py | 122 ++++++++++++++++++++++++---------------------
mne/fiff/tests/test_raw.py | 9 ++--
2 files changed, 69 insertions(+), 62 deletions(-)
diff --git a/mne/fiff/raw.py b/mne/fiff/raw.py
index 20ff73b..4fb12b0 100644
--- a/mne/fiff/raw.py
+++ b/mne/fiff/raw.py
@@ -232,48 +232,15 @@ class Raw(object):
# set the data
self._data[sel, start:stop] = value
- def analytic_signal(self, picks, n_jobs=1, verbose=5):
- """ Compute analytic signal for a subset of channels.
-
- Compute analytic signal for the channels defined in "picks". The
- data of the Raw object is modified inplace and converted to a
- complex representation (the analytic signal is complex valued).
-
- The Raw object has to be constructed using preload=True (or string).
-
- Parameters
- ----------
- picks : list of int
- Indices of channels to apply the function to.
-
- n_jobs: int
- Number of jobs to run in parallel.
-
- verbose: int
- Verbosity level.
-
- Notes
- -----
- The analytic signal "x_a(t)" of "x(t)" is::
-
- x_a = F^{-1}(F(x) 2U) = x + i y
-
- where "F" is the Fourier transform, "U" the unit step function,
- and "y" the Hilbert transform of "x". One usage of the analytic
- signal is the computation of the enevelope signal, which is given by
- "e(t) = abs(x_a(t))". Due to the linearity of Hilbert transform and the
- MNE inverse solution, the enevlope in source space can be obtained
- by computing the analytic signal in sensor space, applying the MNE
- inverse, and computing the envelope in source space.
- """
- self.apply_function(hilbert, picks, n_jobs, verbose)
-
-
- def apply_function(self, fun, picks, n_jobs, verbose, *args, **kwargs):
+ def apply_function(self, fun, picks, dtype, n_jobs, verbose, *args,
+ **kwargs):
""" Apply a function to a subset of channels.
The function "fun" is applied to the channels defined in "picks". The
- data of the Raw object is modified inplace.
+ data of the Raw object is modified inplace. If the function returns
+ a different data type (e.g. numpy.complex) it must be specified using
+ the dtype parameter, which causes the data type used for representing
+ the raw data to change.
The Raw object has to be constructed using preload=True (or string).
@@ -287,6 +254,10 @@ class Raw(object):
picks : list of int
Indices of channels to apply the function to.
+ dtype : numpy.dtype
+ Data type to use for raw data after applying the function. If None
+ the data type is not modified.
+
n_jobs: int
Number of jobs to run in parallel.
@@ -307,24 +278,59 @@ class Raw(object):
if not callable(fun):
raise ValueError('fun needs to be a function')
- # create parallel function
- parallel, p_fun, _ = parallel_func(fun, n_jobs, verbose)
+ data_in = self._data
+ if dtype is not None and dtype != self._data.dtype:
+ self._data = self._data.astype(dtype)
+
+ if n_jobs == 1:
+ # modify data inplace to save memory
+ for idx in picks:
+ self._data[idx, :] = fun(data_in[idx, :], *args, **kwargs)
+ else:
+ # use parallel function
+ parallel, p_fun, _ = parallel_func(fun, n_jobs, verbose)
+
+ data_picks = data_in[picks, :]
+ data_picks_new = np.array(parallel(p_fun(x, *args, **kwargs)
+ for x in data_picks))
+
+ self._data[picks, :] = data_picks_new
+
+ def apply_hilbert(self, picks, n_jobs=1, verbose=5):
+ """ Compute analytic signal for a subset of channels.
+
+ Compute analytic signal for the channels defined in "picks". The
+ data of the Raw object is modified inplace and converted to a
+ complex representation (the analytic signal is complex valued).
- # apply function to channels
- data_picks = self._data[picks, :]
- data_picks_new = np.array(parallel(p_fun(x, *args, **kwargs)
- for x in data_picks))
+ The Raw object has to be constructed using preload=True (or string).
- if np.any(data_picks_new.shape != data_picks.shape):
- raise ValueError('fun must return array with the same size as '
- 'input')
+ Parameters
+ ----------
+ picks : list of int
+ Indices of channels to apply the function to.
- # convert the type of _data if necessary
- if data_picks_new.dtype != self._data.dtype:
- print 'Converting raw data to %s' % data_picks_new.dtype
- self._data = np.array(self._data, dtype=data_picks_new.dtype)
+ n_jobs: int
+ Number of jobs to run in parallel.
- self._data[picks, :] = data_picks_new
+ verbose: int
+ Verbosity level.
+
+ Notes
+ -----
+ The analytic signal "x_a(t)" of "x(t)" is::
+
+ x_a = F^{-1}(F(x) 2U) = x + i y
+
+ where "F" is the Fourier transform, "U" the unit step function,
+ and "y" the Hilbert transform of "x". One usage of the analytic
+ signal is the computation of the enevelope signal, which is given by
+ "e(t) = abs(x_a(t))". Due to the linearity of Hilbert transform and the
+ MNE inverse solution, the enevlope in source space can be obtained
+ by computing the analytic signal in sensor space, applying the MNE
+ inverse, and computing the envelope in source space.
+ """
+ self.apply_function(hilbert, picks, np.complex64, n_jobs, verbose)
def band_pass_filter(self, picks, f_low, f_high, filter_length=None,
n_jobs=1, verbose=5):
@@ -359,7 +365,7 @@ class Raw(object):
Verbosity level.
"""
fs = float(self.info['sfreq'])
- self.apply_function(band_pass_filter, picks, n_jobs, verbose, fs,
+ self.apply_function(band_pass_filter, picks, None, n_jobs, verbose, fs,
f_low, f_high, filter_length=filter_length)
def high_pass_filter(self, picks, fp, filter_length=None, n_jobs=1,
@@ -393,8 +399,8 @@ class Raw(object):
"""
fs = float(self.info['sfreq'])
- self.apply_function(high_pass_filter, picks, n_jobs, verbose, fs, fp,
- filter_length=filter_length)
+ self.apply_function(high_pass_filter, picks, None, n_jobs, verbose,
+ fs, fp, filter_length=filter_length)
def low_pass_filter(self, picks, fp, filter_length=None, n_jobs=1,
verbose=5):
@@ -426,8 +432,8 @@ class Raw(object):
Verbosity level.
"""
fs = float(self.info['sfreq'])
- self.apply_function(low_pass_filter, picks, n_jobs, verbose, fs, fp,
- filter_length=filter_length)
+ self.apply_function(low_pass_filter, picks, None, n_jobs, verbose,
+ fs, fp, filter_length=filter_length)
def save(self, fname, picks=None, tmin=0, tmax=None, buffer_size_sec=10,
drop_small_buffer=False):
diff --git a/mne/fiff/tests/test_raw.py b/mne/fiff/tests/test_raw.py
index 2ceb6a2..744a36b 100644
--- a/mne/fiff/tests/test_raw.py
+++ b/mne/fiff/tests/test_raw.py
@@ -148,7 +148,7 @@ def test_filter():
picks = picks_meg[:4]
raw_lp = deepcopy(raw)
- raw_lp.low_pass_filter(picks, 4.0, verbose=0)
+ raw_lp.low_pass_filter(picks, 4.0, verbose=0, n_jobs=2)
raw_hp = deepcopy(raw)
raw_hp.high_pass_filter(picks, 8.0, verbose=0)
@@ -170,12 +170,13 @@ def test_filter():
assert_array_equal(data, bp_data)
-def test_analytic():
- """ Test computation of analytic signal """
+
+def test_hilbert():
+ """ Test computation of analytic signal using hilbert """
raw = Raw(fif_fname, preload=True)
picks_meg = pick_types(raw.info, meg=True)
picks = picks_meg[:4]
- raw.analytic_signal(picks, verbose=0)
+ raw.apply_hilbert(picks, verbose=0)
#XXX what to test?
--
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