def __parameters_custom_order(self): order = self.custom_order if self.approx_type == 'butterworth': N, self.wn = signal.buttord(self.wp, self.ws, self.template.att_p, self.template.att_s, analog=True) N_norm, self.wn_N = signal.buttord(self.template.omega_pN, self.template.omega_sN, self.template.att_p, self.template.att_s, analog=True) elif self.approx_type == 'bessel': pass elif self.approx_type == 'cheby_1': N, self.wn = signal.cheb1ord(self.wp, self.ws, self.template.att_p, self.template.att_s, analog=True) N_norm, self.wn_N = signal.cheb2ord(self.template.omega_pN, self.template.omega_sN, self.template.att_p, self.template.att_s, analog=True) elif self.approx_type == 'cheby_2': N, self.wn = signal.cheb2ord(self.wp, self.ws, self.template.att_p, self.template.att_s, analog=True) N_norm, self.wn_N = signal.cheb1ord(self.template.omega_pN, self.template.omega_sN, self.template.att_p, self.template.att_s, analog=True) elif self.approx_type == 'legendre': pass elif self.approx_type == 'gauss': pass elif self.approx_type == 'cauer': N, self.wn = signal.ellipord(self.wp, self.ws, self.template.att_p, self.template.att_s, analog=True) N_norm, self.wn_N = signal.ellipord(self.template.omega_pN, self.template.omega_sN, self.template.att_p, self.template.att_s, analog=True) return order
def data_hpass(self, x, Wp, srate): ''' High-pass filter ''' Wp = float(Wp*2/srate) Ws = Wp*float(self.lineEdit_19.text()) Rp = float(self.lineEdit_17.text()) Rs = float(self.lineEdit_18.text()) tempstring = self.lineEdit_16.text() if tempstring == 'auto': if self.comboBox_2.currentIndex() == 0: (norder, Wn) = buttord(Wp, Ws, Rp, Rs) elif self.comboBox_2.currentIndex() == 1: (norder, Wn) = ellipord(Wp, Ws, Rp, Rs) else: (norder, Wn) = cheb1ord(Wp, Ws, Rp, Rs) else: norder = float(tempstring) Wn = Wp if self.comboBox_2.currentIndex() == 0: (b, a) = butter(norder, Wn, btype = 'high') elif self.comboBox_2.currentIndex() == 1: (b, a) = ellip(norder, Rp, Rs, Wn) else: (b, a) = cheby1(norder, Rp, Wn) y = filtfilt(b, a, x) return(y)
def __init__(self,channels=8,yamp = 100,timerange=5,srate = 250, notchfilter=True,bandpass = [1,90]): self.channels = channels self.yamp = yamp self.timerange = timerange self.srate = srate self.notchfilter = notchfilter self.bandpass = [1,90] fs = self.srate/2 if self.bandpass is not None: self._bp = True # bandpass filter Wp = np.array([bandpass[0] / fs, bandpass[1] / fs]) Ws = np.array([(bandpass[0]*0.5) / fs, (bandpass[1]+10) / fs]) N, Wn = scipy_signal.cheb1ord(Wp, Ws, 3, 40) self.bpB, self.bpA = scipy_signal.cheby1(N, 0.5, Wn, 'bandpass') else: self._bp = False # notch filter Fo = 50 Q = 15 w0 = Fo / (fs) self.notchB, self.notchA = scipy_signal.iirnotch(w0=w0, Q=Q) self.signal = [] self._plength = self.srate * timerange self._flength = self.srate * (1+timerange) self._t = np.arange(0,timerange,1/self.srate) self._update_yscale() self.ticks = [] for i in range(self.channels): self.ticks.append('ch'+str(i+1)) plt.ion()
def __init__(self, com, notchfilter, bandpass): #目标是125hz self.ads = adsReader(com, 115200) self.ads.start() srate = 250 self.downsample = 2 self.srate = srate self.notchfilter = notchfilter self.bandpass = bandpass fs = self.srate / 2 if self.bandpass is not None: self._bp = True Wp = np.array([bandpass[0] / fs, bandpass[1] / fs]) Ws = np.array([(bandpass[0] * 0.5) / fs, (bandpass[1] + 10) / fs]) N, Wn = scipy_signal.cheb1ord(Wp, Ws, 3, 40) self.bpB, self.bpA = scipy_signal.cheby1(N, 0.5, Wn, 'bandpass') else: self._bp = False # notch filter Fo = 50 Q = 15 w0 = Fo / (fs) self.notchB, self.notchA = scipy_signal.iirnotch(w0=w0, Q=Q) # 固定显示4秒的数据 timerange = 4 self._plength = int(self.srate * (0.5 + timerange)) self._slength = int(self.srate * timerange) self.signal = []
def filterband(eeg, band_id, fs, axis=-2): fs /= 2 Wp = [PASSBAND[band_id] / fs, 93 / fs] Ws = [STOPBAND[band_id] / fs, 100 / fs] N, Wn = signal.cheb1ord(Wp, Ws, 3, 40) b, a = signal.cheby1(N, 0.5, Wn, btype="bandpass") return signal.filtfilt(b, a, eeg, axis=axis)
def __init__(self, params): self.N = params(0) self.fs = params(1) self.A = params(2) self.W = params(3) * 2 * np.pi if params(0) == 'min': N, wn = sig.cheb1ord(self.W, self.A)
def __init__(self, configs_path='./config.js'): super(SigProApp, self).__init__(configs_path) self.CODER = DefaultCoder() self.data = [] self.accdata = False self.calres = False with open(configs_path, 'r') as f: self.configs = json.loads(f.read()) Fs = self.configs['signal_processing']['samplingrate'] fs = Fs / 2 Wp = [5 / fs, 45 / fs] Ws = [3 / fs, 48 / fs] [N, Wn] = scipy_signal.cheb1ord(Wp, Ws, 4, 20) [self.f_b, self.f_a] = scipy_signal.cheby1(N, 0.5, Wn, btype='bandpass') self.ff = [6.6, 7.6, 8.6, 9.3, 12.2, 13.8] t = np.arange(0, 20, 1. / Fs) self.sx = [] for f in self.ff: x1 = np.mat(np.sin(2 * np.pi * f * t)) x2 = np.mat(np.cos(2 * np.pi * f * t)) x3 = np.mat(np.sin(3 * np.pi * f * t)) x4 = np.mat(np.cos(3 * np.pi * f * t)) x5 = np.mat(np.sin(5 * np.pi * f * t)) x6 = np.mat(np.cos(5 * np.pi * f * t)) x = np.vstack([x1, x2, x3, x4, x5, x6]) self.sx.append(x)
def __init__(self, srate=250, filterdata=True, th_w=[60, 250], th_h=150): self.srate = 250 self.filterdata = filterdata # self.ttemp = [] # notch filter fs = self.srate / 2. Fo = 50 Q = 15 w0 = Fo / (fs) self.notchB, self.notchA = scipy_signal.iirnotch(w0=w0, Q=Q) # bandpass filter Wp = np.array([1 / fs, 5 / fs]) Ws = np.array([0.5 / fs, 10 / fs]) N, Wn = scipy_signal.cheb1ord(Wp, Ws, 3, 40) self.bpB, self.bpA = scipy_signal.cheby1(N, 0.5, Wn, 'bandpass') # 均值降采样 targetSrate = 50 self.meanNum = int(self.srate / targetSrate) # 将信号降采样到50Hz附近 self.meanNumf = np.ones(self.meanNum) / self.meanNum tu = self.meanNum * 1000 / self.srate # 降采样后采样点间隔时间 self.th_w = [int(i / tu) for i in th_w] self.th_h = th_h
def fivth_sixth(signal, frequency, sample_rate, aio_name, spec_name, ndft, noverlap): """ 1) Find Chebyshev filter parameters 2) Apply Chebyshev filter with found parameters to get rid of noise 3) Write filtered signal into .wav file 4) Plot spectrogramm of filtered signal 5) Plot spectrogramm of original signal with sinusoid """ #1 wp = [1850, 2200] ws = [1900, 2150] gpass = 0.1 gstop = 1 order, wn = sl.cheb1ord(wp, ws, gpass, gstop, fs=sample_rate) sos = sl.cheby1(order, 1, wn, btype='bandstop', output='sos', fs=sample_rate) #2 filtered = sl.sosfiltfilt(sos, signal) #3 aio.write_signal(aio_name, filtered, sample_rate) done(5) #4 third_fourth(filtered, ndft, noverlap, sample_rate, spec_name) #5 third_fourth(signal, ndft, noverlap, sample_rate, "spec_orig_and_sin") done(6)
def BSmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_PBC = cheb1ord([self.F_PB, self.F_PB2], [self.F_SB, self.F_SB2], self.A_PB,self.A_SB, analog = self.analog) if not self._test_N(): return -1 self._save(fil_dict, sig.cheby1(self.N, self.A_PB, self.F_PBC, btype='bandstop', analog=self.analog, output=self.FRMT))
def HPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_PBC = cheb1ord(self.F_PB,self.F_SB, self.A_PB,self.A_SB, analog=self.analog) if not self._test_N(): return -1 self._save(fil_dict, sig.cheby1(self.N, self.A_PB, self.F_PBC, btype='highpass', analog=self.analog, output=self.FRMT))
def data_lpass(self, x, Wp, srate): ''' Low-pass filter using various filter type ''' tempstring = self.lineEdit_16.text() if tempstring == 'auto': Wp = float(Wp*2/srate) Ws = Wp*float(self.lineEdit_19.text()) Rp = float(self.lineEdit_17.text()) Rs = float(self.lineEdit_18.text()) if self.comboBox_2.currentIndex() == 0: (norder, Wn) = buttord(Wp, Ws, Rp, Rs) elif self.comboBox_2.currentIndex() == 1: (norder, Wn) = ellipord(Wp, Ws, Rp, Rs) else: (norder, Wn) = cheb1ord(Wp, Ws, Rp, Rs) else: norder = float(tempstring) Wp = float(Wp*2/srate) Ws = Wp*2 self.lineEdit_19.setText(str(Ws/Wp)) Rp = 3 self.lineEdit_17.setText(str(Rp)) Rs = 0.3*norder*20 self.lineEdit_18.setText(str(Rs)) if self.comboBox_2.currentIndex() == 0: (norder, Wn) = buttord(Wp, Ws, Rp, Rs) elif self.comboBox_2.currentIndex() == 1: (norder, Wn) = ellipord(Wp, Ws, Rp, Rs) else: (norder, Wn) = cheb1ord(Wp, Ws, Rp, Rs) if self.comboBox_2.currentIndex() == 0: (b, a) = butter(norder, Wn) elif self.comboBox_2.currentIndex() == 1: (b, a) = ellip(norder, Rp, Rs, Wn) else: (b, a) = cheby1(norder, Rp, Wn) y = filtfilt(b, a, x) return(y)
def compute_parameters(self, target='stopband'): """ This function computes the order and the -3 dB-frequency of the filter for the specific parameters. Arguments: target: The optimization goal for the filter computation. Choices are: - stopband: optimize to the stopband (like MATLAB) - passband: optimize to the passband """ if target not in ['passband', 'stopband', None]: raise ValueError("Target must be one of passband or stopband, \ or not given if filter is not Butterworth.") else: self.filter_target = target if True: # Change here to be more verbose. print("Ws = ", self.Ws) print("Wp = ", self.Wp) print("Rp = ", self.passband_attenuation) print("Rs = ", self.stopband_attenuation) if self.filter_class == 'butterworth': if target == 'passband': self.N, self.Wn = signal.buttord(self.Wp, self.Ws, self.passband_attenuation, self.stopband_attenuation, analog=True) elif target == 'stopband': self.N, self.Wn = custom.custom_buttord(self.Wp, self.Ws, self.passband_attenuation, self.stopband_attenuation, analog=True) else: raise ValueError("Butterworth filters must match either the \ passband or the stopband.") elif self.filter_class == 'chebyshev_1': self.N, self.Wn = signal.cheb1ord(self.Wp, self.Ws, self.passband_attenuation, self.stopband_attenuation, analog=True) elif self.filter_class == 'chebyshev_2': self.N, self.Wn = signal.cheb2ord(self.Wp, self.Ws, self.passband_attenuation, self.stopband_attenuation, analog=True) elif self.filter_class == 'elliptical': self.N, self.Wn = signal.ellipord(self.Wp, self.Ws, self.passband_attenuation, self.stopband_attenuation, analog=True) else: raise NotImplementedError( "Filter family {} not yet implemented".format(self.filter_class)) pass
def cheby_1(self, save=True, show=False): N, Wn = signal.cheb1ord(self.Wpass, self.Wstop, self.gpass, self.gstop) b, a = signal.cheby1(N, Wn, 'low') y = signal.filtfilt(b, a, self.output) if show: self.showGraph(data=y) if save: self.output = y
def _compute_parameters(self): normalized_pb, normalized_sb = self.normalized_pb_sb() self.N, self.Wn = signal.cheb1ord(normalized_pb, normalized_sb, self.filter_parameters['passband_attenuation'], self.filter_parameters['stopband_attenuation'], analog=False) if self.filter_kind == "bandstop": # For some reason it fails. self.Wn = normalized_pb self.already_normalized_Wn = True
def upsample(x, fs, appx_fs=None, r=None, interp='sinc'): if appx_fs is None and r is None: return x if appx_fs is not None and r is not None: raise ValueError('only specify new fs or resample factor, not both') if appx_fs is not None: # new sampling interval must be a multiple of old sample interval, # so find the closest match that is <= appx_fs r = int(np.floor(appx_fs / fs)) x_up = shm.shared_ndarray(x.shape[:-1] + (r * x.shape[-1],), x.dtype.char) x_up[..., ::r] = x new_fs = fs * r from ecogdata.filt.blocks import BlockedSignal from scipy.fftpack import fft, ifft, fftfreq from scipy.interpolate import interp1d if interp == 'sinc': x_up *= r op_size = 2**16 xb = BlockedSignal(x_up, op_size, partial_block=True) for block in xb.fwd(): Xf = fft(block, axis=-1) freq = fftfreq(Xf.shape[-1]) * new_fs Xf[..., np.abs(freq) > fs/2.0] = 0 block[:] = ifft(Xf).real return x_up, new_fs elif interp == 'linear': # always pick up the first and last sample when skipping by r op_size = r * 10000 + 1 t = np.arange(op_size) xb = BlockedSignal(x_up, op_size, overlap=1, partial_block=True) for block in xb.fwd(): N = block.shape[-1] fn = interp1d(t[:N][::r], block[..., ::r], axis=-1, bounds_error=False, fill_value=0, assume_sorted=True) block[:] = fn(t[:N]) return x_up, new_fs # design a cheby-1 lowpass filter # wp: 0.4 * new_fs # ws: 0.5 * new_fs # design specs with halved numbers, since filtfilt will be used wp = 2 * 0.4 * fs / new_fs ws = 2 * 0.5 * fs / new_fs ord, wc = signal.cheb1ord(wp, ws, 0.25, 10) fdesign = dict(ripple=0.25, hi=0.5 * wc * new_fs, Fs=new_fs, ord=ord) filter_array(x_up, ftype='cheby1', inplace=True, design_kwargs=fdesign) x_up *= r return x_up, new_fs
def bandRejectIIRchebyI(wav_file_path, plot_interval, verbose=False): # ------------------------------------------------ # Create a signal. # ------------------------------------------------ samplerate, x = wavfile.read(wav_file_path) nsamples = x.size t = arange(nsamples) / samplerate # ------------------------------------------------ # Create a IIR filter and apply it to x. # ------------------------------------------------ N, Wn = cheb1ord(ws=[0.55, 0.65], wp=[0.5, 0.7], gstop=80, gpass=1) b, a = cheby1(N, 1, Wn, btype='bandstop') w, h = freqz(b, a, fs=200000) fig = plt.figure() h_dB = 20 * np.log10(np.abs(h)) plt.plot(w, h_dB, 'b-') #plt.ylim(-150, 5) plt.ylabel('Magnitude (dB)') plt.xlabel('Frequency (Hz)') plt.grid(True) fig.savefig('results_a6/chebyI_frequency_response.png', bbox_inches='tight') # Apply filtfilt to signal filtered_x = lfilter(b, a, x) wavfile.write('looneytunes_IIR_BR_55-65K.filtered_wav', samplerate, filtered_x) fig = plt.figure() # Plot the original signal. plt.subplot(2, 1, 1) plt.title('Original') plt.plot(t, x, 'b-', linewidth=0.5) plt.xlabel('Time (s)') plt.xlim(plot_interval) plt.ylim(-20500, 20500) plt.grid(True) # Plot the filtered signal, shifted to compensate for the phase delay. plt.subplot(2, 1, 2) plt.title('Filtered') plt.plot(t, filtered_x, 'g', linewidth=0.5) plt.xlim(plot_interval) plt.ylim(-20500, 20500) plt.xlabel('Time (s)') plt.grid(True) plt.subplots_adjust(hspace=0.7) fig.savefig('results_a6/chebyI_filtered_output.png', bbox_inches='tight') if verbose: plt.show()
def __order_min_max_cheby_1(self): N, self.wn = signal.cheb1ord(self.wp, self.ws, self.template.att_p, self.template.att_s, analog=True) N_norm, self.wn_N = signal.cheb1ord(self.template.omega_pN, self.template.omega_sN, self.template.att_p, self.template.att_s, analog=True) if N < self.min_order: order = self.min_order elif N > self.max_order: order = self.max_order else: order = N return order
def design(params): while(1): # Loop until we're happy with our parameters print(params) wp = params['wp'] ws = params['ws'] gstop = params['gstop'] gpass = params['gpass'] if wp < ws: btype = 'lowpass' else: btype = 'highpass' print(f'This is a {btype} filter.') # Calculate the orders of each filter type cheby1 = sig.cheb1ord( params['wp'], params['ws'], params['gpass'], params['gstop']) cheby2 = sig.cheb2ord( params['wp'], params['ws'], params['gpass'], params['gstop']) butter = sig.buttord( params['wp'], params['ws'], params['gpass'], params['gstop']) elliptic = sig.ellipord( params['wp'], params['ws'], params['gpass'], params['gstop']) x = int(input(F'''Please select an implementation: 1: Chebyshev type I ({cheby1[0]} order, corner at {cheby1[1]*nyquist} Hz) 2: Chebyshev type II ({cheby2[0]} order, corner at {cheby2[1]*nyquist} Hz) 3: Butterworth ({butter[0]} order, corner at {butter[1]*nyquist} Hz) 4: Elliptic ({elliptic[0]} order, corner at {elliptic[1]*nyquist} Hz) 5: Choose new design constraints 6: Quit ''')) if x == 1: sos = sig.cheby1(N=cheby1[0], rp=params['gpass'] , Wn=cheby1[1], btype=btype, output='sos' ) elif x == 2: sos = sig.cheby2(N=cheby2[0], rs=params['gstop'] , Wn=cheby2[1], btype=btype, output='sos' ) elif x == 3: sos = sig.butter(N=butter[0], Wn=butter[1], btype=btype, output='sos' ) elif x == 4: sos = sig.ellip(N=elliptic[0], rp=params['gpass'], rs=params['gstop'], Wn=elliptic[1], btype=btype, output='sos' ) elif x==5: params = get_params() continue else: exit() return(sos,params) #Break out of the loop
def BPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_PBC = cheb1ord([self.F_PB, self.F_PB2], [self.F_SB, self.F_SB2], self.A_PB, self.A_SB, analog=self.analog) self._save( fil_dict, sig.cheby1(self.N, self.A_PB, self.F_PBC, btype='bandpass', analog=self.analog, output=FRMT))
def LPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_PBC = cheb1ord(self.F_PB, self.F_SB, self.A_PB, self.A_SB, analog=self.analog) self._save( fil_dict, sig.cheby1(self.N, self.A_PB, self.F_PBC, btype='low', analog=self.analog, output=FRMT))
def calcFiltros(A1,A2,Wc,Wp): plt.figure() Nb, Wnb = signal.buttord(Wp,Wc,A1,A2,True) Nc, Wnc = signal.cheb1ord(Wp,Wc,A1,A2,True) Ne, Wne = signal.ellipord(Wp,Wc,A1,A2,True) print('Butterbord Wp =' + str(Wp)) print("N = "+ str(Nb) ) print("Wn = "+ str(Wnb) ) Zb,Pb,Kb = signal.buttap(Nb) ab,bb = signal.zpk2tf(Zb,Pb,Kb) print("H(s) = ") strFunTrans = funTrans([ab,bb]) print(strFunTrans) print("\n") wb, hb = freqs(ab, bb) plt.semilogx(wb, abs(hb)) print('Chebychev Wp =' + str(Wp)) print("N = "+ str(Nc) ) print("Wn = "+ str(Wnc) ) Zc,Pc,Kc = signal.buttap(Nc) ac,bc = signal.zpk2tf(Zc,Pc,Kc) print("H(s) = ") strFunTrans = funTrans([ac,bc]) print(strFunTrans) print("\n") wc, hc = freqs(ac, bc) plt.semilogx(wc, abs(hc)) print('Eliptica Wp =' + str(Wp)) print("N = "+ str(Ne) ) print("Wn = "+ str(Wne) ) Ze,Pe,Ke = signal.buttap(Ne) ae,be = signal.zpk2tf(Ze,Pe,Ke) print("H(s) = ") strFunTrans = funTrans([ae,be]) print(strFunTrans) print("\n") we, he = freqs(ae, be) plt.semilogx(we, abs(he)) plt.xlabel('Frequency') plt.ylabel('Amplitude response') plt.grid()
def filter_cheby1(self,mode = 'low',analog = 'False'): # 用cheby1滤波器 # 使用的时候根据 mode 来确定是低通还是高通还是带通滤波器{‘lowpass’, ‘highpass’, ‘bandpass’, ‘bandstop’} # analog 为True 是模拟滤波器,为false是数字滤波器 N,Wn = signal.cheb1ord(self.wp, self.ws, self.gp, self.gs, analog) b,a = signal.cheby1(N, self.gp, Wn, mode, analog) self.filter['a'] = a ; self.filter['b'] = b result = signal.lfilter(b,a,self.wave) self.filtered_wave = result return result
def _subband_param_set(self, v=None): ''' Design sub-band filter params. Also you can set value of self._subband_param directly by providing an array by `v`. ''' if v is not None: self._subband_param = v else: nyq = self.srate // 2 self._subband_param = [ # calc order and natural frequency of the filter: N & Wn signal.cheb1ord( [fp / nyq, CHEBY_FMAX / nyq], [fs / nyq, (CHEBY_FMAX + CHEBY_FEDGE) / nyq], gpass=CHEBY_GPASS, gstop=CHEBY_GSTOP) for fp, fs in self._subband_freq.T ] self._subband_filter_set()
def filter_design(self, N=None, Wn=None, frequency_sample=None): if (N is None and Wn is None): if (self.filter_name == 'butter'): N, Wn = signal.buttord(self.fpass, self.fstop, self.gpass, self.gstop, analog=False) elif (self.filter_name == 'cheby1'): N, Wn = signal.cheb1ord(self.fpass, self.fstop, self.gpass, self.gstop, analog=False) elif (self.filter_name == 'cheby2'): N, Wn = signal.cheb2ord(self.fpass, self.fstop, self.gpass, self.gstop, analog=False) elif (self.filter_name == 'ellip'): N, Wn = signal.ellipord(self.fpass, self.fstop, self.gpass, self.gstop, analog=False) else: Wn = np.array(Wn) Wn = Wn/(frequency_sample/2) self.order = N self.Wn = Wn
def plot_transfer (sample_rate): wp = [1850, 2200] ws = [1900, 2150] gpass = 0.1 gstop = 10 order, wn = signal.cheb1ord (wp, ws, gpass, gstop, fs = sample_rate) b, a = signal.cheby1 (order, 1, wn, btype='bandstop', fs = sample_rate) w, h = signal.freqz (b, a) x = w * sample_rate * 1.0 / (2 * np.pi) y = 20 * np.log10(abs(h)) plt.figure(figsize=(10,5)) plt.semilogx(x, y) plt.ylabel('Amplitude [dB]') plt.xlabel('Frequency [Hz]') plt.title('Frequency response') plt.grid(which='both', linestyle='-', color='grey') plt.xticks([20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000], ["20", "50", "100", "200", "500", "1K", "2K", "5K", "10K", "20K"]) save("Here")
def trca_pass(self, data, parameter_list, axis=-1): # wn1=2*freq0/srate # wn2=2*freq1/srate # % 通带的截止频率为2.75 hz - -75hz, 有纹波 fs = parameter_list[1] / parameter_list[2] Wp = np.array([3, 100]) / (fs / 2) # % 阻带的截止频率 Ws = np.array([(3 - 2), (100 + 2)]) / (fs / 2) # % 通带允许最大衰减为 db alpha_pass = 3 # % 阻带允许最小衰减为 db alpha_stop = 25 # % 获取阶数和截止频率 N, Wn = signal.cheb1ord(Wp, Ws, alpha_pass, alpha_stop) b, a = signal.cheby1(N, 0.5, Wn, 'bandpass') filter_data = signal.filtfilt(b, a, data, axis=axis) return filter_data
def __filter_order(self): """ Computing filters order and maximum value of X axis. """ if self.ftype == "butter": if self.btype == 'highpass': self.xaxis_max = 0.2 else: self.xaxis_max = 0.15 (self.ord, self.wn) = signal.buttord(self.wp_norm, self.ws_norm, self.gpass, self.gstop, analog=True) elif self.ftype == "cheby1": if self.btype == 'highpass': self.xaxis_max = 0.6 else: self.xaxis_max = 0.15 (self.ord, self.wn) = signal.cheb1ord(self.wp_norm, self.ws_norm, self.gpass, self.gstop, analog=True) elif self.ftype == "cheby2": if self.btype == 'highpass': self.xaxis_max = 0.2 else: self.xaxis_max = 0.3 (self.ord, self.wn) = signal.cheb2ord(self.wp_norm, self.ws_norm, self.gpass, self.gstop, analog=True) elif self.ftype == "ellip": if self.btype == 'highpass': self.xaxis_max = 0.6 else: self.xaxis_max = 0.2 (self.ord, self.wn) = signal.ellipord(self.wp_norm, self.ws_norm, self.gpass, self.gstop, analog=True)
def __init__(self, srate=250, notch=True, freqs=[5.25, 6.25, 7.25, 8.33], epoch=4): self.srate = 250 self.notch = notch # notch filter fs = self.srate / 2. Fo = 50 Q = 15 w0 = Fo / (fs) self.notchB, self.notchA = scipy_signal.iirnotch(w0=w0, Q=Q) # bandpass filter Wp = np.array([3. / fs, 90. / fs]) Ws = np.array([2. / fs, 100. / fs]) N, Wn = scipy_signal.cheb1ord(Wp, Ws, 3, 40) self.bpB, self.bpA = scipy_signal.cheby1(N, 0.5, Wn, 'bandpass') self.dataLength = epoch * self.srate self.headLength = self.srate self.processLength = self.dataLength + self.headLength t = np.linspace(0, self.dataLength - 1, self.dataLength) / self.srate self.freqs = freqs self.template = [] for f in self.freqs: tem = [ np.sin(2 * np.pi * f * t), np.cos(2 * np.pi * f * t), np.sin(4 * np.pi * f * t), np.cos(4 * np.pi * f * t), np.sin(6 * np.pi * f * t), np.cos(6 * np.pi * f * t) ] tem = np.vstack(tem) self.template.append(tem) self.signal = []
def bandpass(eeg, sfreq, Wp, Ws): """Filter bank design for decomposing EEG data into sub-band components. Parameters ---------- eeg : np.array, shape=(n_samples, n_chans[, n_trials]) Training data. sfreq : int Sampling frequency of the data. Wp : 2-tuple Passband for Chebyshev filter. Ws : 2-tuple Stopband for Chebyshev filter. Returns ------- y: np.array, shape=(n_trials, n_chans, n_samples) Sub-band components decomposed by a filter bank. See Also -------- scipy.signal.cheb1ord : Chebyshev type I filter order selection. """ # Chebyshev type I filter order selection. N, Wn = cheb1ord(Wp, Ws, 3, 40, fs=sfreq) # Chebyshev type I filter design B, A = cheby1(N, 0.5, Wn, btype="bandpass", fs=sfreq) # the arguments 'axis=0, padtype='odd', padlen=3*(max(len(B),len(A))-1)' # correspond to Matlab filtfilt : https://dsp.stackexchange.com/a/47945 y = filtfilt(B, A, eeg, axis=0, padtype='odd', padlen=3 * (max(len(B), len(A)) - 1)) return y
def create_analog_filters(self): self.high_f = 2 * math.pi * self.high_f self.low_f = 2 * math.pi * self.low_f if self.audio is None: self.fs = 44100 self.number_of_samples = 364917 else: self.fs = self.audio.get_sampling_rate() self.number_of_samples = self.audio.get_number_of_samples() self.sampling_period = 1 / self.fs width = self.high_f - self.low_f f_pass = width / 2 if width > 2 * math.pi * 1000: f_stop = f_pass + width / 2 else: f_stop = f_pass + 2000 self.f_stop = self.high_f_Hz self.width = width / (2 * math.pi) self.fn = [self.low_f, self.high_f] tangent = np.tan([wd / (2 * self.fs) for wd in self.fn]) wrapped_corner_freq = [2 * self.fs * f for f in tangent] self.order, self.fc = signal.cheb1ord(f_pass, f_stop, self.pass_atten, self.stop_atten, fs=self.fs) self.Pb_num, self.Pa_den = signal.cheby1(self.order, self.pass_atten, wrapped_corner_freq, btype=self.filter_type, analog=True) self.b_num, self.a_den = signal.cheby1(self.order, self.pass_atten, self.fn, btype=self.filter_type, analog=True) self.Pb_num = [i * self.gain for i in self.Pb_num]
def _filterbank(self, eeg, idx_fbi): ''' ''' if eeg.ndim == 2: num_chans = eeg.shape[0] num_trials = 1 else: num_chans, _, num_trials = eeg.shape fs = self.fs / 2 passband = [6, 14, 22, 30, 38, 46, 54, 62, 70, 78] stopband = [4, 10, 16, 24, 32, 40, 48, 56, 64, 72] Wp = [passband[idx_fbi]/fs, 90/fs] Ws = [stopband[idx_fbi]/fs, 100/fs] [N, Wn] = cheb1ord(Wp, Ws, 3, 40) [B, A] = cheby1(N, 0.5, Wn, 'bp') yy = np.zeros_like(eeg) if num_trials == 1: yy = filtfilt(B, A, eeg, axis=1) else: for trial_i in range(num_trials): for ch_i in range(num_chans): # yy[ch_i, :, trial_i] = filtfilt(B, A, eeg[ch_i, :, trial_i]) yy[ch_i, :, trial_i] = filtfilt(B, A, eeg[ch_i, :, trial_i], padtype='odd', padlen=3*(max(len(B),len(A))-1)) return yy
def test_cheb1ord_5(self): # Test case for analog filter self.assertTrue(np.all(IIRDesign.cheb1ord(60, 75, self.Rp, self.Rs, zs='s') == signal.cheb1ord(60, 75, self.Rp, self.Rs, analog=True, fs=None)))
def test_cheb1ord_2(self): # Test case for highpass filter self.assertTrue(np.all(IIRDesign.cheb1ord(self.f2, self.f1, self.Rp, self.Rs) == signal.cheb1ord(self.f2, self.f1, self.Rp, self.Rs, analog=False, fs=2)))
def test_cheb1ord_4(self): # Test case for bandstop filter ORD = IIRDesign.cheb1ord(self.f4, self.f3, self.Rp, self.Rs) ord = signal.cheb1ord(self.f4, self.f3, self.Rp, self.Rs, analog=False, fs=2) self.assertTrue((ORD[0] == ord[0]) and (ORD[1] == ord[1]).all())
def LPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_PBC = cheb1ord(self.F_PB,self.F_SB, self.A_PB,self.A_SB, analog=self.analog) self._save(fil_dict, sig.cheby1(self.N, self.A_PB, self.F_PBC, btype='low', analog=self.analog, output=self.FRMT))
def BPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_PBC = cheb1ord([self.F_PB, self.F_PB2], [self.F_SB, self.F_SB2], self.A_PB,self.A_SB, analog=self.analog) self._save(fil_dict, sig.cheby1(self.N, self.A_PB, self.F_PBC, btype='bandpass', analog=self.analog, output=self.FRMT))
def BSmin(self, fil_dict): self.get_params(fil_dict) self.N, self.F_PBC = cheb1ord([self.F_PB, self.F_PB2], [self.F_SB, self.F_SB2], self.A_PB,self.A_SB, analog = self.analog) self.save(fil_dict, sig.cheby1(self.N, self.A_PB, self.F_PBC, btype='bandstop', analog = self.analog, output = frmt))
def HPmin(self, fil_dict): self.get_params(fil_dict) self.N, self.F_PBC = cheb1ord(self.F_PB,self.F_SB, self.A_PB,self.A_SB, analog = self.analog) self.save(fil_dict, sig.cheby1(self.N, self.A_PB, self.F_PBC, btype='highpass', analog = self.analog, output = frmt))
def adaptive_notch_filter(bx, df=100, notches=[50,100], notchradius=.5, freqrad=.9, rp=.1, dbstop_limit=5.0): """ adaptive_notch_filter(bx, df, notches=[50,100], notchradius=.3, freqrad=.9) will apply a notch filter to the array bx by finding the nearest peak around the supplied notch locations. The filter is a zero-phase Chebyshev type 1 bandstop filter with minimal ripples. Arguments: ----------- **bx** : np.ndarray(len_time_series) time series to filter **df** : float sampling frequency in Hz **notches** : list of frequencies (Hz) to filter **notchradius** : float radius of the notch in frequency domain (Hz) **freqrad** : float radius to searching for peak about notch from notches **rp** : float ripple of Chebyshev type 1 filter, lower numbers means less ripples **dbstop_limit** : float (in decibels) limits the difference between the peak at the notch and surrounding spectra. Any difference above dbstop_limit will be filtered, anything less will not Outputs: --------- **bx** : np.ndarray(len_time_series) filtered array **filtlst** : list location of notches and power difference between peak of notch and average power. ..Example: :: >>> import RemovePeriodicNoise_Kate as rmp >>> # make a variable for the file to load in >>> fn = r"/home/MT/mt01_20130101_000000.BX" >>> # load in file, if the time series is not an ascii file >>> # might need to add keywords to np.loadtxt or use another >>> # method to read in the file >>> bx = np.loadtxt(fn) >>> # create a list of frequencies to filter out >>> freq_notches = [50, 150, 200] >>> # filter data >>> bx_filt, filt_lst = rmp.adaptiveNotchFilter(bx, df=100. >>> ... notches=freq_notches) >>> #save the filtered data into a file >>> np.savetxt(r"/home/MT/Filtered/mt01_20130101_000000.BX", bx_filt) Notes: ------- Most of the time the default parameters work well, the only thing you need to change is the notches and perhaps the radius. I would test it out with a few time series to find the optimum parameters. Then make a loop over all you time series data. Something like >>> import os >>> dirpath = r"/home/MT" >>> #make a director to save filtered time series >>> save_path = r"/home/MT/Filtered" >>> if not os.path.exists(save_path): >>> os.mkdir(save_path) >>> for fn in os.listdir(dirpath): >>> bx = np.loadtxt(os.path.join(dirpath, fn) >>> bx_filt, filt_lst = rmp.adaptiveNotchFilter(bx, df=100. >>> ... notches=freq_notches) >>> np.savetxt(os.path.join(save_path, fn), bx_filt) """ bx = np.array(bx) if type(notches) != list: notches = [notches] df = float(df) #make sure df is a float dt = 1./df #sampling rate # transform data into frequency domain to find notches BX = np.fft.fft(zero_pad(bx)) n = len(BX) #length of array dfn = df/n #frequency step dfnn = freqrad/dfn #radius of frequency search fn = notchradius #filter radius freq = np.fft.fftfreq(n,dt) filtlst = [] for notch in notches: if notch > freq.max(): pass #print 'Frequency too high, skipping {0}'.format(notch) else: fspot = int(round(notch/dfn)) nspot = np.where(abs(BX)== max(abs(BX[max([fspot-dfnn, 0]):\ min([fspot+dfnn, n])])))[0][0] med_bx =np.median(abs(BX[max([nspot-dfnn*10, 0]):\ min([nspot+dfnn*10, n])])**2) #calculate difference between peak and surrounding spectra in dB dbstop = 10*np.log10(abs(BX[nspot])**2/med_bx) if np.nan_to_num(dbstop) == 0.0 or dbstop < dbstop_limit: filtlst.append('No need to filter \n') pass else: filtlst.append([freq[nspot], dbstop]) ws = 2*np.array([freq[nspot]-fn, freq[nspot]+fn])/df wp = 2*np.array([freq[nspot]-2*fn, freq[nspot]+2*fn])/df ford, wn = SS.cheb1ord(wp, ws, 1, dbstop) b, a = SS.cheby1(1, .5, wn, btype='bandstop') bx = SS.filtfilt(b, a, bx) return bx, filtlst