Ejemplo n.º 1
0
def test_kaiser_beta():
    b = kaiser_beta(58.7)
    assert_almost_equal(b, 0.1102 * 50.0)
    b = kaiser_beta(22.0)
    assert_almost_equal(b, 0.5842 + 0.07886)
    b = kaiser_beta(21.0)
    assert_equal(b, 0.0)
    b = kaiser_beta(10.0)
    assert_equal(b, 0.0)
Ejemplo n.º 2
0
def test_kaiser_beta():
    b = kaiser_beta(58.7)
    assert_almost_equal(b, 0.1102 * 50.0)
    b = kaiser_beta(22.0)
    assert_almost_equal(b, 0.5842 + 0.07886)
    b = kaiser_beta(21.0)
    assert_equal(b, 0.0)
    b = kaiser_beta(10.0)
    assert_equal(b, 0.0)
Ejemplo n.º 3
0
def firwin_kaiser_lpf(f_pass, f_stop, d_stop, fs = 1.0, N_bump=0):
    """
    Design an FIR lowpass filter using the sinc() kernel and
    a Kaiser window. The filter order is determined based on 
    f_pass Hz, f_stop Hz, and the desired stopband attenuation
    d_stop in dB, all relative to a sampling rate of fs Hz.
    Note: the passband ripple cannot be set independent of the
    stopband attenuation.

    Mark Wickert October 2016
    """
    wc = 2*np.pi*(f_pass + f_stop)/2/fs
    delta_w = 2*np.pi*(f_stop - f_pass)/fs
    # Find the filter order
    M = np.ceil((d_stop - 8)/(2.285*delta_w))
    # Adjust filter order up or down as needed
    M += N_bump
    N_taps = M + 1
    # Obtain the Kaiser window
    beta = signal.kaiser_beta(d_stop)
    w_k = signal.kaiser(N_taps,beta)
    n = np.arange(N_taps)
    b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k
    b_k /= np.sum(b_k)
    print('Kaiser Win filter taps = %d.' % N_taps)
    return b_k
Ejemplo n.º 4
0
def firwin_kaiser_hpf(f_stop, f_pass, d_stop, fs = 1.0, N_bump=0, status = True):
    """
    Design an FIR highpass filter using the sinc() kernel and
    a Kaiser window. The filter order is determined based on 
    f_pass Hz, f_stop Hz, and the desired stopband attenuation
    d_stop in dB, all relative to a sampling rate of fs Hz.
    Note: the passband ripple cannot be set independent of the
    stopband attenuation.

    Mark Wickert October 2016
    """
    # Transform HPF critical frequencies to lowpass equivalent
    f_pass_eq = fs/2. - f_pass
    f_stop_eq = fs/2. - f_stop
    # Design LPF equivalent
    wc = 2*np.pi*(f_pass_eq + f_stop_eq)/2/fs
    delta_w = 2*np.pi*(f_stop_eq - f_pass_eq)/fs
    # Find the filter order
    M = np.ceil((d_stop - 8)/(2.285*delta_w))
    # Adjust filter order up or down as needed
    M += N_bump
    N_taps = M + 1
    # Obtain the Kaiser window
    beta = signal.kaiser_beta(d_stop)
    w_k = signal.kaiser(N_taps,beta)
    n = np.arange(N_taps)
    b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k
    b_k /= np.sum(b_k)
    # Transform LPF equivalent to HPF
    n = np.arange(len(b_k))
    b_k *= (-1)**n
    if status:
        log.info('Kaiser Win filter taps = %d.' % N_taps)
    return b_k
Ejemplo n.º 5
0
def bandpass_kaiser(ntaps, lowcut, highcut, fs, width):
    nyq = 0.5 * fs
    atten = kaiser_atten(ntaps, width / nyq)
    beta = kaiser_beta(atten)
    taps = firwin(ntaps, [lowcut, highcut], nyq=nyq, pass_zero=False,
                  window=('kaiser', beta), scale=False)
    return taps
