Source code for mosaic.filters.besselLowpassFilter
# -*- coding: utf-8 -*-
"""
Implementation of an 'N' order Bessel filter
:Created: 7/1/2013
:Author: Arvind Balijepalli <arvind.balijepalli@nist.gov>
:License: See LICENSE.TXT
:ChangeLog:
.. line-block::
11/2/16 KB changed Bessel filter implementation to match expected rise time
9/27/16 AB Control phase delay
9/13/15 AB Updated logging to use mosaicLogFormat class
7/1/13 AB Initial version
"""
import numpy as np
import scipy.signal as sig
import sys
import mosaic.filters.metaIOFilter as metaIOFilter
import mosaic.utilities.mosaicLogging as mlog
__all__ = ["besselLowpassFilter"]
[docs]class besselLowpassFilter(metaIOFilter.metaIOFilter):
"""
:Keyword Args:
In addition to metaIOFilter.__init__ args,
- `filterOrder` : the filter order
- `filterCutoff` : filter cutoff frequency in Hz
"""
def _init(self, **kwargs):
"""
"""
self.logger=mlog.mosaicLogging().getLogger(__name__)
try:
self.filterOrder=float(kwargs['filterOrder'])
self.filterCutoff=float(kwargs['filterCutoff'])
except KeyError:
self.logger.error( "ERROR: Missing mandatory arguments 'filterOrder' or 'filterCutoff'" )
try:
self.causal = kwargs['causal'] == "True"
except KeyError:
self.causal = False
if self.causal:
raise NotImplementedError('Causal filter has not been implemented yet')
self.filterInit=False
[docs] def filterData(self, icurr, Fs):
"""
Denoise an ionic current time-series and store it in self.eventData
:Parameters:
- `icurr` : ionic current in pA
- `Fs` : original sampling frequency in Hz
"""
self.eventData=icurr
self.Fs=Fs
if not self.filterInit:
self.b, self.a=sig.bessel(
N=int(self.filterOrder),
Wn=float(self.filterCutoff/(float(self.Fs)/2.0)),
btype='lowpass',
analog=False,
output='ba',
norm='mag'
)
self.filterInit=True
#pad the data with 10x the transient time at both ends to manually eliminate edge effects of the filter
#for some reason I can't get good results using the pad method in filtfilt so manual it is
#this means there may be some numerical artefacts but they should be well below the level of noise
padding = int(10 * self.Fs/float(self.filterCutoff))
paddedsignal = np.pad(self.eventData,pad_width=padding,mode='edge')
self.eventData=sig.filtfilt(self.b, self.a, paddedsignal, padtype=None, method='pad')[padding:-padding]
def _filterCutoffFrequency(self):
return self.filterCutoff