def butterworth_plot(fig=None, ax=None):
    """
    Plot of frequency response of the Butterworth filter with different orders.
    """

    if fig is None:
        fig, ax = plt.subplots(1, 2, figsize=(10, 4))
        
    b1, a1 = signal.butter(1, 10, 'low', analog=True)
    w, h1 = signal.freqs(b1, a1)
    ang1 = np.rad2deg(np.unwrap(np.angle(h1)))
    h1 = 20 * np.log10(abs(h1))
    b2, a2 = signal.butter(2, 10, 'low', analog=True)
    w, h2 = signal.freqs(b2, a2)
    ang2 = np.rad2deg(np.unwrap(np.angle(h2)))
    h2 = 20 * np.log10(abs(h2))
    b4, a4 = signal.butter(4, 10, 'low', analog=True)
    w, h4 = signal.freqs(b4, a4)
    ang4 = np.rad2deg(np.unwrap(np.angle(h4)))
    h4 = 20 * np.log10(abs(h4))
    b6, a6 = signal.butter(6, 10, 'low', analog=True)
    w, h6 = signal.freqs(b6, a6)
    ang6 = np.rad2deg(np.unwrap(np.angle(h6)))
    h6 = 20 * np.log10(abs(h6))
    w = w/10

    # PLOT
    ax[0].plot(w, h1, 'b', w, h2, 'r', w, h4, 'g', w, h6, 'y', linewidth=2)
    ax[0].axvline(1, color='black') # cutoff frequency
    ax[0].scatter(1, -3, marker='s', edgecolor='0', facecolor='1', s=400)
    #ax1.legend(('1', '2', '4', '6'), title='Filter order', loc='best')
    ax[0].set_xscale('log')
    fig.suptitle('Bode plot for low-pass Butterworth filter with different orders',
                 fontsize=16, y=1.05)
    #ax1.set_title('Magnitude', fontsize=14)
    ax[0].set_xlabel('Frequency / Critical frequency', fontsize=14)
    ax[0].set_ylabel('Magnitude [dB]', fontsize=14)
    ax[0].set_xlim(0.1, 10)
    ax[0].set_ylim(-120, 10)
    ax[0].grid(which='both', axis='both')
    ax[1].plot(w, ang1, 'b', w, ang2, 'r', w, ang4, 'g', w, ang6, 'y', linewidth=2)
    ax[1].axvline(1, color='black')  # cutoff frequency
    ax[1].legend(('1', '2', '4', '6'), title='Filter order', loc='best')
    ax[1].set_xscale('log')
    #ax2.set_title('Phase', fontsize=14)
    ax[1].set_xlabel('Frequency / Critical frequency', fontsize=14)
    ax[1].set_ylabel('Phase [degrees]', fontsize=14)
    ax[1].set_yticks(np.arange(0, -300, -45))
    ax[1].set_ylim(-300, 10)
    ax[1].grid(which='both', axis='both')
    plt.tight_layout(w_pad=1)
    axi = plt.axes([.115, .4, .15, .35])  # inset plot
    axi.plot(w, h1, 'b', w, h2, 'r', w, h4, 'g', w, h6, 'y', linewidth=2)
    #ax11.set_yticks(np.arange(0, -7, -3))
    axi.set_xticks((0.6, 1, 1.4))
    axi.set_yticks((-6, -3, 0))
    axi.set_ylim([-7, 1])
    axi.set_xlim([.5, 1.5])
    axi.grid(which='both', axis='both')
Exemple #2
0
    def __init__(self, fp, fs, gpass, gstop, ftype, btype): 
        #Variables init.
        self.fp = fp
        self.fs = fs
        self.gpass =  gpass
        self.gstop = gstop
        self.ftype = ftype
        self.btype = btype

        #Filter type for plot's title.
        types_dict = {"butter":"Butterworth", "cheby1":"Chebyshev I", "cheby2":"Chebyshev II", "ellip": "Cauer"}
        self.ftype_plot = types_dict[ftype]

        self.__wsk()
        self.__filter_order()
            
        #Designing filter.
        (self.b, self.a) = signal.iirfilter(self.ord,
                                            self.wn,
                                            rp=self.gpass, 
                                            rs=self.gstop, 
                                            btype=self.btype, 
                                            analog=True, 
                                            output='ba', 
                                            ftype=ftype)

        #Frequency response of analog filter.
        (self.w, self.h) = signal.freqs(self.b, self.a, worN=1000)

        #Denormalizing variabels for ploting. Pulsation to frequency.
        self.w = (self.w * (self.sampling_w / 2)) / (2 * pi)
        self.wn = (self.wn * (self.sampling_w / 2)) / (2 * pi)
Exemple #3
0
    def filterba(self, b, a, inplace=False):
        """Apply a filter to this `Spectrum` in numerator-denominator
        format.

        Parameters
        ----------
        b : :class:`~numpy.ndarray`
            Numerator of a linear filter
        a : :class:`~numpy.ndarray`
            Decnominator of a linear filter
        inplace : `bool`, optional, default: `False`
            modify this `Spectrum` in-place

        Returns
        -------
        Spectrum
            either a view of the current `Spectrum` with filtered data,
            or a new `Spectrum` with the filtered data
        """
        fresp = abs(signal.freqs(b, a, self.frequencies)[1])
        if inplace:
            self *= fresp
            return self
        else:
            new = self * fresp
            return new
Exemple #4
0
  	def FilterResponse(self):
  		"""
  		Gives the response of the filter y frequency-amplitude
  		"""

  		self.w, self.h = SGN.freqs(self.ba, self.aa)
  		return self.w, self.h
 def compute_frequencies(self, N=None):
     if hasattr(self, 'sample_rate'):
         try:
             self.W, self.H = signal.freqz(self.B, self.A)
         except:
             self.W, self.H = signal.freqz(self.B)
     else:
         self.W, self.H = signal.freqs(self.B, self.A, N)
Exemple #6
0
def plot_H(b, a):
    ws = np.linspace(2*np.pi*3.7, 2*np.pi*8.6, 200)
    w, h = signal.freqs(b, a, ws)
    plt.semilogx(w/(2*np.pi), 20 * np.log10(abs(h)))
    plt.title('Butterworth filter frequency response')
    plt.xlabel('Frequency [radians / second]')
    plt.ylabel('Amplitude [dB]')
    plt.show()
Exemple #7
0
def make_ctle(rx_bw, peak_freq, peak_mag, w, dc_offset=0):
    """
    Generate the frequency response of a continuous time linear
    equalizer (CTLE), given the:

    - signal path bandwidth,
    - peaking specification, and
    - list of frequencies of interest.

    We use the 'invres()' function from scipy.signal, as it suggests
    itself as a natural approach, given our chosen use model of having
    the user provide the peaking frequency and degree of peaking.

    That is, we define our desired frequency response using one zero
    and two poles, where:

    - The pole locations are equal to:
       - the signal path natural bandwidth, and
       - the user specified peaking frequency.

    - The zero location is chosen, so as to provide the desired degree
      of peaking.

    Inputs:

      - rx_bw        The natural (or, unequalized) signal path bandwidth (Hz).

      - peak_freq    The location of the desired peak in the frequency
                     response (Hz).

      - peak_mag     The desired relative magnitude of the peak (dB). (mag(H(0)) = 1)

      - w            The list of frequencies of interest (rads./s).

      - dc_offset    The d.c. offset of the CTLE gain curve (dB).

    Outputs:

      - w, H         The resultant complex frequency response, at the
                     given frequencies.

    """

    p2   = -2. * pi * rx_bw
    p1   = -2. * pi * peak_freq
    z    = p1 / pow(10., peak_mag / 20.)
    if(p2 != p1):
        r1   = (z - p1) / (p2 - p1)
        r2   = 1 - r1
    else:
        r1   = -1.
        r2   = z - p1
    b, a = invres([r1, r2], [p1, p2], [])

    w, H = freqs(b, a, w)
    H   *= pow(10., dc_offset / 20.) / abs(H[0])  # Enforce d.c. offset.

    return (w, H)
Exemple #8
0
def grp_delay_ana(b, a, w):
    """
    Calculate the group delay of an anlog filter.
    """
    w, H = sig.freqs(b, a, w)
    H_angle = np.unwrap(np.angle(H))
#    tau_g = np.zeros(len(w)-1)
    tau_g = (H_angle[1:]-H_angle[:-1])/(w[0]-w[1])
    return tau_g, w[:-1]
def butter_filter():

        N = 8 #order
        wn = 0.5 #frequency in the transition band when gain drops below -3dB
        type = 'low' #filter type

        b, a = signal.butter(N,wn,'low',analog=False)
        w, h = signal.freqs(b, a)
        return (b,a,w,h)
 def band_stop(self, low_f, high_f, axis='x', order=6):
     f_nyq = self.rate / 2
     band_low = low_f / f_nyq
     band_high = high_f / f_nyq
     b, a = sig.butter(order, [band_low, band_high], btype='bandstop')
     w, h = sig.freqs(b, a)
     vdata = self.ts[axis]
     filtered = sig.lfilter(b,a,vdata)
     return filtered
def test_sos_phys2filter():
    b, a = sos_phys2filter(S0, delta, f0)
    H = freqs(b, a, 2 * np.pi * fe5)[1]
    indmax = np.abs(H).argmax()
    assert np.round(np.abs(f0 - fe5[indmax])) <= 0.01 * f0
    assert np.abs(H[0]) == approx(S0)
    bmulti, amulti = sos_phys2filter(S0 * np.ones(K), delta * np.ones(K), f0 * np.ones(K))
    assert len(bmulti[0]) == K
    assert amulti.shape == (K, 3)