Ejemplo n.º 6
0
def firwin_kaiser_lpf(f_pass, f_stop, d_stop, fs = 1.0, N_bump=0, status = True):
    """
    Design an FIR lowpass filter using the sinc() kernel and
    a Kaiser window. The filter order is determined based on 
    f_pass Hz, f_stop Hz, and the desired stopband attenuation
    d_stop in dB, all relative to a sampling rate of fs Hz.
    Note: the passband ripple cannot be set independent of the
    stopband attenuation.

    Mark Wickert October 2016
    """
    wc = 2*np.pi*(f_pass + f_stop)/2/fs
    delta_w = 2*np.pi*(f_stop - f_pass)/fs
    # Find the filter order
    M = np.ceil((d_stop - 8)/(2.285*delta_w))
    # Adjust filter order up or down as needed
    M += N_bump
    N_taps = M + 1
    # Obtain the Kaiser window
    beta = signal.kaiser_beta(d_stop)
    w_k = signal.kaiser(N_taps,beta)
    n = np.arange(N_taps)
    b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k
    b_k /= np.sum(b_k)
    if status:
        log.info('Kaiser Win filter taps = %d.' % N_taps)
    return b_k
def resample(s, p, q, h=None):
    """Change sampling rate by rational factor. This implementation is based on
    the Octave implementation of the resample function. It designs the 
    anti-aliasing filter using the window approach applying a Kaiser window with
    the beta term calculated as specified by [2].
    
    Ref [1] J. G. Proakis and D. G. Manolakis,
    Digital Signal Processing: Principles, Algorithms, and Applications,
    4th ed., Prentice Hall, 2007. Chap. 6
    Ref [2] A. V. Oppenheim, R. W. Schafer and J. R. Buck, 
    Discrete-time signal processing, Signal processing series,
    Prentice-Hall, 1999
    """
    gcd = fractions.gcd(p,q)
    if gcd>1:
        p=p/gcd
        q=q/gcd
    
    if h is None: #design filter
        #properties of the antialiasing filter
        log10_rejection = -3.0
        stopband_cutoff_f = 1.0/(2.0 * max(p,q))
        roll_off_width = stopband_cutoff_f / 10.0
    
        #determine filter length
        #use empirical formula from [2] Chap 7, Eq. (7.63) p 476
        rejection_db = -20.0*log10_rejection;
        l = numpy.ceil((rejection_db-8.0) / (28.714 * roll_off_width))
  
        #ideal sinc filter
        t = numpy.arange(-l, l + 1)
        ideal_filter=2*p*stopband_cutoff_f*numpy.sinc(2*stopband_cutoff_f*t)  
  
        #determine parameter of Kaiser window
        #use empirical formula from [2] Chap 7, Eq. (7.62) p 474
        beta = signal.kaiser_beta(rejection_db)
          
        #apodize ideal filter response
        h = numpy.kaiser(2*l+1, beta)*ideal_filter

    ls = len(s)
    lh = len(h)

    l = (lh - 1)/2.0
    ly = numpy.ceil(ls*p/float(q))

    #pre and postpad filter response
    nz_pre = numpy.floor(q - numpy.mod(l,q))
    hpad = h[-lh+nz_pre:]

    offset = numpy.floor((l+nz_pre)/q)
    nz_post = 0;
    while numpy.ceil(((ls-1)*p + nz_pre + lh + nz_post )/q ) - offset < ly:
        nz_post += 1
    hpad = hpad[:lh + nz_pre + nz_post]

    #filtering
    xfilt = upfirdn(s, hpad, p, q)

    return xfilt[offset-1:offset-1+ly]
Ejemplo n.º 8
0
def bandpass_kaiser(ntaps, lowcut, highcut, fs, width):
    nyq = 0.5 * fs
    atten = kaiser_atten(ntaps, width / nyq)
    beta = kaiser_beta(atten)
    taps = firwin(ntaps, [lowcut, highcut], nyq=nyq, pass_zero=False,
                  window=('kaiser', beta), scale=False)
    return taps
