[med-svn] [mne-python] 01/01: Imported Upstream version 0.7~rc3
Alexandre Gramfort
agramfort-guest at moszumanska.debian.org
Sat Nov 23 14:41:40 UTC 2013
This is an automated email from the git hooks/post-receive script.
agramfort-guest pushed a commit to branch upstream
in repository mne-python.
commit 6f7c0563066ba434033479decec10815dc43e467
Author: Alexandre Gramfort <alexandre.gramfort at m4x.org>
Date: Sat Nov 23 15:40:32 2013 +0100
Imported Upstream version 0.7~rc3
---
mne/decoding/classifier.py | 11 +++---
mne/fiff/raw.py | 15 ++++----
mne/filter.py | 91 +++++++++++++++++++++++++++-------------------
mne/preprocessing/ssp.py | 23 +++++++-----
mne/tests/test_filter.py | 22 +++++++++++
mne/tests/test_viz.py | 41 +++++++++++++++++++--
6 files changed, 140 insertions(+), 63 deletions(-)
diff --git a/mne/decoding/classifier.py b/mne/decoding/classifier.py
index 05c9852..56b699c 100644
--- a/mne/decoding/classifier.py
+++ b/mne/decoding/classifier.py
@@ -302,16 +302,17 @@ class FilterEstimator(TransformerMixin):
method : str
'fft' will use overlap-add FIR filtering, 'iir' will use IIR
forward-backward filtering (via filtfilt).
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
verbose : bool, str, int, or None
If not None, override default verbose level (see mne.verbose).
Defaults to self.verbose.
"""
def __init__(self, info, l_freq, h_freq, picks=None, filter_length='10s',
l_trans_bandwidth=0.5, h_trans_bandwidth=0.5, n_jobs=1,
- method='fft', iir_params=dict(order=4, ftype='butter')):
+ method='fft', iir_params=None):
self.info = info
self.l_freq = l_freq
self.h_freq = h_freq
@@ -341,8 +342,8 @@ class FilterEstimator(TransformerMixin):
% type(epochs_data))
if self.picks is None:
- self.picks = pick_types(self.info, meg=True, eeg=True, ref_meg=False,
- exclude=[])
+ self.picks = pick_types(self.info, meg=True, eeg=True,
+ ref_meg=False, exclude=[])
if self.l_freq == 0:
self.l_freq = None
diff --git a/mne/fiff/raw.py b/mne/fiff/raw.py
index 5c0032a..0fd2db6 100644
--- a/mne/fiff/raw.py
+++ b/mne/fiff/raw.py
@@ -520,8 +520,7 @@ class Raw(ProjMixin):
@verbose
def filter(self, l_freq, h_freq, picks=None, filter_length='10s',
l_trans_bandwidth=0.5, h_trans_bandwidth=0.5, n_jobs=1,
- method='fft', iir_params=dict(order=4, ftype='butter'),
- verbose=None):
+ method='fft', iir_params=None, verbose=None):
"""Filter a subset of channels.
Applies a zero-phase low-pass, high-pass, band-pass, or band-stop
@@ -570,9 +569,10 @@ class Raw(ProjMixin):
method : str
'fft' will use overlap-add FIR filtering, 'iir' will use IIR
forward-backward filtering (via filtfilt).
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
verbose : bool, str, int, or None
If not None, override default verbose level (see mne.verbose).
Defaults to self.verbose.
@@ -649,7 +649,7 @@ class Raw(ProjMixin):
@verbose
def notch_filter(self, freqs, picks=None, filter_length='10s',
notch_widths=None, trans_bandwidth=1.0, n_jobs=1,
- method='fft', iir_params=dict(order=4, ftype='butter'),
+ method='fft', iir_params=None,
mt_bandwidth=None, p_value=0.05, verbose=None):
"""Notch filter a subset of channels.
@@ -690,9 +690,10 @@ class Raw(ProjMixin):
'fft' will use overlap-add FIR filtering, 'iir' will use IIR
forward-backward filtering (via filtfilt). 'spectrum_fit' will
use multi-taper estimation of sinusoidal components.
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
mt_bandwidth : float | None
The bandwidth of the multitaper windowing function in Hz.
Only used in 'spectrum_fit' mode.
diff --git a/mne/filter.py b/mne/filter.py
index 70adb9a..5ca7f8c 100644
--- a/mne/filter.py
+++ b/mne/filter.py
@@ -345,10 +345,20 @@ def _filter(x, Fs, freq, gain, filter_length='10s', picks=None, n_jobs=1,
return x
+def _check_coefficients(b, a):
+ """Check for filter stability"""
+ z, p, k = signal.tf2zpk(b, a)
+ if np.any(np.abs(p) > 1.0):
+ raise RuntimeError('Filter poles outside unit circle, filter will be '
+ 'unstable. Consider using different filter '
+ 'coefficients.')
+
+
def _filtfilt(x, b, a, padlen, picks, n_jobs, copy):
"""Helper to more easily call filtfilt"""
# set up array for filtering, reshape to 2D, operate on last axis
x, orig_shape, picks = _prep_for_filtering(x, copy, picks)
+ _check_coefficients(b, a)
if n_jobs == 1:
for p in picks:
x[p] = filtfilt(b, a, x[p], padlen=padlen)
@@ -502,10 +512,29 @@ def construct_iir_filter(iir_params=dict(b=[1, 0], a=[1, 0], padlen=0),
return iir_params
+def _check_method(method, iir_params, extra_types):
+ """Helper to parse method arguments"""
+ allowed_types = ['iir', 'fft'] + extra_types
+ if not isinstance(method, basestring):
+ raise TypeError('method must be a string')
+ if method not in allowed_types:
+ raise ValueError('method must be one of %s, not "%s"'
+ % (allowed_types, method))
+ if method == 'iir':
+ if iir_params is None:
+ iir_params = dict(order=4, ftype='butter')
+ if not isinstance(iir_params, dict) or 'ftype' not in iir_params:
+ raise ValueError('iir_params must be a dict with entry "ftype"')
+ elif iir_params is not None:
+ raise ValueError('iir_params must be None if method != "iir"')
+ method = method.lower()
+ return iir_params
+
+
@verbose
def band_pass_filter(x, Fs, Fp1, Fp2, filter_length='10s',
l_trans_bandwidth=0.5, h_trans_bandwidth=0.5,
- method='fft', iir_params=dict(order=4, ftype='butter'),
+ method='fft', iir_params=None,
picks=None, n_jobs=1, copy=True, verbose=None):
"""Bandpass filter for the signal x.
@@ -536,9 +565,10 @@ def band_pass_filter(x, Fs, Fp1, Fp2, filter_length='10s',
method : str
'fft' will use overlap-add FIR filtering, 'iir' will use IIR
forward-backward filtering (via filtfilt).
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
picks : list of int | None
Indices to filter. If None all indices will be filtered.
n_jobs : int | str
@@ -571,10 +601,7 @@ def band_pass_filter(x, Fs, Fp1, Fp2, filter_length='10s',
Fs1 = Fp1 - l_trans_bandwidth in Hz
Fs2 = Fp2 + h_trans_bandwidth in Hz
"""
-
- method = method.lower()
- if method not in ['fft', 'iir']:
- raise RuntimeError('method should be fft or iir (not %s)' % method)
+ iir_params = _check_method(method, iir_params, [])
Fs = float(Fs)
Fp1 = float(Fp1)
@@ -607,7 +634,7 @@ def band_pass_filter(x, Fs, Fp1, Fp2, filter_length='10s',
@verbose
def band_stop_filter(x, Fs, Fp1, Fp2, filter_length='10s',
l_trans_bandwidth=0.5, h_trans_bandwidth=0.5,
- method='fft', iir_params=dict(order=4, ftype='butter'),
+ method='fft', iir_params=None,
picks=None, n_jobs=1, copy=True, verbose=None):
"""Bandstop filter for the signal x.
@@ -638,9 +665,10 @@ def band_stop_filter(x, Fs, Fp1, Fp2, filter_length='10s',
method : str
'fft' will use overlap-add FIR filtering, 'iir' will use IIR
forward-backward filtering (via filtfilt).
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
picks : list of int | None
Indices to filter. If None all indices will be filtered.
n_jobs : int | str
@@ -675,10 +703,8 @@ def band_stop_filter(x, Fs, Fp1, Fp2, filter_length='10s',
Note that multiple stop bands can be specified using arrays.
"""
+ iir_params = _check_method(method, iir_params, [])
- method = method.lower()
- if method not in ['fft', 'iir']:
- raise RuntimeError('method should be fft or iir (not %s)' % method)
Fp1 = np.atleast_1d(Fp1)
Fp2 = np.atleast_1d(Fp2)
if not len(Fp1) == len(Fp2):
@@ -718,7 +744,7 @@ def band_stop_filter(x, Fs, Fp1, Fp2, filter_length='10s',
@verbose
def low_pass_filter(x, Fs, Fp, filter_length='10s', trans_bandwidth=0.5,
- method='fft', iir_params=dict(order=4, ftype='butter'),
+ method='fft', iir_params=None,
picks=None, n_jobs=1, copy=True, verbose=None):
"""Lowpass filter for the signal x.
@@ -745,9 +771,10 @@ def low_pass_filter(x, Fs, Fp, filter_length='10s', trans_bandwidth=0.5,
method : str
'fft' will use overlap-add FIR filtering, 'iir' will use IIR
forward-backward filtering (via filtfilt).
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
picks : list of int | None
Indices to filter. If None all indices will be filtered.
n_jobs : int | str
@@ -777,11 +804,7 @@ def low_pass_filter(x, Fs, Fp, filter_length='10s', trans_bandwidth=0.5,
Fp Fp+trans_bandwidth
"""
-
- method = method.lower()
- if method not in ['fft', 'iir']:
- raise RuntimeError('method should be fft or iir (not %s)' % method)
-
+ iir_params = _check_method(method, iir_params, [])
Fs = float(Fs)
Fp = float(Fp)
Fstop = Fp + trans_bandwidth
@@ -804,7 +827,7 @@ def low_pass_filter(x, Fs, Fp, filter_length='10s', trans_bandwidth=0.5,
@verbose
def high_pass_filter(x, Fs, Fp, filter_length='10s', trans_bandwidth=0.5,
- method='fft', iir_params=dict(order=4, ftype='butter'),
+ method='fft', iir_params=None,
picks=None, n_jobs=1, copy=True, verbose=None):
"""Highpass filter for the signal x.
@@ -831,9 +854,10 @@ def high_pass_filter(x, Fs, Fp, filter_length='10s', trans_bandwidth=0.5,
method : str
'fft' will use overlap-add FIR filtering, 'iir' will use IIR
forward-backward filtering (via filtfilt).
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
picks : list of int | None
Indices to filter. If None all indices will be filtered.
n_jobs : int | str
@@ -864,11 +888,7 @@ def high_pass_filter(x, Fs, Fp, filter_length='10s', trans_bandwidth=0.5,
where Fstop = Fp - trans_bandwidth
"""
-
- method = method.lower()
- if method not in ['fft', 'iir']:
- raise RuntimeError('method should be fft or iir (not %s)' % method)
-
+ iir_params = _check_method(method, iir_params, [])
Fs = float(Fs)
Fp = float(Fp)
@@ -894,7 +914,7 @@ def high_pass_filter(x, Fs, Fp, filter_length='10s', trans_bandwidth=0.5,
@verbose
def notch_filter(x, Fs, freqs, filter_length='10s', notch_widths=None,
trans_bandwidth=1, method='fft',
- iir_params=dict(order=4, ftype='butter'), mt_bandwidth=None,
+ iir_params=None, mt_bandwidth=None,
p_value=0.05, picks=None, n_jobs=1, copy=True, verbose=None):
"""Notch filter for the signal x.
@@ -929,9 +949,10 @@ def notch_filter(x, Fs, freqs, filter_length='10s', notch_widths=None,
use multi-taper estimation of sinusoidal components. If freqs=None
and method='spectrum_fit', significant sinusoidal components
are detected using an F test, and noted by logging.
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
mt_bandwidth : float | None
The bandwidth of the multitaper windowing function in Hz.
Only used in 'spectrum_fit' mode.
@@ -979,11 +1000,7 @@ def notch_filter(x, Fs, freqs, filter_length='10s', notch_widths=None,
& Hemant Bokil, Oxford University Press, New York, 2008. Please
cite this in publications if method 'spectrum_fit' is used.
"""
-
- method = method.lower()
- if method not in ['fft', 'iir', 'spectrum_fit']:
- raise RuntimeError('method should be fft, iir, or spectrum_fit '
- '(not %s)' % method)
+ iir_params = _check_method(method, iir_params, ['spectrum_fit'])
if freqs is not None:
freqs = np.atleast_1d(freqs)
diff --git a/mne/preprocessing/ssp.py b/mne/preprocessing/ssp.py
index f1f77bf..d6727d4 100644
--- a/mne/preprocessing/ssp.py
+++ b/mne/preprocessing/ssp.py
@@ -31,8 +31,7 @@ def _compute_exg_proj(mode, raw, raw_event, tmin, tmax,
average, filter_length, n_jobs, ch_name,
reject, flat, bads, avg_ref, no_proj, event_id,
exg_l_freq, exg_h_freq, tstart, qrs_threshold,
- filter_method, iir_params=dict(order=4, ftype='butter'),
- verbose=None):
+ filter_method, iir_params=None, verbose=None):
"""Compute SSP/PCA projections for ECG or EOG artifacts
Note: raw has to be constructed with preload=True (or string)
@@ -92,9 +91,10 @@ def _compute_exg_proj(mode, raw, raw_event, tmin, tmax,
number of heartbeats (40-160 beats / min). Only for ECG.
filter_method : str
Method for filtering ('iir' or 'fft').
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
verbose : bool, str, int, or None
If not None, override default verbose level (see mne.verbose).
@@ -217,8 +217,7 @@ def compute_proj_ecg(raw, raw_event=None, tmin=-0.2, tmax=0.4,
flat=None, bads=[], avg_ref=False,
no_proj=False, event_id=999, ecg_l_freq=5, ecg_h_freq=35,
tstart=0., qrs_threshold='auto', filter_method='fft',
- iir_params=dict(order=4, ftype='butter'),
- copy=True, verbose=None):
+ iir_params=None, copy=True, verbose=None):
"""Compute SSP/PCA projections for ECG artifacts
Note: raw has to be constructed with preload=True (or string)
@@ -276,9 +275,10 @@ def compute_proj_ecg(raw, raw_event=None, tmin=-0.2, tmax=0.4,
number of heartbeats (40-160 beats / min).
filter_method : str
Method for filtering ('iir' or 'fft').
- iir_params : dict
+ iir_params : dict | None
Dictionary of parameters to use for IIR filtering.
- See mne.filter.construct_iir_filter for details.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
copy : bool
If False, filtering raw data is done in place. Defaults to True.
verbose : bool, str, int, or None
@@ -313,8 +313,7 @@ def compute_proj_eog(raw, raw_event=None, tmin=-0.2, tmax=0.2,
eog=np.inf), flat=None, bads=[],
avg_ref=False, no_proj=False, event_id=998, eog_l_freq=1,
eog_h_freq=10, tstart=0., filter_method='fft',
- iir_params=dict(order=4, ftype='butter'), ch_name=None,
- copy=True, verbose=None):
+ iir_params=None, ch_name=None, copy=True, verbose=None):
"""Compute SSP/PCA projections for EOG artifacts
Note: raw has to be constructed with preload=True (or string)
@@ -368,6 +367,10 @@ def compute_proj_eog(raw, raw_event=None, tmin=-0.2, tmax=0.2,
Start artifact detection after tstart seconds.
filter_method : str
Method for filtering ('iir' or 'fft').
+ iir_params : dict | None
+ Dictionary of parameters to use for IIR filtering.
+ See mne.filter.construct_iir_filter for details. If iir_params
+ is None and method="iir", 4th order Butterworth will be used.
copy : bool
If False, filtering raw data is done in place. Defaults to True.
ch_name: str | None
diff --git a/mne/tests/test_filter.py b/mne/tests/test_filter.py
index 56b0230..5e929d2 100644
--- a/mne/tests/test_filter.py
+++ b/mne/tests/test_filter.py
@@ -19,6 +19,28 @@ tempdir = _TempDir()
log_file = op.join(tempdir, 'temp_log.txt')
+def test_iir_stability():
+ """Test IIR filter stability check
+ """
+ sig = np.empty(1000)
+ fs = 1000
+ # This will make an unstable filter, should throw RuntimeError
+ assert_raises(RuntimeError, high_pass_filter, sig, fs, 0.6,
+ method='iir', iir_params=dict(ftype='butter', order=8))
+ # can't pass iir_params if method='fir'
+ assert_raises(ValueError, high_pass_filter, sig, fs, 0.1,
+ method='fir', iir_params=dict(ftype='butter', order=2))
+ # method must be string
+ assert_raises(TypeError, high_pass_filter, sig, fs, 0.1,
+ method=1)
+ # unknown method
+ assert_raises(ValueError, high_pass_filter, sig, fs, 0.1,
+ method='blah')
+ # bad iir_params
+ assert_raises(ValueError, high_pass_filter, sig, fs, 0.1,
+ method='fir', iir_params='blah')
+
+
def test_notch_filters():
"""Test notch filters
"""
diff --git a/mne/tests/test_viz.py b/mne/tests/test_viz.py
index 583c398..0dbbc24 100644
--- a/mne/tests/test_viz.py
+++ b/mne/tests/test_viz.py
@@ -1,7 +1,7 @@
import os.path as op
from functools import wraps
import numpy as np
-from numpy.testing import assert_raises
+from numpy.testing import assert_raises, assert_equal
import warnings
from mne import fiff, read_events, Epochs, SourceEstimate, read_cov, read_proj
@@ -68,6 +68,20 @@ n_chan = 15
layout = read_layout('Vectorview-all')
+def _fake_click(fig, ax, point, xform='ax'):
+ """Helper to fake a click at a relative point within axes"""
+ if xform == 'ax':
+ x, y = ax.transAxes.transform_point(point)
+ elif xform == 'data':
+ x, y = ax.transData.transform_point(point)
+ else:
+ raise ValueError('unknown transform')
+ try:
+ fig.canvas.button_press_event(x, y, 1, False, None)
+ except: # for old MPL
+ fig.canvas.button_press_event(x, y, 1, False)
+
+
def _get_raw():
return fiff.Raw(raw_fname, preload=False)
@@ -360,9 +374,28 @@ def test_plot_raw():
"""
raw = _get_raw()
events = _get_events()
+ plt.close('all') # ensure all are closed
fig = raw.plot(events=events, show_options=True)
- # test mouse clicks (XXX not complete yet)
- fig.canvas.button_press_event(0.5, 0.5, 1)
+ # test mouse clicks
+ x = fig.get_axes()[0].lines[1].get_xdata().mean()
+ y = fig.get_axes()[0].lines[1].get_ydata().mean()
+ data_ax = fig.get_axes()[0]
+ _fake_click(fig, data_ax, [x, y], xform='data') # mark a bad channel
+ _fake_click(fig, data_ax, [x, y], xform='data') # unmark a bad channel
+ _fake_click(fig, data_ax, [0.5, 0.999]) # click elsewhere in first axes
+ _fake_click(fig, fig.get_axes()[1], [0.5, 0.5]) # change time
+ _fake_click(fig, fig.get_axes()[2], [0.5, 0.5]) # change channels
+ _fake_click(fig, fig.get_axes()[3], [0.5, 0.5]) # open SSP window
+ fig.canvas.button_press_event(1, 1, 1) # outside any axes
+ # sadly these fail when no renderer is used (i.e., when using Agg):
+ #ssp_fig = set(plt.get_fignums()) - set([fig.number])
+ #assert_equal(len(ssp_fig), 1)
+ #ssp_fig = plt.figure(list(ssp_fig)[0])
+ #ax = ssp_fig.get_axes()[0] # only one axis is used
+ #t = [c for c in ax.get_children() if isinstance(c, matplotlib.text.Text)]
+ #pos = np.array(t[0].get_position()) + 0.01
+ #_fake_click(ssp_fig, ssp_fig.get_axes()[0], pos, xform='data') # off
+ #_fake_click(ssp_fig, ssp_fig.get_axes()[0], pos, xform='data') # on
# test keypresses
fig.canvas.key_press_event('escape')
fig.canvas.key_press_event('down')
@@ -393,7 +426,7 @@ def test_plot_raw_psds():
@sample.requires_sample_data
def test_plot_topomap():
- """Testing topomap plotting
+ """Test topomap plotting
"""
# evoked
evoked = fiff.read_evoked(evoked_fname, 'Left Auditory',
--
Alioth's /git/debian-med/git-commit-notice on /srv/git.debian.org/git/debian-med/mne-python.git
More information about the debian-med-commit
mailing list