def zerophase_chebychev_lowpass_filter(trace, freqmax, verbose, ofid=None): """ Custom Chebychev type two zerophase lowpass filter useful for decimation filtering. This filter is stable up to a reduction in frequency with a factor of 10. If more reduction is desired, simply decimate in steps. Partly based on a filter in ObsPy. :param data: Input trace :param freqmax: The desired lowpass frequency. Will be replaced once ObsPy has a proper decimation filter. """ # rp - maximum ripple of passband, rs - attenuation of stopband rp, rs, order = 1, 96, 1e99 ws = freqmax / (trace.stats.sampling_rate * 0.5) # stop band frequency wp = ws # pass band frequency while True: if order <= 12: break wp *= 0.99 order, wn = cheb2ord(wp, ws, rp, rs, analog=0) b, a = cheby2(order, rs, wn, btype="low", analog=0, output="ba") # Apply twice to get rid of the phase distortion. trace.data = filtfilt(b, a, trace.data)
def add_antialias(self,Fs,freq,maxorder=8): # From obspy nyquist = Fs * 0.5 # rp - maximum ripple of passband, rs - attenuation of stopband rp, rs, order = 1, 96, 1e99 ws = freq / nyquist # stop band frequency wp = ws # pass band frequency # raise for some bad scenarios if ws > 1: ws = 1.0 msg = "** Selected corner frequency is above Nyquist. " + \ "** Setting Nyquist as high corner." warnings.warn(msg) while True: if order <= maxorder: break wp = wp * 0.99 order, wn = cheb2ord(wp, ws, rp, rs, analog=0) z, p, k = cheby2(order, rs, wn, btype='low', analog=0, output='zpk') self.anti_alias = zpk2sos(z,p,k) return()
def lowpass_cheby2_coeffs(freq, sr, maxorder=12): # type: (float, int, int) -> Tuple[np.ndarray, np.ndarray, float] """ freq : The frequency above which signals are attenuated with 95 dB sr : Sampling rate in Hz. maxorder: Maximal order of the designed cheby2 filter Returns --> (b coeffs, a coeffs, freq_passband) """ nyquist = sr * 0.5 # rp - maximum ripple of passband, rs - attenuation of stopband rp, rs, order = 1, 96, 1e99 ws = freq / nyquist # stop band frequency wp = ws # pass band frequency # raise for some bad scenarios if ws > 1: ws = 1.0 msg = "Selected corner frequency is above Nyquist. " + \ "Setting Nyquist as high corner." warnings.warn(msg) while True: if order <= maxorder: break wp = wp * 0.99 order, wn = signal.cheb2ord(wp, ws, rp, rs, analog=0) b, a = signal.cheby2(order, rs, wn, btype='low', analog=0, output='ba') return b, a, wp*nyquist
def HPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_SBC = cheb2ord(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.cheby2(self.N, self.A_SB, self.F_SBC, btype='highpass', analog=self.analog, output=self.FRMT))
def BSmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_SBC = cheb2ord([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.cheby2(self.N, self.A_SB, self.F_SBC, btype='bandstop', analog=self.analog, output=self.FRMT))
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 BSmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_SBC = cheb2ord([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.cheby2(self.N, self.A_SB, self.F_SBC, btype='bandstop', analog=self.analog, output=FRMT))
def HPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_SBC = cheb2ord(self.F_PB, self.F_SB, self.A_PB, self.A_SB, analog=self.analog) self._save( fil_dict, sig.cheby2(self.N, self.A_SB, self.F_SBC, btype='highpass', analog=self.analog, output=FRMT))
def lowpass_cheby_2(data, freq, df, maxorder=12, ba=False, freq_passband=False): """ Cheby2-Lowpass Filter Filter data by passing data only below a certain frequency. The main purpose of this cheby2 filter is downsampling. #318 shows some plots of this filter design itself. This method will iteratively design a filter, whose pass band frequency is determined dynamically, such that the values above the stop band frequency are lower than -96dB. :type data: numpy.ndarray :param data: Data to filter. :param freq: The frequency above which signals are attenuated with 95 dB :param df: Sampling rate in Hz. :param maxorder: Maximal order of the designed cheby2 filter :param ba: If True return only the filter coefficients (b, a) instead of filtering :param freq_passband: If True return additionally to the filtered data, the iteratively determined pass band frequency :return: Filtered data. """ nyquist = df * 0.5 # rp - maximum ripple of passband, rs - attenuation of stopband rp, rs, order = 1, 96, 1e99 ws = freq / nyquist # stop band frequency wp = ws # pass band frequency # raise for some bad scenarios if ws > 1: ws = 1.0 msg = "Selected corner frequency is above Nyquist. " + \ "Setting Nyquist as high corner." warnings.warn(msg) while True: if order <= maxorder: break wp = wp * 0.99 order, wn = cheb2ord(wp, ws, rp, rs, analog=0) if ba: return cheby2(order, rs, wn, btype='low', analog=0, output='ba') z, p, k = cheby2(order, rs, wn, btype='low', analog=0, output='zpk') sos = zpk2sos(z, p, k) if freq_passband: return sosfilt(sos, data), wp * nyquist return sosfilt(sos, data)
def _NOTCH_Cheby2_bandstop(interval, sampling_rate, cutoff, order=5): nyq = sampling_rate * 0.5 stopfreq = float(cutoff) + 300.0 cornerfreq = float(cutoff) - 300.0 Ws = stopfreq / nyq Wp = cornerfreq / nyq # N, Wn = cheb2ord(Wp, Ws, 3, 60) # (?) N, Wn = cheb2ord([0.3, 0.5], [0.45, 0.48], 3, 160) # (?) # print N, Wn, Wp, Ws, stopfreq, cornerfreq b, a = cheby2(N, 60, Wn, btype="stop") # should 'high' be here for bandpass? sf = lfilter(b, a, interval) return sf, b, a
def get_signals(fs, tmax, fdisturbance, fsb, steepness, gpass, gstop): """ fs, sampling rate in Hz tmax, measurement time in sec fdisturbance, narrowband disturbance frequency in Hz fsb, width of the stopband in Hz steepness, percentage measure of steepness of stopband boundaries gpass, max attenuation in passband in dB gstop, min attenuation in stopband indB """ # define artificial data time = np.arange(start=0, step=1/fs, stop=tmax) N = time.size data0 = np.ones(N).astype(np.float) # data0 - signal without noise (constant value) data1 = data0 + 0.1 * np.random.randn(N) # data1 - signal with wideband noise w = 2 * np.pi * fdisturbance # angular frequency data2 = data1 + 0.5 * np.cos(w * time) # data2 - signal with wideband and narrowband noise # create a filter based on the stopband parameters fstopband = (fdisturbance - fsb / 2, fdisturbance + fsb / 2) fn = fs / 2 ws = np.array(fstopband) / fn boundary = fsb * (1 - steepness) / fn wp = np.array([ws[0] - boundary, ws[1] + boundary]) N, Wn = signal.cheb2ord(wp=wp, ws=ws, gpass=gpass, gstop=gstop) b, a = signal.iirfilter(N=N, Wn=Wn, rp=gpass, rs=gstop, btype='bandstop', ftype='cheby2') # calculate filter response, convert w from rad/sec to Hz w, h = signal.freqz(b, a) w = w * fs / (2 * np.pi) # filter the artificial data data2f = signal.lfilter(b, a, data2) # calculate psd of signals freq, psd1 = signal.welch(data1, fs=fs) _, psd2 = signal.welch(data2, fs=fs) _, psd2f = signal.welch(data2f, fs=fs) # get psd data in dB units power = lambda x: 10 * np.log10(x) psd1 = power(psd1) psd2 = power(psd2) psd2f = power(psd2f) return time, data0, data1, data2, data2f, w, h, freq, psd1, psd2, psd2f
def BPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_SBC = cheb2ord([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.cheby2(self.N, self.A_SB, self.F_SBC, btype='bandpass', analog=self.analog, output=self.FRMT))
def get_filter_coeff(self): Nyquist_freq = self.fs / 2 bandwidth = [tmp[1] - tmp[0] for tmp in self.mybands] for i, band in enumerate(self.mybands): f_pass = np.asarray( [self.mybands[i][0], self.mybands[i][0] + bandwidth[i]]) if i == 0: f_stop = np.asarray([f_pass[0] - 0.5, f_pass[1] + 1]) else: f_stop = np.asarray([f_pass[0] - 1, f_pass[1] + 1]) wp = f_pass / Nyquist_freq ws = f_stop / Nyquist_freq order, wn = cheb2ord(wp, ws, self.gpass, self.gstop) b, a = signal.cheby2(order, self.gstop, ws, btype='bandpass') self.filter_coeff.update({i: {'b': b, 'a': a}}) return self.filter_coeff
def filter_cheby2(self,mode = 'low',analog = 'False'): # 用cheby2滤波器 # 使用的时候根据 mode 来确定是低通还是高通还是带通滤波器{‘lowpass’, ‘highpass’, ‘bandpass’, ‘bandstop’} # analog 为True 是模拟滤波器,为false是数字滤波器 N,Wn = signal.cheb2ord(self.wp, self.ws, self.gp, self.gs, analog) b,a = signal.cheby2(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 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 cheby2_lowpass(df, freq, maxorder=8): # From obspy nyquist = df * 0.5 # rp - maximum ripple of passband, rs - attenuation of stopband rp, rs, order = 1, 96, 1e99 ws = freq / nyquist # stop band frequency wp = ws # pass band frequency # raise for some bad scenarios if ws > 1: ws = 1.0 msg = "Selected corner frequency is above Nyquist. " + \ "Setting Nyquist as high corner." warnings.warn(msg) while True: if order <= maxorder: break wp = wp * 0.99 order, wn = cheb2ord(wp, ws, rp, rs, analog=0) return cheby2(order, rs, wn, btype='low', analog=0, output='zpk')
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, outputConfig, frequency_hz=0.): ''' Initialize filter object. Parameters ---------- outputConfig : object Output configuration parameters object frequency_hz : float Intermediate frequency ''' super(LowPassFilter, self).__init__(3., 40.) self.bw_hz = 1e6 passBand_hz = frequency_hz + self.bw_hz stopBand_hz = frequency_hz + self.bw_hz * 1.2 nyqFreq_s = 2. / outputConfig.SAMPLE_RATE_HZ # 1.0 /Nyquist frequency wp = passBand_hz * nyqFreq_s ws = stopBand_hz * nyqFreq_s order, wn = cheb2ord(wp=wp, ws=ws, gpass=self.passBandAtt_dbhz, gstop=self.stopBandAtt_dbhz, analog=False) self.order = order self.wn = wn b, a = cheby2( order + 1, # Order of the filter # Minimum attenuation required in the stop band in dB self.stopBandAtt_dbhz, wn, btype="lowpass", analog=False, output='ba') self.a = a self.b = b self.zi = lfiltic(self.b, self.a, [])
def __init__(self, outputConfig, frequency_hz, bw_hz=1e6): ''' Initialize filter object. Parameters ---------- outputConfig : object Output configuration parameters object frequency_hz : float Intermediate frequency in hertz bw_hz : float, optional Noise bandwidth in hertz ''' super(BandPassFilter, self).__init__(3., 40.) self.bw_hz = bw_hz self.frequency_hz = frequency_hz passBand_hz = bw_hz stopBand_hz = bw_hz * 1.2 mult = 2. / outputConfig.SAMPLE_RATE_HZ order, wn = cheb2ord(wp=[(frequency_hz - passBand_hz) * mult, (frequency_hz + passBand_hz) * mult], ws=[(frequency_hz - stopBand_hz) * mult, (frequency_hz + stopBand_hz) * mult], gpass=self.passBandAtt_dbhz, gstop=self.stopBandAtt_dbhz, analog=False) b, a = cheby2( order + 1, # Order of the filter # Minimum attenuation required in the stop band in dB self.stopBandAtt_dbhz, wn, btype="bandpass", analog=False, output='ba') self.a = a self.b = b self.zi = lfiltic(self.b, self.a, [])
def __init__(self, outputConfig, frequency_hz, bw_hz=1e6): ''' Initialize filter object. Parameters ---------- outputConfig : object Output configuration parameters object frequency_hz : float Intermediate frequency in hertz bw_hz : float, optional Noise bandwidth in hertz ''' super(BandPassFilter, self).__init__(3., 40.) self.bw_hz = bw_hz self.frequency_hz = frequency_hz passBand_hz = bw_hz stopBand_hz = bw_hz * 1.2 mult = 2. / outputConfig.SAMPLE_RATE_HZ order, wn = cheb2ord(wp=[(frequency_hz - passBand_hz) * mult, (frequency_hz + passBand_hz) * mult], ws=[(frequency_hz - stopBand_hz) * mult, (frequency_hz + stopBand_hz) * mult], gpass=self.passBandAtt_dbhz, gstop=self.stopBandAtt_dbhz, analog=False) b, a = cheby2(order + 1, # Order of the filter # Minimum attenuation required in the stop band in dB self.stopBandAtt_dbhz, wn, btype="bandpass", analog=False, output='ba') self.a = a self.b = b self.zi = lfiltic(self.b, self.a, [])
def __init__(self, outputConfig, frequency_hz=0.0): """ Initialize filter object. Parameters ---------- outputConfig : object Output configuration parameters object frequency_hz : float Intermediate frequency """ super(LowPassFilter, self).__init__(3.0, 40.0) self.bw_hz = 1e6 passBand_hz = frequency_hz + self.bw_hz stopBand_hz = frequency_hz + self.bw_hz * 1.2 nyqFreq_s = 2.0 / outputConfig.SAMPLE_RATE_HZ # 1.0 /Nyquist frequency wp = passBand_hz * nyqFreq_s ws = stopBand_hz * nyqFreq_s order, wn = cheb2ord(wp=wp, ws=ws, gpass=self.passBandAtt_dbhz, gstop=self.stopBandAtt_dbhz, analog=False) self.order = order self.wn = wn b, a = cheby2( order + 1, # Order of the filter # Minimum attenuation required in the stop band in dB self.stopBandAtt_dbhz, wn, btype="lowpass", analog=False, output="ba", ) self.a = a self.b = b self.zi = lfiltic(self.b, self.a, [])
def test_cheb2ord_5(self): # Test case for analog filter self.assertTrue(IIRDesign.cheb2ord(60, 75, self.Rp, self.Rs, zs='s') == signal.cheb2ord(60, 75, self.Rp, self.Rs, analog=True, fs=None))
def cheb2ord(Wp, Ws, Rp: float, Rs: float, zs: str = 'z') -> Tuple: """ Chebyshev type II filter order selection. Return the order of the lowest order digital or analog Chebyshev Type II filter that loses no more than Rp dB in the passband and has at least Rs dB attenuation in the stopband. Parameters ---------- Wp, Ws : float Passband and stopband edge frequencies, specified as a scalar or a two-element vector with values between 0 and 1 inclusive, with 1 corresponding to the normalized Nyquist frequency, π rad/sample. For digital filters, the unit of passband corner frequency is in radians per sample. For example, ・Lowpass: wp = 0.2, ws = 0.3 ・Highpass: wp = 0.3, ws = 0.2 ・Bandpass: wp = [0.2, 0.5], ws = [0.1, 0.6] ・Bandstop: wp = [0.1, 0.6], ws = [0.2, 0.5] For analog filters, passband corner frequency is in radians per second, and the passband can be infinite. Rp : float The maximum loss in the passband (dB). Rs : float The minimum attenuation in the stopband (dB). zs : {'z', 's'}, optional When 's', return an analog filter, otherwise a digital filter is returned. Returns ------- n : int The lowest order for a Chebyshev type II filter that meets specs. Ws : ndarray or float The Chebyshev natural frequency (the “3dB frequency”) for use with cheby2 to give filter results. """ #Default parameters analog = False fs = None zslist = ['z', 's'] # Digital or Analog if (zs in zslist) == False: raise ValueError("`zs` must be 'z' or 's'.") #Check the consistency of `Wp` and `Ws` if type(Wp) in [float, np.float, np.float16, np.float32, np.float64]: if type(Wp) != type(Ws): raise ValueError("`Wp` and `Ws` must be the same type.") elif type(Wp) == list or tuple or np.array: if type(Wp) != type(Ws): raise ValueError("`Wp` and `Ws` must be the same type.") elif len(Wp) != len(Ws): raise ValueError("`Wp` and `Ws` must have the same length.") else: raise ("`Wp` and `Ws` must be float , list or tuple.") # Check the type of Rp if (type(Rp) in [int, np.int, np.int0, np.int16, np.int32, np.int64\ , np.int8, float, np.float, np.float16, np.float32, np.float64]) == False: raise ValueError("`Rp` must be the number.") # Check the type of Rs if (type(Rs) in [int, np.int, np.int0, np.int16, np.int32, np.int64\ , np.int8, float, np.float, np.float16, np.float32, np.float64]) == False: raise ValueError("`Rp` must be the number.") # Change the default parameters if zs == 's': analog = True else: fs = 2 # calcurate the filter parameters n, Ws = signal.cheb2ord(Wp, Ws, float(Rp), float(Rs), analog=analog, fs=fs) return int(n), Ws
def __parameters_max_q(self): if self.approx_type == 'butterworth': order_q = self.__order_max_q_butter() 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': order_q = self.__order_max_q_bessel() N = order_q elif self.approx_type == 'cheby_1': order_q = self.__order_max_q_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': order_q = self.__order_max_q_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': order_q = self.__order_max_q_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) if order_q > N: self.order = N elif order_q <= N: self.order = order_q return
def tf(self): wp = array((self.left_edge[1], self.right_edge[0])) / self.f_Nyq ws = array((self.left_edge[0], self.right_edge[1])) / self.f_Nyq order, Wn = cheb2ord(wp, ws, self.max_passband_atten, self.min_stopband_atten) return cheby2(order, self.min_stopband_atten, Wn, "bandpass")
def beam_profile_filter_chebyshev(n_macroparticles, resolution, n_slices, filter_option): ''' *This routine is filtering the beam profile with a type II Chebyshev filter. The input is a library having the following structure and informations:* filter_option = {'type':'chebyshev', 'pass_frequency':pass_frequency, 'stop_frequency':stop_frequency,'gain_pass':gain_pass, 'gain_stop':gain_stop} *The function returns nCoefficients, the number of coefficients used in the filter. You can also add the following option to plot and return the filter transfer function:* filter_option = {..., 'transfer_function_plot':True} ''' import matplotlib as mpl mpl.use('Agg') import matplotlib.pyplot as plt # import os from scipy.signal import cheb2ord, cheby2, filtfilt, freqz from numpy.fft import fftfreq, fft noisyProfile = np.array(n_macroparticles, dtype=float) freqSampling = 1 / resolution nyqFreq = freqSampling / 2. frequencyPass = float(filter_option['pass_frequency']) / nyqFreq frequencyStop = float(filter_option['stop_frequency']) / nyqFreq gainPass = float(filter_option['gain_pass']) gainStop = float(filter_option['gain_stop']) # Compute the lowest order for a Chebyshev Type II digital filter nCoefficients, wn = cheb2ord( frequencyPass, frequencyStop, gainPass, gainStop) # Compute the coefficients a Chebyshev Type II digital filter b, a = cheby2(nCoefficients, gainStop, wn, btype='low') # NOTE 2 lines of code have been commented out!! # Apply the filter forward and backwards to cancel the group delay # macroparticles = filtfilt(b, a, noisyProfile) # macroparticles = np.ascontiguousarray(macroparticles) # print "n_macroparticles: ", macroparticles if 'transfer_function_plot' in filter_option and \ filter_option['transfer_function_plot'].lower() == "true": # Plot the filter transfer function w, transferGain = freqz(b, a=a, worN=n_slices) transferFreq = w / np.pi * nyqFreq group_delay = - \ np.diff(-np.unwrap(-np.angle(transferGain))) / - \ np.diff(w*freqSampling) plt.figure() ax1 = plt.subplot(311) plt.plot(transferFreq, 20 * np.log10(abs(transferGain))) plt.ylabel('Magnitude [dB]') plt.subplot(312, sharex=ax1) plt.plot(transferFreq, np.unwrap(-np.angle(transferGain))) plt.ylabel('Phase [rad]') plt.subplot(313, sharex=ax1) plt.plot(transferFreq[:-1], group_delay) plt.ylabel('Group delay [s]') plt.xlabel('Frequency [Hz]') plt.savefig("filter_transfer_function.png") plt.clf() # Plot the bunch spectrum and the filter transfer function plt.figure() plt.plot(np.fft.fftfreq(n_slices, resolution), 20 * np.log10(np.abs(np.fft.fft(noisyProfile)))) plt.xlabel('Frequency [Hz]') plt.twinx() plt.plot(transferFreq, 20 * np.log10(abs(transferGain)), 'r') plt.xlim(0, plt.xlim()[1]) plt.savefig("bunch_spectrum_filter_tranfer_function.png") plt.clf() res = np.array([nCoefficients], dtype=float) res = np.append(res, [transferFreq, transferGain.real, transferGain.imag]) # print n_slices # print res.shape return res else: # print "I am about to return" res = np.array([nCoefficients], dtype=float) res = np.append(res, [b, a]) # print res return res
def denoise(data, trans_bi=False, by_hand=False, verbose=True, show_plot=True): fd_pass = 500 fd_stop = 750 fe = 1600 w = 1 / fe wd_pass = fd_pass wd_stop = fd_stop g_pass = 0.5 g_stop = 40 if trans_bi: if not by_hand: # "Gauchissement" wa_pass = h.gauchissement(fd_pass, fe) if verbose: print(wa_pass) # Write H(s) -> H(z) function z = sp.Symbol('z') s = 2 * fe * (z - 1) / (z + 1) H = 1 / ((s / wa_pass)**2 + np.sqrt(2) * (s / wa_pass) + 1) H = sp.simplify(H) if verbose: print(H) # Seperate num and denum into fractions num, denum = sp.fraction(H) # Put them in polynomial form num = sp.poly(num) denum = sp.poly(denum) # Extract all coefficients and write it in np.array form k = 1 / 2.3914 num = np.float64(np.array(num.all_coeffs())) * k denum = np.float64(np.array(denum.all_coeffs())) * k if verbose: print("Num and Denum: " + str(num) + ", " + str(denum)) # Extract zeros and poles by finding roots of num and den zeros = np.roots(num) poles = np.roots(denum) if verbose: print("Zeros and poles: " + str(zeros) + ", " + str(poles)) if verbose: zplane(num, denum, t="zPlane 2nd order butterworth bilinéaire filter") h.plot_filter(num, denum, t="2nd order butterworth bilinéaire filter", in_dB=True, in_freq=True, fe=fe) else: # Done by hand zeros = [-1, -1] poles = [np.complex(-0.2314, 0.3951), np.complex(-0.2314, -0.3951)] k = 1 / 2.39 num = np.poly(zeros) * k num = k * np.poly(zeros) denum = np.poly(poles) if verbose: print("Num and Denum: " + str(num, ) + ", " + str(denum)) zplane(num, denum, t="Butterworth order 2 (trans. bilinéaire) zplane") h.plot_filter(num, denum, t="Butterworth order 2 (trans. bilinéaire)", in_dB=True, in_freq=True, fe=fe) data_denoised = signal.lfilter(num, denum, data) if show_plot: h.imshow(data_denoised, t="After Butterworth order 2 trans. bilinéaire filter") else: order = np.zeros(4) wn = np.zeros(4) # Butterworth order[0], wn[0] = signal.buttord(wd_pass, wd_stop, g_pass, g_stop, False, fe) # Chebyshev type 1 order[1], wn[1] = signal.cheb1ord(wd_pass, wd_stop, g_pass, g_stop, False, fe) # Chebyshev type 2 order[2], wn[2] = signal.cheb2ord(wd_pass, wd_stop, g_pass, g_stop, False, fe) # Elliptic order[3], wn[3] = signal.ellipord(wd_pass, wd_stop, g_pass, g_stop, False, fe) lowest_order_index = np.argmin(order) if verbose: print(order) print(lowest_order_index) print(wn) if (lowest_order_index == 0): filter_name = "Butterworth filter order {order}".format( order=order[0]) num, denum = signal.butter(order[0], wn[0], 'lowpass', False, 'ba', fe) elif (lowest_order_index == 1): filter_name = "Cheby1 filter order {order}".format(order=order[1]) num, denum = signal.cheby1(order[1], g_pass, wn[1], 'lowpass', False, 'ba', fe) elif (lowest_order_index == 2): filter_name = "Cheby2 filter order {order}".format(order=order[2]) num, denum = signal.cheby2(order[2], g_stop, wn[2], 'lowpass', False, 'ba', fe) filter_name = "Cheby2 " + str(order[2]) + " order" else: filter_name = "Ellip filter order {order}".format(order=order[3]) num, denum = signal.ellip(order[3], g_pass, g_stop, wn[3], 'lowpass', False, 'ba', fe) if verbose: print(filter_name) filter_response_str = "Filter response " + filter_name zplane_str = "zPlane " + filter_name h.plot_filter(num, denum, t=filter_response_str, in_dB=True, in_freq=True, fe=fe) zplane(num, denum, t=zplane_str) data_denoised = signal.lfilter(num, denum, data) if show_plot: h.imshow(data_denoised, "After python function noise filter") return data_denoised
from h5py import File from os import listdir import numpy as np import scipy.signal as ss dataPath = './Data/' newPath = './Data.npz/' h5Files = listdir(dataPath) fs = 500 fl = 4 fh = 36 ext = .9 eps = 1e-5 N, Wn = ss.cheb2ord([fl*2/fs, fh*2/fs], [fl*ext*2/fs, fh/ext*2/fs], 3, 20) b, a = ss.cheby2(N, 40, Wn, 'bandpass') downSample = 5 fsamples = 9 W = 9 padded = fs+4 c = np.log(np.linspace(fl+1, fh, fh-fl)/np.linspace(fl, fh-1, fh-fl)) \ /np.log(fh/fl)*fsamples w = np.zeros((fsamples, fh-fl)) w[0, 0] = c[0] row = 0 for i in range(1, len(c)-1): if np.sum(c[:i+1]) > row+1: row += 1 w[row-1, i] = row-np.sum(c[:i]) w[row, i] = np.sum(c[:i+1])-row
# frecuencia de muestreo fs = 5*np.max(np.hstack((fstop,fpass))) if aprox_name == 'butter': order, wcutof = sig.buttord( 2*np.pi*fpass, 2*np.pi*fstop, ripple, attenuation, analog=True) orderz, wcutofz = sig.buttord( 2*fpass/fs, 2*fstop/fs, ripple, attenuation, analog=False) elif aprox_name == 'cheby1': order, wcutof = sig.cheb1ord( 2*np.pi*fpass, 2*np.pi*fstop, ripple, attenuation, analog=True) orderz, wcutofz = sig.cheb1ord( 2*fpass/fs, 2*fstop/fs, ripple, attenuation, analog=False) elif aprox_name == 'cheby2': order, wcutof = sig.cheb2ord( 2*np.pi*fpass, 2*np.pi*fstop, ripple, attenuation, analog=True) orderz, wcutofz = sig.cheb2ord( 2*fpass/fs, 2*fstop/fs, ripple, attenuation, analog=False) elif aprox_name == 'ellip': order, wcutof = sig.ellipord( 2*np.pi*fpass, 2*np.pi*fstop, ripple, attenuation, analog=True) orderz, wcutofz = sig.ellipord( 2*fpass/fs, 2*fstop/fs, ripple, attenuation, analog=False) # Diseño del filtro analógico num, den = sig.iirfilter(order, wcutof, rp=ripple, rs=attenuation, btype=filter_type, analog=True, ftype=aprox_name) my_analog_filter = sig.TransferFunction(num,den) my_analog_filter_desc = aprox_name + '_ord_' + str(order) + '_analog'
this_order, _ = sig.cheb1ord(omega_p, omega_s, alfa_max, alfa_min, analog=True) z, p, k = sig.cheb1ap(this_order, alfa_max) elif aprox_name == 'Chebyshev2': if force_order > 0: this_order = force_order else: this_order, _ = sig.cheb2ord(omega_p, omega_s, alfa_max, alfa_min, analog=True) z, p, k = sig.cheb2ap(this_order, alfa_min) elif aprox_name == 'Bessel': if force_order > 0: this_order = force_order else: this_order = besselord(omega_p, omega_s, alfa_max, alfa_min, omega_d, max_pc_delay) z, p, k = sig.besselap(this_order, norm='mag')
def beam_profile_filter_chebyshev(Y_array, X_array, filter_option): """ This routine is filtering the beam profile with a type II Chebyshev filter. The input is a library having the following structure and informations: filter_option = {'type':'chebyshev', 'pass_frequency':pass_frequency, 'stop_frequency':stop_frequency, 'gain_pass':gain_pass, 'gain_stop':gain_stop} The function returns nCoefficients, the number of coefficients used in the filter. You can also add the following option to plot and return the filter transfer function: filter_option = {..., 'transfer_function_plot':True} """ noisyProfile = np.array(Y_array) freqSampling = 1 / (X_array[1] - X_array[0]) nyqFreq = freqSampling / 2. frequencyPass = filter_option['pass_frequency'] / nyqFreq frequencyStop = filter_option['stop_frequency'] / nyqFreq gainPass = filter_option['gain_pass'] gainStop = filter_option['gain_stop'] # Compute the lowest order for a Chebyshev Type II digital filter nCoefficients, wn = cheb2ord(frequencyPass, frequencyStop, gainPass, gainStop) # Compute the coefficients a Chebyshev Type II digital filter b, a = cheby2(nCoefficients, gainStop, wn, btype='low') # Apply the filter forward and backwards to cancel the group delay Y_array = filtfilt(b, a, noisyProfile) Y_array = np.ascontiguousarray(Y_array) if (('transfer_function_plot' in filter_option) and filter_option['transfer_function_plot']): # Plot the filter transfer function w, transferGain = freqz(b, a=a, worN=len(Y_array)) transferFreq = w / np.pi * nyqFreq group_delay = -np.diff(-np.unwrap(-np.angle(transferGain))) / \ -np.diff(w*freqSampling) plt.figure() ax1 = plt.subplot(311) plt.plot(transferFreq, 20 * np.log10(abs(transferGain))) plt.ylabel('Magnitude [dB]') plt.subplot(312, sharex=ax1) plt.plot(transferFreq, np.unwrap(-np.angle(transferGain))) plt.ylabel('Phase [rad]') plt.subplot(313, sharex=ax1) plt.plot(transferFreq[:-1], group_delay) plt.ylabel('Group delay [s]') plt.xlabel('Frequency [Hz]') # Plot the bunch spectrum and the filter transfer function plt.figure() plt.plot( np.fft.fftfreq(len(Y_array), X_array[1]-X_array[0]), 20.*np.log10(np.abs(np.fft.fft(noisyProfile)))) plt.xlabel('Frequency [Hz]') plt.twinx() plt.plot(transferFreq, 20 * np.log10(abs(transferGain)), 'r') plt.xlim(0, plt.xlim()[1]) plt.show() return Y_array else: return Y_array
# Design a digital bandstop filter which rejects -60 dB from 0.2*(fs/2) to # 0.5*(fs/2), while staying within 3 dB below 0.1*(fs/2) or above # 0.6*(fs/2). Plot its frequency response, showing the passband and # stopband constraints in gray. from scipy import signal import matplotlib.pyplot as plt N, Wn = signal.cheb2ord([0.1, 0.6], [0.2, 0.5], 3, 60) b, a = signal.cheby2(N, 60, Wn, 'stop') w, h = signal.freqz(b, a) plt.semilogx(w / np.pi, 20 * np.log10(abs(h))) plt.title('Chebyshev II bandstop filter fit to constraints') plt.xlabel('Normalized frequency') plt.ylabel('Amplitude [dB]') plt.grid(which='both', axis='both') plt.fill([.01, .1, .1, .01], [-3, -3, -99, -99], '0.9', lw=0) # stop plt.fill([.2, .2, .5, .5], [9, -60, -60, 9], '0.9', lw=0) # pass plt.fill([.6, .6, 2, 2], [-99, -3, -3, -99], '0.9', lw=0) # stop plt.axis([0.06, 1, -80, 3]) plt.show()
def BPmin(self, fil_dict): self._get_params(fil_dict) self.N, self.F_SBC = cheb2ord([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.cheby2(self.N, self.A_SB, self.F_SBC, btype='bandpass', analog=self.analog, output=self.FRMT))
def HPmin(self, fil_dict): self.get_params(fil_dict) self.N, self.F_SBC = cheb2ord(self.F_PB, self.F_SB,self.A_PB,self.A_SB, analog = self.analog) self.save(fil_dict, sig.cheby2(self.N, self.A_SB, self.F_SBC, btype='highpass', analog = self.analog, output = frmt))
def _compute_parameters(self): normalized_pb, normalized_sb = self.normalized_pb_sb() self.N, self.Wn = signal.cheb2ord(normalized_pb, normalized_sb, self.filter_parameters['passband_attenuation'], self.filter_parameters['stopband_attenuation']) self.already_normalized_Wn = True
def beam_profile_filter_chebyshev(self, filter_option): ''' *This routine is filtering the beam profile with a type II Chebyshev filter. The input is a library having the following structure and informations:* filter_option = {'type':'chebyshev', 'pass_frequency':pass_frequency, 'stop_frequency':stop_frequency, 'gain_pass':gain_pass, 'gain_stop':gain_stop} *The function returns nCoefficients, the number of coefficients used in the filter. You can also add the following option to plot and return the filter transfer function:* filter_option = {..., 'transfer_function_plot':True} ''' noisyProfile = np.array(self.n_macroparticles) freqSampling = 1 / (self.bin_centers[1] - self.bin_centers[0]) nyqFreq = freqSampling / 2. frequencyPass = filter_option['pass_frequency'] / nyqFreq frequencyStop = filter_option['stop_frequency'] / nyqFreq gainPass = filter_option['gain_pass'] gainStop = filter_option['gain_stop'] # Compute the lowest order for a Chebyshev Type II digital filter nCoefficients, wn = cheb2ord(frequencyPass, frequencyStop, gainPass, gainStop) # Compute the coefficients a Chebyshev Type II digital filter b, a = cheby2(nCoefficients, gainStop, wn, btype='low') # Apply the filter forward and backwards to cancel the group delay self.n_macroparticles = filtfilt(b, a, noisyProfile) self.n_macroparticles = np.ascontiguousarray(self.n_macroparticles) if 'transfer_function_plot' in filter_option and filter_option[ 'transfer_function_plot'] == True: # Plot the filter transfer function w, transferGain = freqz(b, a=a, worN=self.n_slices) transferFreq = w / np.pi * nyqFreq group_delay = -np.diff(-np.unwrap(-np.angle(transferGain)) ) / -np.diff(w * freqSampling) plt.figure() ax1 = plt.subplot(311) plt.plot(transferFreq, 20 * np.log10(abs(transferGain))) plt.ylabel('Magnitude [dB]') plt.subplot(312, sharex=ax1) plt.plot(transferFreq, np.unwrap(-np.angle(transferGain))) plt.ylabel('Phase [rad]') plt.subplot(313, sharex=ax1) plt.plot(transferFreq[:-1], group_delay) plt.ylabel('Group delay [s]') plt.xlabel('Frequency [Hz]') ## Plot the bunch spectrum and the filter transfer function plt.figure() plt.plot( np.fft.fftfreq(self.n_slices, self.bin_centers[1] - self.bin_centers[0]), 20. * np.log10(np.abs(np.fft.fft(noisyProfile)))) plt.xlabel('Frequency [Hz]') plt.twinx() plt.plot(transferFreq, 20 * np.log10(abs(transferGain)), 'r') plt.xlim(0, plt.xlim()[1]) plt.show() return nCoefficients, [transferFreq, transferGain] else: return nCoefficients, b, a
def test_cheb2ord_4(self): # Test case for bandstop filter ORD = IIRDesign.cheb2ord(self.f4, self.f3, self.Rp, self.Rs) ord = signal.cheb2ord(self.f4, self.f3, self.Rp, self.Rs, analog=False, fs=2) self.assertTrue((ORD[0] == ord[0]) and (ORD[1] == ord[1]).all())
csvLen = len(csvArray) chans = len(chanLabels) data = np.zeros((csvLen, chans)) data[:, :6] = csvArray[:, 2:8] data[:, 6:12] = csvArray[:, 10:16] for i in [2, 4, 6, 8]: marker = np.where(csvArray[:, 20] == i)[0] if len(marker): break start = marker[-1] + 128 timeStamp = csvArray[:, 22] * 1000 + csvArray[:, 23] timeStamp = timeStamp[start:] timeStamp -= timeStamp[0] freq = len(timeStamp) / timeStamp[-1] * 1000 / 2 if FILT: N, Wn = cheb2ord([8 / freq, 35 / freq], [5 / freq, 40 / freq], 3, 20) b, a = cheby2(N, 20, Wn, 'bandpass') data = data[start:] for i in range(chans): data[:, i] = filtfilt(b, a, data[:, i], method='gust') # np.save(data, './data/'+csvFile[:3]+'.npy') if FILT: f = h5py.File(dataPath + csvFile[:3] + '.h5', 'w') else: f = h5py.File(dataPath + 'raw' + csvFile[:3] + '.h5', 'w') f['data'] = data f['time'] = timeStamp f['frequency'] = freq * 2 f['marker'] = marker f.close() print(csvFile[:3] + ' ' + str(freq * 2 - 126.89))
def test_cheb2ord_2(self): # Test case for highpass filter self.assertTrue(IIRDesign.cheb2ord(self.f2, self.f1, self.Rp, self.Rs) == signal.cheb2ord(self.f2, self.f1, self.Rp, self.Rs, analog=False, fs=2))
def beam_profile_filter_chebyshev(n_macroparticles, resolution, n_slices, filter_option): ''' *This routine is filtering the beam profile with a type II Chebyshev filter. The input is a library having the following structure and informations:* filter_option = {'type':'chebyshev', 'pass_frequency':pass_frequency, 'stop_frequency':stop_frequency,'gain_pass':gain_pass, 'gain_stop':gain_stop} *The function returns nCoefficients, the number of coefficients used in the filter. You can also add the following option to plot and return the filter transfer function:* filter_option = {..., 'transfer_function_plot':True} ''' import matplotlib as mpl mpl.use('Agg') import matplotlib.pyplot as plt # import os from scipy.signal import cheb2ord, cheby2, filtfilt, freqz from numpy.fft import fftfreq, fft noisyProfile = np.array(n_macroparticles, dtype=float) freqSampling = 1 / resolution nyqFreq = freqSampling / 2. frequencyPass = float(filter_option['pass_frequency']) / nyqFreq frequencyStop = float(filter_option['stop_frequency']) / nyqFreq gainPass = float(filter_option['gain_pass']) gainStop = float(filter_option['gain_stop']) # Compute the lowest order for a Chebyshev Type II digital filter nCoefficients, wn = cheb2ord(frequencyPass, frequencyStop, gainPass, gainStop) # Compute the coefficients a Chebyshev Type II digital filter b, a = cheby2(nCoefficients, gainStop, wn, btype='low') # NOTE 2 lines of code have been commented out!! # Apply the filter forward and backwards to cancel the group delay # macroparticles = filtfilt(b, a, noisyProfile) # macroparticles = np.ascontiguousarray(macroparticles) # print "n_macroparticles: ", macroparticles if 'transfer_function_plot' in filter_option and \ filter_option['transfer_function_plot'].lower() == "true": # Plot the filter transfer function w, transferGain = freqz(b, a=a, worN=n_slices) transferFreq = w / np.pi * nyqFreq group_delay = - \ np.diff(-np.unwrap(-np.angle(transferGain))) / - \ np.diff(w*freqSampling) plt.figure() ax1 = plt.subplot(311) plt.plot(transferFreq, 20 * np.log10(abs(transferGain))) plt.ylabel('Magnitude [dB]') plt.subplot(312, sharex=ax1) plt.plot(transferFreq, np.unwrap(-np.angle(transferGain))) plt.ylabel('Phase [rad]') plt.subplot(313, sharex=ax1) plt.plot(transferFreq[:-1], group_delay) plt.ylabel('Group delay [s]') plt.xlabel('Frequency [Hz]') plt.savefig("filter_transfer_function.png") plt.clf() # Plot the bunch spectrum and the filter transfer function plt.figure() plt.plot(np.fft.fftfreq(n_slices, resolution), 20 * np.log10(np.abs(np.fft.fft(noisyProfile)))) plt.xlabel('Frequency [Hz]') plt.twinx() plt.plot(transferFreq, 20 * np.log10(abs(transferGain)), 'r') plt.xlim(0, plt.xlim()[1]) plt.savefig("bunch_spectrum_filter_tranfer_function.png") plt.clf() res = np.array([nCoefficients], dtype=float) res = np.append(res, [transferFreq, transferGain.real, transferGain.imag]) # print n_slices # print res.shape return res else: # print "I am about to return" res = np.array([nCoefficients], dtype=float) res = np.append(res, [b, a]) # print res return res
def cheby2(**kwargs): ftype = kwargs['ftype'] freq_min = kwargs['fmin'] freq_max = kwargs['fmax'] tband = kwargs['tb'] ss2 = kwargs['sampling'] / 2 Rp = kwargs['rp'] Rs = kwargs['rs'] # значения для отрисовки линии частоты среза и частоты перехода lines = [[None, None], [None, None]] ftype_desc = None if ftype == f_type_bandpass: # полосовой фильтр Wp = [freq_min / ss2, freq_max / ss2 ] # диапазон пропускаемых частот (числа в диапазоне 0..1) Ws = [(freq_min - tband) / ss2, (freq_max + tband) / ss2 ] # дипазон частот задержания ( Ws(1) < Wp(1) < Wp(2) < Ws(2) ) ftype_desc = 'bandpass' lines[0][0] = freq_min lines[0][1] = freq_min - tband lines[1][0] = freq_max lines[1][1] = freq_max + tband # низкочастотный фильтр elif ftype == f_type_low: Wp = freq_max / ss2 # частота среза (числа в диапазоне 0..1) Ws = (freq_max + tband) / ss2 # частота перехода ftype_desc = 'lowpass' lines[1][0] = freq_max lines[1][1] = freq_max + tband # высокочастотный фильтр elif ftype == f_type_high: Wp = freq_min / ss2 # частота среза (числа в диапазоне 0..1) Ws = (freq_min - tband) / ss2 # частота перехода ftype_desc = 'highpass' lines[0][0] = freq_min lines[0][1] = freq_min - tband # режекторный фильтр else: Wp = [freq_min / ss2, freq_max / ss2 ] # диапазон пропускаемых частот (числа в диапазоне 0..1) Ws = [(freq_min + tband) / ss2, (freq_max - tband) / ss2 ] # дипазон частот задержания ( Ws(1) < Wp(1) < Wp(2) < Ws(2) ) ftype_desc = 'bandstop' lines[0][0] = freq_min lines[0][1] = freq_min + tband lines[1][0] = freq_max lines[1][1] = freq_max - tband # порядок фильтра n, частоты среза фильтра Wn n, Wn = signal.cheb2ord(Wp, Ws, Rp, Rs) # параметры фильтра b, a b, a = signal.cheby2(n, Rs, Wn, btype=ftype_desc) title = 'Chebyshev 2 {} {} order filter'.format(ftype_desc, n) return b, a, lines, title
Wp = fp / fn Ws = fs / fn # ローパスフィルタで波形整形 # バターワースフィルタ N, Wn = signal.buttord(Wp, Ws, gpass, gstop) b1, a1 = signal.butter(N, Wn, "low") y1 = signal.filtfilt(b1, a1, y) # 第一種チェビシェフフィルタ N, Wn = signal.cheb1ord(Wp, Ws, gpass, gstop) b2, a2 = signal.cheby1(N, gpass, Wn, "low") y2 = signal.filtfilt(b2, a2, y) # 第二種チェビシェフフィルタ N, Wn = signal.cheb2ord(Wp, Ws, gpass, gstop) b3, a3 = signal.cheby2(N, gstop, Wn, "low") y3 = signal.filtfilt(b3, a3, y) # 楕円フィルタ N, Wn = signal.ellipord(Wp, Ws, gpass, gstop) b4, a4 = signal.ellip(N, gpass, gstop, Wn, "low") y4 = signal.filtfilt(b4, a4, y) # ベッセルフィルタ N = 4 b5, a5 = signal.bessel(N, Ws, "low") y5 = signal.filtfilt(b5, a5, y) # FIR フィルタ a6 = 1
def cheby_lowpass(wp, ws, fs, gpass, gstop): wp = wp / fs ws = ws / fs order, wn = cheb2ord(wp, ws, gpass, gstop) b, a = cheby2(order, gstop, wn) return b, a
def demon(data, fs, n_fft=1024, max_freq=35, overlap_ratio=0.5, apply_bandpass=True, bandpass_specs=None, method='abs'): if not isinstance(data, np.ndarray): raise ValueError("Input must be of type numpy.ndarray. %s was passed" % type(data)) x = data.copy() first_pass_sr = 1250 # 31250/25 q1 = round(fs / first_pass_sr ) # 25 for 31250 sample rate ; decimatio ratio for 1st pass q2 = round((fs / q1) / (2 * max_freq)) # decimatio ratio for 2nd pass fft_over = math.floor(n_fft - 2 * max_freq * overlap_ratio) if apply_bandpass: if bandpass_specs is None: nyq = fs / 2 wp = [1000 / nyq, 2000 / nyq] ws = [700 / nyq, 2300 / nyq] rp = 0.5 As = 50 elif isinstance(bandpass_specs, dict): try: fp = bandpass_specs["fp"] fs = bandpass_specs["fs"] wp = np.array(fp) / nyq ws = np.array(fs) / nyq rp = bandpass_specs["rs"] As = bandpass_specs["as"] except KeyError as e: raise KeyError("Missing %s specification for bandpass filter" % e) else: raise ValueError( "bandpass_specs must be of type dict. %s was passed" % type(bandpass_specs)) N, wc = cheb2ord(wp, ws, rp, As) b, a = cheby2(N, rs=As, Wn=wc, btype='bandpass', output='ba', analog=True) x = lfilter(b, a, x, axis=0) if method == 'hilbert': x = hilbert(x) elif method == 'abs': x = np.abs(x) # demodulation else: raise ValueError("Method not found") x = decimate(x, q1, ftype='fir', zero_phase=False) x = decimate(x, q2, ftype='fir', zero_phase=False) final_fs = (fs // q1) // q2 x /= x.max() x -= np.mean(x) sxx = stft(x, window=('hann'), win_length=n_fft, hop_length=(n_fft - fft_over), n_fft=n_fft) freq = fft_frequencies(sr=final_fs, n_fft=n_fft) time = frames_to_time(np.arange(0, sxx.shape[1]), sr=final_fs, hop_length=(n_fft - fft_over)) sxx = np.absolute(sxx) sxx = sxx / tpsw(sxx) sxx, freq = sxx[8:, :], freq[8:] # ?? return np.transpose(sxx), freq, time
def bandpassFilter(self, data, bandFiltCutF, fs, filtAllowance=2, axis=1, filtType='filter'): """ Filter a signal using cheby2 iir filtering. Parameters ---------- data: 2d/ 3d np array trial x channels x time bandFiltCutF: two element list containing the low and high cut off frequency in hertz. if any value is specified as None then only one sided filtering will be performed fs: sampling frequency filtAllowance: transition bandwidth in hertz filtType: string, available options are 'filtfilt' and 'filter' Returns ------- dataOut: 2d/ 3d np array after filtering Data after applying bandpass filter. """ aStop = 30 # stopband attenuation aPass = 3 # passband attenuation nFreq = fs / 2 # Nyquist frequency if (bandFiltCutF[0] == 0 or bandFiltCutF[0] is None) and ( bandFiltCutF[1] == None or bandFiltCutF[1] >= fs / 2.0): # no filter print("Not doing any filtering. Invalid cut-off specifications") return data elif bandFiltCutF[0] == 0 or bandFiltCutF[0] is None: # low-pass filter print("Using lowpass filter since low cut hz is 0 or None") fPass = bandFiltCutF[1] / nFreq fStop = (bandFiltCutF[1] + filtAllowance) / nFreq # find the order [N, ws] = signal.cheb2ord(fPass, fStop, aPass, aStop) b, a = signal.cheby2(N, aStop, fStop, 'lowpass') elif (bandFiltCutF[1] is None) or (bandFiltCutF[1] == fs / 2.0): # high-pass filter print( "Using highpass filter since high cut hz is None or nyquist freq" ) fPass = bandFiltCutF[0] / nFreq fStop = (bandFiltCutF[0] - filtAllowance) / nFreq # find the order [N, ws] = signal.cheb2ord(fPass, fStop, aPass, aStop) b, a = signal.cheby2(N, aStop, fStop, 'highpass') else: # band-pass filter # print("Using bandpass filter") fPass = (np.array(bandFiltCutF) / nFreq).tolist() fStop = [(bandFiltCutF[0] - filtAllowance) / nFreq, (bandFiltCutF[1] + filtAllowance) / nFreq] # find the order [N, ws] = signal.cheb2ord(fPass, fStop, aPass, aStop) b, a = signal.cheby2(N, aStop, fStop, 'bandpass') if filtType == 'filtfilt': dataOut = signal.filtfilt(b, a, data, axis=axis) else: dataOut = signal.lfilter(b, a, data, axis=axis) return dataOut
def BSmin(self, fil_dict): self.get_params(fil_dict) self.N, self.F_SBC = cheb2ord([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.cheby2(self.N, self.A_SB, self.F_SBC, btype='bandstop', analog = self.analog, output = frmt))
def denoising(resource, NOISE_LEVEL, WAVELET_LEVEL): try: C = pywt.wavedec(resource, 'sym8',level=WAVELET_LEVEL); # If the noise is not very large, then comment the following two lines if NOISE_LEVEL == 2: C[5] = np.zeros(C[5].size); C[6] = np.zeros(C[6].size); C[7] = np.zeros(C[7].size); C[8] = np.zeros(C[8].size); elif NOISE_LEVEL == 1: C[7] = np.zeros(C[7].size); C[8] = np.zeros(C[8].size); denoiseWave = pywt.waverec(C,'sym8'); C2 = pywt.wavedec(denoiseWave, 'sym8',level=WAVELET_LEVEL); C2[1] = np.zeros(C2[1].size); C2[2] = np.zeros(C2[2].size); C2[3] = np.zeros(C2[3].size); C2[4] = np.zeros(C2[4].size); C2[5] = np.zeros(C2[5].size); C2[6] = np.zeros(C2[6].size); C2[7] = np.zeros(C2[7].size); C2[8] = np.zeros(C2[8].size); baseline = pywt.waverec(C2,'sym8'); x1 = denoiseWave - baseline; except ValueError: C = pywt.wavedec(resource, 'sym8',level=WAVELET_LEVEL-1); # If the noise is not very large, then comment the following two lines if NOISE_LEVEL == 2: C[4] = np.zeros(C[4].size); C[5] = np.zeros(C[5].size); C[6] = np.zeros(C[6].size); C[7] = np.zeros(C[7].size); elif NOISE_LEVEL == 1: C[6] = np.zeros(C[6].size); C[7] = np.zeros(C[7].size); denoiseWave = pywt.waverec(C,'sym8'); C2 = pywt.wavedec(denoiseWave, 'sym8',level=WAVELET_LEVEL-1); C2[1] = np.zeros(C2[1].size); C2[2] = np.zeros(C2[2].size); C2[3] = np.zeros(C2[3].size); C2[4] = np.zeros(C2[4].size); C2[5] = np.zeros(C2[5].size); C2[6] = np.zeros(C2[6].size); C2[7] = np.zeros(C2[7].size); baseline = pywt.waverec(C2,'sym8'); x1 = denoiseWave - baseline; # plt.close('all') # plt.plot(x1) # plt.plot(resource) Wp=[0.9/500,50.0/500]; Ws=[0.3/500,140.0/500]; n, Wn = sci.buttord(Wp,Ws, 3, 10); b, a = sci.butter(n, Wn, 'bandpass'); x2 = sci.filtfilt(b, a, x1); Wp1=[30.0/500,65.0/500]; Ws1=[45.0/500,55.0/500]; rp=3; rs=60; n1,Wn1 = sci.cheb2ord(Wp1,Ws1,rp,rs); b1,a1 = sci.cheby2(n1,rs,Wn1,'bandstop'); re = sci.filtfilt(b1,a1,x2); return re;