Ejemplo n.º 9
0
def firwin_kaiser_hpf(f_stop, f_pass, d_stop, fs = 1.0, N_bump=0):
    """
    Design an FIR highpass filter using the sinc() kernel and
    a Kaiser window. The filter order is determined based on 
    f_pass Hz, f_stop Hz, and the desired stopband attenuation
    d_stop in dB, all relative to a sampling rate of fs Hz.
    Note: the passband ripple cannot be set independent of the
    stopband attenuation.

    Mark Wickert October 2016
    """
    # Transform HPF critical frequencies to lowpass equivalent
    f_pass_eq = fs/2. - f_pass
    f_stop_eq = fs/2. - f_stop
    # Design LPF equivalent
    wc = 2*np.pi*(f_pass_eq + f_stop_eq)/2/fs
    delta_w = 2*np.pi*(f_stop_eq - f_pass_eq)/fs
    # Find the filter order
    M = np.ceil((d_stop - 8)/(2.285*delta_w))
    # Adjust filter order up or down as needed
    M += N_bump
    N_taps = M + 1
    # Obtain the Kaiser window
    beta = signal.kaiser_beta(d_stop)
    w_k = signal.kaiser(N_taps,beta)
    n = np.arange(N_taps)
    b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k
    b_k /= np.sum(b_k)
    # Transform LPF equivalent to HPF
    n = np.arange(len(b_k))
    b_k *= (-1)**n
    print('Kaiser Win filter taps = %d.' % N_taps)
    return b_k
Ejemplo n.º 10
0
def lpf(sample_rate, x, cutoff_hz=500.0, attenuation=25):

    nyq_rate = sample_rate / 2.0
    attenuation = attenuation
    N = 100
    beta = kaiser_beta(attenuation)
    cutoff_hz = cutoff_hz
    taps = firwin(N, cutoff_hz / nyq_rate, window=('kaiser', beta))
    filtered_x = lfilter(taps, [1.0, 0], x)
    return filtered_x
Ejemplo n.º 11
0
 def bandpass_kaiser(self, channel,freqs=(1, 15)):
     ntaps = 16
     nyq = 0.5 * self.rate
     width = 1.6
     atten = signal.kaiser_atten(ntaps, width / nyq)
     beta = signal.kaiser_beta(atten)
     taps = signal.firwin(ntaps, [freqs[0], freqs[1]], nyq=nyq, pass_zero=False,
                   window=('kaiser', beta), scale=False)
     newsig = signal.filtfilt(taps_kaiser16, 1.0, self.single_sweep_data[channel], padlen=500)
     return newsig
Ejemplo n.º 12
0
def firwin_kaiser_bsf(f_stop1,
                      f_pass1,
                      f_pass2,
                      f_stop2,
                      d_stop,
                      fs=1.0,
                      n_bump=0,
                      status=True):
    """
    Design an FIR bandstop filter using the sinc() kernel and
    a Kaiser window. The filter order is determined based on 
    f_stop1 Hz, f_pass1 Hz, f_pass2 Hz, f_stop2 Hz, and the 
    desired stopband attenuation d_stop in dB for both stopbands,
    all relative to a sampling rate of fs Hz.
    Note: The passband ripple cannot be set independent of the
    stopband attenuation.
    Note: The filter order is forced to be even (odd number of taps)
    so there is a center tap that can be used to form 1 - H_BPF.

    Mark Wickert October 2016    
    """
    # First design a BPF starting from simple LPF equivalent
    # The upper and lower stopbands are assumed to have
    # the same attenuation level. The LPF equivalent critical
    # frequencies:
    f_pass = (f_pass2 - f_pass1) / 2
    f_stop = (f_stop2 - f_stop1) / 2
    # Continue to design equivalent LPF
    wc = 2 * np.pi * (f_pass + f_stop) / 2 / fs
    delta_w = 2 * np.pi * (f_stop - f_pass) / fs
    # Find the filter order
    M = np.ceil((d_stop - 8) / (2.285 * delta_w))
    # Adjust filter order up or down as needed
    M += n_bump
    # Make filter order even (odd number of taps)
    if ((M + 1) / 2.0 - int((M + 1) / 2.0)) == 0:
        M += 1
    N_taps = M + 1
    # Obtain the Kaiser window
    beta = signal.kaiser_beta(d_stop)
    w_k = signal.kaiser(N_taps, beta)
    n = np.arange(N_taps)
    b_k = wc / np.pi * np.sinc(wc / np.pi * (n - M / 2)) * w_k
    b_k /= np.sum(b_k)
    # Transform LPF to BPF
    f0 = (f_pass2 + f_pass1) / 2
    w0 = 2 * np.pi * f0 / fs
    n = np.arange(len(b_k))
    b_k_bs = 2 * b_k * np.cos(w0 * (n - M / 2))
    # Transform BPF to BSF via 1 - BPF for odd N_taps
    b_k_bs = -b_k_bs
    b_k_bs[int(M / 2)] += 1
    if status:
        log.info('Kaiser Win filter taps = %d.' % N_taps)
    return b_k_bs
