def filtro_sinal(sinal, freq_low, freq_high, fs, ordem=5, rp=0): nyq = fs / 2 if rp == 0: bh, ah = signal.bessel(ordem, freq_low / nyq, btype='highpass', analog=False) bl, al = signal.bessel(ordem, freq_high / nyq, btype='lowpass', analog=False) else: bh, ah = signal.cheby1(ordem, rp, freq_low / nyq, btype='highpass', analog=False) bl, al = signal.cheby1(ordem, rp, freq_high / nyq, btype='lowpass', analog=False) sinal_ = signal.filtfilt(bl, al, sinal) result = signal.filtfilt(bh, ah, sinal_) return result
def dosomething(self): # do somethin when received package of full 60 int BP_b1, BP_a1 = signal.bessel(4, [8.0 / 30.0, 14.0 / 30.0], 'bandpass') # alpha bandpass parameter BP_b2, BP_a2 = signal.bessel(4, [15.0 / 30.0, 29.0 / 30.0], 'bandpass') # beta bandpass parameter nc_int_filter = filterloop(self.body_c) #print(str(len(nc_int_filter))) #print(nc_int_filter) alpha_db_filter = signal.filtfilt(BP_b1, BP_a1, nc_int_filter) beta_db_filter = signal.filtfilt(BP_b2, BP_a2, nc_int_filter) g_alpha_arr.extend(alpha_db_filter) g_beta_arr.extend(beta_db_filter) g_nc_int_filter.extend(nc_int_filter) if (len(self.body_fft) >= 300): self.body_fft = self.body_fft[60:300] self.body_fft.extend(nc_int_filter) self.body_fft_result = fft(self.body_fft) body_fft_result_temp = abs(self.body_fft_result) for i in range(len(body_fft_result_temp) / 2): g_ss_spectrum[i] = body_fft_result_temp[i] self.seperate_complexe() attentionLevel = self.clc_attn(self.body_fft_re_real, self.body_fft_re_imag) g_attention[0] = attentionLevel print(attentionLevel) else: self.body_fft.extend(nc_int_filter)
def _getFiltDesign(sf, f, npts, filtname, cycle, order, axis): """Get the designed filter sf : sample frequency f : frequency vector/list [ex : f = [2,4]] npts : number of points - 'fir1' - 'butter' - 'bessel' """ if type(f) != np.ndarray: f = np.array(f) # fir1 filter : if filtname == 'fir1': fOrder = fir_order(sf, npts, f[0], cycle=cycle) b, a = fir1(fOrder, f/(sf / 2)) # butterworth filter : elif filtname == 'butter': b, a = butter(order, [(2*f[0])/sf, (2*f[1])/sf], btype='bandpass') fOrder = None # bessel filter : elif filtname == 'bessel': b, a = bessel(order, [(2*f[0])/sf, (2*f[1])/sf], btype='bandpass') fOrder = None def filtSignal(x): return filtfilt(b, a, x, padlen=fOrder, axis=axis) return filtSignal
def acc_bessellow(): raw_signal = acc_read_variable["ax"] d, c = signal.bessel(3, 0.03, 'low', analog=False, norm='phase') result = signal.filtfilt(d, c, raw_signal) return result
def __compute_approximation_denorm_bessel(self): self.num, self.den = signal.bessel(self.order, self.wp, self.filter_t, analog=True, output='ba') self.zeros, self.poles, self.gain = signal.bessel(self.order, self.wp, self.filter_t, analog=True, output='zpk') self.sos = signal.bessel(self.order, self.wp, self.filter_t, analog=True, output='sos')
def __init__(self, step_dict): # set the filter b, a cohefficients self.filter = sig.bessel(int(step_dict['order']), float(step_dict['cutoff'])) # set steady state-like step response initial condition # in order to give the right value it will need to be multiplied by the first value processed self.init = sig.lfilter_zi(self.filter[0], self.filter[1]) self.first = True
def _getFiltDesign(sf, f, npts, filtname, cycle, order, axis): """Get the designed filter sf : sample frequency f : frequency vector/list [ex : f = [2,4]] npts : number of points - 'fir1' - 'butter' - 'bessel' """ if type(f) != np.ndarray: f = np.array(f) # fir1 filter : if filtname == 'fir1': fOrder = fir_order(sf, npts, f[0], cycle=cycle) b, a = fir1(fOrder, f / (sf / 2)) # butterworth filter : elif filtname == 'butter': b, a = butter(order, [(2 * f[0]) / sf, (2 * f[1]) / sf], btype='bandpass') fOrder = None # bessel filter : elif filtname == 'bessel': b, a = bessel(order, [(2 * f[0]) / sf, (2 * f[1]) / sf], btype='bandpass') fOrder = None def filtSignal(x): return filtfilt(b, a, x, padlen=fOrder, axis=axis) return filtSignal
def calculate_dvdt(v, t, filter=None): """Low-pass filters (if requested) and differentiates voltage by time. Parameters ---------- v : numpy array of voltage time series in mV t : numpy array of times in seconds filter : cutoff frequency for 4-pole low-pass Bessel filter in kHz (optional, default None) Returns ------- dvdt : numpy array of time-derivative of voltage (V/s = mV/ms) """ if has_fixed_dt(t) and filter: delta_t = t[1] - t[0] sample_freq = 1. / delta_t filt_coeff = (filter * 1e3) / (sample_freq / 2.) # filter kHz -> Hz, then get fraction of Nyquist frequency if filt_coeff < 0 or filt_coeff > 1: raise FeatureError("bessel coeff (%f) is outside of valid range [0,1]. cannot compute features." % filt_coeff) b, a = signal.bessel(4, filt_coeff, "low") v_filt = signal.filtfilt(b, a, v, axis=0) dv = np.diff(v_filt) else: dv = np.diff(v) dt = np.diff(t) dvdt = 1e-3 * dv / dt # in V/s = mV/ms # Remove nan values (in case any dt values == 0) dvdt = dvdt[~np.isnan(dvdt)] return dvdt
def calculate_dvdt(v, t, filter=None): """Low-pass filters (if requested) and differentiates voltage by time. Parameters ---------- v : numpy array of voltage time series in mV t : numpy array of times in seconds filter : cutoff frequency for 4-pole low-pass Bessel filter in kHz (optional, default None) Returns ------- dvdt : numpy array of time-derivative of voltage (V/s = mV/ms) """ if has_fixed_dt(t) and filter: delta_t = t[1] - t[0] sample_freq = 1. / delta_t filt_coeff = (filter * 1e3) / ( sample_freq / 2. ) # filter kHz -> Hz, then get fraction of Nyquist frequency if filt_coeff < 0 or filt_coeff >= 1: filt_coeff = 0.99 b, a = signal.bessel(4, filt_coeff, "low") v_filt = signal.filtfilt(b, a, v, axis=0) dv = np.diff(v_filt) else: dv = np.diff(v) dt = np.diff(t) dvdt = 1e-3 * dv / dt # in V/s = mV/ms # some data sources, such as neuron, occasionally report # duplicate timestamps, so we require that dt is not 0 return dvdt[np.fabs(dt) > sys.float_info.epsilon]
def lowBessel(data, fs, cutoff, order): #this is a bessel lowpass filter nyq = 0.5 * fs normal_cutoff = cutoff / nyq b, a = bessel(order, normal_cutoff, btype='low', analog=False) y = filtfilt(b, a, data) return y
def signal_bypass(self, cutoff, order, a_pass, rp, rs, btype='high'): nyq = 0.5 * self.fs normal_cutoff = cutoff / nyq if self.band_type == 'cheby1': b, a = signal.cheby1(order, a_pass, normal_cutoff, btype=btype, analog=False) elif self.band_type == 'cheby2': b, a = signal.cheby2(order, a_pass, normal_cutoff, btype=btype, analog=False) elif self.band_type == 'ellip': b, a = signal.ellip(order, rp, rs, normal_cutoff, btype=btype, analog=False) elif self.band_type == 'bessel': b, a = signal.bessel(order, normal_cutoff, btype=btype, analog=False) else: b, a = signal.butter(order, normal_cutoff, btype=btype, analog=False) return b, a
def HPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_PBC = buttord(self.F_PB,self.F_SB, self.A_PB,self.A_SB) if not self._test_N(): return -1 self._save(fil_dict, sig.bessel(self.N, self.F_PBC, btype='highpass', analog=False, output=self.FRMT))
def bandPass(self, order, cut_off1, cut_off2, sampling_frequency): python_freq1 = cut_off1 / sampling_frequency python_freq2 = cut_off2 / sampling_frequency self.sos = signal.bessel(order, [python_freq1*2, python_freq2*2], 'bandpass', output='sos') self.filter_list = [] for filt in self.sos: self.filter_list.append(IIR2Filter(filt))
def filter(self, ftype='butter', freq=1000.0): '''This method filters the self.working_data attribute to produce more reliable detection. ::Params:: freq = frequency of filtering. Default is 1 kHz. type = type of filter to use (Options: Bessel, Butterworth, Gaussian). Default us Bessel. ::Returns:: True if executed fully ''' rad_samp = freq / (10000.0/2) if ftype == 'butter': b, a = signal.butter(4, rad_samp) elif ftype == 'bessel': b, a = signal.bessel(4, rad_samp) else: print("Filter {0} not implemented".format(ftype)) self.working_data['channel1'] = signal.filtfilt( b, a, self.working_data['channel1'] ) self.working_data['channel2'] = signal.filtfilt( b, a, self.working_data['channel2'] ) return True
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 #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') b, a=sig.bessel( N=self.filterOrder, Wn=(self.filterCutoff/(float(self.Fs)/2.0)), btype='lowpass', analog=False, output='ba', norm='mag' ) self.eventData=sig.filtfilt(b, a, paddedsignal, padtype=None, method='pad')[padding:-padding]
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 #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') b, a = sig.bessel(N=self.filterOrder, Wn=(self.filterCutoff / (float(self.Fs) / 2.0)), btype='lowpass', analog=False, output='ba', norm='mag') self.eventData = sig.filtfilt(b, a, paddedsignal, padtype=None, method='pad')[padding:-padding]
def parse( self, current ): ''' Apply the filter-derivative method to filter the ionic current. ''' # Filter the current using a first order Bessel filter twice, one in # both directions to preserve phase from scipy import signal nyquist = self.sampling_freq / 2. b, a = signal.bessel( 1, self.cutoff_freq / nyquist, btype='low', analog=0, output='ba' ) filtered_current = signal.filtfilt( b, a, np.array( current ).copy() ) # Take the derivative deriv = np.abs( np.diff( filtered_current ) ) # Find the edges of the blocks which fulfill pass the lower threshold blocks = np.where( deriv > self.low_threshold, 1, 0 ) block_edges = np.abs( np.diff( blocks ) ) tics = np.where( block_edges == 1 )[0] + 1 # Split points are points in the each block which pass the high # threshold, with a maximum of one per block split_points = [0] for start, end in it.izip( tics[:-1:2], tics[1::2] ): # For all pairs of edges for a block.. segment = deriv[ start:end ] # Save all derivatives in that block to a segment if np.argmax( segment ) > self.high_threshold: # If the maximum derivative in that block is above a threshold.. split_points = np.concatenate( ( split_points, [ start, end ] ) ) # Save the edges of the segment # Now you have the edges of all transitions saved, and so the states are the current between these transitions tics = np.concatenate( ( split_points, [ current.shape[0] ] ) ) tics = list(map( int, tics )) return [ Segment( current=current[ tics[i]:tics[i+1] ], start=tics[i] ) for i in range( 0, len(tics)-1, 2 ) ]
def parse(self, current): """ Apply the filter-derivative method to filter the ionic current. """ # Filter the current using a first order Bessel filter twice, one in # both directions to preserve phase from scipy import signal nyquist = self.sampling_freq / 2.0 b, a = signal.bessel(1, self.cutoff_freq / nyquist, btype="low", analog=0, output="ba") filtered_current = signal.filtfilt(b, a, np.array(current).copy()) # Take the derivative deriv = np.abs(np.diff(filtered_current)) # Find the edges of the blocks which fulfill pass the lower threshold blocks = np.where(deriv > self.low_threshold, 1, 0) block_edges = np.abs(np.diff(blocks)) tics = np.where(block_edges == 1)[0] + 1 # Split points are points in the each block which pass the high # threshold, with a maximum of one per block split_points = [0] for start, end in it.izip(tics[:-1:2], tics[1::2]): # For all pairs of edges for a block.. segment = deriv[start:end] # Save all derivatives in that block to a segment if ( np.argmax(segment) > self.high_threshold ): # If the maximum derivative in that block is above a threshold.. split_points = np.concatenate((split_points, [start, end])) # Save the edges of the segment # Now you have the edges of all transitions saved, and so the states are the current between these transitions tics = np.concatenate((split_points, [current.shape[0]])) tics = map(int, tics) return [Segment(current=current[tics[i] : tics[i + 1]], start=tics[i]) for i in xrange(0, len(tics) - 1, 2)]
def filt(data, cutoff, fs=1., order=1, rp=10., rs=10., kind='butter', btype='low', ftype='filtfilt', axis=0, analog=False): """ Apply a digital filter. :param data: :param cutoff: :param fs: :param order: :param rp: :param rs: :param kind: :param btype: :param ftype: :param axis: :param analog: :return: """ nyquistFreqInRads = (2 * pi * fs) / 2 crit = 2 * pi * cutoff / nyquistFreqInRads if kind == 'butter': b, a = signal.butter(order, crit, btype=btype, analog=analog) elif kind == 'bessel': b, a = signal.bessel(order, Wn=crit, btype=btype, analog=analog) elif kind == 'cheby1': b, a = signal.cheby1(order, rp=rp, Wn=crit, btype=btype, analog=analog) elif kind == 'cheby2': b, a = signal.cheby2(order, rs=rs, Wn=crit, btype=btype, analog=analog) elif kind == 'ellip': b, a = signal.ellip(order, rp=rp, rs=rs, Wn=crit, btype=btype, analog=analog) else: raise ValueError('Invalid filter type specified: {}'.format(kind)) if ftype == 'filtfilt': y = signal.filtfilt(b, a, data, axis=axis) elif ftype == 'lfilt': y = signal.lfilter(b, a, data, axis=axis) else: raise ValueError('Invalid filter type specified: {}'.format(btype)) # If data is dataframe, restore the original column and index info if isinstance(data, pd.DataFrame): y = pd.DataFrame(y, index=data.index, columns=data.columns) elif isinstance(data, pd.Series): y = pd.Series(y, index=data.index, name=data.name) return y
def __order_min_max_bessel(self): order = self.min_order - 1 founded = False while order <= self.max_order and not founded: order += 1 num, den = signal.bessel(order, 1, 'low', analog=True, output='ba') # switched num and den to get attenuation 'points' sys = signal.TransferFunction(den, num) w, mag, phase = signal.bode(sys) mag_db = np.log10(mag) i = 0 compatible = True for i in range(0, len(w)): if w[i] < 1: if mag_db[i] > self.template.att_p: compatible = False break elif w[i] > self.template.omega_sN: if mag_db[i] < self.template.att_s: compatible = False break if compatible: founded = True if order < self.min_order: order = self.min_order elif order > self.max_order: order = self.max_order return order
def lowpass(sig, cutoff, filter_=('cheby1', 8), sr=44100): """Lowpasses input signal based on a cutoff frequency Arguments: sig {numpy 1d array} -- input signal cutoff {int} -- cutoff frequency Keyword Arguments: sr {int} -- sampling rate of the input signal (default: {44100}) filter_type {str} -- type of filter, only butter and cheby1 are implemented (default: {'butter'}) Returns: numpy 1d array -- lowpassed signal """ nyq = sr / 2 cutoff /= nyq if filter_[0] == 'butter': B, A = signal.butter(filter_[1], cutoff) elif filter_[0] == 'cheby1': B, A = signal.cheby1(filter_[1], 0.05, cutoff) elif filter_[0] == 'bessel': B, A = signal.bessel(filter_[1], cutoff, norm='mag') elif filter_[0] == 'ellip': B, A = signal.ellip(filter_[1], 0.05, 20, cutoff) sig_lp = signal.filtfilt(B, A, sig) return sig_lp.astype(np.float32)
def __compute_approximation_norm_bessel(self): self.num_norm, self.den_norm = signal.bessel(self.order, 1, 'lowpass', analog=True, output='ba') self.zeros_norm, self.poles_norm, self.gain_norm = signal.bessel( self.order, self.template.omega_pN, 'lowpass', analog=True, output='zpk') self.sos_norm = signal.bessel(self.order, self.template.omega_pN, 'lowpass', analog=True, output='sos')
def filterCalc(order, bandarr, fs, btype, ftype): nyq = 0.5 * fs bandarr = [i/nyq for i in bandarr] if ftype == 'butter': b, a = signal.butter(order, bandarr, btype=btype, analog=False) if ftype == 'bessel': b, a = signal.bessel(order, bandarr, btype=btype) return b, a
def bessel_filter(data_sig, cutoff): nyq = 0.5 * fs cutoff_low = cutoff / nyq [b, a] = signal.bessel(2, cutoff_low, 'low') y = signal.lfilter(b, a, data_sig) return y
def BSmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_PBC = buttord([self.F_PB, self.F_PB2], [self.F_SB, self.F_SB2], self.A_PB,self.A_SB) if not self._test_N(): return -1 self._save(fil_dict, sig.bessel(self.N, self.F_PBC, btype='bandstop', analog=False, output=self.FRMT))
def filter_data(self): cutoff = float(self.cutoff_entry.get()) order = int(self.order_entry.get()) Wn = 2.0 * cutoff/float(self.samplerate) b, a = bessel(order,Wn,'low') padding = 1000 padded = np.pad(self.filtered_data, pad_width=padding, mode='median') self.filtered_data = filtfilt(b, a, padded, padtype=None)[padding:-padding]
def __init__(self, N=2, Wn=100e6, btype='low', norm='phase', fs=1e9): # 为避免麻烦,不继承 baFilter.__init__ 函数,只继承其他函数 # 默认参数是一个100MHz的 2阶低通贝塞尔滤波器 # 配置字典, default: output='ba',analog=False, self.dict=dict(N=N, Wn=Wn, btype=btype, analog=False, output='ba', norm=norm, fs=fs) self.ba = signal.bessel(**self.dict)
def filter_data(self): cutoff = float(self.cutoff_entry.get()) order = int(self.order_entry.get()) Wn = 2.0 * cutoff/float(self.samplerate) b, a = bessel(order,Wn,'low') padding = 1000 padded = np.pad(self.data, pad_width=padding, mode='median') self.filtered_data = filtfilt(b, a, padded, padtype=None)[padding:-padding]
def BSman(self, fil_dict): self._get_params(fil_dict) self._save( fil_dict, sig.bessel(self.N, [self.F_C, self.F_C2], btype='bandstop', analog=False, output=self.FRMT))
def HPman(self, fil_dict): self._get_params(fil_dict) self._save( fil_dict, sig.bessel(self.N, self.F_C, btype='highpass', analog=False, output=self.FRMT))
def bessel(self, save=True, show=False): N, Wn = signal.ellipord(self.Wpass, self.Wstop, self.gpass, self.gstop) b, a = signal.bessel(N, Wn, 'low') y = signal.filtfilt(b, a, self.output) if show: self.showGraph(data=y) if save: self.output = y
def __set_filter_coefs(self): #implemet just a nyquist freqyency filter self.filter_coefs = sig.bessel(self.AA_FILTER_ORDER, self.AA_FILTER_NYQUIST_COEF, btype='lowpass', analog=False, output='ba') #bessel filter is used to have minimum ringing and risk of overshooting the analog output range of the hardware pass
def filter_data(self): fc = 1000 * float(self.fc_entry.get()) fs = 1000 * float(self.fs_entry.get()) poles = int(self.poles.get()) Wn = 2.0 * fc / fs b, a = bessel(poles, Wn, 'low') padded = np.pad(self.perfect_data, pad_width=poles, mode='edge') self.filtered_data = filtfilt(b, a, padded, method='pad', padlen=None)[poles:-poles]
def _denormalised_transfer_function(self): b, a = ss.bessel(self.denorm_order, np.divide(1, self.group_delay * 1e-3), analog=True, norm='delay') self.h_denorm = ss.TransferFunction(b, a).to_zpk() self.adjust_function_gain(self.h_denorm, np.float_power(10, np.divide(self.gain, 20))) return ApproximationErrorCode.OK
def bessel_bandpass_filter(data, lowcut, highcut, fs, order=2): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq # bessel() and lfilter() are from scipy.signal b, a = bessel(order, [low, high], btype='band') y = lfilter(b, a, data) return y
def test_bad_filter(self): """Regression test for #651: better handling of badly conditioned filter coefficients.""" warnings.simplefilter("error", BadCoefficients) try: b, a = bessel(20, 0.1) z, p, k = tf2zpk(b, a) raise AssertionError("tf2zpk did not warn about bad "\ "coefficients") except BadCoefficients: pass finally: warnings.simplefilter("always", BadCoefficients)
def filter_design(sf, N, f, filtname='fir1', cycle=3, order=3, axis=0): if filtname == 'fir1': fOrder = fir_order(sf, N, f[0], cycle=cycle) b, a = fir1(fOrder, f/(sf / 2)) elif filtname == 'butter': b, a = butter(order, [(2*f[0])/sf, (2*f[1])/sf], btype='bandpass') fOrder = None elif filtname == 'bessel': b, a = bessel(order, [(2*f[0])/sf, (2*f[1])/sf], btype='bandpass') fOrder = None def FiltDesign(x): return filtfilt(b, a, x, padlen=fOrder, axis=axis) return FiltDesign
def _gufunc_filtfilt_bessel(x, y, N, Wn, out=None): # pragma: no cover # Pre-process xynm = preprocess_interp1d_nan_func(x, y, out) if xynm is None: # all nan return x, y, x_even, y_even, num_nan, mask = xynm # filter function b, a = signal.bessel(N=N[0], Wn=Wn[0]) # filter even data yf_even = signal.filtfilt(b, a, y_even, method='gust') # Post-process postprocess_interp1d_nan_func(x, x_even, yf_even, num_nan, mask, out)
def filt(sf, f, x, btype='bandpass', order=3, method='butterworth', way='filtfilt', axis=0): """Filt data. Parameters ---------- sf : float The sampling frequency f : array_like Frequency vector (2,) x : array_like The data to filt. btype : {'bandpass', 'bandstop', 'highpass', 'lowpass'} If highpass, the first value of f will be used. If lowpass the second value of f will be used. order : int | 3 The filter order. method : {'butterworth', 'bessel'} Filter type to use. way : {'filtfilt', 'lfilter'} Specify if the filter has to be one way ('lfilter') or two ways ('filtfilt'). axis : int | 0 The axis along which the filter is applied. Returns ------- xfilt : array_like Filtered data. """ # Normalize frequency vector according to btype : if btype in ['bandpass', 'bandstop']: fnorm = np.divide(f, .5 * sf) elif btype == 'lowpass': fnorm = np.array(f[-1] / (.5 * sf)) elif btype == 'highpass': fnorm = np.array(f[0] / (.5 * sf)) # Get filter coefficients : if method == 'butterworth': b, a = butter(order, fnorm, btype=btype) elif method == 'bessel': b, a = bessel(order, fnorm, btype=btype) # Apply filter : if way == 'filtfilt': return filtfilt(b, a, x, axis=axis) elif way == 'lfilter': return lfilter(b, a, x, axis=axis)
def filter(self, order=1, cutoff=2000.0): """ Performs a bessel filter on the selected data, normalizing the cutoff frequency by the nyquist limit based on the sampling rate. """ if type(self) != Event: raise TypeError("Cannot filter a metaevent. Must have the current.") from scipy import signal nyquist = self.second / 2.0 (b, a) = signal.bessel(order, cutoff / nyquist, btype="low", analog=0, output="ba") self.current = signal.filtfilt(b, a, self.current) self.filtered = True self.filter_order = order self.filter_cutoff = cutoff
def besselfilter(ECGdata): """ Filters the data using IIR bessel filter Description: Digital filter which returns the filtered signal using bessel 4th order low pass design. The cutoff frequency is 0-35Hz with 100Hz as sampling frequency. Input: ECGdata -- list of integers (ECG data) Output: lfilter(b,a,ECGdata)-- filtered data along one-dimension with IIR bessel filter """ fs = 500.00 f = 35.00 N=4 [b,a]=bessel(N,f/fs) return lfilter(b,a,ECGdata)
def bessel_bandpass_filter(data, lowcut, highcut, fs, order=2): """This is a wrapper for the bessel bandpass filter. :param: data - 1d numpy array to be filtered :param: lowcut - low pass frequency, in Hz :param: highcut - high pass frequency, in Hz :param: fs - sampling frequency, in samples / second (i.e.: 10000) :param: order - filter order :returns: filtered data """ nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq # bessel() and lfilter() are from scipy.signal b, a = bessel(order, [low, high], btype='band') y = lfilter(b, a, data) return y
def bandpass(x, dt, f_lo, f_hi): """ Highpass filter Parameters ---------- x : stfio_plot.Timeseries Input data dt : float Sampling interval in ms f_c : float Cutoff frequency in kHz (-3 dB) Returns ------- x convolved with a Gaussian filter kernel. """ fs = 1.0/dt B, A = bessel(1, [f_lo / (fs / 2), f_hi / (fs / 2)], btype='bandpass') # 1st order Butterworth low-pass return lfilter(B, A, x, axis=0)
def lowpass(x, dt, f_c): """ Lowpass filter Parameters ---------- x : stfio_plot.Timeseries Input data dt : float Sampling interval in ms f_c : float Cutoff frequency in kHz (-3 dB) Returns ------- x convolved with a Gaussian filter kernel. """ fs = 1.0/dt cutoff = f_c B, A = bessel(1, cutoff / (fs / 2), btype='low') # 1st order Butterworth low-pass return lfilter(B, A, x, axis=0)
def design(self, ripple=None): if self.filter_class == 'butterworth': self.B, self.A = signal.butter(self.N, self.Wn, self.filter_type, analog=True, output='ba') elif self.filter_class == 'chebyshev_1': if ripple is None or ripple <= 0: raise ValueError("Must give a ripple that is > 0") self.B, self.A = signal.cheby1(self.N, ripple, self.Wn, self.filter_type, analog=True, output='ba') elif self.filter_class == 'chebyshev_2': self.B, self.A = signal.cheby2(self.N, self.stopband_attenuation, self.Wn, self.filter_type, analog=True, output='ba') elif self.filter_class == 'elliptical': self.B, self.A = signal.ellip(self.N, self.passband_attenuation, self.stopband_attenuation, self.Wn, self.filter_type, analog=True, output='ba') elif self.filter_class == 'bessel': self.B, self.A = signal.bessel(self.N, self.Wn, self.filter_type, analog=True) else: raise NotImplementedError("Computation of {} not implemented yet.".format(self.filter_class))
def bessel(data, **kwargs): """ Implement a Bessel type analog filter ---------- data: xarray DataSet as obtained from a TDI call Returns ------- Smoothed array and time derivative """ time = data.time.values dt = (time.max() - time.min()) / (time.size - 1) Ny = numpy.round( 1. / ((time.max() - time.min()) / (time.size - 1))) / 2 # implement an appropriate Bessel analog filter fcutoff = kwargs.get('fcutoff', 30.) _Wn = fcutoff / Ny b, a = signal.bessel(4, _Wn) # create a copy of the signals sm = data.values.transpose().copy() smd = signal.filtfilt(b, a, numpy.gradient(sm, dt, axis=-1), axis=-1) return sm.transpose(), smd.transpose()
def _getFiltDesign(self, sf, f, npts): """Get the designed filter sf : sample frequency f : frequency vector/list [ex : f = [2,4]] npts : number of points """ if type(f) != n.ndarray: f = n.array(f) if self.filtname == 'fir1': fOrder = fir_order(sf, npts, f[0], cycle=self.cycle) b, a = fir1(fOrder, f/(sf / 2)) elif self.filtname == 'butter': b, a = butter(self.order, [(2*f[0])/sf, (2*f[1])/sf], btype='bandpass') fOrder = None elif self.filtname == 'bessel': b, a = bessel(self.order, [(2*f[0])/sf, (2*f[1])/sf], btype='bandpass') fOrder = None def filSignal(x): return filtfilt(b, a, x, padlen=fOrder, axis=self.axis) return filSignal
import matplotlib.pyplot as plt import oversampling import simple_overdrive SampleRate = 48000 Samples = 1000000 FreqMax = 20000 t = np.arange(Samples, dtype=np.float64) / SampleRate input1 = np.sin(np.pi * (SampleRate * FreqMax / Samples * (t + .1)) * t) input2 = input1[::-1].flatten() signal = np.array((input1, input2)) b, a = ssignal.bessel(8, float(FreqMax) / SampleRate) print "Oversampling" oversampled_signal = oversampling.oversample2_6point_5_order(signal) oversampling.plot_me(signal, 0, 2, MySampleRate = SampleRate) print "Overdrive" overdriven_signal = (simple_overdrive.overdrive(signal[0], fs = SampleRate), simple_overdrive.overdrive(signal[1], fs = SampleRate)) oversampling.plot_me(overdriven_signal, 1, 2, MySampleRate = SampleRate) plt.figure() oversampling.plot_me(signal, 0, 2, MySampleRate = SampleRate) print "Overdrive oversampling" overdriven_oversampled_signal = np.asarray((simple_overdrive.overdrive(oversampled_signal[0], fs = SampleRate * 2), simple_overdrive.overdrive(oversampled_signal[1], fs = SampleRate * 2))) oversampling.plot_me(overdriven_oversampled_signal, 1, 2, MySampleRate = SampleRate * 2)
def lpFilter(trace, Fs, Fcut): b, a = signal.bessel(4, Fcut/(Fs * 1.0), 'low') lp_trace = signal.filtfilt(b,a,trace, padlen=150) return lp_trace
def BSmin(self, fil_dict): self.get_params(fil_dict) self.N, self.F_PBC = buttord([self.F_PB, self.F_PB2], [self.F_SB, self.F_SB2], self.A_PB,self.A_SB) self.save(fil_dict, sig.bessel(self.N, self.F_PBC, btype='bandstop', analog = False, output = frmt))
def process_instance(self, name, v, curr, t, onset, dur, stim_name): feature = EphysFeatures(name) ################################################################ # set stop time -- run until end of stimulus or end of sweep # comment-out the one of the two approaches # detect spikes only during stimulus start = onset stop = onset + dur # detect spikes for all of sweep #start = 0 #stop = t[-1] ################################################################ # pull out spike times # calculate the derivative only within target window # otherwise get spurious detection at ends of stimuli # filter with 10kHz cutoff if constant 200kHz sample rate (ie experimental trace) start_idx = np.where(t >= start)[0][0] stop_idx = np.where(t >= stop)[0][0] v_target = v[start_idx:stop_idx] if np.abs(t[1] - t[0] - 5e-6) < 1e-7 and np.var(np.diff(t)) < 1e-6: b, a = signal.bessel(4, 0.1, "low") smooth_v = signal.filtfilt(b, a, v_target, axis=0) dv = np.diff(smooth_v) else: dv = np.diff(v_target) dvdt = dv / (np.diff(t[start_idx:stop_idx]) * 1e3) # in mV/ms dv_cutoff = 20 thresh_pct = 0.05 spikes = [] temp_spk_idxs = np.where(np.diff(np.greater_equal(dvdt, dv_cutoff).astype(int)) == 1)[0] # find positive-going crossings of 100 mV/ms spk_idxs = [] for i, temp in enumerate(temp_spk_idxs): if i == 0: spk_idxs.append(temp) elif np.any(dvdt[temp_spk_idxs[i - 1]:temp] < 0): # check if the dvdt has gone back down below zero between presumed spike times # sometimes the dvdt bobbles around detection threshold and produces spurious guesses at spike times spk_idxs.append(temp) spk_idxs += start_idx # set back to the "index space" of the original trace # recalculate full dv/dt for feature analysis (vs spike detection) if np.abs(t[1] - t[0] - 5e-6) < 1e-7 and np.var(np.diff(t)) < 1e-6: b, a = signal.bessel(4, 0.1, "low") smooth_v = signal.filtfilt(b, a, v, axis=0) dv = np.diff(smooth_v) else: dv = np.diff(v) dvdt = dv / (np.diff(t) * 1e3) # in mV/ms # First time through, accumulate upstrokes to calculate average threshold target for spk_n, spk_idx in enumerate(spk_idxs): # Etay defines spike as time of threshold crossing spk = {} if spk_n < len(spk_idxs) - 1: next_idx = spk_idxs[spk_n + 1] else: next_idx = stop_idx if spk_n > 0: prev_idx = spk_idxs[spk_n - 1] else: prev_idx = start_idx # Find the peak peak_idx = np.argmax(v[spk_idx:next_idx]) + spk_idx spk["peak_idx"] = peak_idx spk["f_peak"] = v[peak_idx] spk["f_peak_i"] = curr[peak_idx] spk["f_peak_t"] = t[peak_idx] # Check if end of stimulus interval cuts off spike - if so, don't process spike if spk_n == len(spk_idxs) - 1 and peak_idx == next_idx-1: continue if spk_idx == peak_idx: continue # this was bugfix, but why? ramp? # Determine maximum upstroke of spike upstroke_idx = np.argmax(dvdt[spk_idx:peak_idx]) + spk_idx spk["upstroke"] = dvdt[upstroke_idx] if np.isnan(spk["upstroke"]): # sometimes dvdt will be NaN because of multiple cvode points at same time step close_idx = upstroke_idx + 1 while (np.isnan(dvdt[close_idx])): close_idx += 1 spk["upstroke_idx"] = close_idx spk["upstroke"] = dvdt[close_idx] spk["upstroke_v"] = v[close_idx] spk["upstroke_i"] = curr[close_idx] spk["upstroke_t"] = t[close_idx] else: spk["upstroke_idx"] = upstroke_idx spk["upstroke_v"] = v[upstroke_idx] spk["upstroke_i"] = curr[upstroke_idx] spk["upstroke_t"] = t[upstroke_idx] # Preliminarily define threshold where dvdt = 5% * max upstroke thresh_pct = 0.05 find_thresh_idxs = np.where(dvdt[prev_idx:upstroke_idx] <= thresh_pct * spk["upstroke"])[0] if len(find_thresh_idxs) < 1: # Can't find a good threshold value - probably a bad simulation case # Fall back to the upstroke value threshold_idx = upstroke_idx else: threshold_idx = find_thresh_idxs[-1] + prev_idx spk["threshold_idx"] = threshold_idx spk["threshold"] = v[threshold_idx] spk["threshold_v"] = v[threshold_idx] spk["threshold_i"] = curr[threshold_idx] spk["threshold_t"] = t[threshold_idx] spk["rise_time"] = spk["f_peak_t"] - spk["threshold_t"] PERIOD = t[1] - t[0] width_volts = (v[peak_idx] + v[threshold_idx]) / 2 recording_width = False for i in range(threshold_idx, min(len(v), threshold_idx + int(0.001 / PERIOD))): if not recording_width and v[i] >= width_volts: recording_width = True idx0 = i elif recording_width and v[i] < width_volts: spk["half_height_width"] = t[i] - t[idx0] break # </KEITH> # Check for things that are probably not spikes: # if there is more than 2 ms between the detection event and the peak, don't count it if t[peak_idx] - t[threshold_idx] > 0.002: continue # if the "spike" is less than 2 mV, don't count it if v[peak_idx] - v[threshold_idx] < 2.0: continue # if the absolute value of the peak is less than -30 mV, don't count it if v[peak_idx] < -30.0: continue spikes.append(spk) # Refine threshold target based on average of all spikes if len(spikes) > 0: threshold_target = np.array([spk["upstroke"] for spk in spikes]).mean() * thresh_pct for spk_n, spk in enumerate(spikes): if spk_n < len(spikes) - 1: next_idx = spikes[spk_n + 1]["threshold_idx"] else: next_idx = stop_idx if spk_n > 0: prev_idx = spikes[spk_n - 1]["peak_idx"] else: prev_idx = start_idx # Restore variables from before # peak_idx = spk['peak_idx'] peak_idx = np.argmax(v[spk['threshold_idx']:next_idx]) + spk['threshold_idx'] spk["peak_idx"] = peak_idx spk["f_peak"] = v[peak_idx] spk["f_peak_i"] = curr[peak_idx] spk["f_peak_t"] = t[peak_idx] # Determine maximum upstroke of spike # upstroke_idx = spk['upstroke_idx'] upstroke_idx = np.argmax(dvdt[spk['threshold_idx']:peak_idx]) + spk['threshold_idx'] spk["upstroke"] = dvdt[upstroke_idx] if np.isnan(spk["upstroke"]): # sometimes dvdt will be NaN because of multiple cvode points at same time step close_idx = upstroke_idx + 1 while (np.isnan(dvdt[close_idx])): close_idx += 1 spk["upstroke_idx"] = close_idx spk["upstroke"] = dvdt[close_idx] spk["upstroke_v"] = v[close_idx] spk["upstroke_i"] = curr[close_idx] spk["upstroke_t"] = t[close_idx] else: spk["upstroke_idx"] = upstroke_idx spk["upstroke_v"] = v[upstroke_idx] spk["upstroke_i"] = curr[upstroke_idx] spk["upstroke_t"] = t[upstroke_idx] # Find threshold based on average target find_thresh_idxs = np.where(dvdt[prev_idx:upstroke_idx] <= threshold_target)[0] if len(find_thresh_idxs) < 1: # Can't find a good threshold value - probably a bad simulation case # Fall back to the upstroke value threshold_idx = upstroke_idx else: threshold_idx = find_thresh_idxs[-1] + prev_idx spk["threshold_idx"] = threshold_idx spk["threshold"] = v[threshold_idx] spk["threshold_v"] = v[threshold_idx] spk["threshold_i"] = curr[threshold_idx] spk["threshold_t"] = t[threshold_idx] # Define the spike time as threshold time spk["t_idx"] = threshold_idx spk["t"] = t[threshold_idx] # Save the -30 mV crossing time for backward compatibility with Etay code overn30_idxs = np.where(v[threshold_idx:peak_idx] >= -30)[0] if len(overn30_idxs) > 0: spk["t_idx_n30"] = overn30_idxs[0] + threshold_idx else: # fall back to threshold definition if spike doesn't cross -30 mV spk["t_idx_n30"] = threshold_idx spk["t_n30"] = t[spk["t_idx_n30"]] # Figure out initial "slope" of phase plot post-threshold plus_5_vec = np.where(v[threshold_idx:upstroke_idx] >= spk["threshold"] + 5)[0] if len(plus_5_vec) > 0: thresh_plus_5_idx = plus_5_vec[0] + threshold_idx spk["thresh_ramp"] = dvdt[thresh_plus_5_idx] - dvdt[threshold_idx] else: spk["thresh_ramp"] = dvdt[upstroke_idx] - dvdt[threshold_idx] # go forward to determine peak downstroke of spike downstroke_idx = np.argmin(dvdt[peak_idx:next_idx]) + peak_idx spk["downstroke_idx"] = downstroke_idx spk["downstroke_v"] = v[downstroke_idx] spk["downstroke_i"] = curr[downstroke_idx] spk["downstroke_t"] = t[downstroke_idx] spk["downstroke"] = dvdt[downstroke_idx] if np.isnan(spk["downstroke"]): # sometimes dvdt will be NaN because of multiple cvode points at same time step close_idx = downstroke_idx + 1 while (np.isnan(dvdt[close_idx])): close_idx += 1 spk["downstroke"] = dvdt[close_idx] features = {} feature.mean["base_v"] = v[np.where((t > onset - 0.1) & (t < onset - 0.001))].mean() # baseline voltage, 100ms before stim feature.mean["spikes"] = spikes isi_cv = self.isicv(spikes) if isi_cv is not None: feature.mean["ISICV"] = isi_cv n_spikes = len(spikes) feature.mean["n_spikes"] = n_spikes feature.mean["rate"] = 1.0 * n_spikes / (stop - start); feature.mean["adapt"] = self.adaptation_index(spikes, stop) if len(spikes) > 1: feature.mean["doublet"] = 1000 * (spikes[1]["t"] - spikes[0]["t"]) if len(spikes) > 0: for i, spk in enumerate(spikes): idx_next = spikes[i + 1]["t_idx"] if i < len(spikes) - 1 else stop_idx self.calculate_trough(spk, v, curr, t, idx_next) half_max_v = (spk["f_peak"] - spk["f_trough"]) / 2.0 + spk["f_trough"] over_half_max_v_idxs = np.where(v[spk["t_idx"]:spk["trough_idx"]] > half_max_v)[0] if len(over_half_max_v_idxs) > 0: spk["width"] = 1000. * (t[over_half_max_v_idxs[-1] + spk["t_idx"]] - t[over_half_max_v_idxs[0] + spk["t_idx"]]) feature.mean["latency"] = 1000. * (spikes[0]["t"] - onset) feature.mean["latency_n30"] = 1000. * (spikes[0]["t_n30"] - onset) # extract properties for each spike isicnt = 0 isitot = 0 for i in range(0, len(spikes)-1): spk = spikes[i] idx_next = spikes[i+1]["t_idx"] isitot += spikes[i+1]["t"] - spikes[i]["t"] isicnt += 1 if isicnt > 0: feature.mean["isi_avg"] = 1000 * isitot / isicnt else: feature.mean["isi_avg"] = None # average feature data from individual spikes # build superset dictionary of possible features superset = {} for i in range(len(spikes)): for k in spikes[i].keys(): if k not in superset: superset[k] = k for k in superset.keys(): cnt = 0 mean = 0 for i in range(len(spikes)): if k not in spikes[i]: continue mean += float(spikes[i][k]) cnt += 1.0 # this shouldn't be possible, but it may be in future version # so might as well trap for it if cnt == 0: continue mean /= cnt stdev = 0 for i in range(len(spikes)): if k not in spikes[i]: continue dif = mean - float(spikes[i][k]) stdev += dif * dif stdev = math.sqrt(stdev / cnt) feature.mean[k] = mean feature.stdev[k] = stdev # self.feature_list.append(feature) self.feature_source.append(name)
def HPman(self, fil_dict): self._get_params(fil_dict) if not self._test_N(): return -1 self._save(fil_dict, sig.bessel(self.N, self.F_C, btype='highpass', analog=False, output=self.FRMT))
import sys sys.path.append('../..') import dsp_fpga_lib as dsp plt.rcParams['lines.linewidth'] = 2 #================================ W_c = 2; A_PB_log = 0.5; A_SB_log = 40.; L = 2 filt_type = 'LP' zeta = sqrt(3)/2 # damping factor for Bessel zeta = 0.25 #%omega_n sqrt{ 1 - 2 %zeta^2 + sqrt{4 %zeta^4 - 4 %zeta^2 + 2}} [bb,aa] = sig.bessel(L, W_c, analog=True) [bb,aa] = sig.butter(L, W_c, analog=True) [bb,aa] = sig.cheby1(L, A_PB_log, W_c, analog=True) #[bb,aa] = sig.cheby2(L, A_SB_log, W_c, analog=True) #[bb,aa] = sig.ellip(L, A_PB_log, A_SB_log, W_c, analog=True) # Define system function from polynomial coefficients # e.g. H(s) = (b2 s^2 + b1 s + b0) / (a2 s^2 + a1 s + a0) ## Second order systems aa = [1, 2 * zeta * W_c, 1] # general 2nd order denominator bb = [W_c * W_c] # lowpass #b = # 1st order LP: H(s) = 1 / (s RC + 1) #bb = [1]; aa = [1, 1]
def BSman(self, fil_dict): self._get_params(fil_dict) if not self._test_N(): return -1 self._save(fil_dict, sig.bessel(self.N, [self.F_C,self.F_C2], btype='bandstop', analog=False, output=self.FRMT))
def SignalFilter_LPFBessel(signal, LPF, samplefreq, NPole=8, reduce=False): """Low pass filter a signal with a Bessel filter Digitally low-pass filter a signal using a multipole Bessel filter filter. Does not apply reverse filtering so that result is causal. Possibly reduce the number of points in the result array. Parameters ---------- signal : a numpy array of dim = 1, 2 or 3. The "last" dimension is filtered. The signal to be filtered. LPF : float The low-pass frequency of the filter (Hz) samplefreq : float The uniform sampling rate for the signal (in seconds) NPole : int Number of poles for Butterworth filter. Positive integer. reduce : boolean (default: False) If True, subsample the signal to the lowest frequency needed to satisfy the Nyquist critera. If False, do not subsample the signal. Returns ------- w : array Filtered version of the input signal """ if debugFlag: print "sfreq: %f LPF: %f HPF: %f" % (samplefreq, LPF) flpf = float(LPF) sf = float(samplefreq) wn = [flpf / (sf / 2.0)] reduction = 1 if reduce: if LPF <= samplefreq / 2.0: reduction = int(samplefreq / LPF) if debugFlag is True: print "signalfilter: samplef: %f wn: %f, lpf: %f, NPoles: %d " % (sf, wn, flpf, NPole) filter_b, filter_a = spSignal.bessel(NPole, wn, btype="low", output="ba") if signal.ndim == 1: sm = np.mean(signal) w = spSignal.lfilter(filter_b, filter_a, signal - sm) # filter the incoming signal w = w + sm if reduction > 1: w = spSignal.resample(w, reduction) return w if signal.ndim == 2: sh = np.shape(signal) for i in range(0, np.shape(signal)[0]): sm = np.mean(signal[i, :]) w1 = spSignal.lfilter(filter_b, filter_a, signal[i, :] - sm) w1 = w1 + sm if reduction == 1: w1 = spSignal.resample(w1, reduction) if i == 0: w = np.empty((sh[0], np.shape(w1)[0])) w[i, :] = w1 return w if signal.ndim == 3: sh = np.shape(signal) for i in range(0, np.shape(signal)[0]): for j in range(0, np.shape(signal)[1]): sm = np.mean(signal[i, j, :]) w1 = spSignal.lfilter(filter_b, filter_a, signal[i, j, :] - sm) w1 = w1 + sm if reduction == 1: w1 = spSignal.resample(w1, reduction) if i == 0 and j == 0: w = np.empty((sh[0], sh[1], np.shape(w1)[0])) w[i, j, :] = w1 return w if signal.ndim > 3: print "Error: signal dimesions of > 3 are not supported (no filtering applied)" return signal
def get_filter(ftype='FIR', band='lowpass', order=None, frequency=None, sampling_rate=1000., **kwargs): """Compute digital (FIR or IIR) filter coefficients with the given parameters. Parameters ---------- ftype : str Filter type: * Finite Impulse Response filter ('FIR'); * Butterworth filter ('butter'); * Chebyshev filters ('cheby1', 'cheby2'); * Elliptic filter ('ellip'); * Bessel filter ('bessel'). band : str Band type: * Low-pass filter ('lowpass'); * High-pass filter ('highpass'); * Band-pass filter ('bandpass'); * Band-stop filter ('bandstop'). order : int Order of the filter. frequency : int, float, list, array Cutoff frequencies; format depends on type of band: * 'lowpass' or 'bandpass': single frequency; * 'bandpass' or 'bandstop': pair of frequencies. sampling_rate : int, float, optional Sampling frequency (Hz). ``**kwargs`` : dict, optional Additional keyword arguments are passed to the underlying scipy.signal function. Returns ------- b : array Numerator coefficients. a : array Denominator coefficients. See Also: scipy.signal """ # check inputs if order is None: raise TypeError("Please specify the filter order.") if frequency is None: raise TypeError("Please specify the cutoff frequency.") if band not in ['lowpass', 'highpass', 'bandpass', 'bandstop']: raise ValueError( "Unknown filter type '%r'; choose 'lowpass', 'highpass', \ 'bandpass', or 'bandstop'." % band) # convert frequencies frequency = _norm_freq(frequency, sampling_rate) # get coeffs b, a = [], [] if ftype == 'FIR': # FIR filter if order % 2 == 0: order += 1 a = np.array([1]) if band in ['lowpass', 'bandstop']: b = ss.firwin(numtaps=order, cutoff=frequency, pass_zero=True, **kwargs) elif band in ['highpass', 'bandpass']: b = ss.firwin(numtaps=order, cutoff=frequency, pass_zero=False, **kwargs) elif ftype == 'butter': # Butterworth filter b, a = ss.butter(N=order, Wn=frequency, btype=band, analog=False, output='ba', **kwargs) elif ftype == 'cheby1': # Chebyshev type I filter b, a = ss.cheby1(N=order, Wn=frequency, btype=band, analog=False, output='ba', **kwargs) elif ftype == 'cheby2': # chevyshev type II filter b, a = ss.cheby2(N=order, Wn=frequency, btype=band, analog=False, output='ba', **kwargs) elif ftype == 'ellip': # Elliptic filter b, a = ss.ellip(N=order, Wn=frequency, btype=band, analog=False, output='ba', **kwargs) elif ftype == 'bessel': # Bessel filter b, a = ss.bessel(N=order, Wn=frequency, btype=band, analog=False, output='ba', **kwargs) return utils.ReturnTuple((b, a), ('b', 'a'))
def SignalFilter_LPFBessel(signal, LPF, samplefreq, NPole = 8, reduce = False): """ Low pass filter a signal, possibly reducing the number of points in the data array. signal: a numpya array of dim = 1, 2 or 3. The "last" dimension is filtered. LPF: low pass filter frequency, in Hz samplefreq: sampline frequency (points/second) NPole: number of poles in the filter. reduce: Flag that controls whether the resulting data is subsampled or not """ if debugFlag: print "sfreq: %f LPF: %f HPF: %f" % (samplefreq, LPF) flpf = float(LPF) sf = float(samplefreq) wn = [flpf/(sf/2.0)] reduction = 1 if reduce: if LPF <= samplefreq/2.0: reduction = int(samplefreq/LPF) if debugFlag is True: print "signalfilter: samplef: %f wn: %f, lpf: %f, NPoles: %d " % ( sf, wn, flpf, NPole) filter_b,filter_a=spSignal.bessel( NPole, wn, btype = 'low', output = 'ba') if signal.ndim == 1: sm = numpy.mean(signal) w=spSignal.lfilter(filter_b, filter_a, signal-sm) # filter the incoming signal w = w + sm if reduction > 1: w = spSignal.resample(w, reduction) return(w) if signal.ndim == 2: sh = numpy.shape(signal) for i in range(0, numpy.shape(signal)[0]): sm = numpy.mean(signal[i,:]) w1 = spSignal.lfilter(filter_b, filter_a, signal[i,:]-sm) w1 = w1 + sm if reduction == 1: w1 = spSignal.resample(w1, reduction) if i == 0: w = numpy.empty((sh[0], numpy.shape(w1)[0])) w[i,:] = w1 return w if signal.ndim == 3: sh = numpy.shape(signal) for i in range(0, numpy.shape(signal)[0]): for j in range(0, numpy.shape(signal)[1]): sm = numpy.mean(signal[i,j,:]) w1 = spSignal.lfilter(filter_b, filter_a, signal[i,j,:]-sm) w1 = w1 + sm if reduction == 1: w1 = spSignal.resample(w1, reduction) if i == 0 and j == 0: w = numpy.empty((sh[0], sh[1], numpy.shape(w1)[0])) w[i,j,:] = w1 return(w) if signal.ndim > 3: print "Error: signal dimesions of > 3 are not supported (no filtering applied)" return signal