def _design(self): if not self.stopband_attenuation and 'stopband_attenuation' in self.filter_parameters: self.stopband_attenuation = self.filter_parameters['stopband_attenuation'] elif not self.stopband_attenuation and 'stopband_attenuation' not in self.filter_parameters: raise ValueError("Needs a stopband_attenuation value.") if self.already_normalized_Wn: self.Z, self.P, self.K = signal.cheby2(self.N, self.stopband_attenuation, self.Wn, self.filter_kind, analog=False, output='zpk') else: self.Z, self.P, self.K = signal.cheby2(self.N, self.stopband_attenuation, self.normalize_Wn(), self.filter_kind, analog=False, output='zpk')
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 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 add_lfp(spike_entry, raw_entry, Nlfp, cutoff=300, order=4, ripple=20, lfp_sampling_rate=1000, verbose=True): """adds first N lfp channels to the spike_entry""" data_channels = [x for x in raw_entry.values() if isinstance(x, h5py.Dataset) and 'datatype' in x.attrs and int(x.attrs['datatype']) < 1000] print(len(data_channels)) data_channels = sorted(data_channels, key=repr)[:Nlfp] for chan in data_channels: if verbose: print("lfp chan: {}".format(chan)) # low pass filter b, a = cheby2(order, ripple, cutoff / (chan.attrs['sampling_rate'] / 2.)) lfp = filtfilt(b, a, chan) # resample old_x = np.arange(len(chan)) / chan.attrs['sampling_rate'] resample_ratio = chan.attrs['sampling_rate'] / lfp_sampling_rate new_x = np.arange(len(chan) / resample_ratio) / lfp_sampling_rate resamp_lfp = np.interp(new_x, old_x, lfp) arf.create_dataset(spike_entry, chan.name, resamp_lfp, units='samples', datatype=2, sampling_rate=lfp_sampling_rate)
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 __init__(self, frequency, band): """ """ fn = frequency / 2.0 b, a = cheby2(1, 10, np.array(band)/ fn, btype = "bandpass") self.b = b self.a = a
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 __init__(self, frequency, threshold): """ """ fn = frequency / 2.0 b, a = cheby2(1, 10, threshold / fn, btype = "lowpass") self.b = b self.a = a
def decode_efm(apply_filters=True, apply_demp=False, just_log=True, random_input=False): """ Decode EFM from STDIN, assuming it's a 28Mhz 8bit raw stream. apply_filters apply lowpass/highpass filters apply_demp apply de-emphasis filter (False for CD Audio) just_log just log to stderr, don't bother decoding random_input run against white noise""" if random_input: data = np.random.random_integers(-10000, 10000, SAMPLES) else: data = np.fromstring(sys.stdin.read(SAMPLES), dtype=np.uint8).astype(np.int16) data = sps.detrend(data, type='constant') # Remove DC data = auto_gain(data, 10000, 'pre-filter') # Expand before filtering, since we'll lose much of signal otherwise if apply_demp: # This is too slow, need to work out a way to do it in scipy de_emphasis_filter = biquad_filter(-1.8617006585639506, 0.8706642683920058, 0.947680874725466, -1.8659578411373265, 0.9187262110931641) data = np.fromiter(run_filter(de_emphasis_filter, data), np.int16) # De-emph - 26db below 500khz if apply_filters: # bandpass = sps.firwin(8191, [0.013 / FREQ_MHZ, 2.1 / FREQ_MHZ], pass_zero=False) # data = sps.lfilter(bandpass, 1, data) low_pass = sps.cheby2(16, 100., 4.3 / FREQ_MHZ) # Looks a bit odd, but is a reasonable tie for the spec filter (-26db at 2.0 Mhz, -50+ at 2.3Mhz) # low_pass = sps.cheby2(10, 50., 4.3 / FREQ_MHZ) # Looks a bit odd, but is a reasonable tie for the spec filter (-26db at 2.0 Mhz, -50+ at 2.3Mhz) data = sps.filtfilt(low_pass[0], low_pass[1], data) bit_gen = edgeclock_decode(data, 0., 6.626) data_frames = [] try: frame_bytes = [] frames = 0 while 1: if just_log: printerr([ bit_gen.next(), bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next(),bit_gen.next()]) else: run_until_start_code(bit_gen) consume_merging_bites(bit_gen) frames += 1 frame_bytes.append(list(consume_f3_frame(bit_gen))) # 31 14 bit EFM codes in a frame if len(frame_bytes) == EFM_FRAME_LENGTH: f2frame = consume_f2_frame(frame_bytes) data_frames.append(consume_f1_frame(f2frame)) frame_bytes = [] # except StopIteration: printerr('Hit the end of the bitstream') printerr('Found %d frames ' % frames) printerr(' Expected %.2f frames' % ((SAMPLES / 6.626 ) / 588 )) ## Output data should now contain all the decoded frames audioleft, audioright = extract_audio_samples(data_frames) data = np.clip(data, 0, 255).astype(np.uint8) sys.stdout.write(data.tostring())
def cheby2_lowpass_filter(_data, _frequency_cutoff, _carrier_frequency, order): """ :param _data: The data to be lowpassed :param _frequency_cutoff: The frequency cutoff for the filter :param _carrier_frequency: The carrier frequency for the filter :param order: The order of the filter :return: The output of the lowpass filter (entire window) """ nyq = 0.5 * _carrier_frequency low = _frequency_cutoff / nyq b, a = signal.cheby2(order, 5, low, 'low', analog=False, output='ba') return signal.lfilter(b, a, _data)
def cheby2_highpass_test(): import numpy as np from numpy.testing import assert_almost_equal from scipy.signal import cheby2 x = np.arange(10000).reshape(1, -1) d = np.sin(x * 2 * np.pi * 1000 / 48000) out, b, a = filter_high(d) bref, aref = cheby2(5, 3, 1000/24000., btype='highpass') assert_almost_equal(-b, bref) assert_almost_equal(np.hstack(([1], -a[::-1])), aref)
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 iir_basic(a): filt_type = a["Response Type"] print('filt_type', filt_type) design_method = a["Design_Methode"] if design_method == 'Elliptic': ftype = 'ellip' elif design_method == 'Chebychev 1': ftype = 'cheby1' elif design_method == 'Chebychev 2': ftype = 'cheby2' elif design_method == 'Butterworth': ftype = 'butter' # else: raise_exception print('design_method', design_method) N = a['Order'] print('order',N) fs = a["Fs"] F_pass = 2 * a["Fpass"]/fs # F_stop = 2 * a[3][2][2]/fs F_stop = 0.8 print('fs','fpass','fstop',fs, F_pass, F_stop) A_pass = a["Apass"] A_stop = a["Astop"] # A_stop = a[4][2][2] print('A_pass', 'A_stop', A_pass, A_stop) # W = a[5] # print('W',W) if N == 'min': b,a = sig.iirdesign(F_pass, F_stop, A_pass, A_stop, analog = False, ftype = ftype, output = 'ba') else: if ftype == 'ellip': b,a = sig.ellip(N, A_pass, A_stop, [F_pass, F_stop], btype ='low' ) elif ftype == 'cheby1': b,a = sig.cheby1(N, A_pass, [F_pass, F_stop], btype ='low' ) elif ftype == 'cheby2': b,a = sig.cheby2(N, A_stop, [F_pass, F_stop], btype ='low' ) elif ftype == 'butter': b,a = sig.butter(N, (2 * a["Fc"]/fs), btype ='low' ) return b, a
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 montage(self, name, type='linkedears', filtr='high', start=None, stop=None, mixed=False): if filtr: [b,a] = butter(3,1.0/(self.samplingFrequency()/2.0), btype='high') if filtr == 'alpha': Wn = [8.5/(128/2.0),14.5/(128/2.0)] [g,h] = cheby2(4, 20, Wn, btype='bandpass', analog=0, output='ba') if type == 'linkedears': s = self.channel(name, 'name') #s = filtfilt(b,a,s - (self.channel('A1', 'name') + self.channel('A2', 'name'))/2) if start and stop: t = filtfilt(b,a,s[start:stop] - (self.channel('A1', 'name')[start:stop] + self.channel('A2', 'name')[start:stop])/2) if filtr == 'alpha': t = filtfilt(g,h,t) elif stop: t = filtfilt(b,a,s[:stop] - (self.channel('A1', 'name')[:stop] + self.channel('A2', 'name')[:stop])/2) if filtr == 'alpha': t = filtfilt(g,h,t) elif start: t = filtfilt(b,a,s[start:] - (self.channel('A1', 'name')[start:] + self.channel('A2', 'name')[start:])/2) else: t = filtfilt(b,a,s - (self.channel('A1', 'name') + self.channel('A2', 'name'))/2) if filtr == 'alpha': t = filtfilt(g,h,t) if mixed: t = self.mixer(t) return t
def __init__(self, filter_type, filter_order, filter_freq, filter_direction, filter_atten=0): """Return a FilterTools object of type *filter_type* as 0 == cheby2 or 1 == butter of order *filter_order* with minimum attenuation *filter_atten* (for cheby2). *filter_freq* is the normalized cutoff frequency 2*fc/fs and *filter_direction* a string determining 'high' or 'low' pass behavior. """ # Handle exceptions # http://stackoverflow.com/questions/2525845/proper-way- # in-python-to-raise-errors-while-setting-variables if(filter_type==0): self.b, self.a = sig.cheby2(filter_order, filter_atten, filter_freq, filter_direction, analog=False, output='ba') elif(filter_type==1): self.b, self.a = sig.butter(filter_order, filter_freq, filter_direction, analog=False, output='ba') self.filter_order = filter_order
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 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 test_cheby2_7(self): # Test case for analog filter IIR = IIRDesign.cheby2(self.n, self.Rs, self.Wss, zs='s') iir = signal.cheby2(self.n, self.Rs, self.Wss, analog=True) self.assertTrue((IIR[0] == iir[0]).all() and (IIR[1] == iir[1]).all())
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 else:
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 LPman(self, fil_dict): self._get_params(fil_dict) if not self._test_N(): return -1 self._save(fil_dict, sig.cheby2(self.N, self.A_SB, self.F_C, btype='low', analog=self.analog, output=self.FRMT))
plt.ylim([-60, 12]) plt.ylabel('Amplitude [dB]') plt.grid(which='both', axis='both') plt.axvline(omega_c * np.pi, color='black') # cutoff frequency plt.legend() plt.savefig('ChebyshevT1.png') # ---------- chebyshev 2 ---------- bArray = [] aArray = [] wArray = [] hArray = [] orderArray = [1, 2, 4, 5] omega_c = 0.25 for i in orderArray: b, a = signal.cheby2(N=i, rs=54, Wn=omega_c) if i == 4: filterSystems.append([b, a]) w, h = signal.freqz(b, a) bArray.append(b) aArray.append(a) wArray.append(w) hArray.append(h) fig = plt.figure(figsize=(16, 9)) for index in range(len(orderArray)): plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index])) plt.title('Chebyshev Type 2 Filter Frequency Response: Comparison') plt.xlabel('Frequency [up to Nyquist]')
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 numtaps = n
""" Created on Sat Apr 13 12:14:28 2019 @author: ivanpauno """ import scipy.signal as sig import matplotlib.pyplot as plt import filter_utils # Comparación orden 3, att max 3dB num, den = sig.butter(3, 1, analog=True) # n, wp butter = sig.TransferFunction(num, den) num, den = sig.cheby1(3, 3, 1, analog=True) # n, att max, wp cheby1 = sig.TransferFunction(num, den) num, den = sig.cheby2(3, 20, 1.539389818149637, analog=True) # n, att min, ws cheby2 = sig.TransferFunction(num, den) num, den = sig.bessel(3, 1, analog=True, norm='mag') # n, wp bessel = sig.TransferFunction(num, den) num, den = sig.ellip(3, 3, 20, 1, analog=True) # n, att max, att min, wp ellip = sig.TransferFunction(num, den) print('Transferencia Butterworth:\n') filter_utils.pretty(butter.num, butter.den) print('\n\n') filter_utils.print_zpk(butter.num, butter.den) print('\n\nTransferencia Chebyshev tipo 1:\n') filter_utils.pretty(cheby1.num, cheby1.den) print('\n\n') filter_utils.print_zpk(cheby1.num, cheby1.den) print('\n\nTransferencia Chebyshev tipo 2:\n')
def transform_signal(dat, s_freq, method, method_opt=None): """Transform the data using different methods. Parameters ---------- dat : ndarray (dtype='float') vector with all the data for one channel s_freq : float sampling frequency method : str one of 'cheby2', 'butter', 'morlet', 'morlet_real', 'hilbert', 'abs', 'moving_avg', 'gaussian' method_opt : dict depends on methods Returns ------- ndarray (dtype='float') vector with all the data for one channel Notes ----- Wavelets pass only absolute values already, it does not make sense to store the complex values. Methods ------- cheby2 has parameters: freq : tuple of float high and low values for bandpass order : int filter order butter has parameters: freq : tuple of float high and low values for bandpass order : int filter order morlet has parameters: f0 : float center frequency in Hz sd : float standard deviation of frequency dur : float window length in number of standard deviations morlet_real has parameters: freqs : ndarray vector of wavelet frequencies for spindle detection dur : float duration of the wavelet (sec) width : float wavelet width win : float moving average window length (sec) of wavelet convolution moving_avg has parameters: dur : float duration of the window (sec) moving_rms has parameters: dur : float duration of the window (sec) gaussian has parameters: dur : float standard deviation of the Gaussian kernel, aka sigma (sec) """ if 'cheby2' == method: freq = method_opt['freq'] N = method_opt['order'] Rs = 80 nyquist = s_freq / 2 Wn = asarray(freq) / nyquist b, a = cheby2(N, Rs, Wn, btype='bandpass') dat = filtfilt(b, a, dat) if 'butter' == method: freq = method_opt['freq'] N = method_opt['order'] nyquist = s_freq / 2 Wn = asarray(freq) / nyquist b, a = butter(N, Wn, btype='bandpass') # print('butter: a=' + str(a) + ' b=' + str(b) + ' Wn=' + str(Wn) + ' N=' + str(N) + ' freq: ' + str(freq)) dat = filtfilt(b, a, dat) if 'morlet' == method: f0 = method_opt['f0'] sd = method_opt['sd'] dur = method_opt['dur'] wm = _wmorlet(f0, sd, s_freq, dur) dat = absolute(fftconvolve(dat, wm, mode='same')) if 'wavelet_real' == method: freqs = method_opt['freqs'] dur = method_opt['dur'] width = method_opt['width'] win = int(method_opt['win'] * s_freq) wm = _realwavelets(s_freq, freqs, dur, width) tfr = empty((dat.shape[0], wm.shape[0])) for i, one_wm in enumerate(wm): x = abs(fftconvolve(dat, one_wm, mode='same')) tfr[:, i] = fftconvolve(x, tukey(win), mode='same') dat = mean(tfr, axis=1) if 'hilbert' == method: dat = hilbert(dat) if 'abs' == method: dat = absolute(dat) if 'moving_avg' == method: dur = method_opt['dur'] flat = ones(int(dur * s_freq)) dat = fftconvolve(dat, flat / sum(flat), mode='same') if 'moving_rms' == method: dur = method_opt['dur'] halfdur = int(floor(s_freq * dur / 2)) ldat = len(dat) rms = zeros((ldat)) for i in range(ldat): rms[i] = sqrt( mean(square(dat[max(0, i - halfdur):min(ldat, i + halfdur)]))) dat = rms if 'gaussian' == method: sigma = method_opt['dur'] dat = gaussian_filter(dat, sigma) return dat
print('Server Listening: {}'.format(server.server_address)) # reader in threading reader_thread = threading.Thread(target=reader) reader_thread.start() # normal blocking server shutdownEvent.wait(300) q.join() server.shutdown() reader_thread.join() # after stop show plot ch1 = hampel(ch1_data, HAMPEL_WINDOW, 1) ch2 = hampel(ch2_data, HAMPEL_WINDOW, 1) #ch2 = kalman(ch2_data) sos = cheby2(20, 40, 45, 'lowpass', fs=250, output='sos') # sos1 = butter(20, 45, 'lowpass', fs=250, output='sos') # ch2b = sosfilt(sos1, ch2) ch1 = sosfilt(sos, ch1) ch2 = sosfilt(sos, ch2) ''' ch3 = [] aVR = [] aVL = [] aVF = [] for i in range(len(ch1)): ch3.append(ch2[i] - ch1[i]) aVR.append(-0.5*(ch1[i]+ch2[i])) aVL.append(ch1[i]-0.5*ch2[i]) aVF.append(ch2[i]-0.5*ch1[i])
def test_cheby2_5(self): # Test case for bandpass filter without default IIR = IIRDesign.cheby2(self.n, self.Rs, self.Ws2, ftype='bandpass') iir = signal.cheby2(self.n, self.Rs, self.Ws2, btype='bandpass', fs=2) self.assertTrue((IIR[0] == iir[0]).all() and (IIR[1] == iir[1]).all())
def __init__(self, _order, _cutoff, *args, **kwargs): ''' Constructor to calculate the coefficients of the filter and set up various arrays/variables to be used in the filter Takes in: _order = the order of the filter to by created _cutoff = the cutoff frequency(s) of the filter normalised to sample rate Optional: filter_type = defines if the filter is lowpass/bandpass/highpass/bandstop analogue_filter = defines the type of analogue filter to be replicated cheby_ripple = defines the acceptable ripple in a chebyshev filter in dB direct_form = defines if a direct form 1 or 2 filter is to be used fixed_point = defines if a direct form 1 filter should be fixed point ''' #Check the optional arguments filter_type = kwargs.get('filter_type', 'low') analogue_filter = kwargs.get('analogue_filter', 'butter') cheby_ripple = kwargs.get('cheby_ripple', 5) self.direct_form = kwargs.get('direct_form', 2) self.fixed_point = kwargs.get('fixed_point', False) #change the cutoffs to be normalised to Nyquist rather than sample rate _cutoff = 2 * _cutoff #select which type of analogue filter to replicate #output = 'sos' to give second order sections coefficients if analogue_filter == 'bessel': self.sos = signal.bessel(_order, _cutoff, btype=filter_type, analog=False, output='sos') elif analogue_filter == 'butter': self.sos = signal.butter(_order, _cutoff, btype=filter_type, analog=False, output='sos') elif analogue_filter == 'cheby1': self.sos = signal.cheby1(_order, cheby_ripple, _cutoff, btype=filter_type, analog=False, output='sos') elif analogue_filter == 'cheby2': self.sos = signal.cheby2(_order, cheby_ripple, _cutoff, btype=filter_type, analog=False, output='sos') #convert the coefficients to scaled integers if fixed point requested #only available for Direct Form 1 self.fixed_scaling = 30 if self.fixed_point == True and self.direct_form == 1: self.sos = self.sos * (2**self.fixed_scaling) self.sos = self.sos.astype(int) #define the number of second order sections required to implement that order of filter shape = np.shape(self.sos) self.sections = shape[0] #set up arrays to store the x and y values for each second order section for direct form 1 self.x = np.zeros([(self.sections), 3]) self.y = np.zeros([(self.sections), 3]) #set up delays for direct form 2 self.delay = np.zeros([self.sections, 2])
def getI32(file_name, numberOfSlices, numberOfAllRepitionsParTable): #fileSize = fileInfo.bytes/4 fid = open(file_name) fileTable = np.fromfile(fid, dtype=np.float32) #fpRawTime = fileTable[0:len(fileTable):4] fpRawResp = fileTable[1:len(fileTable):4] fpRawTrig = fileTable[2:len(fileTable):4] fpRawCard = fileTable[3:len(fileTable):4] # Process Respiration Data # Merge 10 Values N = 10 RespBLC = np.convolve(fpRawResp, np.ones((N, )) / N, mode='same') # Evalute Baseline Shift RespBLC = RespBLC - np.median(RespBLC, axis=None) # derivative of respiration kernel = [1, 0, -1] RespDeriv = np.convolve(RespBLC, kernel, mode='same') #RespDeriv = np.gradient(RespBLC) # peak detection pksRespMax, pksResMin = pk.peakdet(RespBLC * 20, delta=1) print('avg. Respiration Rate: ' + str(len(pksRespMax) / (len(RespBLC) / 60000)) + ' 1/min') # Process Cardiac Data fs = 1000 # Sampling Frequency(1 kHz) lowcut = 2.5 highcut = 10.0 nyq = 0.5 * fs # Nyquist Frequency (Hz) Wp = [lowcut / nyq, highcut / nyq] # Passband Frequencies (Normalised 2.5 - 10 Hz) Ws = [0.1 / nyq, 35 / nyq] # Stopband Frequencies (Normalised) Rs = 40 # Sroppband Ripple (dB) N = 3 # Filter order b, a = sc.cheby2(N, Rs, Ws, btype='bandpass') filtCardBLC = sc.filtfilt(b, a, fpRawCard) N = 10 CardBLC = np.convolve(filtCardBLC, np.ones((N, )) / N, mode='same') # Evalute Baseline Shift CardBLC = CardBLC - np.median(CardBLC, axis=None) # derivative of respiration kernel = [1, 0, -1] CardDeriv = np.convolve(CardBLC, kernel, mode='same') # peak detection pksCardpMax, pksCardMin = pk.peakdet(CardBLC * 20, delta=1) print('avg. Card Rate: ' + str(len(pksCardpMax) / (len(CardBLC) / 60000)) + ' 1/min') # if the trigger max is not equal 1 but higher if max(fpRawTrig) != 1.0: fpRawTrig = fpRawTrig - (max(fpRawTrig) - 1) # find missing trigger and replace 1 by 0 idx_missedTrigger = np.where(np.diff(fpRawTrig, 2) == 2)[0] + 1 if len(idx_missedTrigger) > 0: fpRawTrig[idx_missedTrigger + 1] = 0 triggerDataPoints = np.argwhere(fpRawTrig == 0) numberOfTiggers = len(triggerDataPoints) numberOfRepitions = numberOfTiggers / (numberOfSlices * 2) print('Number of Repetitions: ' + str(numberOfRepitions)) # if two dataset in a single i32 file if numberOfTiggers >= ( (numberOfAllRepitionsParTable + 5) * numberOfSlices * 2) * 2: triggerDataPoints = triggerDataPoints[:int( numberOfTiggers / 2)] # if more than two dataset in a single i32 file old_numberOfTriggers = numberOfTiggers # corrected number of triggers numberOfTiggers = len(triggerDataPoints) # if some wrong triggers in i32 file if numberOfTiggers > (numberOfAllRepitionsParTable + 5) * numberOfSlices * 2: wrongAmountOfTriggers = numberOfTiggers - ( numberOfAllRepitionsParTable + 5) * numberOfSlices * 2 fpRawTrig_cut = fpRawTrig[wrongAmountOfTriggers * 100 - 1::] triggerDataPoints = np.argwhere(fpRawTrig_cut == 0) numberOfTiggers = len(triggerDataPoints) numberOfRepitions = numberOfTiggers / (numberOfSlices * 2) print('Number of Repetitions: ' + str(numberOfRepitions)) triggerDataPoints_1st = triggerDataPoints[numberOfSlices * 5 * 2:numberOfTiggers:2, 0] triggerDataPoints_2nd = triggerDataPoints[numberOfSlices * 5 * 2 + 1:numberOfTiggers:2, 0] usedTriggerAmount = ( (numberOfAllRepitionsParTable + 5) * numberOfSlices * 2 - 5 * 2 * numberOfSlices) / 2 if not len(triggerDataPoints_1st) == len(triggerDataPoints_2nd): print('Miss one Trigger in file_name in %s', file_name) if len(triggerDataPoints_1st) < usedTriggerAmount: if len(triggerDataPoints_2nd) == usedTriggerAmount: triggerDataPoints_1st = triggerDataPoints_2nd else: sys.exit('Trigger does not relate to any slice or rep. Time') if len(RespBLC) == len(CardBLC): i32Table = np.zeros([len(RespBLC), 4]) else: sys.exit('Respiration and Cardiac Data do not have the same length!') i32Table[:, 0] = RespBLC i32Table[:, 1] = RespDeriv i32Table[:, 2] = CardBLC i32Table[:, 3] = CardDeriv return triggerDataPoints_1st, i32Table
def test_cheby2_3(self): # Test case for highpass filter IIR = IIRDesign.cheby2(self.n, self.Rs, self.Ws1, ftype='high') iir = signal.cheby2(self.n, self.Rs, self.Ws1, btype='highpass', fs=2) self.assertTrue((IIR[0] == iir[0]).all() and (IIR[1] == iir[1]).all())
from scipy import signal import matplotlib.pyplot as plt import numpy as np b, a = signal.cheby2(4, 5, 100, 'low', analog=True) w, h = signal.freqs(b, a) plt.plot(w, 20 * np.log10(abs(h))) plt.xscale('log') plt.title('Chebyshev Type II frequency response (rp=5)') plt.xlabel('Frequency [radians / second]') plt.ylabel('Amplitude [dB]') plt.margins(0, 0.1) plt.grid(which='both', axis='both') plt.axvline(100, color='green') # cutoff frequency plt.axhline(-5, color='green') # rp plt.show()
def HPman(self, fil_dict): self.get_params(fil_dict) self.save(fil_dict, sig.cheby2(self.N, self.A_SB, self.F_C, btype='highpass', analog = self.analog, output = frmt))
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 BSman(self, fil_dict): self.get_params(fil_dict) self.save(fil_dict, sig.cheby2(self.N, self.A_SB, [self.F_C, self.F_C2], btype='bandstop', analog = self.analog, output = frmt))
a_ft[imsize[0]//2-1, 0] = 1 # aliasing a_ft[imsize[0]//2+1, 0] = 1 # aliasing a_ft[imsize[0]-2, 0] = 1 # no aliasing a_ft[2, 0] = 1 # no aliasing a = np.fft.ifftn(a_ft) if np.max(np.imag(a)) < 1e-5 * np.max(np.real(a)): a = np.real(a) else: print('max imaginary part of a is ', np.max(np.imag(a))) a_subsam1 = a[::subsam_factor,:] #a_subsam2 = signal.decimate(a, 2, axis=0) #num, den = signal.cheby1(4, 1, 0.2, 'low') num, den = signal.cheby2(4, 25, 0.27, 'low') #num, den = signal.butter(4, 0.16, 'low') w, h = signal.freqz(num, den, imsize[0]) #w1, h1 = signal.freqz(num1, den1, imsize[0]) #a_filtered = signal.filtfilt(num, den, a, axis=0) #a_subsam2 = a_filtered[::subsam_factor,:] a_subsam2 = signal.decimate(a, subsam_factor, axis=0, ftype=signal.dlti(num, den)) #print(np.max(a_subsam2 - a_subsam3)) # 0.0 print(np.mean(a)) print(np.mean(a_subsam1)) print(np.mean(a_subsam2)) print() print(np.max(a)) print(np.max(a_subsam1)) print(np.max(a_subsam2)) print()
def test_cheby2_1(self): # Test case for lowpass filter with default IIR = IIRDesign.cheby2(self.n, self.Rs, self.Ws1) iir = signal.cheby2(self.n, self.Rs, self.Ws1, fs=2) self.assertTrue((IIR[0] == iir[0]).all() and (IIR[1] == iir[1]).all())
def BSman(self, fil_dict): self._get_params(fil_dict) if not self._test_N(): return -1 self._save(fil_dict, sig.cheby2(self.N, self.A_SB, [self.F_C, self.F_C2], btype='bandstop', analog=self.analog, output=self.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. 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. Parameters ---------- data : array Data to filter. freq : float The frequency above which signals are attenuated with 95 dB. df : float Sampling rate in Hz. maxorder : int Maximal order of the designed cheby2 filter. **Default:** ``12`` ba : bool If True return only the filter coefficients (b, a) instead of filtering. **Default:** ``False`` freq_passband : bool If True return additionally to the filtered data, the iteratively determined pass band frequency. **Default:** ``False`` Returns ------- data : array 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 cheby2_bandpass(lowcut, highcut, fs, order=5): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = cheby2(order, 60, [low, high], btype='bandpass') return b, a
#from nnmnkwii.baseline.gmm import MLPG from nnmnkwii.paramgen import mlpg from Utils_GMM import GMM_M from KalmanSmoother import * from scipy.signal import butter, filtfilt from scipy import signal from nnmnkwii.util import trim_zeros_frames, remove_zeros_frames from keras.backend.tensorflow_backend import set_session config = tf.ConfigProto() config.gpu_options.allow_growth = True set_session(tf.Session(config=config)) # In[10]: fb, fa = signal.cheby2(10,40,7.0/(100/2),'low', analog=False)#, 'low', analog=True)#(4, 5, 100, 'low', analog=True) NoUnits=128#256 #LSTM units BatchSize=5 #50 NoEpoch=50 htkfile = HTK.HTKFile() std_frac=0.25 n_mfcc=13 inputDim=n_mfcc*3 OutDim=128 # In[11]: def Get_Wav_EMA_PerFile(EMA_file,Wav_file,F):
def start_CSP(self, signal_time, to_frequency = 128, baseline = True,\ base_time = 4, filt = 'ellip', method = 'pfu', train_tags = None): """Produces CSP filter from the data. THIS VERSION CALCULATES ONE FILTER FOR ALL FREQUENCIES The filter is stored in a variable P Parameters: ----------- signal_time : float Time in seconds of signal to take as a class for maximalization to_frequency [= 128Hz] : int The frequency to which signal will be resampled baseline [= True] : bool If true a base line of base_time seconds will be taken as a class for minimalization [If baseline = True] base_time [= 4] : float Time in seconds of baseline to take as minimalization class filt [= 'ellip']: string ['ellip', 'cov', 'cheby', None] a filter to use. If method is 'maxcontrast' the variable is set to None method [= 'pfu'] : string ['pfu', 'regular','maxcontrast'] method of calculation CSP filter train_tags : list a list of tags to process. Each list entry is a tuple with first element position of tag in seconds, and second is a frequency of stimulation """ if not self.__is_int(to_frequency): raise ValueError, 'to_frequency is not int!' self.method = method signal = self.parsed_data.prep_signal( to_frequency, self.electrodes, montage=self.montage, montage_channels=self.montage_channels) if train_tags == None: all_tags = self.parsed_data.get_train_tags(ccof=True) else: all_tags = train_tags N = len(self.electrodes) if method == 'maxcontrast' or method == 'minimalentropy': baseline = True filt = None cov_pre = np.zeros([N, N]) cov_post = np.zeros([N, N]) pre_i = 0 post_i = 0 for i, frq in enumerate(self.frequencies): if filt == 'ellip': filt_b, filt_a = ellip(3, 0.1 , 100, \ [2*(frq - 1) / float(to_frequency), 2*(frq + 1) / float(to_frequency)],\ btype='pass') signal_tmp = np.array( [filtfilt(filt_b, filt_a, x) for x in signal]) elif filt == 'cheby': filt_b, filt_a = cheby2(1, 10, [ 2 * (frq - 1) / float(to_frequency), 2 * (frq + 1) / float(to_frequency) ], 'pass') signal_tmp = np.array( [filtfilt(filt_b, filt_a, x) for x in signal]) elif filt == 'conv': t_vec = np.linspace(0, 0.5 - 1.0 / to_frequency, 0.5 * to_frequency) sin = np.sin(t_vec * 2 * np.pi) sin /= sum(sin**2) M = len(sin) K = len(signal[0, :]) signal_tmp = np.array([ np.convolve(sin, x, mode='full')[M:K + M] for x in signal ]) elif filt == None: signal_tmp = signal tags = [x for (x, y) in all_tags if y == frq] rest_tags = [x for (x, y) in all_tags if y != frq] for idx in xrange(min(len(tags), len(rest_tags))): s_post = signal_tmp[:, to_frequency * (tags[idx] ) : to_frequency * (tags[idx] +\ signal_time)] dane_B = np.matrix(s_post) R_B = dane_B * dane_B.T / np.trace(dane_B * dane_B.T) cov_post += R_B post_i += 1 if baseline: if method == 'maxcontrast' or method == 'minimalentropy': s_pre = signal_tmp[:, to_frequency *\ (tags[idx] + 1) : to_frequency * (tags[idx] + signal_time)] dane_A = np.matrix(s_pre) X = np.matrix( self.__get_model_matrix(frq, s_pre.shape[1], to_frequency)) Y = dane_A - (X.T * np.linalg.inv(X * X.T) * X * dane_A.T).T cov_pre += Y * Y.T / np.trace(Y * Y.T) pre_i += 1 else: s_pre = signal_tmp[:, to_frequency * (tags[idx] -\ 1 - base_time) : to_frequency * (tags[idx] -1)] dane_A = np.matrix(s_pre) R_A = dane_A * dane_A.T / np.trace(dane_A * dane_A.T) cov_pre += R_A pre_i += 1 if not baseline: for idx in rest_tags: s_pre = signal_tmp[:, to_frequency * (idx ) : to_frequency *\ (idx + signal_time)] dane_A = np.matrix(s_pre) R_A = dane_A * dane_A.T / np.trace(dane_A * dane_A.T) cov_pre += R_A pre_i += 1 if method == 'regular' or method == 'maxcontrast': self.P[:, :], self.vals = self.__get_filter( cov_post / post_i, cov_pre / pre_i) elif method == 'pfu': self.P[:, :] = pfu_csp(cov_pre / pre_i, cov_post / post_i) elif method == 'minimalentropy': self.P[:, :], self.vals = self.__get_min_entropy(cov_pre / pre_i)
def test_cheby2_6(self): # Test case for bandstop filter IIR = IIRDesign.cheby2(self.n, self.Rs, self.Ws2, ftype='stop') iir = signal.cheby2(self.n, self.Rs, self.Ws2, btype='bandstop', fs=2) self.assertTrue((IIR[0] == iir[0]).all() and (IIR[1] == iir[1]).all())
'CB1': 60, 'O1': 61, 'Oz': 62, 'O2': 63, 'CB2': 64 } # Only channel_idx is selected channel_idx = [ channels[items] for items in ['PZ', 'PO3', 'PO4', 'PO5', 'PO6', 'POz', 'O1', 'O2', 'Oz'] ] channel_idx = np.array(channel_idx) - 1 # bandpass filter fmax = fs / 2 sos = cheby2(6, 20, [6 / fmax, 60 / fmax], btype='bandpass', output='sos') # data path dir_list = os.listdir(PathData) dir_list.sort( key=lambda a: int(re.findall('\d+', a)[0])) # sort list by numbers for ii, f_name in enumerate(dir_list): path1 = os.path.join(PathData, f_name) temp_file = sio.loadmat(path1) data = temp_file['data'] # select [0.5+0.14 s : 5.5+0.14 s] time window time_index = np.arange((fs / 2) + round(subject_latency[ii] * fs),
t = str(data['FilterType']) n = int(data['Order']) fc1 = data['cutoff1'] fc2 = data['cutoff2'] att = int(data['attenuation']) # Bandpass and Bandstop requires 2 cutoff points if t == 'bandpass' or t == 'bandstop': fc = [float(fc1), float(fc2)] else: fc = float(fc1) # Generate filter coefficients sos = signal.cheby2(N=n, rs=att, Wn=fc, btype=t, output='sos') # Create empty dictionary with DirectForm field out = {} out['DirectForm'] = [] # Create as many fields of DirectForm as many the sos does in a json format for i in range(len(sos)): coeff = { "i": i, "b0": np.round(sos[i][0] * (2**14)), "b1": np.round(sos[i][1] * (2**14)), "b2": np.round(sos[i][2] * (2**14)),
def synthesizeQNTF(order=4, OSR=64, f0=0., NG=-60, ING=-20, n_im=None): """Synthesize a noise transfer function for a quadrature modulator. **Parameters:** order : int, optional The order of the modulator. Defaults to 4. OSR : int, optional The oversampling ratio. Defaults to 64. f0 : float, optional The center frequency, normalized such that :math:`1 \\rightarrow f_s`. Defaults to 0, ie to a low-pass modulator. NG : float, optional The in-band noise gain, expressed in dB. Defaults to -60. ING : float, optional The image-band noise gain, in dB. Defaults to -20. n_im : int, optional The number of in-band image zeros, defaults to ``floor(order/3)``. **Returns:** ntf : (z, p, k) tuple ``ntf`` is a zpk tuple containing the zeros, poles and the gain of the synthesized NTF. .. note:: From the MATLAB Delta-Sigma Toolbox: ALPHA VERSION: This function uses an experimental ad-hoc method that is neither optimal nor robust. **Example:** Fourth order quadrature modulator:: from deltasigma import * order = 4 osr = 32 NG = -50 ING = -10 f0 = 1 / 16 ntf0 = synthesizeQNTF(order, osr, f0, NG, ING) pretty_lti(ntf0) Returns:: (z - 0.888 - 0.4598j) (z - 0.9239 + 0.3827j) (z - 0.9239 - 0.3827j) (z - 0.953 - 0.3028j) --------------------------------------------------------------------------------------------- (z - 0.5739 - 0.5699j) (z - 0.5913 - 0.2449j) (z - 0.6731 + 0.2788j) (z - 0.8088 - 0.0028j) .. image:: _static/synthesizeQNTF.png """ if n_im is None: n_im = np.floor(order/3) debug_it = 0 if n_im == 0: # Use synthesizeNTF to get an NTF with the specified NG; ignore ING f1 = 0.5/OSR x = 1.5 lowest_f = np.inf dfdx = None for itn in range(ITN_MAX): ntf = synthesizeNTF(order, OSR, 1., x) f = dbv(rmsGain(ntf, 0., f1)) - NG if debug_it: print('x=%.2f f=%.2f' % (x, f)) if abs(f) < 0.01: break if dfdx is None: dx = 0.1*np.sign(f) dfdx = 0 else: dfdx = (f - f_old)/dx dx_old = dx dx = - f/dfdx if abs(dx) > max((1, 2*abs(dx_old))): dx = np.sign(dx)*max((1, 2*abs(dx_old))) if x + dx <= 1: # Hinf must be at least 1 dx = dx/2. f_old = f x = x + dx if itn == ITN_MAX - 1: warn('Iteration limit reached. NTF may be poor.') # Rotate the NTF z0 = np.exp(2j*np.pi*f0) zeros, poles, k = _get_zpk(ntf) ntf = (z0*zeros, z0*poles, k) else: n_in = order - n_im f1 = f0 - 0.5/OSR f2 = f0 + 0.5/OSR z0 = np.exp(2j*np.pi*f0) x = np.array([20., 20.]) # "R" parameters for cheby2() lowest_f = np.inf dfdx = np.array([float('NaN'), float('NaN')]) freq = np.linspace(-0.5, 0.5, 200) for itn in range(ITN_MAX): if debug_it: print('\nx = [%.2f, %.2f]' % (x[0], x[1])) b1, a1 = cheby2(n_in, x[0], 1./OSR, 'highpass') b2, a2 = cheby2(n_im, x[1], 1./OSR, 'highpass') ntf0 = (np.concatenate((np.roots(b1)*z0, np.roots(b2)*np.conj(z0))), np.concatenate((np.roots(a1)*z0, np.roots(a2)*np.conj(z0))), 1) m = evalTF(ntf0, np.exp(2j*np.pi*freq)) NG0 = dbv(rmsGain(ntf0, f1, f2)) ING0 = dbv(rmsGain(ntf0, -f1, -f2)) if debug_it: import pylab as plt from ._plotPZ import plotPZ from ._figureMagic import figureMagic plt.figure() plt.subplot(121) plotPZ(ntf0) plt.subplot(122) print('NG = %.1f, ING= %.1f' % (NG0, ING0)) plt.plot(freq, dbv(m)) figureMagic([-0.5, 0.5], 0.05, 2, [-100, 30], 10, 2) plt.hold(True) plt.plot([f1, f2], [NG0, NG0], 'k') plt.text(np.mean([f1, f2]), NG0, ('NG=%.1fdB' % NG0), va='bottom') plt.plot([-f1, -f2], [ING0, ING0], 'k') plt.text(np.mean([-f1, -f2]), ING0, ('ING=%.1fdB' % ING0), va='bottom') plt.show() f = np.array([NG0 - NG, ING0 - ING]) if max(abs(f)) < 0.01: break if norm(f) < lowest_f: lowest_f = norm(f) # ntf0 is ALREADY a zpk tuple zeros, poles, k = ntf0 best = (zeros.copy(), poles.copy(), k) if abs(f[0]) > abs(f[1]): # adjust x(1) i = 0 else: # adjust x(2) i = 1 if np.isnan(dfdx[i]): dx = np.sign(f[i]) dfdx[i] = 0 dfdx[1 - i] = float('NaN') else: dfdx[i] = (f[i] - f_old[i])/dx dfdx[1 - i] = float('NaN') dx = -f[i]/dfdx[i] xnew = x[i] + dx if xnew < 0.5*x[i]: dx = -0.5*x[i] else: if xnew > 2*x[i]: dx = x[i] f_old = f.copy() x[i] = x[i] + dx if itn == ITN_MAX - 1: warn('Iteration limit reached. NTF may be poor') ntf = best return ntf
# extract time = data[:, 0] * 1e-03 flow = data[:, 1] * 1e-03 N2 = data[:, 4] #-------------------- # SIGNAL PROCESSING #-------------------- # store raw time_raw = np.copy(time) flow_raw = np.copy(flow) # low-pass filter flow signal b, a = cheby2(4, 40, 0.05, btype='low') flow_f = filtfilt(b, a, flow) # re-sample time = np.arange(time[0], time[-1], dt) interpolant_flow = interp1d(time_raw, flow_f, kind='quadratic') flow_f = interpolant_flow(time) #flow_f = np.interp(time, time_raw, flow_f) interpolant_N2 = interp1d(time_raw, N2, kind='quadratic') N2 = interpolant_N2(time) #N2 = np.interp(time, time_raw, N2) # find start of washout st_estim = min(time[N2 < 0.5 * max(N2)]) - 0.5
def transform_signal(dat, s_freq, method, method_opt=None): """Transform the data using different methods. Parameters ---------- dat : ndarray (dtype='float') vector with all the data for one channel s_freq : float sampling frequency method : str one of 'cheby2', 'butter', 'morlet', 'morlet_real', 'hilbert', 'abs', 'moving_avg' method_opt : dict depends on methods Returns ------- ndarray (dtype='float') vector with all the data for one channel Notes ----- Wavelets pass only absolute values already, it does not make sense to store the complex values. Methods ------- cheby2 has parameters: freq : tuple of float high and low values for bandpass order : int filter order butter has parameters: freq : tuple of float high and low values for bandpass order : int filter order morlet has parameters: f0 : float center frequency in Hz sd : float standard deviation of frequency dur : float window length in number of standard deviations morlet_real has parameters: freqs : ndarray vector of wavelet frequencies for spindle detection dur : float duration of the wavelet (sec) width : float wavelet width win : float moving average window length (sec) of wavelet convolution moving_avg has parameters: dur : float duration of the window (sec) """ if 'cheby2' == method: freq = method_opt['freq'] N = method_opt['order'] Rs = 80 nyquist = s_freq / 2 Wn = asarray(freq) / nyquist b, a = cheby2(N, Rs, Wn, btype='bandpass') dat = filtfilt(b, a, dat) if 'butter' == method: freq = method_opt['freq'] N = method_opt['order'] nyquist = s_freq / 2 Wn = asarray(freq) / nyquist b, a = butter(N, Wn, btype='bandpass') dat = filtfilt(b, a, dat) if 'morlet' == method: f0 = method_opt['f0'] sd = method_opt['sd'] dur = method_opt['dur'] wm = _wmorlet(f0, sd, s_freq, dur) dat = absolute(fftconvolve(dat, wm, mode='same')) if 'wavelet_real' == method: freqs = method_opt['freqs'] dur = method_opt['dur'] width = method_opt['width'] win = method_opt['win'] * s_freq wm = _realwavelets(s_freq, freqs, dur, width) tfr = empty((dat.shape[0], wm.shape[0])) for i, one_wm in enumerate(wm): x = abs(fftconvolve(dat, one_wm, mode='same')) tfr[:, i] = fftconvolve(x, tukeywin(win), mode='same') dat = mean(tfr, axis=1) if 'hilbert' == method: dat = hilbert(dat) if 'abs' == method: dat = absolute(dat) if 'moving_avg' == method: dur = method_opt['dur'] flat = ones(int(dur * s_freq)) dat = fftconvolve(dat, flat / sum(flat), mode='same') return dat
k=0 for x in df['path']: k=k+1 spf = wave.open(x,'r') signal = spf.readframes(-1) signal = np.fromstring(signal, 'Int16') frames=spf.getnframes() max_amp,min_amp=get_min_max_amp(signal) for i in range(0,frames): signal[i]=(min_amp-signal[i]/max_amp-min_amp)*1000 beat=beat_cout(signal,0.25,max_amp) # frinch_search_beat(signal,frames) sos = sc.cheby2(10, 40, 17, btype='highpass', fs=4000, output='sos') filtered = sc.sosfilt(sos, signal) local_maxima_plot(signal) # spectrum=fft.fft(signal) # freq = fft.fftfreq(len(spectrum)) # # threshold = 0.5 * max(abs(spectrum)) # mask = abs(spectrum) > threshold # peaks = freq[mask] # plot.plot(freq, abs(spectrum)) # plot.show() # plot.plot(signal)
def monhe(raw, srate, show=0, show2=0, show3=1, filter=True): """ GREAT but: discard crossings close to one another by less than 100 ms """ # 0 - Remove EMG, powerline and baseline shift if filter: rawend = prefilt(raw, srate, show) else: rawend = np.copy(raw) # 0.5 - Choice sign of peaks (batch) up = definepeak(rawend, srate) # 1 - filter block (chebyshev 4th order 6-18 Hz) nyqfreq = srate / 2. filtband = [6 / nyqfreq, 18 / nyqfreq] num, den = ss.cheby2(4, 40, filtband, btype='bandpass') # filtafter2 = ss.filtfilt(num, den, raw) filtafter = ss.filtfilt(num, den, rawend) if show: fig = pl.figure() mngr = pl.get_current_fig_manager() mngr.window.setGeometry(950, 50, 1000, 800) ax = fig.add_subplot(411) ax.plot(raw) ax.set_title('raw signal') ax = fig.add_subplot(412) ax.plot(rawend) ax.set_title('filtered from raw') ax = fig.add_subplot(413) # ax.plot(filtafter2) ax.plot(filtafter, 'r') ax.set_title('filtered for algorithm after preprocessing') ax = fig.add_subplot(414) ax.plot(filtafter) ax.set_title('filtered for algorithm') pl.show() raw_input('cleaning') # 2 - differentiate the signal and normalize according to max derivative in the signal diffsig = np.diff(filtafter) diffmax = np.max(np.abs(diffsig)) dsignal = diffsig / diffmax # 3 - Get Shannon energy envelope diffsquare = dsignal**2 logdiff = np.log(diffsquare) shannon = -1 * diffsquare * logdiff # 4 - Two sided zero-phase filtering windowlen = 0.15 * srate # safe length of a QRS pulse rectangular = ss.boxcar(windowlen) smoothfirst = ss.convolve(shannon, rectangular, mode='same') revfirst = smoothfirst[::-1] smoothsec = ss.convolve(revfirst, rectangular, mode='same') smoothfinal = smoothsec[::-1] # 5 - Hilbert transform applied to the smoothed shannon energy envelope hilbbuff = ss.hilbert(smoothfinal) hilbsign = np.imag(hilbbuff) # 6 - Get moving average of the hilbert transform so as to subtract after n = int(2.5 * srate) movwind = np.ones(n) / n movav = ss.convolve(hilbsign, movwind, mode='same') analyser = hilbsign - movav # 7 - Get zero crossings (from negative to positive) of the 'analyser' signal zero_crossings = np.where(np.diff(np.sign(analyser)))[0] zero_crossings = zero_crossings[ zero_crossings > 0.05 * srate] # discard boundary effect that might appear at start crossers = analyser[zero_crossings] beats = zero_crossings[crossers < 0] crossdiffs = np.diff(beats) dangerous = crossdiffs < 0.15 * srate # to avoid stupid repetitions dangerous = np.nonzero(dangerous)[0] if len(dangerous): print 'DANGER', beats[dangerous] beats = np.delete(beats, dangerous) # 7.1 -------- EXTRA ANTI-FALSE-POSITIVES -------- store_size = 5 index_store = 0 anti_fp = 0.26 anti_massive = 4 anti_badset = 3 reset_count = 0 cross_storer = np.zeros(store_size) crossderivs = np.diff(analyser) beats = sorted(list(beats)) iterator = beats[:] evilbeats = [] for b in iterator: cross_med = np.median(cross_storer) # print 'info', b, crossderivs[b], anti_fp*cross_med, cross_med, anti_massive*cross_med # massive slopes can be eliminated here too (decided not too because it helps in defining Agrafioti windows) if crossderivs[b] > anti_fp * cross_med: reset_count = 0 if crossderivs[b] < anti_massive * cross_med or cross_med < 1e-10: # print 'store' cross_storer[index_store] = crossderivs[b] index_store += 1 if index_store == store_size: index_store = 0 else: reset_count += 1 print '\tEVIL SLOPE', b, crossderivs[ b], anti_fp * cross_med, reset_count evilbeats.append(b) beats.remove(b) if reset_count >= anti_badset: print '\tRESET' reset_count = 0 cross_storer = np.zeros(store_size) beats = np.array(beats, dtype=int) evilbeats = np.array(evilbeats) # 8 ----------------------------------------- Find the R-peak exactly ----------------------------------------- search = int(0.15 * srate) adjacency = int(0.03 * srate) diff_nr = int(0.01 * srate) rawbeats = [] for b in xrange(len(beats)): if beats[b] - search < 0: rawwindow = rawend[0:beats[b] + search] add = 0 elif beats[b] + search >= len(rawend): rawwindow = rawend[beats[b] - search:len(rawend)] add = beats[b] - search else: rawwindow = rawend[beats[b] - search:beats[b] + search] add = beats[b] - search # ----- get peaks ----- w_peaks = peakd.sgndiff(Signal=rawwindow)['Peak'] w_negpeaks = peakd.sgndiff(Signal=window, a=1)['Peak'] zerdiffs = np.where(np.diff(rawwindow) == 0)[0] w_peaks = np.concatenate((w_peaks, zerdiffs)) w_negpeaks = np.concatenate((w_negpeaks, zerdiffs)) if up: pospeaks = sorted(zip(rawwindow[w_peaks], w_peaks), reverse=True) else: pospeaks = sorted(zip(rawwindow[w_negpeaks], w_negpeaks)) # print '\n peaksssss', pospeaks try: twopeaks = [pospeaks[0]] except IndexError: twopeaks = [] # ----------- getting peaks ----------- for i in xrange(len(pospeaks) - 1): if abs(pospeaks[0][1] - pospeaks[i + 1][1]) > adjacency: twopeaks.append(pospeaks[i + 1]) break poslen = len(twopeaks) if poslen == 2: # --- get maximum slope for max peak --- if twopeaks[0][1] < diff_nr: diff_f = np.diff(rawwindow[0:twopeaks[0][1] + diff_nr]) elif twopeaks[0][1] + diff_nr >= len(rawwindow): diff_f = np.diff(rawwindow[twopeaks[0][1] - diff_nr:len(rawwindow)]) else: diff_f = np.diff(rawwindow[twopeaks[0][1] - diff_nr:twopeaks[0][1] + diff_nr]) max_f = np.max(np.abs(diff_f)) # --- get maximum slope for second peak --- if twopeaks[1][1] < diff_nr: diff_s = np.diff(rawwindow[0:twopeaks[1][1] + diff_nr - 1]) elif twopeaks[1][1] + diff_nr >= len(rawwindow): diff_s = np.diff(rawwindow[twopeaks[1][1] - diff_nr + 1:len(rawwindow)]) else: diff_s = np.diff(rawwindow[twopeaks[1][1] - diff_nr + 1:twopeaks[1][1] + diff_nr - 1]) max_s = np.max(np.abs(diff_s)) if show2: print 'diffs, main', diff_f, max_f, '\nsec', diff_s, max_s if max_f > max_s: # print '\tbigup' assignup = [twopeaks[0][0], twopeaks[0][1]] else: # print '\tsmallup' assignup = [twopeaks[1][0], twopeaks[1][1]] rawbeats.append(assignup[1] + add) elif poslen == 1: rawbeats.append(twopeaks[0][1] + add) else: rawbeats.append(beats[b]) if show2: fig = pl.figure() mngr = pl.get_current_fig_manager() mngr.window.setGeometry(950, 50, 1000, 800) ax = fig.add_subplot(111) ax.plot(rawwindow, 'b') for i in xrange(poslen): ax.plot(twopeaks[i][1], twopeaks[i][0], 'bo', markersize=10) ax.plot(rawbeats[b] - add, rawwindow[rawbeats[b] - add], 'yo', markersize=7) ax.grid('on') ax.axis('tight') pl.show() raw_input('---') pl.close() # 8 ----------------------------------------- END OF POINT 8 ----------------------------------------- if show3: fig = pl.figure() mngr = pl.get_current_fig_manager() mngr.window.setGeometry(950, 50, 1000, 800) ax = fig.add_subplot(412) ax.plot(rawend) if len(rawbeats): ax.plot(rawbeats, rawend[rawbeats], 'go') ax.set_title('end signal') ax = fig.add_subplot(411) ax.plot(raw) if beats.any(): ax.plot(beats, raw[beats], 'go') ax.set_title('filtered from raw') ax = fig.add_subplot(413) ax.plot(smoothfinal) ax.set_title('smooth shannon') ax = fig.add_subplot(414) ax.plot(analyser) if beats.any(): ax.plot(beats, analyser[beats], 'go') if evilbeats.any(): ax.plot(evilbeats, analyser[evilbeats], 'ro') ax.plot(hilbsign, 'r') ax.set_title('analysed signal') pl.show() raw_input('shannon') # pl.close('all') # kwrvals kwrvals = {'Signal': rawend, 'R': sorted(list(frozenset(rawbeats)))} return kwrvals
For digital filters, Wn are in the same units as fs. By default, fs is 2 half-cycles/sample, so these are normalized from 0 to 1, where 1 is the Nyquist frequency. (Wn is thus in half-cycles / sample.) For analog filters, Wn is an angular frequency (e.g., rad/s). """ """ ███████ ██ ██ ██████ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ █████ ███ ██ ██ ███████ █████ ██ ██ ██ ██ ██ ██ ██ ███████ ██ ██ ██████ ███████ ███████ """ sosTypeII = signal.cheby2(10, 20, fc, 'highpass', fs=2000, output='sos') #cheby2 #rs = 20 #rs float The minimum attenuation required in the stop band. Specified in decibels, as a positive number. filtered_II = signal.sosfilt(sosTypeII, s) affichage('Exos 2 : After 25 Hz high-pass filter with Chebyshev Type II',2,s,filtered_II) """ ███████ ██ ██ ██████ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ █████ ███ ██ ██ ███████ █████ ██ ██ ██ ██ ██ ██ ██ ███████ ██ ██ ██████ ███████ ██████
def LPmin(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='lowpass', analog = self.analog, output = frmt))
def synthesizeQNTF(order=4, OSR=64, f0=0., NG=-60, ING=-20, n_im=None): """Synthesize a noise transfer function for a quadrature modulator. **Parameters:** order : int, optional The order of the modulator. Defaults to 4. OSR : int, optional The oversampling ratio. Defaults to 64. f0 : float, optional The center frequency, normalized such that :math:`1 \\rightarrow f_s`. Defaults to 0, ie to a low-pass modulator. NG : float, optional The in-band noise gain, expressed in dB. Defaults to -60. ING : float, optional The image-band noise gain, in dB. Defaults to -20. n_im : int, optional The number of in-band image zeros, defaults to ``floor(order/3)``. **Returns:** ntf : (z, p, k) tuple ``ntf`` is a zpk tuple containing the zeros, poles and the gain of the synthesized NTF. .. note:: From the MATLAB Delta-Sigma Toolbox: ALPHA VERSION: This function uses an experimental ad-hoc method that is neither optimal nor robust. **Example:** Fourth order quadrature modulator:: from deltasigma import * order = 4 osr = 32 NG = -50 ING = -10 f0 = 1 / 16 ntf0 = synthesizeQNTF(order, osr, f0, NG, ING) pretty_lti(ntf0) Returns:: (z - 0.888 - 0.4598j) (z - 0.9239 + 0.3827j) (z - 0.9239 - 0.3827j) (z - 0.953 - 0.3028j) --------------------------------------------------------------------------------------------- (z - 0.5739 - 0.5699j) (z - 0.5913 - 0.2449j) (z - 0.6731 + 0.2788j) (z - 0.8088 - 0.0028j) .. image:: _static/synthesizeQNTF.png """ if n_im is None: n_im = np.floor(order/3) debug_it = 0 if n_im == 0: # Use synthesizeNTF to get an NTF with the specified NG; ignore ING f1 = 0.5/OSR x = 1.5 lowest_f = np.inf dfdx = None for itn in range(ITN_MAX): ntf = synthesizeNTF(order, OSR, 1., x) f = dbv(rmsGain(ntf, 0., f1)) - NG #f_old = f if debug_it: print('x=%.2f f=%.2f' % (x, f)) if abs(f) < 0.01: break if dfdx is None: dx = 0.1*np.sign(f) dfdx = 0 else: dfdx = (f - f_old)/dx dx_old = dx dx = - f/dfdx if abs(dx) > max((1, 2*abs(dx_old))): dx = np.sign(dx)*max((1, 2*abs(dx_old))) if x + dx <= 1: # Hinf must be at least 1 dx = dx/2. f_old = f x = x + dx if itn == ITN_MAX - 1: warn('Iteration limit reached. NTF may be poor.') # Rotate the NTF z0 = np.exp(2j*np.pi*f0) zeros, poles, k = _get_zpk(ntf) ntf = (z0*zeros, z0*poles, k) else: n_in = order - n_im f1 = f0 - 0.5/OSR f2 = f0 + 0.5/OSR z0 = np.exp(2j*np.pi*f0) x = np.array([20., 20.]) # "R" parameters for cheby2() lowest_f = np.inf dfdx = np.array([float('NaN'), float('NaN')]) freq = np.linspace(-0.5, 0.5, 200) for itn in range(ITN_MAX): if debug_it: print('\nx = [%.2f, %.2f]' % (x[0], x[1])) b1, a1 = cheby2(n_in, x[0], 1./OSR, 'highpass') b2, a2 = cheby2(n_im, x[1], 1./OSR, 'highpass') ntf0 = (np.concatenate((np.roots(b1)*z0, np.roots(b2)*np.conj(z0))), np.concatenate((np.roots(a1)*z0, np.roots(a2)*np.conj(z0))), 1) m = evalTF(ntf0, np.exp(2j*np.pi*freq)) NG0 = dbv(rmsGain(ntf0, f1, f2)) ING0 = dbv(rmsGain(ntf0, -f1, -f2)) if debug_it: import pylab as plt from ._plotPZ import plotPZ from ._figureMagic import figureMagic plt.figure() plt.subplot(121) plotPZ(ntf0) plt.subplot(122) print('NG = %.1f, ING= %.1f' % (NG0, ING0)) plt.plot(freq, dbv(m)) figureMagic([-0.5, 0.5], 0.05, 2, [-100, 30], 10, 2) plt.hold(True) plt.plot([f1, f2], [NG0, NG0], 'k') plt.text(np.mean([f1, f2]), NG0, ('NG=%.1fdB' % NG0), va='bottom') plt.plot([-f1, -f2], [ING0, ING0], 'k') plt.text(np.mean([-f1, -f2]), ING0, ('ING=%.1fdB' % ING0), va='bottom') plt.show() f = np.array([NG0 - NG, ING0 - ING]) #f_old = f.copy() if max(abs(f)) < 0.01: break if norm(f) < lowest_f: lowest_f = norm(f) # ntf0 is ALREADY a zpk tuple zeros, poles, k = ntf0 best = (zeros.copy(), poles.copy(), k) if abs(f[0]) > abs(f[1]): # adjust x(1) i = 0 else: # adjust x(2) i = 1 if np.isnan(dfdx[i]): dx = np.sign(f[i]) dfdx[i] = 0 dfdx[1 - i] = float('NaN') else: dfdx[i] = (f[i] - f_old[i])/dx dfdx[1 - i] = float('NaN') dx = -f[i]/dfdx[i] xnew = x[i] + dx if xnew < 0.5*x[i]: dx = -0.5*x[i] else: if xnew > 2*x[i]: dx = x[i] f_old = f.copy() x[i] = x[i] + dx if itn == ITN_MAX - 1: warn('Iteration limit reached. NTF may be poor') ntf = best return ntf
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 synthesizeChebyshevNTF(order=3, OSR=64, opt=0, H_inf=1.5, f0=0.): """Synthesize a noise transfer function for a delta-sigma modulator. The NTF is a type-2 highpass Chebyshev function. func:`synthesizeNTF` assumes that magnitude of the denominator of the NTF is approximately constant in the passband. When the OSR or ``H_inf`` are low, this assumption breaks down and synthesizeNTF yields a non-optimal NTF. :func:`synthesizeChebyshevNTF` creates non-optimal NTFs, but fares better than synthesizeNTF in the aforementioned circumstances. **Parameters:** order : int, optional order of the modulator, defaults to 3 OSR : int, optional oversampling ratio, defaults to 64 opt : int, optional ignored value, for consistency with ::func:synthesizeNTF H_inf : float, optional maximum NTF gain, defaults to 1.5 f0 : float, optional center frequency (1->fs), defaults to 0. **Returns:** z, p, k : tuple a zpk tuple containing the zeros and poles of the NTF. **Warns:** * If a non-zero value is passed for ``opt``. **Raises:** * ValueError: Order must be even for a bandpass modulator **Example:** Compare the NTFs created by :func:`synthesizeNTF` and :func:`synthesizeChebyshevNTF` when ``OSR`` is low:: OSR = 4 order = 8 H_inf = 3 H0 = synthesizeNTF(order,OSR,1,H_inf) H1 = synthesizeChebyshevNTF(order,OSR,0,H_inf) .. plot:: import pylab as plt import numpy as np from deltasigma import * OSR = 4 order = 8 H_inf = 3 H0 = synthesizeNTF(order,OSR,1,H_inf) H1 = synthesizeChebyshevNTF(order,OSR,0,H_inf) # 1. Plot the singularities. plotsize = (14, 7) plt.subplot(121) # we plot the singularities of the optimized NTF in light # green with slightly bigger markers so that we can better # distinguish the two NTF's when overlayed. plotPZ(H1, markersize=7, color='#90EE90') plt.hold(True) plotPZ(H0, markersize=5) plt.title('NTF Poles and Zeros') f = np.concatenate((np.linspace(0, 0.75/OSR, 100), np.linspace(0.75/OSR, 0.5, 100))) z = np.exp(2j*np.pi*f) magH0 = dbv(evalTF(H0, z)) magH1 = dbv(evalTF(H1, z)) # 2. Plot the magnitude responses. plt.subplot(222) plt.plot(f, magH0, label='synthesizeNTF') plt.hold(True) plt.plot(f, magH1, label='synthesizeChebyshevNTF') figureMagic([0, 0.5], 0.05, None, [-80, 20], 10, None, plotsize) plt.xlabel('Normalized frequency ($1\\\\rightarrow f_s)$') plt.ylabel('dB') plt.legend(loc=4) plt.title('NTF Magnitude Response') # 3. Plot the magnitude responses in the signal band. plt.subplot(224) fstart = 0.01 f = np.linspace(fstart, 1.2, 200)/(2*OSR) z = np.exp(2j*np.pi*f) magH0 = dbv(evalTF(H0, z)) magH1 = dbv(evalTF(H1, z)) plt.semilogx(f*2*OSR, magH0, label='synthesizeNTF') plt.hold(True) plt.semilogx(f*2*OSR, magH1, label='synthesizeChebyshevNTF') plt.axis([fstart, 1, -50, 0]) plt.grid(True) sigma_H0 = dbv(rmsGain(H0, 0, 0.5/OSR)) sigma_H1 = dbv(rmsGain(H1, 0, 0.5/OSR)) plt.semilogx([fstart, 1], sigma_H0*np.array([1, 1]), linewidth=3, color='#191970') plt.text(0.15, sigma_H0 + 1.5, 'RMS gain = %5.0fdB' % sigma_H0) plt.semilogx([fstart, 1], sigma_H1*np.array([1, 1]), linewidth=3, color='#228B22') plt.text(0.15, sigma_H1 + 1.5, 'RMS gain = %5.0fdB' % sigma_H1) plt.xlabel('Normalized frequency ($1\\\\rightarrow f_B$)') plt.ylabel('dB') plt.legend(loc=3) plt.tight_layout() Repeat for ``H_inf`` low:: OSR = 32 order = 5 H_inf = 1.2 H0 = synthesizeNTF(order, OSR, 1, H_inf) H1 = synthesizeChebyshevNTF(order, OSR, 1, H_inf) .. plot:: import pylab as plt import numpy as np from deltasigma import * OSR = 32 order = 5 H_inf = 1.2 H0 = synthesizeNTF(order, OSR, 1, H_inf) H1 = synthesizeChebyshevNTF(order, OSR, 1, H_inf) # 1. Plot the singularities. plotsize = (14, 7) plt.subplot(121) # we plot the singularities of the optimized NTF in light # green with slightly bigger markers so that we can better # distinguish the two NTF's when overlayed. plotPZ(H1, markersize=7, color='#90EE90') plt.hold(True) plotPZ(H0, markersize=5) plt.title('NTF Poles and Zeros') f = np.concatenate((np.linspace(0, 0.75/OSR, 100), np.linspace(0.75/OSR, 0.5, 100))) z = np.exp(2j*np.pi*f) magH0 = dbv(evalTF(H0, z)) magH1 = dbv(evalTF(H1, z)) # 2. Plot the magnitude responses. plt.subplot(222) plt.plot(f, magH0, label='synthesizeNTF') plt.hold(True) plt.plot(f, magH1, label='synthesizeChebyshevNTF') figureMagic([0, 0.5], 0.05, None, [-80, 20], 10, None, plotsize) plt.xlabel('Normalized frequency ($1\\\\rightarrow f_s)$') plt.ylabel('dB') plt.legend(loc=4) plt.title('NTF Magnitude Response') # 3. Plot the magnitude responses in the signal band. plt.subplot(224) fstart = 0.01 f = np.linspace(fstart, 1.2, 200)/(2*OSR) z = np.exp(2j*np.pi*f) magH0 = dbv(evalTF(H0, z)) magH1 = dbv(evalTF(H1, z)) plt.semilogx(f*2*OSR, magH0, label='synthesizeNTF') plt.hold(True) plt.semilogx(f*2*OSR, magH1, label='synthesizeChebyshevNTF') plt.axis([fstart, 1, -60, -20]) plt.grid(True) sigma_H0 = dbv(rmsGain(H0, 0, 0.5/OSR)) sigma_H1 = dbv(rmsGain(H1, 0, 0.5/OSR)) plt.semilogx([fstart, 1], sigma_H0*np.array([1, 1]), linewidth=3, color='#191970') plt.text(0.15, sigma_H0 + 1.5, 'RMS gain = %5.0fdB' % sigma_H0) plt.semilogx([fstart, 1], sigma_H1*np.array([1, 1]), linewidth=3, color='#228B22') plt.text(0.15, sigma_H1 + 1.5, 'RMS gain = %5.0fdB' % sigma_H1) plt.xlabel('Normalized frequency ($1\\\\rightarrow f_B$)') plt.ylabel('dB') plt.legend(loc=3) plt.tight_layout() """ if opt: warn("Got a non-zero 'opt' value. Not such optimization is " + \ "available, opt is only meant to ease switching between " + \ "synthesizeNTF and synthesizeChebyshevNTF.") if f0 != 0: if order % 2 != 0: raise ValueError('Order must be even for a bandpass modulator.') else: f1, f2 = ds_f1f2(OSR, f0) f1f2 = np.array([f1, f2]) x_min = 0 x_max = 300 dx_max = 10 ftol = 1e-06 xtol = 1e-06 x = 60 itn_limit = 10 converged = False for itn in range(itn_limit): if f0 == 0: z, p, k = cheby2(order, x, 1./OSR, btype='high', output='zpk') else: z, p, k = cheby2(order/2., x, 2.*f1f2, btype='stop', output='zpk') f = 1./k - H_inf if f > 0: x_max = x else: x_min = x if itn == 0: dx = -dx_max*np.sign(f) else: df = f - f_p if abs(df) < ftol: converged = True break dx = -f*dx/df if converged: break x_p = x f_p = f x = max(x_min, min(x + dx, x_max)) dx = x - x_p if abs(dx) < xtol: break ntf = (z, p, 1) return ntf
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