Ejemplo n.º 13
0
def bandpass_kaiser(ntaps, lowcut, highcut, fs, width):
    nyq = 0.5 * fs
    atten = kaiser_atten(ntaps, width / nyq)
    beta = kaiser_beta(atten)
    taps = firwin(
        ntaps,
        [lowcut, highcut],
        nyq=nyq,
        pass_zero="bandpass",
        window=("kaiser", beta),
        scale=True,
    )
    return taps
Ejemplo n.º 14
0
def resample(s, p, q, h=None):

    gcd = fractions.gcd(p, q)
    if gcd > 1:
        p = p / gcd
        q = q / gcd

    if h is None:  #design filter
        #properties of the antialiasing filter
        log10_rejection = -3.0
        stopband_cutoff_f = 1.0 / (2.0 * max(p, q))
        roll_off_width = stopband_cutoff_f / 10.0

        #determine filter length
        #use empirical formula from [2] Chap 7, Eq. (7.63) p 476
        rejection_db = -20.0 * log10_rejection
        l = numpy.ceil((rejection_db - 8.0) / (28.714 * roll_off_width))

        #ideal sinc filter
        t = numpy.arange(-l, l + 1)
        ideal_filter = 2 * p * stopband_cutoff_f * numpy.sinc(
            2 * stopband_cutoff_f * t)

        #determine parameter of Kaiser window
        #use empirical formula from [2] Chap 7, Eq. (7.62) p 474
        beta = signal.kaiser_beta(rejection_db)

        #apodize ideal filter response
        h = numpy.kaiser(2 * l + 1, beta) * ideal_filter

    ls = len(s)
    lh = len(h)

    l = (lh - 1) / 2.0
    ly = numpy.ceil(ls * p / float(q))

    #pre and postpad filter response
    nz_pre = numpy.floor(q - numpy.mod(l, q))
    hpad = h[int(-lh + nz_pre):]
    offset = numpy.floor((l + nz_pre) / q)
    nz_post = 0
    while numpy.ceil(((ls - 1) * p + nz_pre + lh + nz_post) / q) - offset < ly:
        nz_post += 1
    hpad = hpad[:int(lh + nz_pre + nz_post)]

    #filtering
    xfilt = upfirdn(s, hpad, p, q)

    return xfilt[int(offset - 1):int(offset - 1 + ly)]
