[med-svn] [python-mne] 02/353: zero phase, not yet working correctly
Yaroslav Halchenko
debian at onerussian.com
Fri Nov 27 17:24:23 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 e3a2b8a16293c902ed83d5f26765fb8bdddddac3
Author: Martin Luessi <mluessi at nmr.mgh.harvard.edu>
Date: Fri Oct 14 09:13:00 2011 -0400
zero phase, not yet working correctly
---
mne/filter.py | 91 ++++++++++++++++++++++++++++++++---------------------------
1 file changed, 50 insertions(+), 41 deletions(-)
diff --git a/mne/filter.py b/mne/filter.py
index b492e3c..90a88e0 100644
--- a/mne/filter.py
+++ b/mne/filter.py
@@ -3,7 +3,7 @@ from scipy import signal
from scipy.fftpack import fft, ifft
-def overlap_add_filter(x, h, N_fft=None):
+def overlap_add_filter(x, h, N_fft=None, zero_phase=True):
""" Calculate linear convolution using overlap-add FFTs
Implements the linear convolution between x and h using overlap-add FFTs.
@@ -25,9 +25,11 @@ def overlap_add_filter(x, h, N_fft=None):
if N_fft == None:
if N_x > N_h:
+ N_tot = 2*N_x if zero_phase else N_x
+
N = 2**np.arange(np.ceil(np.log2(N_h)),
- np.floor(np.log2(N_x)))
- cost = np.ceil(N_x / (N - N_h + 1)) * N * (np.log2(N) + 1)
+ np.floor(np.log2(N_tot)))
+ cost = np.ceil(N_tot / (N - N_h + 1)) * N * (np.log2(N) + 1)
N_fft = N[np.argmin(cost)]
else:
# Use only a single block
@@ -41,32 +43,53 @@ def overlap_add_filter(x, h, N_fft=None):
raise ValueError('N_fft is too short, has to be at least len(h)')
# Filter in frequency domain
- # FIXME: abs?
- h_fft = np.abs(fft(np.concatenate((h, np.zeros(N_fft - N_h)))))
-
+ h_fft = fft(np.concatenate((h, np.zeros(N_fft - N_h))))
+
+ if zero_phase:
+ # We will apply the filter in forward and backward direction: Scale
+ # frequency response of the filter so that the shape of the amplitude
+ # response stays the same when it is applied twice
+
+ # be careful not to divide by too small numbers
+ #idx = np.where(np.abs(h_fft) > 1e-6)
+ #h_fft[idx] = h_fft[idx] / np.sqrt(np.abs(h_fft[idx]))
+ pass
+
x_filtered = np.zeros_like(x)
- # Go through segments
+ # Number of segements (including fractional segments)
num_segments = int(np.ceil(N_x / float(N_seg)))
+
+ filter_input = x
- for seg_ind in range(num_segments):
- seg = x[seg_ind*N_seg:(seg_ind+1)*N_seg]
- seg_fft = fft(np.concatenate((seg, np.zeros(N_fft - len(seg)))))
-
-
- if seg_ind*N_seg+N_fft < N_x:
- x_filtered[seg_ind*N_seg:seg_ind*N_seg+N_fft] \
- += np.real(ifft(h_fft * seg_fft))
- else:
- # Last segment
- x_filtered[seg_ind*N_seg:] \
- += np.real(ifft(h_fft * seg_fft))[:N_x-seg_ind*N_seg]
-
+ for pass_no in range(2) if zero_phase else range(1):
+
+ if pass_no == 1:
+ # second pass: flip signal
+ filter_input = x_filtered[::-1]
+ x_filtered = np.zeros_like(x)
+
+ for seg_ind in range(num_segments):
+ seg = filter_input[seg_ind*N_seg:(seg_ind+1)*N_seg]
+ seg_fft = fft(np.concatenate((seg, np.zeros(N_fft - len(seg)))))
+
+
+ if seg_ind*N_seg+N_fft < N_x:
+ x_filtered[seg_ind*N_seg:seg_ind*N_seg+N_fft] \
+ += np.real(ifft(h_fft * seg_fft))
+ else:
+ # Last segment
+ x_filtered[seg_ind*N_seg:] \
+ += np.real(ifft(h_fft * seg_fft))[:N_x-seg_ind*N_seg]
+ if zero_phase:
+ # flip signal back
+ x_filtered = x_filtered[::-1]
+
return x_filtered
-def band_pass_filter(x, Fs, Fp1, Fp2, ov_add):
+def band_pass_filter(x, Fs, Fp1, Fp2):
"""Bandpass filter for the signal x.
An acausal fft algorithm is applied (i.e. no phase shift). The filter
@@ -127,28 +150,14 @@ def band_pass_filter(x, Fs, Fp1, Fp2, ov_add):
Np2 = Fp2 / (Fs / 2)
# Construct the filter function H(f)
-# N = len(x)
-# B = signal.firwin2(N, [0, Ns1, Np1, Np2, Ns2, 1], [0, 0, 1, 1, 0, 0])
-#
-# # Make zero-phase filter function
-# H = np.abs(fft(B))
-# xf = np.real(ifft(fft(x) * H))
-#
-
- if ov_add:
- N = int(2 * Fs)
- B = signal.firwin2(N, [0, Ns1, Np1, Np2, Ns2, 1], [0, 0, 1, 1, 0, 0])
+ N = len(x)
- xf = overlap_add_filter(x, B)
- else:
- N = int(2 * Fs)
- B = signal.firwin2(N, [0, Ns1, Np1, Np2, Ns2, 1], [0, 0, 1, 1, 0, 0])
+ B = signal.firwin2(N, [0, Ns1, Np1, Np2, Ns2, 1], [0, 0, 1, 1, 0, 0])
- B = ifft(np.abs(fft(B)))
- # Make zero-phase filter function
-
- xf = (signal.convolve(x, B, 'full'))
-
+ # Make zero-phase filter function
+ H = np.abs(fft(B))
+
+ xf = np.real(ifft(fft(x) * H))
xf = xf[:Norig]
x = x[:Norig]
--
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