Exemple #12
0
    def test_filter(self, array):
        a2 = array.filter([100], [1], 1e-2)
        assert isinstance(a2, type(array))
        utils.assert_quantity_equal(a2.frequencies, array.frequencies)

        # manually rebuild the filter to test it works
        b, a, = signal.zpk2tf([100], [1], 1e-2)
        fresp = abs(signal.freqs(b, a, array.frequencies.value)[1])
        utils.assert_array_equal(a2.value, fresp * array.value)
Exemple #13
0
 def test_filter(self):
     array = self.create()
     a2 = array.filter([100], [1], 1e-2)
     self.assertIsInstance(a2, type(array))
     self.assertArraysEqual(a2.frequencies, array.frequencies)
     # manually rebuild the filter to test it works
     b, a, = signal.zpk2tf([100], [1], 1e-2)
     fresp = abs(signal.freqs(b, a, array.frequencies.value)[1])
     nptest.assert_array_equal(a2.value, fresp * array.value)
Exemple #14
0
def crossCalib(monitor_trace, response_trace, **kwargs):
	
	m_trace=monitor_trace.copy()
	r_trace=response_trace.copy()

	if 'demean' in kwargs and kwargs['demean']:
		m_trace.detrend('demean')
		r_trace.detrend('demean')

	if 'taper' in kwargs and kwargs['taper']:
		m_trace.taper(0.05)
		r_trace.taper(0.05)

	#Paramètres des PSD
	if 'nfft' in kwargs:
		n_fft=kwargs['nfft']
	else:
		n_fft=1024

	if 'npad' in kwargs:
		n_pad=kwargs['npad']
	else:
		n_pad=n_fft*4

	if 'noverlap' in kwargs:
		n_overlap=kwargs['noverlap']
	else:
		n_overlap=int(n_fft*0.90)

	#paz par défaut: chaine générique
	if 'paz' in kwargs:
		paz=kwargs['paz']
	else:
		paz=dict()
		paz['zeros']=np.array([])
		paz['poles']=np.array([])
		paz['gain']=1
		paz['seismometer_gain']=1
		paz['datalogger_gain']=1
		paz['sensitivity']=paz['seismometer_gain']*paz['datalogger_gain']*paz['gain']

	
	fs=m_trace.stats.sampling_rate
	(P00,f)=mlab.psd(m_trace.data,Fs=fs,NFFT=n_fft,noverlap=n_overlap,pad_to=n_pad,detrend=mlab.detrend_mean,window=mlab.window_hanning)
	(P01,f)=mlab.csd(m_trace.data,r_trace.data,Fs=fs,NFFT=n_fft,noverlap=n_overlap,pad_to=n_pad,detrend=mlab.detrend_mean,window=mlab.window_hanning)
	(C,f)=mlab.cohere(m_trace.data,r_trace.data,Fs=fs,NFFT=n_fft,noverlap=n_overlap,pad_to=n_pad,detrend=mlab.detrend_mean,window=mlab.window_hanning)
	
	(b,a)=sp.zpk2tf(paz['zeros'],paz['poles'],paz['sensitivity'])
	(_w,H0)=sp.freqs(b,a,f*2*np.pi)

	H1=P01*H0/P00
	H1=H1[1:]
	C=C[1:]
	f=f[1:]

	return (H1,C,f)
Exemple #15
0
def plot_filter_response(b, a):
    w, h = signal.freqs(b, a)
    plt.plot(w, 20 * np.log10(abs(h)))
    plt.xscale('log')
    plt.title('Chebyl1 filter frequency response')
    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.show()
Exemple #16
0
def FDLS_fromfilt(B, A, N, D, shift = 0.0, phasemult = 1.0, analog = False):

    if analog:
        w, h = sps.freqs(B, A)
    else:
        w, h = sps.freqz(B, A, worN = 1024)

    Am = np.absolute(h)
    Th = np.angle(h) * phasemult 

    return FDLS(N, D, w, Am = Am, Th = Th, shift = shift) 
def Rule_7(w_start, w_end):
    # Rule 7 determining the phase of GGm at -180deg
    # this is solved visually from a plot

    w = np.logspace(w_start, w_end, 1000)

    Pz = np.polymul(G()[0], Gm()[0])
    Pp = np.polymul(G()[1], Gm()[1])
    [w, h] = scs.freqs(Pz, Pp, w)

    plt.semilogx(w, (180 / np.pi) * (phase(h) + w * Time_Delay()))
    plt.show()
def elliptical_filter(): #Design an elliptical filter with some predefined parameters

	N = 8 #order
	rp = 1 #max ripple below unity in passband [dB]
	rs = 10 #max attenuation in the stop band [dB]

	wn = 0.5 #frequency in the transition band when gain drops below rp (for ellip)
	type = 'low' #filter type

	b, a = signal.ellip(N,rp,rs,wn,'low',analog=False)
	w, h = signal.freqs(b, a)
	return (b,a,w,h)
Exemple #19
0
 def __method(self):
     # TODO Check CPU time
     '''
     low pass filtering for mode estimation function 
     array must be declared and passed through the function 
     '''
     # step 1 vedran, design filter
     ''' Wn= length-2 sequence giving the critical frequencies - Fp, Fst parameters from matlab fdesign.lowpass(Fp,Fst,Ap,Ast)
     rp: maximum ripple in the pass band. (dB) - Ap parameter from matlab fdesign.lowpass(Fp,Fst,Ap,Ast)
     rs:  minimum attenuation in the stop band. (dB) - Ast parameter from matlab fdesign.lowpass(Fp,Fst,Ap,Ast)
     '''
     b, a= signal.iirfilter(self.__order, Wn=[2/25,2.5/25], rp=0.1, rs=50, btype='lowpass', 
                            analog=True, ftype='cheby2')
     # step 2 vedran, apply filter
     simsignalFilter= signal.lfilter(b, a, self.__simulationsSignal)
     # step 3 vedran, downsample the signal
     simsignalsampled = signal.decimate(simsignalFilter, 10, ftype='iir')
     # step 4 with signal.freqs(b,a,y) we obtain frequency response of the signal
     freqHz, amplitude = signal.freqs(b, a, simsignalsampled)
     print 'angular frequency ', freqHz
     print 'amplitude response ', amplitude
     for vfreq, vdamp in zip(freqHz, amplitude):
         mode= EigenValue(vfreq,vdamp)
         self.__simulationModes.append(mode)
     # step 2 vedran, apply filter
     maessignalFilter= signal.lfilter(b, a, self.__measurementSignal)
     # step 3 vedran, downsample the signal
     maessignalsampled = signal.decimate(maessignalFilter, 10, ftype='iir')
     # step 4 with signal.freqs(b,a,y) we obtain frequency response of the signal
     freqHz, amplitude = signal.freqs(b, a, maessignalsampled)
     print 'angular frequency ', freqHz
     print 'amplitude response ', amplitude
     for vfreq, vdamp in zip(freqHz, amplitude):
         mode= EigenValue(vfreq,vdamp)
         self.__simulationModes.append(mode)
     # step 4 vedran, armax, _signal.real or signal.magnitude and signal.sampling data
     sys_ident= smapi.tsa.ARMA(simsignalsampled, order=(self.__order,self.__order)).fit()
     print sys_ident
     sys_ident= smapi.tsa.ARMA(maessignalsampled, order=(self.__order,self.__order)).fit()
     print sys_ident
def draw_frequency_response(b,a):
    from scipy.signal import freqs
    w, h = freqs(b, a)
    plt.figure(figsize=(8, 6), dpi=100)
    plt.plot(w, 20 * np.log10(abs(h)))
    plt.xscale('log')
    plt.title('Butterworth filter frequency response')
    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.savefig('frequency_response.png',dpi=500)
def butterplot(fs, fc):
    """
    https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.butter.html
    """
    b, a = signal.butter(4, 100, 'low', analog=True)
    w, h = signal.freqs(b, a)
    ax = figure().gca()
    ax.semilogx(fs*0.5/np.pi*w, 20*np.log10(abs(h)))
    ax.set_title('Butterworth filter frequency response')
    ax.set_xlabel('Frequency [Hz]')
    ax.set_ylabel('Amplitude [dB]')
    ax.grid(which='both', axis='both')
    ax.axvline(fc, color='green')  # cutoff frequency
    ax.set_ylim(-50, 0)
def test_ITU_R_468_weight(fs=None):
    """
    Test that frequency response meets tolerance from Rec. ITU-R BS.468-4
    """
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.signal import freqz

    frequencies = np.array((
        31.5, 63, 100, 200, 400, 800, 1000, 2000, 3150, 4000, 5000,
        6300,
        7100, 8000, 9000, 10000, 12500, 14000, 16000, 20000, 31500
        ))

    responses = np.array((
        -29.9, -23.9, -19.8, -13.8, -7.8, -1.9, 0, +5.6, +9.0, +10.5, +11.7,
        +12.2,
        +12.0, +11.4, +10.1, +8.1, 0, -5.3, -11.7, -22.2, -42.7
        ))

    upper_limits = np.array((
        +2.0, +1.4, +1.0, +0.85, +0.7, +0.55, +0.5, +0.5, +0.5, +0.5, +0.5,
        +0.01,   # Actually 0 tolerance, but specified as "+12.2" dB
        +0.2, +0.4, +0.6, +0.8, +1.2, +1.4, +1.6, +2.0, +2.8
        ))

    lower_limits = np.array((
        -2.0, -1.4, -1.0, -0.85, -0.7, -0.55, -0.5, -0.5, -0.5, -0.5, -0.5,
        -0.01,   # Actually 0 tolerance, but specified as "+12.2" dB
        -0.2, -0.4, -0.6, -0.8, -1.2, -1.4, -1.6, -2.0, -float('inf')
        ))

    if fs is None:
        z, p, k = ITU_R_468_weighting_analog()
        b, a = zpk2tf(z, p, k)
        w, h = freqs(b, a, 2*pi*frequencies)
    else:
        # Passes if fs >= 180000 Hz but not at typical audio fs
        b, a = ITU_R_468_weighting(fs)
        w = 2*pi * frequencies / fs
        w, h = freqz(b, a, w)

    levels = 20 * np.log10(abs(h))

    plt.semilogx(frequencies, levels)
    plt.semilogx(frequencies, responses + upper_limits, 'r--')
    plt.semilogx(frequencies, responses + lower_limits, 'r--')

    assert all(np.less_equal(levels, responses + upper_limits))
    assert all(np.greater_equal(levels, responses + lower_limits))