Ejemplo n.º 15
0
def firwin_kaiser_bsf(f_stop1, f_pass1, f_pass2, f_stop2, d_stop, 
                  fs = 1.0, N_bump=0):
    """
    Design an FIR bandstop filter using the sinc() kernel and
    a Kaiser window. The filter order is determined based on 
    f_stop1 Hz, f_pass1 Hz, f_pass2 Hz, f_stop2 Hz, and the 
    desired stopband attenuation d_stop in dB for both stopbands,
    all relative to a sampling rate of fs Hz.
    Note: The passband ripple cannot be set independent of the
    stopband attenuation.
    Note: The filter order is forced to be even (odd number of taps)
    so there is a center tap that can be used to form 1 - H_BPF.

    Mark Wickert October 2016    
    """
    # First design a BPF starting from simple LPF equivalent
    # The upper and lower stopbands are assumed to have 
    # the same attenuation level. The LPF equivalent critical
    # frequencies:
    f_pass = (f_pass2 - f_pass1)/2
    f_stop = (f_stop2 - f_stop1)/2
    # Continue to design equivalent LPF
    wc = 2*np.pi*(f_pass + f_stop)/2/fs
    delta_w = 2*np.pi*(f_stop - f_pass)/fs
    # Find the filter order
    M = np.ceil((d_stop - 8)/(2.285*delta_w))
    # Adjust filter order up or down as needed
    M += N_bump
    # Make filter order even (odd number of taps)
    if ((M+1)/2.0-int((M+1)/2.0)) == 0:
        M += 1
    N_taps = M + 1
    # Obtain the Kaiser window
    beta = signal.kaiser_beta(d_stop)
    w_k = signal.kaiser(N_taps,beta)
    n = np.arange(N_taps)
    b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k
    b_k /= np.sum(b_k)
    # Transform LPF to BPF
    f0 = (f_pass2 + f_pass1)/2
    w0 = 2*np.pi*f0/fs
    n = np.arange(len(b_k))
    b_k_bs = 2*b_k*np.cos(w0*(n-M/2))
    # Transform BPF to BSF via 1 - BPF for odd N_taps
    b_k_bs = -b_k_bs
    b_k_bs[int(M/2)] += 1 
    print('Kaiser Win filter taps = %d.' % N_taps)
    return b_k_bs
Ejemplo n.º 16
0
 def bandpass_kaiser(self, channel, freqs=(1, 15)):
     ntaps = 16
     nyq = 0.5 * self.rate
     width = 1.6
     atten = signal.kaiser_atten(ntaps, width / nyq)
     beta = signal.kaiser_beta(atten)
     taps = signal.firwin(ntaps, [freqs[0], freqs[1]],
                          nyq=nyq,
                          pass_zero=False,
                          window=('kaiser', beta),
                          scale=False)
     newsig = signal.filtfilt(taps_kaiser16,
                              1.0,
                              self.single_sweep_data[channel],
                              padlen=500)
     return newsig
Ejemplo n.º 17
0
def firwin_kaiser_bpf(f_stop1,
                      f_pass1,
                      f_pass2,
                      f_stop2,
                      d_stop,
                      fs=1.0,
                      N_bump=0):
    """
    Design an FIR bandpass filter using the sinc() kernel and
    a Kaiser window. The filter order is determined based on 
    f_stop1 Hz, f_pass1 Hz, f_pass2 Hz, f_stop2 Hz, and the 
    desired stopband attenuation d_stop in dB for both stopbands,
    all relative to a sampling rate of fs Hz.
    Note: the passband ripple cannot be set independent of the
    stopband attenuation.

    Mark Wickert October 2016    
    """
    # Design BPF starting from simple LPF equivalent
    # The upper and lower stopbands are assumed to have
    # the same attenuation level. The LPF equivalent critical
    # frequencies:
    f_pass = (f_pass2 - f_pass1) / 2
    f_stop = (f_stop2 - f_stop1) / 2
    # Continue to design equivalent LPF
    wc = 2 * np.pi * (f_pass + f_stop) / 2 / fs
    delta_w = 2 * np.pi * (f_stop - f_pass) / fs
    # Find the filter order
    M = np.ceil((d_stop - 8) / (2.285 * delta_w))
    # Adjust filter order up or down as needed
    M += N_bump
    N_taps = M + 1
    # Obtain the Kaiser window
    beta = signal.kaiser_beta(d_stop)
    w_k = signal.kaiser(N_taps, beta)
    n = np.arange(N_taps)
    b_k = wc / np.pi * np.sinc(wc / np.pi * (n - M / 2)) * w_k
    b_k /= np.sum(b_k)
    # Transform LPF to BPF
    f0 = (f_pass2 + f_pass1) / 2
    w0 = 2 * np.pi * f0 / fs
    n = np.arange(len(b_k))
    b_k_bp = 2 * b_k * np.cos(w0 * (n - M / 2))
    print('Kaiser Win filter taps = %d.' % N_taps)
    return b_k_bp
