[med-svn] [python-mne] 97/353: ENH: filtering and apply_function for Raw
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 f6cd0f3a5cb412bc4afe67dabf3c38c59197951f
Author: Martin Luessi <mluessi at nmr.mgh.harvard.edu>
Date: Fri Mar 2 15:02:29 2012 -0500
ENH: filtering and apply_function for Raw
---
doc/source/whats_new.rst | 1 +
mne/fiff/raw.py | 161 +++++++++++++++++++++++++++++++++++++++++++++
mne/fiff/tests/test_raw.py | 32 +++++++++
3 files changed, 194 insertions(+)
diff --git a/doc/source/whats_new.rst b/doc/source/whats_new.rst
index 277c463..e52f39a 100644
--- a/doc/source/whats_new.rst
+++ b/doc/source/whats_new.rst
@@ -23,6 +23,7 @@ Changelog
- Write BEM surfaces in Python by `Alex Gramfort`_.
+ - Filtering operations and apply_function interface for Raw object by `Martin Luessi`_.
Version 0.2
-----------
diff --git a/mne/fiff/raw.py b/mne/fiff/raw.py
index e835485..6b98063 100644
--- a/mne/fiff/raw.py
+++ b/mne/fiff/raw.py
@@ -6,6 +6,8 @@
from math import floor, ceil
import copy
+import types
+
import numpy as np
from .constants import FIFF
@@ -14,6 +16,9 @@ from .meas_info import read_meas_info, write_meas_info
from .tree import dir_tree_find
from .tag import read_tag
+from ..filter import low_pass_filter, high_pass_filter, band_pass_filter
+from ..parallel import parallel_func
+
class Raw(object):
"""Raw data
@@ -224,6 +229,162 @@ class Raw(object):
# set the data
self._data[sel, start:stop] = value
+ def apply_function(self, fun, picks, 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 in-place.
+
+ The Raw object has to be constructed using preload=True (or string).
+
+ Parameters
+ ----------
+ fun : function
+ A function to be applied to the channels. The first argument of
+ fun has to be a timeseries (numpy.ndarray). The function must
+ return an numpy.ndarray with the same size as the input.
+
+ 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.
+
+ *args:
+ Additional positional arguments to pass to fun (first pos. argument
+ of fun is the timeseries of a channel).
+
+ **kwargs:
+ Keyword arguments to pass to fun.
+ """
+
+ if not isinstance(fun, types.FunctionType):
+ raise ValueError('fun needs to be a function')
+
+ if not self._preloaded:
+ raise RuntimeError('Raw data needs to be preloaded. Use '
+ 'preload=True (or string) in the constructor.')
+
+ # create parallel function
+ parallel, p_fun, _ = parallel_func(fun, n_jobs, verbose)
+
+ # 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))
+
+ if np.any(data_picks_new.shape != data_picks.shape):
+ raise ValueError('fun must return array with the same size as '
+ 'input')
+
+ self._data[picks, :] = data_picks_new
+
+ def band_pass_filter(self, picks, Fp1, Fp2, filter_length=None, n_jobs=1,
+ verbose=5):
+ """Band-pass filter a subset of channels.
+
+ Applies a zero-phase band-pass filter to the channels selected by
+ "picks". The data of the Raw object is modified in-place.
+
+ The Raw object has to be constructed using preload=True (or string).
+
+ Parameters
+ ----------
+ picks : list of int
+ Indices of channels to filter.
+
+ Fp1 : float
+ Low cut-off frequency in Hz.
+
+ Fp2 : float
+ High cut-off frequency in Hz.
+
+ filter_length : int (default: None)
+ Length of the filter to use. If None or "ntimes < filter_length",
+ (ntimes: number of timepoints in Raw object) the filter length
+ used is ntimes. Otherwise, overlap-add filtering with a
+ filter of the specified length is used (faster for long signals).
+
+ n_jobs: int (default: 1)
+ Number of jobs to run in parallel.
+
+ verbose: int (default: 5)
+ Verbosity level.
+ """
+ Fs = float(self.info['sfreq'])
+ self.apply_function(band_pass_filter, picks, n_jobs, verbose, Fs, Fp1,
+ Fp2, filter_length=filter_length)
+
+ def high_pass_filter(self, picks, Fp, filter_length=None, n_jobs=1,
+ verbose=5):
+ """High-pass filter a subset of channels.
+
+ Applies a zero-phase high-pass filter to the channels selected by
+ "picks". The data of the Raw object is modified in-place.
+
+ The Raw object has to be constructed using preload=True (or string).
+
+ Parameters
+ ----------
+ picks : list of int
+ Indices of channels to filter.
+
+ Fp : float
+ Cut-off frequency in Hz.
+
+ filter_length : int (default: None)
+ Length of the filter to use. If None or "ntimes < filter_length",
+ (ntimes: number of timepoints in Raw object) the filter length
+ used is ntimes. Otherwise, overlap-add filtering with a
+ filter of the specified length is used (faster for long signals).
+
+ n_jobs: int (default: 1)
+ Number of jobs to run in parallel.
+
+ verbose: int (default: 5)
+ Verbosity level.
+ """
+
+ Fs = float(self.info['sfreq'])
+ self.apply_function(high_pass_filter, picks, n_jobs, verbose, Fs, Fp,
+ filter_length=filter_length)
+
+ def low_pass_filter(self, picks, Fp, filter_length=None, n_jobs=1,
+ verbose=5):
+ """Low-pass filter a subset of channels.
+
+ Applies a zero-phase low-pass filter to the channels selected by
+ "picks". The data of the Raw object is modified in-place.
+
+ The Raw object has to be constructed using preload=True (or string).
+
+ Parameters
+ ----------
+ picks : list of int
+ Indices of channels to filter.
+
+ Fp : float
+ Cut-off frequency in Hz.
+
+ filter_length : int (default: None)
+ Length of the filter to use. If None or "ntimes < filter_length",
+ (ntimes: number of timepoints in Raw object) the filter length
+ used is ntimes. Otherwise, overlap-add filtering with a
+ filter of the specified length is used (faster for long signals).
+
+ n_jobs: int (default: 1)
+ Number of jobs to run in parallel.
+
+ verbose: int (default: 5)
+ Verbosity level.
+ """
+ Fs = float(self.info['sfreq'])
+ self.apply_function(low_pass_filter, picks, 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):
"""Save raw data to file
diff --git a/mne/fiff/tests/test_raw.py b/mne/fiff/tests/test_raw.py
index 35edb86..520e32b 100644
--- a/mne/fiff/tests/test_raw.py
+++ b/mne/fiff/tests/test_raw.py
@@ -1,4 +1,5 @@
import os.path as op
+from copy import deepcopy
import numpy as np
from nose.tools import assert_true
@@ -111,3 +112,34 @@ def test_preload_modify():
data_new, _ = raw_new[picks, :nsamp / 2]
assert_array_almost_equal(data, data_new)
+
+
+def test_filter():
+ """ Test filtering and Raw.apply_function interface """
+
+ raw = Raw(fif_fname, preload=True)
+ picks_meg = pick_types(raw.info, meg=True)
+ picks = picks_meg[:4]
+
+ raw_lp = deepcopy(raw)
+ raw_lp.low_pass_filter(picks, 4.0)
+
+ raw_hp = deepcopy(raw)
+ raw_hp.high_pass_filter(picks, 8.0)
+
+ raw_bp = deepcopy(raw)
+ raw_bp.band_pass_filter(picks, 4.0, 8.0)
+
+ data, _ = raw[picks, :]
+
+ lp_data, _ = raw_lp[picks, :]
+ hp_data, _ = raw_hp[picks, :]
+ bp_data, _ = raw_bp[picks, :]
+
+ assert_array_almost_equal(data, lp_data + hp_data + bp_data)
+
+ # make sure we didn't touch other channels
+ data, _ = raw[picks_meg[4:], :]
+ bp_data, _ = raw_bp[picks_meg[4:], :]
+
+ assert_array_equal(data, bp_data)
--
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