Exemple #23
0
 def _response_prototype_and_filters(self, freqs):
     freqs = num.asarray(freqs, dtype=num.float)
     iomega = 1.0j * 2. * num.pi * freqs
     
     trans =   iomega * self._prototype_response_velocity(iomega)
     
     for (order, corner) in self.filters:
         if order < 0. or corner < 0.:
             b,a = signal.butter(abs(order), [abs(corner)], btype='high', analog=1)
         else:
             b,a = signal.butter(order, [corner], btype='low', analog=1)
             
         trans *= signal.freqs(b,a, freqs)[1]
     
     return trans
def chebyshevplot(fs):
    """
    https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.cheby1.html#scipy.signal.cheby1
    """
    b, a = signal.cheby1(4, 5, 100, 'high', analog=True)
    w, h = signal.freqs(b, a)

    ax = figure().gca()
    ax.semilogx(w, 20*np.log10(abs(h)))
    ax.set_title('Chebyshev Type I frequency response (rp=5)')
    ax.set_xlabel('Frequency [radians / second]')
    ax.set_ylabel('Amplitude [dB]')
    ax.grid(which='both', axis='both')
    ax.axvline(100, color='green')  # cutoff frequency
    ax.axhline(-5, color='green')  # rp
Exemple #25
0
def compute_response(freqlist, paz, mode='vel'):

    if isinstance(freqlist, float) or isinstance(freqlist, int):
        freqlist = array([freqlist])

    b, a = zpk2tf(paz.zeros(units='rad', mode=mode),
                                      paz.poles(units='rad', mode=mode),
                                      paz.h0)
    # a has to be a list for the scipy.signal.freqs() call later but zpk2tf()
    # strangely returns it as an integer.
    if not isinstance(a, ndarray) and a == 1.0:
        a = [1.0]

    _, h = freqs(b, a, freqlist * 2 * pi)

    return h
def Rule_4(w_star, w_end, wr):
    # this is rule 4 on pg-207 for input constraint check towards reference changes
    wr = 10 ** wr
    w = np.logspace(w_star, w_end, 1000)

    [w, h] = scs.freqs(G()[0], G()[1], w)

    plt.loglog(w, abs(h), "b")
    plt.loglog([w[0], w[-1]], [(R() - 1), (R() - 1)], "r")
    plt.loglog([wr, wr], [0.8 * np.min([(R() - 1), np.min(abs(h))]), 1.2 * np.max([(R() - 1), np.max(abs(h))])], "g")

    print "The blue line needs to be larger than the red line up to the freqeuncy where control is needed"
    print "This plot is done up to the wr"
    print "The green vertical line is the wr"

    plt.show()
def ITU_R_468_weighting_analog():
    """
    Return ITU-R 468 analog weighting filter zeros, poles, and gain
    """

    z = [0]
    p = [-25903.70104781628,
         +36379.90893732929j-23615.53521363528,
         -36379.90893732929j-23615.53521363528,
         +62460.15645250649j-18743.74669072136,
         -62460.15645250649j-18743.74669072136,
         -62675.1700584679]

    # Normalize to +12.2 dB at 6.3 kHz, numerically
    b, a = zpk2tf(z, p, 1)
    w, h = freqs(b, a, 2*pi*6300)
    k = 10**(+12.2/20) / abs(h[0])

    return z, p, k
Exemple #28
0
    def add_filter(self, filter_, frequencies=None, dB=True, **kwargs):
        """Add a linear time-invariant filter to this BodePlot

        Parameters
        ----------
        filter_ : `~scipy.signal.lti`, `tuple`
            the filter to plot, either as a `~scipy.signal.lti`, or a
            `tuple` with the following number and meaning of elements

                 - 2: (numerator, denominator)
                 - 3: (zeros, poles, gain)
                 - 4: (A, B, C, D)

        frequencies : `numpy.ndarray`, optional
            list of frequencies (in Hertz) at which to plot
        db : `bool`, optional, default: `True`
            if `True`, display magnitude in decibels, otherwise display
            amplitude.
        **kwargs
            any other keyword arguments accepted by
            :meth:`~matplotlib.axes.Axes.plot`

        Returns
        -------
        mag, phase : `tuple` of `lines <matplotlib.lines.Line2D>`
            the lines drawn for the magnitude and phase of the filter.
        """
        if frequencies is None:
            w = None
        else:
            w = frequencies * 2. * pi
        if not isinstance(filter_, signal.lti):
            filter_ = signal.lti(*filter_)
        w, h = signal.freqs(filter_.num, filter_.den, w)
        w /= (2. * pi)
        mag = numpy.absolute(h)
        if dB:
            mag = 2 * to_db(mag)
        phase = numpy.degrees(numpy.unwrap(numpy.angle(h)))
        lm = self.maxes.plot(w, mag, **kwargs)
        lp = self.paxes.plot(w, phase, **kwargs)
        return lm, lp
Exemple #29
0
    def frequency_response(self, f_min=20.0, f_max=300.0):
        """ Calculate frequency response of the speaker (box/driver combination)

        Calculate system response of a certain driver in a vented box,
        according to Small [1]_.

        Parameters
        ----------
        f_min :
            Lower frequency
        f_max :
            Upper frequency

        EReturns
        -------
        freqs : ndarray
            the frequencies at which h was computed
        amplitude : ndarray
            the frequency response

        References
        ----------
        .. [1] Richard H. Small, "Vented-Box Loudspeaker Systems -- Part I"
        """
        start = np.log10(2*np.pi*f_min)
        stop = np.log10(2*np.pi*f_max)
        frequencies = np.logspace(start, stop, num=100)
        a = self.a
        b = self.b
        b[0] *= self.T_0**4

        a[0] *= self.T_0**4
        a[1] *= self.T_0**3
        a[2] *= self.T_0**2
        a[3] *= self.T_0

        w, h = signal.freqs(self.b, self.a, worN=frequencies)
        freqs = w / (2*np.pi)
        amplitude = 20.0*np.log10(h)
        return (freqs, amplitude)
Exemple #30
0
 def __init__(self, source, gain=1, **kwds):
     # Automatically duplicate mono input to fit the desired output shape
     gain = np.atleast_1d(gain)
     if len(gain) != source.nchannels and len(gain) != 1:
         if source.nchannels != 1:
             raise ValueError('Can only automatically duplicate source '
                              'channels for mono sources, use '
                              'RestructureFilterbank.')
         source = RestructureFilterbank(source, len(gain))
     samplerate = source.samplerate
     zeros = np.array([-200, -200])
     poles = np.array([-250 + 400j, -250 - 400j,
                       -2000 + 6000j, -2000 - 6000j])
     # use an arbitrary gain here, will be normalized afterwards
     b, a = signal.zpk2tf(zeros, poles * 2 * np.pi, 1.5e9)
     # normalize the response at 1000Hz (of the analog filter)
     resp = np.abs(signal.freqs(b, a, [1000*2*np.pi])[1])  # response magnitude
     b /= resp
     bd, ad = signal.bilinear(b, a, samplerate)
     bd = (np.tile(bd, (source.nchannels, 1)).T * gain).T
     ad = np.tile(ad, (source.nchannels, 1))
     LinearFilterbank.__init__(self, source, bd, ad, **kwds)
Exemple #31
0
def plot_response(w, h, *args, **kwargs):
    plt.semilogx(w, 20 * np.log10(np.abs(h)), *args, **kwargs)


# inverse notch filter
#         s^2 + s/Q + 1
# H(s) = ---------------
#            s^2 + 1
def inverse_notch_s(freq, Q):
    w = freq
    return [1.0 / w**2, 1.0 / w / Q, 1], [1.0 / w**2, 0, 1]


b_s, a_s = inverse_notch_s(100, 0.5)
w, h = signal.freqs(b_s, a_s, worN=worN)
plot_response(w, h)


def inverse_notch_z(freq, Q, fs):
    wc = 2 * np.pi * freq / fs
    wS = np.sin(wc)
    wC = np.cos(wc)
    alpha = wS / (2.0 * Q)

    a0 = 1.0 + alpha
    return [a0, -2.0 * wC, (1.0 - alpha)], [1.0, -2.0 * wC, 1.0]