Ejemplo n.º 18
0
def resample(s, p, q, h=None):
    """Change sampling rate by rational factor. This implementation is based on
    the Octave implementation of the resample function. It designs the 
    anti-aliasing filter using the window approach applying a Kaiser window with
    the beta term calculated as specified by [2].
    
    Ref [1] J. G. Proakis and D. G. Manolakis,
    Digital Signal Processing: Principles, Algorithms, and Applications,
    4th ed., Prentice Hall, 2007. Chap. 6

    Ref [2] A. V. Oppenheim, R. W. Schafer and J. R. Buck, 
    Discrete-time signal processing, Signal processing series,
    Prentice-Hall, 1999
    """
    gcd = fractions.gcd(p, q)
    if gcd > 1:
        p = p / gcd
        q = q / gcd

    if h is None:  #design filter
        #properties of the antialiasing filter
        log10_rejection = -3.0
        stopband_cutoff_f = 1.0 / (2.0 * max(p, q))
        roll_off_width = stopband_cutoff_f / 10.0

        #determine filter length
        #use empirical formula from [2] Chap 7, Eq. (7.63) p 476
        rejection_db = -20.0 * log10_rejection
        l = numpy.ceil((rejection_db - 8.0) / (28.714 * roll_off_width))

        #ideal sinc filter
        t = numpy.arange(-l, l + 1)
        ideal_filter = 2 * p * stopband_cutoff_f * numpy.sinc(
            2 * stopband_cutoff_f * t)

        #determine parameter of Kaiser window
        #use empirical formula from [2] Chap 7, Eq. (7.62) p 474
        beta = signal.kaiser_beta(rejection_db)

        #apodize ideal filter response
        h = numpy.kaiser(2 * l + 1, beta) * ideal_filter

    ls = len(s)
    lh = len(h)

    l = (lh - 1) / 2.0
    ly = numpy.ceil(ls * p / float(q))

    #pre and postpad filter response
    nz_pre = numpy.floor(q - numpy.mod(l, q))
    hpad = h[-lh + nz_pre:]

    offset = numpy.floor((l + nz_pre) / q)
    nz_post = 0
    while numpy.ceil(((ls - 1) * p + nz_pre + lh + nz_post) / q) - offset < ly:
        nz_post += 1
    hpad = hpad[:lh + nz_pre + nz_post]

    #filtering
    xfilt = upfirdn(s, hpad, p, q)

    return xfilt[offset - 1:offset - 1 + ly]
Ejemplo n.º 19
0
    tol_db = -20.0 * np.log10(tolerance)
    window_size = size(tol_db, transition_width)
    window_beta = beta(tol_db)
    return window_size, window_beta



tol_list = np.arange(1e-6, 0.2, 1e-4)
tol_db_list = -20.0 * np.log10(tol_list)
beta_list = np.empty_like(tol_db_list)
for i, tol in enumerate(np.nditer(tol_db_list)):
    beta_list[i] = beta(tol)

beta_list_ref = np.empty_like(tol_db_list)
for i, tol in enumerate(np.nditer(tol_db_list)):
    beta_list_ref[i] = kaiser_beta(tol)

print('max abs beta error:', np.abs(beta_list - beta_list_ref).max())
hdf5util.write_ndarray(data=tol_db_list, file_path='kaiser_tol_db.h5', dataset_name='v')
hdf5util.write_ndarray(data=beta_list_ref, file_path='kaiser_beta.h5', dataset_name='v')

