# encoding: utf-8
"""
filters.py -- Custom signal filtering functions
Exported namespace: halfwave, quick_boxcar, circular_blur
Created by Joe Monaco on 2007-11-15. Updated 2009-09-11.
Copyright (c) 2007-2009 Columbia University. All rights reserved.
Copyright (c) 2009-2011 Johns Hopkins University. All rights reserved.
This software is provided AS IS under the terms of the Open Source MIT License.
See http://www.opensource.org/licenses/mit-license.php.
"""
from numpy import r_, empty, zeros, ceil, trapz, ndarray
from scipy.signal import gaussian, convolve
def halfwave(x, copy=False):
"""Half-wave rectifier for arrays or scalars
NOTE: Specify copy=True if array data should be copied before performing
halwave rectification.
"""
if type(x) is ndarray and x.ndim:
if copy:
x = x.copy()
x[x<0.0] = 0.0
else:
x = float(x)
if x < 0.0:
x = 0.0
return x
def quick_boxcar(s, M=4, centered=False):
"""Returns a boxcar-filtered version of the input signal
Keyword arguments:
M -- number of averaged samples (default 4)
centered -- recenter the filtered signal to reduce lag (default False)
"""
# Sanity check on signal and filter window
length = s.shape[0]
if length <= 2*M:
raise ValueError, 'signal too short for specified filter window'
# Set up staggered arrays for vectorized average
z = empty((M, length+M-1), 'd')
for i in xrange(M):
z[i] = r_[zeros(i)+s[0], s, zeros(M-i-1)+s[-1]]
# Center the average if specified
start_ix = 0
end_ix = length
if centered:
start_ix += int(M/2)
end_ix += int(M/2)
return z.mean(axis=0)[start_ix:end_ix]
def circular_blur(s, blur_width):
"""Return a wrapped gaussian smoothed (blur_width in degrees) signal for
data binned on a full circle range [0, 2PI/360).
"""
bins = s.shape[0]
width = blur_width / (360.0/bins)
size = ceil(8*width)
if size > bins:
size = bins
wrapped = r_[s[-size:], s, s[:size]]
G = gaussian(size, width)
G /= trapz(G)
S = convolve(wrapped, G, mode='same')
return S[size:-size]