b_z, a_z = inverse_notch_z(100, 0.5, FS)
w, h = signal.freqz(b_z, a_z, worN=worN, fs=FS)
def ABC_weighting(curve='A'):
    """
    Design of an analog weighting filter with A, B, or C curve.
    Returns zeros, poles, gain of the filter.
    Examples
    --------
    Plot all 3 curves:
    >>> from scipy import signal
    >>> import matplotlib.pyplot as plt
    >>> for curve in ['A', 'B', 'C']:
    ...     z, p, k = ABC_weighting(curve)
    ...     w = 2*pi*logspace(log10(10), log10(100000), 1000)
    ...     w, h = signal.freqs_zpk(z, p, k, w)
    ...     plt.semilogx(w/(2*pi), 20*np.log10(h), label=curve)
    >>> plt.title('Frequency response')
    >>> plt.xlabel('Frequency [Hz]')
    >>> plt.ylabel('Amplitude [dB]')
    >>> plt.ylim(-50, 20)
    >>> plt.grid(True, color='0.7', linestyle='-', which='major', axis='both')
    >>> plt.grid(True, color='0.9', linestyle='-', which='minor', axis='both')
    >>> plt.legend()
    >>> plt.show()
    """
    if curve not in 'ABC':
        raise ValueError('Curve type not understood')

    # ANSI S1.4-1983 C weighting
    #    2 poles on the real axis at "20.6 Hz" HPF
    #    2 poles on the real axis at "12.2 kHz" LPF
    #    -3 dB down points at "10^1.5 (or 31.62) Hz"
    #                         "10^3.9 (or 7943) Hz"
    #
    # IEC 61672 specifies "10^1.5 Hz" and "10^3.9 Hz" points and formulas for
    # derivation.  See _derive_coefficients()

    z = [0, 0]
    p = [
        -2 * pi * 20.598997057568145, -2 * pi * 20.598997057568145,
        -2 * pi * 12194.21714799801, -2 * pi * 12194.21714799801
    ]
    k = 1

    if curve == 'A':
        # ANSI S1.4-1983 A weighting =
        #    Same as C weighting +
        #    2 poles on real axis at "107.7 and 737.9 Hz"
        #
        # IEC 61672 specifies cutoff of "10^2.45 Hz" and formulas for
        # derivation.  See _derive_coefficients()

        p.append(-2 * pi * 107.65264864304628)
        p.append(-2 * pi * 737.8622307362899)
        z.append(0)
        z.append(0)

    elif curve == 'B':
        # ANSI S1.4-1983 B weighting
        #    Same as C weighting +
        #    1 pole on real axis at "10^2.2 (or 158.5) Hz"

        p.append(-2 * pi * 10**2.2)  # exact
        z.append(0)

    # TODO: Calculate actual constants for this
    # Normalize to 0 dB at 1 kHz for all curves
    b, a = zpk2tf(z, p, k)
    k /= abs(freqs(b, a, [2 * pi * 1000])[1][0])

    return np.array(z), np.array(p), k
Exemple #33
0
 def filter_function(self, freqs):
     b, a = signal.butter(self.order,
                          2 * np.pi * self.fc,
                          'lowpass',
                          analog=True)
     return self.gain * np.abs(signal.freqs(b, a, 2 * np.pi * freqs)[1])
Exemple #34
0
################### Calculate roots #############################
nulls = np.roots(bb) # zeros of H(s)
poles = np.roots(aa) # poles of H(s)

#nulls = [0,0]
#poles = [-1,-2]
#bb = np.poly(nulls
#aa = np.poly(poles)
print("aa, bb =", aa,bb)
print("P, N =", np.roots(aa), np.roots(bb))
print("Angle(P) = ", angle(np.roots(aa))/ pi * 180)


W_max = 2 # normalized circular frequency; W = 2 pi f tau
W = np.linspace(0, W_max, 201) # start, stop, step. endpoint is included
[W,H] = sig.freqs(bb, aa, W) # Calculate H(w) at the frequency points w1
#[w,H]=sig.freqs(bb,aa)  # calculate H(w) at 200 frequencies "around the
                        # interesting parts of the response curve"
f = W
H_abs = abs(H)
H_max = max(H_abs); H_max_dB = 20*log10(H_max)
W_max = W[np.argmax(H_abs)] # frequency where |H(Omega)| is max.
H_angle = np.unwrap(angle(H))

#====================================================
figure(1)
dsp.zplane(bb, aa, analog=True, style = 'square', anaCircleRad=W_c,
           mzc = (0,0.5,0) )
axzp = plt.gca()
axzp.set_xlabel(r'$\sigma \, / \,\omega_n \; \rightarrow$',fontsize=18)
axzp.set_ylabel(r'$j \omega \,  / \,\omega_n \;  \rightarrow$',fontsize=18)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Nov 21 16:56:44 2019

@author: bassem
"""
import numpy as np

from scipy import signal
import matplotlib.pyplot as plt
b, a = signal.butter(4, 5000, 'low', analog=True)
w, h = signal.freqs(b, a)
plt.figure(figsize=(6, 6))
plt.semilogx(w, 20 * np.log10(abs(h)))
plt.title('Butterworth filter frequency response')
plt.xlabel('Frequency [radians / second]')
plt.ylabel('Amplitude [dB]')
plt.margins(0, 0.1)
plt.grid(which='both', axis='both')
plt.axvline(5000, color='green')
plt.axvline(20000, color='green')

b1, a1 = signal.butter(4, 10000, 'High', analog=True)
w1, h1 = signal.freqs(b1, a1)
plt.semilogx(w1, 20 * np.log10(abs(h1)))
plt.show()
'''notre signale'''
''' for the path in this script ,you have to download the file in the main repository named "signaljour1.txt" and make the necessary changes to run the code below'''
from scipy import signal
import pandas as pd
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 18 12:30:50 2020

@author: anavr
"""

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

order = 10
normal_cutoff = 15
b, a = signal.butter(order, normal_cutoff, 'low', analog=True)
w, h = signal.freqs(b, a)
#fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)

plt.subplot(2, 1, 1)
plt.title('Butterworth filter frequency response')
plt.semilogx(w, 20 * np.log10(abs(h)))
plt.xlabel('Frequency [radians / second]')
plt.ylabel('Amplitude [dB]')
plt.margins(0, 0.1)
plt.grid(which='both', axis='both')
plt.axvline(normal_cutoff, color='green')  # cutoff frequency
plt.tight_layout()

t = np.linspace(0, 1, 1000, False)  # 1 second
sig = np.sin(2 * np.pi * 10 * t) + np.sin(2 * np.pi * 20 * t)

sos = signal.butter(10, 15, 'hp', fs=1000, output='sos')
Exemple #37
0
def fft_integration(data, fs, fc=None, order=-1):
    """Intergration of a signal in the frequency domain using FFT.
    
    This function implements the integration in the time domain by means of the
    Fast Fourier Transform. It also performs a band pass filter, removing all
    the unwanted frequencies.

    Args:
        signal (array): Numpy 1d-array with the data.
        fs (float or int): Sampling frequency.
        fc (float or tuple): This is the cut-off frequency. If fc is floating or
            integer a lowpass filter is performed. If fc is a list a band
            pass-pass filter is made between the two given frequencies.
        order (integer): Indicates the order of the integration. Negative number
            indicates integration while positive indicates differentiontion (not
            implemented yet).

    Return (array): Signal integrated.
    """

    # check for nans if more than 10 percents
    nans = np.isnan(data)
    if len(nans.nonzero()[0]) / len(data) < 0.1:
        data[nans] = np.nanmean(data[~nans])
    else:
        return data * np.nan

    # if order == 0 do nothing
    if order == 0:
        return data

    # if order > 0 raise an error
    if order > 0:
        raise ValueError("Order must be a negative integer")

    # get frequency array
    N = len(data)
    freqs = np.fft.fftfreq(N, 1 / fs)

    # the first element of freqs array is zero, so we have
    # to discard it to avoid division by zero
    # the factor of integration is iw
    factor = 1j * 2 * np.pi * freqs[1:]

    # compute fft of the signal for the non-zero frequencies
    # and apply integration factor
    fft = np.zeros(len(freqs), 'complex')
    fft[1:] = np.fft.fft(data)[1:] * factor**order

    # high pass filter
    if fc is None:
        return np.fft.ifft(fft).real
    #
    elif isinstance(fc, float) or isinstance(fc, int):
        #
        if False:  # <-- ideal filter just in case
            ix = abs(freqs) <= fc
            fft[ix] = 0.
        #
        else:  # <- freqs response of a 3th order butterworth filter
            b, a = signal.butter(3, fc, 'high', analog=True)
            w, h = signal.freqs(b, a, worN=freqs)
            fft = fft * abs(h)

    return np.fft.ifft(fft).real
def create_coeffs_ts9(alpha):
  R1 = 1e3
  R2 = 10e3
  R3 = 1e3
  R4 = 220
  C1 = 0.022e-6
  C2 = 0.022e-6
  P = 22e3
  
  return (0, alpha * C2 * R2 * R3 + alpha * (1-alpha) * C2 * P * R2 + R2 * R4 * C2, R2), (C2 * R4 * C1 * R2 * R1 + (1-alpha) * C2 * R1 * P * C1 * R2, (1-alpha) * C2 * (alpha * P * R2 + R1 * alpha * P + R1 * R2) + R4 * C2 * (R2 + R1) + R1 * C1 * R2, R2 + R1)

b0, a0 = create_coeffs_sd1(0)
b1, a1 = create_coeffs_sd1(1)
b, a = create_coeffs_sd1(0.5)

sd10 = signal.freqs(b0, a0, worN=np.logspace(1, 4.5, 1000))
sd11 = signal.freqs(b1, a1, worN=np.logspace(1, 4.5, 1000))
sd1 = signal.freqs(b, a, worN=np.logspace(1, 4.5, 1000))

fig = plt.figure()
plt.title('Analog filter frequency response (SD1 tone circuit)')
ax1 = fig.add_subplot(111)

plt.loglog(sd10[0], np.abs(sd10[1]), 'b', label="alpha=0")
plt.loglog(sd11[0], np.abs(sd11[1]), 'g', label="alpha=1")
plt.loglog(sd1[0], np.abs(sd1[1]), 'r', label="alpha=0.5")
plt.xlabel("Frequency (Hz)")
plt.ylabel("Amplitude (dB)")
plt.legend()

b0d, a0d = signal.bilinear(b0, a0, 44100)
Exemple #39
0
    def frequencyResponse(self, *args, **kwargs):

        return freqs(*self.butter, *args, **kwargs)[1]
Exemple #40
0
m = loadmat('s5d2nap_justdata.mat')

# In[3]:

matrix = m['s5d2nap']

low = 0.3
high = 30
fs = 1000

lowcut = low / (0.5 * fs)
highcut = high / (0.5 * fs)

#bandpass
b3, a3 = signal.butter(2, [lowcut, highcut], 'band')
w3, h3 = signal.freqs(b3, a3)