plt.figure()
plt.plot(tol_db_list, beta_list, label='local')
plt.plot(tol_db_list, beta_list_ref, label='scipy')
plt.title('Beta list')
plt.legend(loc='upper right', labelspacing=0.2)



trans_width_list = np.array([0.05, 0.1, 0.5])
size_matrix = np.zeros((len(trans_width_list), len(tol_list)), dtype=int)
Ejemplo n.º 20
0
def construct_fir_filter(rate, frequencies, gains, order, phase, window,
                         design):
    """ Construct coeffs of FIR filter.

    Args:
        rate (float): Nominal sampling rate of the input data.
        order (int): Filter order
        frequencies (list): Transition frequencies in Hz.
        design (str|'firwin2'): Design of the transfert function of the filter.
        phase (str|`linear`): Phase response ("zero", "zero-double" or "minimum").
        window (float|`hamming`): The window to use in FIR design, ("hamming", "hann", or "blackman").

    Returns:
        array h. FIR coeffs.

    Notes:

        Adapted from mne.filters, see the documentation of:

        * `mne.filters <https://martinos.org/mne/stable/generated/mne.filter.construct_fir_filter.html>`_
        * `scipy.signal.firwin2 <https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.firwin2.html>`_



    """
    nyq = rate / 2.
    if design == 'firwin2':
        from scipy.signal import firwin2 as design
    else:
        # not implemented yet
        raise ValueError(
            'firwin, remez and firls have not been implemented yet ')

    # issue a warning if attenuation is less than this
    min_att_db = 12 if phase == 'minimum' else 20

    if frequencies[0] != 0 or frequencies[-1] != nyq:
        raise ValueError(
            'freq must start at 0 and end an Nyquist (%s), got %s' %
            (nyq, frequencies))
    gains = np.array(gains)

    if window == "kaiser":
        diffs = np.diff(frequencies)
        width = min(diffs[diffs > 0])
        beta = signal.kaiser_beta(signal.kaiser_atten(order, width / nyq))
        window = ("kaiser", beta)

    # check zero phase length
    N = int(order)
    if N % 2 == 0:
        if phase == 'zero':
            LOGGER.info('filter_length must be odd if phase="zero", '
                        'got %s' % N)
            N += 1
        elif phase == 'zero-double' and gains[-1] == 1:
            N += 1
    # construct symmetric (linear phase) filter
    if phase == 'minimum':
        h = design(N * 2 - 1, frequencies, gains, fs=rate, window=window)
        h = signal.minimum_phase(h)
    else:
        h = design(N, frequencies, gains, fs=rate, window=window)
    assert h.size == N
    att_db, att_freq = _filter_attenuation(h, frequencies, gains)
    if phase == 'zero-double':
        att_db += 6
    if att_db < min_att_db:
        att_freq *= rate / 2.
        LOGGER.info('Attenuation at stop frequency %0.1fHz is only %0.1fdB. '
                    'Increase filter_length for higher attenuation.' %
                    (att_freq, att_db))
    return h
Ejemplo n.º 21
0
Archivo: fir.py Proyecto: emd/filters
 def getFilterCoefficients(self):
     'Get coefficients via `:py:function:`firwin <scipy.signal.firwin>`.'
     return signal.firwin(self.getNumTaps(), cutoff=self.cutoff,
                          window=('kaiser', kaiser_beta(self.ripple_dB)),
                          pass_zero=self.pass_zero, nyq=(0.5 * self.Fs))
Ejemplo n.º 22
0
 def cpu_version(self, a):
     return signal.kaiser_beta(a)
Ejemplo n.º 23
0
def kaiserord(f: np.ndarray,
              a: np.ndarray,
              dev: np.ndarray,
              fs: float = 2) -> Tuple:
    """Kaiser window FIR filter design estimation parameters

    Parameters
    ----------
    f : ndarray
        Band edges. The length of `f` is the length of `2*len(a)-2`.

    a : ndarray
        Band amplitude. The amplitude is specified on the bands defined by `f`. 
        Together, `f` and `a` define a piecewise-constant response function.

    dev : ndarray
        Maximum allowable deviation. 
        `dev` is a vector the same size as `a` that specifies the maximum allowable
        deviation between the frequency response of the output filter and its band 
        amplitude, for each band. The entries in dev specify the passband ripple 
        and the stopband attenuation. Specify each entry in `dev` as a positive number, 
        representing absolute filter gain (unit-less).

    fs : float, optional
        Sample rate in Hz. Use this syntax to specify band edges scaled to a particular 
        application's sample rate. The frequency band edges in f must be from 0 to fs/2.
        Default is 2.

    
    Raises
    ------
    ValueError
        If the length of `f` is not same as `2*len(a)-2`.
        If the length `a` and `dev` is not the same.
        If `dev` includes minus value.

    
    Returns
    -------
    n : int
        Filter order.

    Wn : ndarray
        Normalized frequency band edges.

    beta : float
        The `beta` parameter to be used in the formula for a Kaiser window.

    ftype : string
        Filter type of filter('low', 'high', 'bandpass', 'stop', 'DC-0' 
            or 'DC-1').
            Specified as one of the following.
            
            1. 'low' specifies a lowpass filter with cutoff frequency Wn. 
               'low' is the default for scalar Wn.
            2. 'high' specifies a highpass filter with cutoff frequency Wn.
            3. 'bandpass' specifies a bandpass filter if Wn is a two-element vector. 
               'bandpass' is the default when Wn has two elements.
            4. 'stop' specifies a bandstop filter if Wn is a two-element vector.
            5. 'DC-0' specifies that the first band of a multiband filter is 
               a stopband. 
               'DC-0' is the default when Wn has more than two elements.
            6. 'DC-1' specifies that the first band of a multiband filter is 
               a passband.
               
    """
    if type(f) != np.ndarray:
        if type(f) == list:
            f = np.array(f)
        else:
            f = np.array([f])

    if type(a) != np.ndarray:
        if type(a) == list:
            a = np.array(a)
        else:
            a = np.array([a])

    if type(dev) != np.ndarray:
        if type(dev) == list:
            dev = np.array(dev)
        else:
            dev = np.array([dev])

    # Parameter check
    if len(f) != 2 * len(a) - 2:
        raise ValueError("The length of 'f' must be the length of 2*len(a)-2.")

    if np.any(a[0:len(a) - 2] != a[2:len(a)]):
        raise ValueError(
            "Pass and stop bands in a must be strictly alternating.")

    if (len(dev) != len(a)) and (len(dev) != 1):
        raise ValueError("'dev' and 'a' must be the same size.")

    dev = np.min(dev)
    if dev <= 0:
        raise ValueError("'dev' must be larger than 0.")

    # Calcurate normalized frequency band edges.
    Wn = (f[0:len(f):2] + f[1:len(f):2]) / fs

    # Determine ftype
    if len(Wn) == 1:
        if a[0] > a[1]:
            ftype = 'low'
        else:
            ftype = 'high'
    elif len(Wn) == 2:
        if a[0] > a[1]:
            ftype = 'stop'
        else:
            ftype = 'bandpass'
    else:
        if a[0] > a[1]:
            ftype = 'DC-1'
        else:
            ftype = 'DC-0'

    # Calcurate beta
    A = -20 * np.log10(dev)
    beta = signal.kaiser_beta(A)

    # Calcurate n from beta and dev
    width = 2 * np.pi * np.min(f[1:len(f):2] - f[0:len(f):2]) / fs
    n = np.max((1, int(np.ceil((A - 8) / (2.285 * width)))))

    # If last band is high, make sure the order of the filter is even
    if ((a[0] > a[1]) == (len(Wn) % 2 == 0)) and (n % 2 == 1):
        n += 1

    if len(Wn) == 1:
        Wn = Wn[0]

    return int(n), Wn, beta, ftype