new_matrix = []
for index, row in enumerate(matrix):
    new_matrix.append(row[100000:460000])
# print len(new_matrix[0])
eeg = np.array(new_matrix)
# In[7]:

# In[8]:
s = pd.DataFrame(new_matrix).transpose()
# print s
# plt.subplot(8,8)
fig1 = plt.figure()
fig2 = plt.figure()
fig3 = plt.figure()
from scipy.signal import butter, lfilter, freqs
import numpy as np
import FeatureExtractorUtils as fe
import scipy

data = pd.read_csv('../METAWEAR_cap_sensor_accel.csv')
data = data.iloc[:,0:4]
data = data.values

dataTime = data[:, 0]
dataX, dataY, dataZ = data[:,1], data[:,2], data[:,3]

plt.figure(1)
plt.clf()   
b, a = butter(3, 0.3, 'low' , analog = 'True')
w, h = freqs(b, a, worN=2000)
plt.plot((100 * 0.5 / np.pi) * w, abs(h), label="order = %d" % 3)

plt.figure(2)
plt.clf()
#plt.plot(dataTime[20000:30000], dataY[20000:30000], label = 'Noisy signal')

y = lfilter(b,a, dataY[20000:30000])

#plt.plot(dataTime[20000:30000], y, label = 'Filtered Signal')
#
#b, a = butter(9, 0.3, 'high' , analog = 'True')
#yhigh = lfilter(b,a, dataY[20000:])
#    
#plt.plot(dataTime[20000:], yhigh, label = 'body Signal')
#plt.show()
#---Filter Parameters-----------------------------------------------------------------------#
Rs = R6 + t * Rt
a4 = Rs * C3 * C4 * C5 * C6 * R4 * R7 * R8
a3 = C3 * C5 * C6 * R4 * R7 * R8 + Rs * C4 * C5 * C6 * R7 * R8 + Rs * C3 * C4 * C6 * R4 * R8 + Rs * C3 * C4 * C5 * R4 * R7
a2 = C5 * C6 * R7 * R8 + C3 * C6 * R4 * R8 + Rs * C4 * C6 * R8 + C3 * C5 * R4 * R7 + Rs * C4 * C5 * R7 + Rs * C3 * C4 * R4
a1 = C6 * R8 + C5 * R7 + C3 * R4 + Rs * C4
a0 = 1
b4 = a4
b3 = C3 * C5 * C6 * R4 * R7 * R8 + Rs * C3 * C4 * C6 * R4 * R8 + Rs * C3 * C4 * C5 * R4 * R7 + Rs * C3 * C5 * C6 * R4 * R7 + Rs * C3 * C5 * C6 * R4 * R8
b2 = C3 * C6 * R4 * R8 + C3 * C5 * R4 * R7 + Rs * C3 * C4 * R4 + Rs * C3 * C5 * R4 + Rs * C3 * C6 * R4
b1 = C3 * R4
b0 = 0
B = [b4, b3, b2, b1, b0]
A = [a4, a3, a2, a1, a0]
#---Frequency response of tone control analog circuit---------------------------------------#
w, h = sig.freqs(B, A)
plt.semilogx(w, abs(h))
plt.title('Magnitude response of first stage analog circuit')
plt.ylabel('Magnitude(linear scale)')
plt.xlabel('Frequency(Hz)')
plt.savefig('MagResAnaCir.png')
plt.show()
#---Frequency response of digitized tone control circuit------------------------------------#
targetFreq = 20540
alpha = targetFreq * 2 * np.pi / np.tan(targetFreq * np.pi * T)
B0 = alpha**4 * b4 + alpha**3 * b3 + alpha**2 * b2 + alpha * b1
B1 = -4 * alpha**4 * b4 - 2 * alpha**3 * b3 + 2 * alpha * b1
B2 = 6 * alpha**4 * b4 - 2 * alpha**2 * b2
B3 = -4 * alpha**4 * b4 + 2 * alpha**3 * b3 - 2 * alpha * b1
B4 = alpha**4 * b4 - alpha**3 * b3 + alpha**2 * b2 - alpha * b1
A0 = alpha**4 * a4 + alpha**3 * a3 + alpha**2 * a2 + alpha * a1 + a0
Exemple #43
0
def run():
    fs = 44100.0  # Define frecuencia de muestreo
    lowcut = 3000.0  # define frecuencia corte bajo
    highcut = 5000.0  # define frecuencia de corte alto
    ftype = 'cheby2'  # Aqui se define el tipo de filtro que se usara
    btype = 'highpass'  # Aqui se decide que tipo de bandas se dejaran pasar
    T = 0.5  # Se define la longitud en segundos de la señal de ruido
    nsamples = T * fs  # Obtiene el numero de muestras
    t = np.linspace(0, T, nsamples, endpoint=False)
    x, f = ruido_gen(t)  # Genera señal aleatoria

    analog = False
    orders = [1, 5, 10, 15]
    plt.figure(1)
    plt.clf()
    # Itera para graficar las funciones de filtro segun su orden
    for order in orders:
        b, a = filter(fs,
                      x,
                      lowcut=lowcut,
                      highcut=highcut,
                      order=order,
                      btype=btype,
                      ftype=ftype,
                      graph=True,
                      analog=True)
        w, h = signal.freqs(b, a)
        plt.semilogx(w, 20 * np.log10(np.abs(h)), label="Orden = %d" % order)
    plt.margins(0, 0.1)
    plt.grid(which='both', axis='both')
    plt.xlabel('Frecuencia (Hz)')
    plt.ylabel('Ganancia (dB)')
    plt.grid(True)
    plt.legend(loc='best')

    plt.figure(2)
    plt.clf()
    plt.plot(t, 0 * x - .5)
    plt.plot(t, x - 2.25, label='Señal con ruido')
    n = 100
    yHz = []
    f = np.fft.fftfreq(len(t), 1 / fs)
    # Filtra la señal  aleatoria segun el filtro
    ordn = 0
    for order in orders:
        y = filter(fs,
                   data=x,
                   lowcut=lowcut,
                   highcut=highcut,
                   btype=btype,
                   ftype=ftype,
                   analog=analog)
        yHz.append(
            np.abs(1.0 / len(t) *
                   np.fft.fft(y)))  # obtiene muestra de espectro de cada señal
        label = label_gen(btype, lowcut, highcut, orders, ordn)
        plt.plot(t, y - .5 * n, label=label)
        n = n + 100
        ordn = ordn + 1
    plt.xlabel('Tiempo (segundos)')
    plt.grid(True)
    plt.axis('tight')
    plt.legend(loc='upper left')

    plt.figure(3)
    plt.clf()
    x = np.abs(1.0 / len(t) * np.fft.fft(x))
    plt.plot(f, 0 * x - .5)
    plt.plot(f, x - 1.00, label='Señal con ruido')
    n = 3
    ordn = 0
    for y in yHz:
        label = label_gen(btype, lowcut, highcut, orders, ordn)
        plt.plot(f, y - .5 * n, label=label)
        n = n + 1
        ordn = ordn + 1
    plt.xlabel('Frecuencia (Hz)')
    plt.grid(True)
    plt.axis('tight')
    plt.legend(loc='upper left')
    plt.show()
import numpy as np
import scipy.signal as signal
import matplotlib.pyplot as plt
from matplotlib import style
'''
Can filter any noisy signals
 Input for Lowpass Filter
1. Order of the filter

3. Cutoff Frequency
4. High or low pass filter
5. Digital or Analog
'''

bessel_coeff_y, bessel_coeff_x = signal.bessel(4, 100, 'low', analog=True)

#Frequency Response of the Filter
w, h = signal.freqs(bessel_coeff_y, bessel_coeff_x)

plt.plot(w, 20 * np.log10(abs(h)))
plt.xscale('log')
plt.title('Bessel Filter Frequency Response')
plt.xlabel('Frequency (rad/second')
plt.ylabel('Amplitude (dB)')
plt.margins(0, 0.1)
plt.grid()
plt.axvline(100, color='green')
plt.show()
Exemple #45
0
    def analysis(self, show=False):
        """perform a PDM analysis on each lightcurve"""
        from matplotlib import rcParams
        from functions import sigma_clip, phase
        print 'Analysis'

        fig_width = 18.3/2.54  # width in inches, was 7.48in
        fig_height = 23.3/2.54  # height in inches, was 25.5
        fig_size =  [fig_width,fig_height]
        #set plot attributes
        params = {'backend': 'Agg',
          'axes.labelsize': 12,
          'axes.titlesize': 12,
          'font.size': 12,
          'xtick.labelsize': 12,
          'ytick.labelsize': 12,
          'figure.figsize': fig_size,
          'savefig.dpi' : 300,
          'font.family': 'sans-serif',
          'axes.linewidth' : 0.5,
          'xtick.major.size' : 2,
          'ytick.major.size' : 2,
          }
        rcParams.update(params)

        for starid in self.stars:
            star = NGC2236Star(starid)
            print '%-24s '% starid,
            lc = star.lightcurve()
            meanflux = np.nanmean(lc.flux)
            lc.flux /= meanflux
            lc.flux *= meanflux
            lc.rebin(0.0125)
            lc.interpolate()
            lc.normalize()
            raw_time, raw_flux = (lc.time, lc.flux)
            
            lc.medfilter()
            lc.jmpflt()
            lc.detrend()
            time, flux = (lc.time, lc.flux)
            time -= min(time)
            
            # convert to magnitudes
            mag = -2.512*np.log10(meanflux*flux) + 24
            # remove the mean so we are around 0.0 magnitudes
            mag -= np.mean(mag)
            
            # perform a 3sigma clipping
            time, mag = sigma_clip(time, mag)

            # calculate fourier spectrum with zero padding
            n = len(mag)
            n2 = 8*n
            ft = np.fft.rfft(mag, n2)
            #amp = abs(ft)/n
            power = abs(ft)**2/n
            
            freq = np.fft.fftfreq(n2, d=lc.dt())
            
            
            # apply a bessel filter to eliminate runlength artifacts
            from scipy import signal
            
            b, a = signal.butter(4, 2./max(time), 'high', analog=True)
            _, h = signal.freqs(b, a, worN=freq[1:n])
            filt_pwr = abs(ft[1:n]*h)**2/n

            i = np.argmax(filt_pwr)+1
            maxfreq = freq[i]
            period = 1./maxfreq
            
            from pdm import pdm

            #refine period using pdm
            pdm_periods, pdm_thetas = pdm(time, mag, period/1.5, period*1.5, 0.0125)
            
            i = np.argmin(pdm_thetas)
            period = pdm_periods[i]
            
            print 'P = %5.2f' % period,
            star['period'] = period
            periods = 1./freq[1:n]
            periods = periods[::-1]
            filt_pwr = filt_pwr[::-1]
            
            norm = np.mean(filt_pwr)
            print '%.1f' % (max(filt_pwr)/norm)
            power[1:n] /= norm
            filt_pwr /= norm
            star['amp'] = max(filt_pwr)/norm
            ph_time, ph_mag = phase(time, mag, period)
            num = len(ph_time)/round(max(time)/period)
            rph_mag, _ = signal.resample(ph_mag, num, t = ph_time)
            rph_time =  np.linspace(min(ph_time),max(ph_time),num)
            bv = star['bv']
            if bv is None: bv=-99
            
            plt.subplot(411) ##################################################
            plt.title('%s (%d) B-V=%.2f' % (starid, star['corotid'], bv))
            plt.scatter(raw_time-min(raw_time), raw_flux, edgecolor='none', alpha=0.5, s=3, color='k')
            plt.ylim(min(raw_flux),max(raw_flux))
            plt.xlim(0,max(time))
            
            plt.subplot(412) ##################################################
            plt.plot(time, -mag, 'k')
            plt.ylim(min(-mag),max(-mag))
            plt.xlim(0,max(time))
            
            plt.subplot(413) ##################################################
            plt.plot(1./freq[1:n], power[1:n], 'k')
            plt.plot(1./freq[1:n], filt_pwr, 'g')
            #plt.plot(1./w, 20 * np.log10(abs(h)))
            plt.axvline(period)
            #plt.axhline(np.mean(filt_pwr[1:n]))
            plt.xlim(0.1, max(time))
            
            plt.subplot(414) ##################################################
            plt.plot(rph_time, -rph_mag,color='k')
            plt.plot(rph_time+period, -rph_mag,color='k')
            #plt.plot(phased_time, phased_mag, 'g')
            #plt.plot(phased_time+period, phased_mag, 'g')
            plt.axvline(period, linestyle='--')
            plt.xlabel('P = %.2f' % period)
            plt.xlim(0., period*2)
            
            #plt.grid()

            if show:
                plt.show()
            else:
                plt.savefig(config.plotpath+'%s(%d).pdf' % (starid,star['corotid']))
            plt.close()
Exemple #46
0
#%%
from scipy import signal
import matplotlib.pyplot as plt
import numpy as np
#%%
f1 = 1.1E6
f2 = 0.9e6
w1 = 2 * np.pi * f1
w2 = 2 * np.pi * f2
#%%
B, A = signal.iirfilter(2, [w1, w2],
                        btype='band',
                        analog=True,
                        ftype='butter',
                        output='ba')
w, h = signal.freqs(B, A)
plt.plot(w / 2 / 3.14, 20 * np.log10(abs(h)), color='red', linewidth=2)
plt.xscale('log')
plt.title('Butterworth band pass filter frequency response', fontsize=20)
plt.xlabel('Frequency [Hz]', fontsize=20)
plt.ylabel('Amplitude [dB]', fontsize=20)
plt.margins(0, 0.01)
plt.grid(which='both', axis='both')
plt.yticks(size=20)
plt.xticks(size=20)
plt.axvline(f1, color='green', linewidth=2)  # cutoff frequency
plt.axvline(f2, color='blue', linewidth=2)  # cutoff frequency
plt.show()
print("a=", A)
print("b=", B)
i = 0
Exemple #47
0
b, a = signal.butter(2, 1.0, analog=1)

# 低通->带通的频率变换函数
w1 = 1.0  # 低通带频率
w2 = 2.0  # 高通带频率
dw = w2 - w1  # 通带宽度
w0 = np.sqrt(w1 * w2)  # 通带中心频率

# 产生10**-2到10**2的频率点
w = np.logspace(-2, 2, 1000)

# 使用频率变换公式计算出转换之后的频率
nw = np.imag(w0 / dw * (1j * w / w0 + w0 / (1j * w)))

_, h = signal.freqs(b, a, worN=nw)
h\
    = 20 * np.log10(np.abs(h))

pl.figure(figsize=(8, 5))

pl.subplot(221)
pl.semilogx(w, nw)  # X轴使用log坐标绘图
pl.xlabel(u"变换前圆频率(弧度/秒)")
pl.ylabel(u"变换后圆频率(弧度/秒)")

pl.subplot(222)
pl.plot(h, nw)
pl.xlabel(u"低通滤波器的频率响应(dB)")

pl.subplot(212)
Exemple #48
0
f = 4.7e-6

#%%
b_4 = a**2 * d**2 * b * c * e * f
b_3 = a**2 * d**2 * (b * e + b * f + c * f)
b_2 = a**2 * d**2
b_1 = 0
b_0 = 0

a_3 = a * b * c * d * e * f
a_2 = (b * c * e * f) + (a * c * d * f) - (a * b * d * f) + (a * b * d * e)
a_1 = a * d + b * e + c * f
a_0 = 1

#%%
w, H = signal.freqs([b_4, b_3, b_2, b_1, b_0], [a_3, a_2, a_1, a_0])

plt.figure()
plt.semilogx(w / 2 / np.pi, 20 * np.log10(np.abs(H)))
plt.xlim(20, 30000)
plt.ylim(-100, 50)


#%%
def myBilinear(b, a, fs):
    z = np.zeros(5)  # numerator
    p = np.zeros(5)  # denominator
    c = 2 * fs  # no warping (for now)

    b_0 = b[0] * c**4
    b_1 = b[1] * c**3
Exemple #49
0
def filter_ecog_signal(signalArray, sampFq, filtFqs=[60, 120, 180], filtBandwidths=[4, 4, 4], filtOrder=2, plotSpectrogram=False, plotFilter=False):
    """
    Performs notch filtering of input frequencies (filtFqs with bandwidth filtBandwidths)
    Option to plot spectrogram and filter
    Returns filtered signals
    """

    NyquistFq = float(sampFq/2)
    filtRanges = [[0 for j in range(2)] for i in range(len(filtFqs))]

    for p in range(len(filtRanges)):
        filtRanges[p][0] = (filtFqs[p] - filtBandwidths[p]/2)/NyquistFq
        filtRanges[p][1] = (filtFqs[p] + filtBandwidths[p]/2)/NyquistFq

    signalArrayFiltered = np.zeros_like(signalArray)

    # Check if signalArray is multidimensional, or just corresponds to a single electrode:
    if len(np.shape(signalArray)) > 1:
        nElectrode = 0
        for electrode in signalArray:
            for filtRange in filtRanges:
                if filtRange[1] < 1:
                    filtNume, filtDenom = signal.butter(
                        filtOrder, filtRange, btype='bandstop')
                    electrode = signal.filtfilt(filtNume, filtDenom, electrode)
                    if plotFilter:
                        # Only want to plot filter once in the loop:
                        if nElectrode == 0:
                            w, h = signal.freqs(filtNume, filtDenom, 1000)
                            fig = plt.figure()
                            ax = fig.add_subplot(111)
                            ax.plot(w, 20 * np.log10(abs(h)))
                            ax.set_xscale('log')
                            ax.set_title('Filter frequency response')
                            ax.set_xlabel('Frequency [radians / second]')
                            ax.set_ylabel('Amplitude [dB]')
                            #ax.axis((10, 1000, -100, 10))
                            ax.grid(which='both', axis='both')
                            plt.show()
            if plotSpectrogram:
                fig = plt.figure()
                plt.specgram(electrode, NFFT=512, Fs=sampFq)
                plt.title('Filtered spectrogram for electrode '+str(nElectrode))
                plt.xlabel('Time [sec]')
                plt.ylabel('Frequency [Hz]')
#                plt.xlim(0, (header['edfInfo']['nRecords']-2))
                plt.ylim(0, sampFq/2.)
                cbar = plt.colorbar()
                cbar.set_label('Power spectral density [W/Hz]')
                plt.show()
            signalArrayFiltered[nElectrode] = electrode
            nElectrode = nElectrode+1
    # if signalArray is one dimensional vector (single electrode)
    elif len(np.shape(signalArray)) == 1:
        nElectrode = 0
        electrode = signalArray
        for filtRange in filtRanges:
            if filtRange[1] < 1:
                filtNume, filtDenom = signal.butter(
                    filtOrder, filtRange, btype='bandstop')
                electrode = signal.filtfilt(filtNume, filtDenom, electrode)
                if plotFilter:
                    w, h = signal.freqs(filtNume, filtDenom, 1000)
                    fig = plt.figure()
                    ax = fig.add_subplot(111)
                    ax.plot(w, 20 * np.log10(abs(h)))
                    ax.set_xscale('log')
                    ax.set_title('Filter frequency response')
                    ax.set_xlabel('Frequency [radians / second]')
                    ax.set_ylabel('Amplitude [dB]')
                    #ax.axis((10, 1000, -100, 10))
                    ax.grid(which='both', axis='both')
                    plt.show()
        if plotSpectrogram:
            fig = plt.figure()
            plt.specgram(electrode, NFFT=512, Fs=sampFq)
            plt.title('Filtered spectrogram for electrode '+str(nElectrode))
            plt.xlabel('Time [sec]')
            plt.ylabel('Frequency [Hz]')
#            plt.xlim(0, (header['edfInfo']['nRecords']-2))
            plt.ylim(0, sampFq/2.)
            cbar = plt.colorbar()
            cbar.set_label('Power spectral density [W/Hz]')
            plt.show()
        signalArrayFiltered = electrode

    return signalArrayFiltered
# w is the maximum frequency which is f2 which is 5.
# dx <= 1/10 <-> dx > 10 Hz
# all sampling frequencies lower (and inclusive) than 10 Hz lead to aliasing.


# ------------------------------
# ex2.3
# sc.signal.butter()
# generate Butterworth low-pass filter coefficients:
# select an appropriate cutoff frequency
# work on the 10 Hz example


b, a = sig.butter(4, 100, 'low', analog=True)
plt.plot(b, a)
w, h = sig.freqs(b, a)
plt.plot(w, 20 * np.log10(abs(h)))

# check out the sample functions and forum!
down_freq = 10
indices = np.arange(0, down_freq * 10, 1) * (10000 // (down_freq * 10))
indices.shape[0] == down_freq * 10
# power spectrum values
t_down_sampled = scfft.fft(samples[indices])
t_down_sampled = np.sqrt(np.power(t_down_sampled.imag, 2) + np.power(t_down_sampled.real, 2))
t_freqs = np.linspace(0, down_freq, 10*down_freq, endpoint=False)
# plot both spaces
plt.subplot(1, 2, 1)
plt.plot(fs, samples)
plt.plot(fs[indices], samples[indices], 'ro')
plt.plot(fs[indices], samples[indices])
Exemple #51
0
def make_ctle(rx_bw, peak_freq, peak_mag, w, mode='Passive', dc_offset=0):
    """
    Generate the frequency response of a continuous time linear
    equalizer (CTLE), given the:

    - signal path bandwidth,
    - peaking specification
    - list of frequencies of interest, and
    - operational mode/offset.

    We use the 'invres()' function from scipy.signal, as it suggests
    itself as a natural approach, given our chosen use model of having
    the user provide the peaking frequency and degree of peaking.

    That is, we define our desired frequency response using one zero
    and two poles, where:

    - The pole locations are equal to:
       - the signal path natural bandwidth, and
       - the user specified peaking frequency.

    - The zero location is chosen, so as to provide the desired degree
      of peaking.

    Inputs:

      - rx_bw        The natural (or, unequalized) signal path bandwidth (Hz).

      - peak_freq    The location of the desired peak in the frequency
                     response (Hz).

      - peak_mag     The desired relative magnitude of the peak (dB). (mag(H(0)) = 1)

      - w            The list of frequencies of interest (rads./s).

      - mode         The operational mode; must be one of:
                       - 'Off'    : CTLE is disengaged.
                       - 'Passive': Maximum frequency response has magnitude one.
                       - 'AGC'    : Automatic gain control. (Handled by calling routine.)
                       - 'Manual' : D.C. offset is set manually.

      - dc_offset    The d.c. offset of the CTLE gain curve (dB).
                     (Only valid, when 'mode' = 'Manual'.)

    Outputs:

      - w, H         The resultant complex frequency response, at the
                     given frequencies.

    """

    if (mode == 'Off'):
        return (w, ones(len(w)))

    p2 = -2. * pi * rx_bw
    p1 = -2. * pi * peak_freq
    z = p1 / pow(10., peak_mag / 20.)
    if (p2 != p1):
        r1 = (z - p1) / (p2 - p1)
        r2 = 1 - r1
    else:
        r1 = -1.
        r2 = z - p1
    b, a = invres([r1, r2], [p1, p2], [])
    w, H = freqs(b, a, w)

    if (mode == 'Passive'):
        H /= max(abs(H))
    elif (mode == 'Manual' or mode == 'AGC'):
        H *= pow(10., dc_offset / 20.) / abs(H[0])  # Enforce d.c. offset.
    else:
        raise RunTimeException(
            "pybert_util.make_ctle(): Unrecognized value for 'mode' parameter: {}."
            .format(mode))

    return (w, H)
from scipy import signal
import matplotlib.pyplot as plt
import numpy as np

# References : Scipy.org, buttord.html

#An analog bandpass filter with passband within 3 dB from 20 to 50 rad/s, while rejecting at least -40 dB below 14 and above 60 rad/s.

# Expt1 : Run the program as is and observe the output

# Expt2 : Comment line 15 and uncomment line 16, to visualise bandstop filter

N, Wn = signal.buttord([20, 50], [14, 60], 3, 40, True)
#b, a = signal.butter(N, Wn, 'band', True) # Bandpass cfg
b, a = signal.butter(N, Wn, 'stop', True)  # Bandstop cfg
w, h = signal.freqs(b, a, np.logspace(1, 2, 500))
plt.semilogx(w, 20 * np.log10(abs(h)))
plt.title('Butterworth bandpass filter')
plt.xlabel('Frequency [radians / second]')
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.fill([1, 14, 14, 1], [-40, -40, 99, 99], '0.9', lw=0)  # stop
plt.fill([20, 20, 50, 50], [-99, -3, -3, -99], '0.9', lw=0)  # pass
plt.fill([60, 60, 1e9, 1e9], [99, -40, -40, 99], '0.9', lw=0)  # stop
plt.axis([10, 100, -60, 3])
plt.show()
Exemple #53
0
import matplotlib.pyplot as plt
import numpy as np

N = 5
ftype_name = 'butter'
db = False
freq = np.array([[1 / 30, 1 / 20], [1 / 20, 1 / 10], [1 / 10, 1 / 5],
                 [1 / 5, 1 / 2], [1 / 2, 1]])

fig = plt.figure()
ax = fig.add_subplot(111)

for f in freq:
    b, a = signal.iirfilter(N, (2 * np.pi) * f,
                            btype='bandpass',
                            analog=True,
                            ftype=ftype_name)
    w, h = signal.freqs(b, a, 1000)
    w = (2 * np.pi) / w
    tips = str(1 / f[0]) + 's - ' + str(1 / f[1]) + 's'
    if db == True: ax.semilogx(w, 20 * np.log10(abs(h)), label=tips)
    elif db == False: ax.semilogx(w, abs(h), label=tips)

ax.set_title(ftype_name + ' Order ' + str(N) + ' bandpass frequency response')
ax.set_xlabel('Periods [s]')
ax.set_ylabel('Amplitude')
ax.axis((0.1, 100, 0, 1.5))
ax.grid(which='both', axis='both')
ax.legend(shadow=True, fontsize=8, fancybox=True, framealpha=0.5)
plt.show()
def test_ITU_R_468_weight(fs=None):
    """
    Test that frequency response meets tolerance from Rec. ITU-R BS.468-4
    """
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.signal import freqz

    frequencies = np.array(
        (31.5, 63, 100, 200, 400, 800, 1000, 2000, 3150, 4000, 5000, 6300,
         7100, 8000, 9000, 10000, 12500, 14000, 16000, 20000, 31500))

    responses = np.array(
        (-29.9, -23.9, -19.8, -13.8, -7.8, -1.9, 0, +5.6, +9.0, +10.5, +11.7,
         +12.2, +12.0, +11.4, +10.1, +8.1, 0, -5.3, -11.7, -22.2, -42.7))

    upper_limits = np.array((
        +2.0,
        +1.4,
        +1.0,
        +0.85,
        +0.7,
        +0.55,
        +0.5,
        +0.5,
        +0.5,
        +0.5,
        +0.5,
        +0.01,  # Actually 0 tolerance, but specified as "+12.2" dB
        +0.2,
        +0.4,
        +0.6,
        +0.8,
        +1.2,
        +1.4,
        +1.6,
        +2.0,
        +2.8))

    lower_limits = np.array((
        -2.0,
        -1.4,
        -1.0,
        -0.85,
        -0.7,
        -0.55,
        -0.5,
        -0.5,
        -0.5,
        -0.5,
        -0.5,
        -0.01,  # Actually 0 tolerance, but specified as "+12.2" dB
        -0.2,
        -0.4,
        -0.6,
        -0.8,
        -1.2,
        -1.4,
        -1.6,
        -2.0,
        -float('inf')))

    if fs is None:
        z, p, k = ITU_R_468_weighting_analog()
        b, a = zpk2tf(z, p, k)
        w, h = freqs(b, a, 2 * pi * frequencies)
    else:
        # Passes if fs >= 180000 Hz but not at typical audio fs
        b, a = ITU_R_468_weighting(fs)
        w = 2 * pi * frequencies / fs
        w, h = freqz(b, a, w)

    levels = 20 * np.log10(abs(h))

    plt.semilogx(frequencies, levels)
    plt.semilogx(frequencies, responses + upper_limits, 'r--')
    plt.semilogx(frequencies, responses + lower_limits, 'r--')

    assert all(np.less_equal(levels, responses + upper_limits))
    assert all(np.greater_equal(levels, responses + lower_limits))
Exemple #55
0
    K = 3.0 - 1 / Q  # ganho por estagio
    R = 1 / (Wc * C)
    R4 = R3 * (K - 1)
    Av = K * Av  # ganho total

    print(f'Estagio {N+1}')
    print(f'R = {R}')
    print(f'R3 = {R3}')
    print(f'R4 = {R4}')
    print(f'C2 = {C}')
    print(f'Wc = {Wc}')
    print(f'Q = {Q}')
    print(f'K = {K}')
    print(f'Funcao de trasferencia = {a}\n\n')

RF = RB / Av  # resistor para normalização do ganho
print(f'RF = {RF}')
print(f'Ganho total = {Av}')
print(f'Equação geral = {k,transfer_func}')

w, h = signal.freqs([k], transfer_func)
plt.semilogx(w / (2 * np.pi), 20 * np.log10(abs(h)), label=f'Ordem = {ordem}')
plt.title('Respsosta em frequencia do filtro Chebyshev')
plt.xlabel('Frequencia [Hz]')
plt.ylabel('Amplitude [dB]')
plt.margins(0, 0.1)
plt.grid(which='both', axis='both')
plt.axvline(Fn, color='green')  # cutoff frequency
plt.legend(loc='upper right')
plt.show()
def bessel_analog(f, fcut, order=2):
    b, a = bessel(order, 2 * np.pi * fcut, analog=True)
    return freqs(b, a, 2 * np.pi * f)[1]
Exemple #57
0
def bode_plot(B, A, b, a, fs, N, fig=None):
    """Realize a bode plot containing magnitude, phase and zplane.

    input:
    B...numerator coefficients Laplace transfer function
    A...denominator coefficients Laplace transfer function
    b...numerator coefficients z-transfer function
    a...denominator coefficients z-transfer function
    fs...sampling frequency in Hz
    output:
    bode plot as new figure
    """
    if fig is None:
        fig = plt.figure()
    p = np.roots(a)
    z = np.roots(b)
    W, Hd = signal.freqz(b, a, N)
    s, Ha = signal.freqs(B, A, fs * W)
    if Hd[0] == 0:
        Hd[0] = 1e-15  # avoid zero at DC for plotting dB
    if Ha[0] == 0:
        Ha[0] = 1e-15
    f = fs * W / (2 * np.pi)

    gs = fig.add_gridspec(2, 2)
    # magnitude
    ax1 = fig.add_subplot(gs[0, 0])
    ax1.plot(f,
             20 * np.log10(np.abs(Ha)),
             "C0",
             label=r'$|H(\omega)|$ continuous-time',
             linewidth=3)
    ax1.plot(f,
             20 * np.log10(np.abs(Hd)),
             "C1",
             label=(r'$|H(\Omega)|$ discrete-time, fs=%5.f Hz' % fs),
             linewidth=2)
    ax1.set_xscale("log")
    ax1.set_yscale("linear")
    ax1.set_xlabel(r'$f$ / Hz', color="xkcd:navy blue")
    ax1.set_ylabel(r'$A$ / dB', color="xkcd:navy blue")
    ax1.set_title("Bode plot: magnitude", color="xkcd:navy blue")
    ax1.set_xlim(20, 20000)
    ax1.set_xticks((20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000))
    ax1.set_xticklabels(
        ["20", "50", "100", "200", "500", "1k", "2k", "5k", "10k", "20k"],
        color="xkcd:navy blue")
    ax1.set_ylim(-15, 15)
    ax1.set_yticks(np.arange(-15, 15 + 3, 3))
    ax1.set_yticklabels(
        ["-15", "-12", "-9", "-6", "-3", "0", "3", "6", "9", "12", "15"],
        color="xkcd:navy blue")
    ax1.legend(loc="best")
    ax1.grid(True,
             which="both",
             axis="both",
             linestyle="-",
             linewidth=0.5,
             color=(0.8, 0.8, 0.8))

    # phase
    ax2 = fig.add_subplot(gs[1, 0])
    ax2.plot(f, (np.angle(Ha) * 180 / np.pi),
             "C0",
             label=r'$\mathrm{angle}(H('
             r'\omega))$ continuous-time',
             linewidth=3)
    ax2.plot(f, (np.angle(Hd) * 180 / np.pi),
             'C1',
             label=(r'$\mathrm{angle}(H(\Omega))$ discrete-time, '
                    'fs=%5.f Hz' % fs),
             linewidth=2)
    ax2.set_xscale("log")
    ax2.set_yscale("linear")
    ax2.set_xlabel(r'$f$ / Hz', color="xkcd:navy blue")
    ax2.set_ylabel(r'$\phi$ / deg', color="xkcd:navy blue")
    ax2.set_title("Bode plot: phase", color="xkcd:navy blue")
    ax2.set_xlim(20, 20000)
    ax2.set_xticks((20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000))
    ax2.set_xticklabels(
        ["20", "50", "100", "200", "500", "1k", "2k", "5k", "10k", "20k"],
        color="xkcd:navy blue")
    ax2.set_ylim(-180, +180)
    ax2.set_yticks(np.arange(-180, 180 + 45, 45))
    ax2.set_yticklabels(
        ["-180", "-135", "-90", "-45", "0", "45", "90", "135", "180"],
        color="xkcd:navy blue")
    ax2.legend(loc="best")
    ax2.grid(True,
             which="both",
             axis="both",
             linestyle="-",
             linewidth=0.5,
             color=(0.8, 0.8, 0.8))

    # zplane
    ax3 = fig.add_subplot(gs[:, 1])
    zplane_plot(ax3, z, p)

    print("B =", B)
    print("A =", A)
    print("b =", b)
    print("a =", a)
Exemple #58
0
    def filter(self, *filt, **kwargs):
        """Apply the given filter to this `Spectrum`.

        Recognised filter arguments are converted into the standard
        ``(numerator, denominator)`` representation before being applied
        to this `Spectrum`.

        .. note::

           Unlike the related
           :meth:`TimeSeries.filter <gwpy.timeseries.TimeSeries.filter>`
           method, here all frequency information (e.g. frequencies of
           poles or zeros in a ZPK) is assumed to be in Hertz.

        Parameters
        ----------
        *filt
            one of:

            - :class:`scipy.signal.lti`
            - ``(numerator, denominator)`` polynomials
            - ``(zeros, poles, gain)``
            - ``(A, B, C, D)`` 'state-space' representation

        Returns
        -------
        result : `Spectrum`
            the filtered version of the input `Spectrum`

        See also
        --------
        Spectrum.zpk
            for information on filtering in zero-pole-gain format
        scipy.signal.zpk2tf
            for details on converting ``(zeros, poles, gain)`` into
            transfer function format
        scipy.signal.ss2tf
            for details on converting ``(A, B, C, D)`` to transfer function
            format
        scipy.signal.freqs
            for details on the filtering calculation

        Raises
        ------
        ValueError
            If ``filt`` arguments cannot be interpreted properly
        """
        # parse filter
        if len(filt) == 1 and isinstance(filt[0], signal.lti):
            filt = filt[0]
            a = filt.den
            b = filt.num
        elif len(filt) == 2:
            b, a = filt
        elif len(filt) == 3:
            b, a = signal.zpk2tf(*filt)
        elif len(filt) == 4:
            b, a = signal.ss2tf(*filt)
        else:
            raise ValueError("Cannot interpret filter arguments. Please give "
                             "either a signal.lti object, or a tuple in zpk "
                             "or ba format. See scipy.signal docs for "
                             "details.")
        # parse keyword args
        inplace = kwargs.pop('inplace', False)
        if kwargs:
            raise TypeError("Spectrum.filter() got an unexpected keyword "
                            "argument '%s'" % list(kwargs.keys())[0])
        fresp = abs(signal.freqs(b, a, self.frequencies.value)[1])
        if inplace:
            self.value *= fresp
            return self
        else:
            new = (self.value * fresp).view(type(self))
            new.__dict__ = deepcopy(self.__dict__)
            return new
Exemple #59
0
# -*- coding: utf-8 -*-
from scipy import signal
import pylab as pl
from numpy import *

fs = 8000.0  # 取样频率
fc = 1000.0  # 通带频率

# 频率为2kHz的3阶低通滤波器
b, a = signal.butter(3, 2 * pi * fc, analog=1)

w, h = signal.freqs(b, a, worN=10000)
p = 20 * log10(abs(h))

# 转换为取样频率为8kHz的数字滤波器
b2, a2 = signal.bilinear(b, a, fs=fs)

# 计算数字滤波器的频率响应
w2, h2 = signal.freqz(b2, a2, worN=10000)

# 计算增益特性
p2 = 20 * log10(abs(h2))

# 找到增益为-3dB[精确值为: 10*log10(0.5)]的下标
idx = argmin(abs(p2 - 10 * log10(0.5)))

# 输出增益为-3dB时的频率
print((w2[idx] / 2 / pi * 8000))

# 输出公式 w = 2/T*arctan(wa*T/2) 计算的频率
print((2 * fs * arctan(2 * pi * fc / 2 / fs) / 2 / pi))
Exemple #60
0
# shelving filter
N = 4
f_cutoff = 1000
w_cutoff = 2 * np.pi * f_cutoff
Gd = -12
z, p, k = higher_order_shelving_holters(Gd, N, wc=w_cutoff, normalize=True)
b, a = zpk2tf(z, p, k)

# frequency response
fmin, fmax, num_f = 20, 22000, 2000
f = np.logspace(np.log10(fmin), np.log10(fmax), num=num_f, endpoint=True)
w = 2 * np.pi * f
_, H_zpk = freqs_zpk(z, p, k, worN=w)
_, gd_zpk = zpk_group_delays(z, p, k, w=w)
_, H_tf = freqs(b, a, worN=w)
_, gd_tf = group_delays(b, a, w=w)
gd_zorp = 0  # adding up group delays of individual zeros and poles
for z_i in z:
    gd_zorp += zorp_group_delays(z_i, w=w)[1]
for p_i in p:
    gd_zorp -= zorp_group_delays(p_i, w=w)[1]


# plots
kw_zpk = dict(color='lightgray', lw=5, ls='-', alpha=1, label='zpk')
kw_tf = dict(color='C0', lw=2, ls='-', alpha=0.85, label='tf')
kw_zorp = dict(color='k', lw=2, ls=':', alpha=0.85, label='zorp')
flim = fmin, fmax
fig, ax = plt.subplots(figsize=(12, 3), ncols=3, sharex=False,
                       gridspec_kw=dict(wspace=0.4))