Exemple #1
0
    def test_tf2minphase(self):
        htest = np.copy(self.h)
        h_min = adsp.tf2minphase(htest)

        # test group delay
        _, orig_delay = signal.group_delay((htest, 1))
        _, min_delay = signal.group_delay((h_min, 1))
        self.assertTrue(min_delay[0] <= orig_delay[0],
                        'Minimum phase IR does not have minimum group delay!')
Exemple #2
0
def main():
    if voucher_val == 'Slayerz':
        voucher_page()
    else:

        if add_selectbox == 'Lowpass':
            N = int(
                st.slider('Select butterfilter order',
                          min_value=0,
                          max_value=10))
            system = dsp.butter(N, 25, fs=fs)
            lp_filtered = dsp.lfilter(*system, chrp)
            ww, gd = dsp.group_delay(system, fs=fs)
            fig, ax = plt.subplots(2, 1, figsize=[12, 9])
            ax[0].plot(t, lp_filtered)
            ax[0].set_title('Lowpass filtered')
            ax[0].set_xlabel('Time')
            ax[0].set_ylabel('Amplitude')
            ax[1].plot(ww, gd)
            ax[1].set_title('Filter group delay')
            ax[1].set_xlabel('Frequency')
            ax[1].set_ylabel('Delay samples')
            plt.tight_layout()
            st.pyplot()

        if add_selectbox == 'Highpass':
            N = int(
                st.slider('Select butterfilter order',
                          min_value=0,
                          max_value=10))
            system = dsp.butter(N, 25, btype='high', fs=fs)
            hp_filtered = dsp.lfilter(*system, chrp)
            ww, gd = dsp.group_delay(system, fs=fs)
            fig, ax = plt.subplots(2, 1, figsize=[12, 9])
            ax[0].plot(t, hp_filtered)
            ax[0].set_title('Lowpass filtered')
            ax[0].set_xlabel('Time')
            ax[0].set_ylabel('Amplitude')
            ax[1].plot(ww, gd)
            ax[1].set_title('Filter group delay')
            ax[1].set_xlabel('Frequency')
            ax[1].set_ylabel('Delay samples')
            plt.tight_layout()
            st.pyplot()

        if add_selectbox == 'Original':
            plt.plot(t, chrp)
            plt.title('Chirp')
            plt.xlabel('Time')
            plt.ylabel('Amplitude')
            st.pyplot()
Exemple #3
0
def char_plot(num, denom, sample_rate):

    w, h = freqz(num, denom)
    figure(1)
    subplot(2,1,1)
    hold(True)
    pow = plot((sample_rate*0.5/pi)*w, abs(h),'b-', label = 'Char. amplitudowa')
    title('Charakterystyki filtru')
    xlabel('Czestotliwosc [Hz]')
    ylabel('Amplituda')


    twinx(ax=None)
    angles = unwrap(angle(h))
    aznie = plot((sample_rate*0.5/pi)*w, angles, 'g-', label = 'Char. fazowa')
    ylabel('Faza')

    grid()
    tekst = pow + aznie
    wybierz = [l.get_label() for l in tekst]

    legend(tekst, wybierz, loc='best')
########################################################################################################################
    subplot(2,1,2)

    w2, gd = group_delay((num, denom))

    plot((sample_rate*0.5/pi)*w2, gd)
    grid()
    xlabel('Czestotliwosc [Hz]')
    ylabel('Opoznienie grupowe [probki]')
    title('Opoznienie grupowe filtru')

    show()
Exemple #4
0
def get_plot_data(fs_hz, number_coeffs, f_low_hz, f_high_hz, rp, rs, f_type,
                  design):
    if f_type == 'lowpass':
        Wn = f_low_hz
    elif f_type == 'highpass':
        Wn = f_high_hz
    else:
        Wn = [f_low_hz, f_high_hz]
    if design not in ['cheby1', 'cheby2', 'ellip']:
        rp = None
        rs = None
    b, a = signal.iirfilter(number_coeffs,
                            Wn,
                            rp=rp,
                            rs=rs,
                            btype=f_type,
                            ftype=design,
                            output='ba',
                            fs=fs_hz)
    worN = np.logspace(0, 4, num=1024) * (fs_hz / 2) / 1e4
    frequency_hz, h = signal.freqz(b,
                                   a,
                                   worN=worN,
                                   fs=fs_hz,
                                   include_nyquist=False)
    _, gd_samples = signal.group_delay((b, a), w=worN, fs=fs_hz)
    amplitude_dB = 20 * np.log10(abs(h))
    angle_deg = np.unwrap(np.angle(h)) * (180 / np.pi)
    return frequency_hz, amplitude_dB, angle_deg, gd_samples
Exemple #5
0
def show_filters(filters, fs, ideal_delays=[]):
    fig, (linax, logax, grpax) = plt.subplots(3)

    for fil in filters:
        print_filter(fil)

        w, h = sps.freqz(fil.b, fil.a, fs=fs)
        linax.plot(w, np.abs(h))
        logax.plot(w, 20 * np.log10(np.abs(h)))
        dw, d = sps.group_delay((fil.b, fil.a), w, fs=fs)
        grpax.plot(dw, d - d[0])

    for ideal in ideal_delays:
        xs = np.linspace(ideal.fs[0], ideal.fs[-1], num=1000)
        vs_interp = sint.interp1d(ideal.fs, ideal.vs, kind='quadratic')(xs)
        grpax.plot(ideal.fs, ideal.vs, 'o')
        if ideal.tols is not None:
            tols_interp = sint.interp1d(ideal.fs, ideal.tols, kind='quadratic')(xs)
            grpax.fill_between(xs, vs_interp - tols_interp, vs_interp + tols_interp, alpha=0.2)

    for ax in (linax, logax, grpax):
        if ax is grpax:
            extras = [ideal.name for ideal in ideal_delays]
        else:
            extras = []
        ax.legend(['%s <%d>' % (fil.name, len(fil.b)) for fil in filters] + extras)
        ax.set_xlabel('Frequency')
        ax.set_xlim(0, fs / 2)
        ax.grid(True)
    linax.set_ylabel('Magnitude response (linear)')
    logax.set_ylabel('Magnitude response (dB)')
    grpax.set_ylabel('Relative group delay (samples)')

    plt.show()
def filter_char(b, a, show=True):
    # Pole-zero characteristics
    zero, pole, __ = sp.tf2zpk(b, a)
    if (pole.shape < zero.shape):
        pole = np.concatenate(
            (pole, np.zeros(zero.shape[0] - pole.shape[0], dtype=complex)))
    zp = [zero, pole]
    # Magnitude and Phase Characteristics
    w1, H = sp.freqz(b, a, 1024, whole=True)
    # Time domain sequence (= Coefficients for given filter since it is FIR)
    h = ifft(H)
    ii = np.where(abs(h) > 1e-4)
    h = np.real(
        h[ii])  # remove noisy imaginary components- h is a real FIR filter
    # Group Delay of Filter
    w2, gd = sp.group_delay((b, a), whole=True)
    if show == True:
        plt.figure("Pole-Zero Plot")
        plt.polar(np.angle(zp[0]), np.abs(zp[0]), 'bo')
        plt.polar(np.angle(zp[1]), np.abs(zp[1]), 'gx')
        plt.polar(np.linspace(0, 2 * pi, 360), np.ones(360), 'k-')
        plt.title("Pole-Zero Plot")
        plt.figure("Mag-Phase Characteristics")
        plt.subplot(211)
        plt.plot(w1, abs(H))
        plt.title("Mag-Phase Characteristics of FIR filter")
        plt.subplot(212)
        plt.plot(w1, np.unwrap(np.angle(H)))
        plt.figure("h[n]")
        plt.plot(h, "ro")
        plt.title("Time Domain: FIR Filter")
        plt.figure("Group Delay of Filter")
        plt.plot(w2, gd)
        plt.title("Group Delay of Filter")
    return zp, H, h, gd
Exemple #7
0
def plot_group_delay(b, a):
    w, gd = signal.group_delay((b, a))
    plt.plot(w, np.round(gd, 5))
    plt.ylabel('Retardo de grupo [muestras]')
    plt.xlabel('Frecuencia [rad/muestra]')
    plt.title('Retardo de grupo')
    plt.show()
Exemple #8
0
def plot_groupdelay_error(prefix, irs, delta_min, omega_max):
    omega_max *= numpy.pi

    pyplot.figure(figsize=(8, 4.8), dpi=100)
    pyplot.title(f"{prefix} Group Delay, N={len(irs[0])}")

    ax = pyplot.gca()
    ax.grid()

    cmap = pyplot.get_cmap("plasma")

    for index, ir in enumerate(irs):
        w, gd = signal.group_delay((ir, [1]))
        trim = numpy.searchsorted(w, omega_max)
        ax.plot(
            w[:trim + 1],
            gd[:trim + 1] - delta_min - index / (len(irs) - 1),
            label=str(delta_min + index / (len(irs) - 1)),
            color=cmap(index / len(irs)),
            lw=1,
        )

    ax.axvline(omega_max,
               label="$\omega_{\max}$",
               color="black",
               alpha=0.25,
               ls="--")

    ax.set_ylabel("Error [samples]")
    ax.set_xlabel("Frequency [rad/sample]")
    ax.legend(ncol=2)
    pyplot.savefig(f"img/{prefix}_error.png", dpi=100)
Exemple #9
0
def plotSos(sos, oversample, fs, worN=2048):
    fig, ax = plt.subplots(3, 1)
    fig.set_size_inches(6, 8)
    fig.set_tight_layout(True)

    ax[0].set_title("Amplitude Response")
    ax[0].set_ylabel("Amplitude [dB]")
    ax[1].set_title("Phase Response")
    ax[1].set_ylabel("Phase [rad]")
    ax[2].set_title("Group Delay")
    ax[2].set_ylabel("Group Delay [sample]")
    ax[2].set_xlabel("Frequency [rad/sample]")

    cmap = plt.get_cmap("plasma")

    freq, h0 = signal.sosfreqz(sos, worN=worN, fs=oversample * fs)

    b, a = signal.sos2tf(sos)
    _, gd = signal.group_delay((b, a), w=worN)

    ax[0].plot(freq, ampToDecibel(h0), alpha=0.75, color="black")
    ax[0].set_ylim((-140, 5))
    ax[1].plot(freq, np.unwrap(np.angle(h0)), alpha=0.75, color="black")
    ax[2].plot(freq, gd, alpha=0.75, color="black")

    for axis in ax:
        # axis.set_xscale("log")
        axis.grid(which="both")

    plt.show()
Exemple #10
0
    def plot_filter_characteristics(self):
        w, h = freqz(self.freq_filter.num, self.freq_filter.denom)
        plt.figure(1)
        plt.subplot(2,1,1)
        plt.hold(True)
        powa = plt.plot((self.filter_parameters.sample_rate*0.5/pi)*w, abs(h),'b-', label = 'Char. amplitudowa')
        plt.title('Charakterystyki filtru')
        plt.xlabel('Czestotliwosc [Hz]')
        plt.ylabel('Amplituda')


        plt.twinx(ax=None)
        angles = unwrap(angle(h))
        plt.znie = plot((self.filter_parameters.sample_rate*0.5/pi)*w,angles, 'g-', label = 'Char. fazowa')
        plt.ylabel('Faza')

        plt.grid()
        tekst = powa + znie
        wybierz = [l.get_label() for l in tekst]

        plt.legend(tekst, wybierz, loc='best')
    ########################################################################################################################
        plt.subplot(2,1,2)

        w2, gd = group_delay((num, denom))

        plt.plot((sample_rate*0.5/pi)*w2, gd)
        plt.grid()
        plt.xlabel('Czestotliwosc [Hz]')
        plt.ylabel('Opoznienie grupowe [probki]')
        plt.title('Opoznienie grupowe filtru')

        plt.show()
Exemple #11
0
def plot(firTable, ylim):
    fig, ax = plt.subplots(3, 1)
    fig.set_size_inches(6, 8)
    fig.set_tight_layout(True)

    ax[0].set_title("Amplitude Response")
    ax[0].set_ylabel("Amplitude [dB]")
    ax[1].set_title("Phase Response")
    ax[1].set_ylabel("Phase [degree]")
    ax[2].set_title("Group Delay")
    ax[2].set_ylabel("Group Delay [sample]")
    ax[2].set_xlabel("Frequency [rad/sample]")
    ax[2].set_ylim(ylim)

    cmap = plt.get_cmap("plasma")
    for index, fir in enumerate(firTable):
        freq, mag, phase = signal.dbode((fir, 1, 1), n=1024)
        freq, gd = signal.group_delay((fir, 1), w=1024)

        cmapValue = index / len(firTable)
        ax[0].plot(freq, mag, alpha=0.75, color=cmap(cmapValue), label=f"{index}")
        ax[1].plot(freq, phase, alpha=0.75, color=cmap(cmapValue), label=f"{index}")
        ax[2].plot(freq, gd, alpha=0.75, color=cmap(cmapValue), label=f"{index}")

    for axis in ax:
        axis.grid()
        axis.legend()
    plt.show()
Exemple #12
0
 def test_grpdelay_1(self):
     # Test case for FIR filter
     fil = FIRDesign.fir1(self.order, self.cut)
     w, gd = signal.group_delay(fil, w=512, fs=2 * np.pi)
     gd = np.round(gd)
     ww, gdgd = FilterSpec.grpdelay(fil)
     self.assertTrue(np.all(w == ww) and np.all(gd == gdgd))
Exemple #13
0
def group_delayz(b, a, w, plot=None, fs=2*np.pi):
    """
    Compute the group delay of digital filter.

    Parameters
    ----------
    b : array_like
        Numerator of a linear filter.
    a : array_like
        Denominator of a linear filter.
    w : array_like
        Frequencies in the same units as `fs`.
    plot : callable
        A callable that takes two arguments. If given, the return parameters
        `w` and `gd` are passed to plot.
    fs : float, optional
        The angular sampling frequency of the digital system.

    Returns
    -------
    w : ndarray
        The frequencies at which `gd` was computed, in the same units as `fs`.
    gd : ndarray
        The group delay in seconds.
    """
    b, a = map(np.atleast_1d, (b, a))
    if len(a) == 1:
        # scipy.signal.group_delay returns gd in samples thus scaled by 1/fs
        gd = sig.group_delay((b, a), w=w, fs=fs)[1]
    else:
        sos = sig.tf2sos(b, a)
        gd = sos_group_delayz(sos, w, plot, fs)[1]
    if plot is not None:
        plot(w, gd)
    return w, gd
Exemple #14
0
def plot_filter(b, a, dB=True, plot_gd=False):
    '''
  Plots a filter's response
  '''
    w, h = freqz(b, a)
    fig = plt.figure()
    ax1 = fig.add_subplot(1, 1, 1)
    ax1.set_title('frequency response')

    if dB:
        ax1.plot(w, 20 * np.log10(abs(h)), 'b', linewidth=2)
        ax1.set_ylabel('$20log_{10}|H|$', color='b')
    else:
        ax1.plot(w, abs(h), 'b')
        ax1.set_ylabel('$|H|$', color='b')

    ax1.set_xlabel('frequency [Rad/Sample]')
    ax1.grid()

    if plot_gd:
        ax2 = ax1.twinx()
        w, gd = group_delay((b, a), w)
        ax2.plot(w, gd, 'g', linewidth=2)
        ax2.set_ylabel('Group Delay [s]', color='g')

    fig.show()
    return
Exemple #15
0
def filterplot(H):
    H = H[1]
    t1 = np.shape(H)
    f = np.linspace(-.5, .5, t1[2])

    fig = plt.figure()
    ax1 = fig.add_subplot(311)
    ax1.plot(f, 20*np.log10(abs(npfft.fftshift(npfft.fft(H)))))
    ax1.set_xlabel('Uniform frequnency')
    ax1.set_ylabel('Power (dB)')
    ax1.set_title('Filter properties')
    ax1.grid(True)

    ax2 = fig.add_subplot(312)
    a = np.unwrap(np.angle(npfft.fftshift(npfft.fft(H))))
    ax2.plot(f, a)
    ax2.set_xlabel('Uniform frequency')
    ax2.set_ylabel('Angle (rad)')
    ax2.axis([-.5, .5, min(a), 0])
    ax2.grid(True)

    ax3 = fig.add_subplot(313)
    a = sps.group_delay((H, 1))
    ax3.plot(np.linspace(-.5, .5, 512), npfft.fftshift(a) - t1(2)/2)
    ax3.set_xlabel('Uniform frequency')
    ax3.set_ylabel('Group delay')
    ax3.axis([-.5, .5, -500, 500])
    ax3.grid(True)
Exemple #16
0
def plotFilter(b, a, mag_type='abs', fs=2, ax1=None):
    w1, h = sig.freqz(b, a, fs=fs)
    w2, gd = sig.group_delay((b, a), fs=fs)

    if ax1 is None:
        fig, ax1 = plt.subplots()
    ax1.set_title('Digital filter frequency response')

    # ax1.plot(w1, 20 * np.log10(abs(h)), 'b')
    # ax1.plot(w1[:-1], (abs(h[:-1]) - abs(h[1:]))/(w1[1]-w1[0]), 'b')

    if mag_type == 'abs':
        mag = np.abs(h)
        mag_label = 'Magnitude'
    elif mag_type == 'dB':
        mag = 20 * np.log10(np.abs(h))
        mag_label = 'Magnitude [dB]'
    elif mag_type == 'loss':
        mag = 20 * np.log10(1 / np.abs(h))
        mag_label = 'Attenuation [dB]'

    ax1.plot(w1, mag, 'b')
    ax1.set_ylabel(mag_label, color='b')
    ax1.set_xlabel('Frequency [normalized]')

    ax2 = ax1.twinx()
    ax2.plot(w2, gd, 'g')
    ax2.set_ylabel('Group delay', color='g')
    ax2.grid()
    ax2.axis('tight')
    if mag_type == 'loss':
        ax2.set_ylim(-5, 5)
Exemple #17
0
def lfilter0(b, a, x, axis=-1):
    """Filter data with an IIR or FIR filter with zero DC group delay.

    :func:`scipy.signal.lfilter` provides a way to filter a signal `x` using a FIR/IIR
    filter defined by `b` and `a`. The resulting output is delayed, as compared to the
    input by the group delay. This function corrects for the group delay, resulting in
    an output that is synchronized with the input signal. If the filter as an acausal
    impulse response, some precursor signal from the output will be lost. To avoid this,
    pad input signal `x` with sufficient zeros at the beginning to capture the precursor.
    Since both, :func:`scipy.signal.lfilter` and this function return a signal with the
    same length as the input, some signal tail is lost at the end. To avoid this, pad
    input signal `x` with sufficient zeros at the end.

    See documentation for :func:`scipy.signal.lfilter` for more details.

    >>> import arlpy
    >>> import numpy as np
    >>> fs = 250000
    >>> b = arlpy.uwa.absorption_filter(fs, distance=500)
    >>> x = np.pad(arlpy.signal.sweep(20000, 40000, 0.5, fs), (127, 127), 'constant')
    >>> y = arlpy.signal.lfilter0(b, 1, x)
    """
    w, g = _sig.group_delay((b, a))
    ndx = _np.argmin(_np.abs(w))
    d = int(round(g[ndx]))
    x = _np.apply_along_axis(lambda a: _np.pad(a, (0, d), 'constant'), axis, x)
    y = _sig.lfilter(b, a, x, axis)[d:]
    return y
Exemple #18
0
def group_delay(w,phase,b,a):
    w, gd = sg.group_delay((b, a),w=w)
    plt.figure(6)
    plt.title('WMA filter group delay')
    plt.plot(w[1:990]/(2*np.pi),np.round(gd[1:990]))
    plt.ylabel('Group delay [samples]')
    plt.xlabel('Frequency [Hz]')
    plt.savefig(file_gd)
Exemple #19
0
def freqz_plot(line, cell):
    # line, cellをparse
    N, FS = [float(v) for v in line.split()]
    ba = cell.split("\n")
    b = [float(v) for v in ba[0].split(",")]
    a = [float(v) for v in ba[1].split(",")]

    # 時間特性、周波数特性、位相特性、群遅延特性等を計算
    w, h = sg.freqz(b, a, worN=int(N))
    f = w * FS / (2.0 * np.pi)
    z, p, k = sg.tf2zpk(b, a)
    _, gd = sg.group_delay((b, a), w=w)

    # 上記パラメータをプロット
    fig = plt.figure(1, figsize=(8, 12))
    
    ax = fig.add_subplot(321)
    ax.plot(b, "o-")
    ax.plot(a, "x-")
    ax.grid()
    ax.set_xlabel("time [pt]")
    ax.set_ylabel("amplitude")
    
    ax = fig.add_subplot(322)
    ax.semilogx(f, 20.0 * np.log10(np.abs(h)))
    ax.grid()
    ax.set_xlabel("frequency [Hz]")
    ax.set_ylabel("power [dB]")
    ax.set_xlim([10.0, FS/2.0])
    ax.set_ylim([-40.0, 10.0])

    ax = fig.add_subplot(323)
    ax.semilogx(f, np.angle(h))
    ax.grid()
    ax.set_xlim([10.0, FS/2.0])
    ax.set_ylim([-np.pi, np.pi])
    ax.set_xlabel("frequency [Hz]")
    ax.set_ylabel("phase [rad]")
    
    ax = fig.add_subplot(324)
    ax.semilogx(f, gd)
    ax.grid()
    ax.set_xlabel("frequency [Hz]")
    ax.set_ylabel("group delay [pt]")
    ax.set_xlim([10.0, FS/2.0])
    ax.set_ylim([-40.0, 40.0])

    ax = fig.add_subplot(325)
    ax.add_patch(plt.Circle((0.0, 0.0), 1.0, fc="white"))
    ax.plot(np.real(z), np.imag(z), "o", mfc="white")
    ax.plot(np.real(p), np.imag(p), "x", mfc="white")
    ax.grid()
    ax.set_xlim([-1.5, 1.5])
    ax.set_ylim([-1.5, 1.5])

    plt.show()
Exemple #20
0
 def set_band_pass(self):
     self.num = [1, 0]
     self.den = [1, 1, 1]
     self.sys = signal.TransferFunction([1, 0], [1, 1, 1])
     self.w, self.mag, self.phase = signal.bode(self.sys)
     self.stepT, self.stepMag = signal.step(self.sys)
     self.impT, self.impMag = signal.impulse(self.sys)
     self.pzg = signal.tf2zpk(self.sys.num, self.sys.den)
     self.GDfreq, self.gd = signal.group_delay((self.num, self.den))
     self.plotMag()
Exemple #21
0
def calc_error(irs, delta_min, omega_max):
    """
    irs[fraction][tap]
    """
    error = []
    for index, ir in enumerate(irs):
        w, gd = signal.group_delay((ir, [1]))
        trim = numpy.searchsorted(w, omega_max * numpy.pi)
        error.append(gd[:trim + 1] - delta_min - index / (len(irs) - 1))
    return numpy.sum(numpy.abs(numpy.array(error))) / omega_max / len(irs)
Exemple #22
0
    def plot_group_delay_to_axes(self, axes, limits):
        legend = 'Group Delay'
        n_points = 1000
        w, gd = signal.group_delay((self.num, self.den))
        axes.plot(w, gd, label=legend)
        axes.set_xlabel(r'Frequency [rad/sample]')
        axes.set_ylabel(r'Group Delay [samples]')
        first_w = w.item(0)
        last_w = w[-1]

        return first_w, last_w
Exemple #23
0
def addFilter(b, a, sampling_freq, name=""):
    w, h = signal.freqz(b, a, fs=sampling_freq)
    t, y = signal.dstep((b, a, 1.0 / fs))
    w_gd, gd = signal.group_delay((b, a))

    frequencies.append(w)
    amplitudes.append(h)
    times.append(t)
    step_responses.append(y)
    group_delays.append(gd)
    names.append(name)
Exemple #24
0
def fvtool(b, fs, a=1, worN=8192, fc1=None, fc2=None):
    '''
    MATLAB関数fvtoolを参考
    この関数を呼んだあと、必ずplt.show()を叩くこと
    param
    -----
    b: array_like
        伝達関数の分子の係数
    a: array_like
        伝達関数の分母の係数 デフォルト値は1
    fs: float
        サンプリング周波数[Hz]
    worN: int
        単位円の半円の分割数
        周波数に変換するときは w/pi*fn をする
    fc1: float
        周波数応答のグラフにカットオフ周波数などの印(縦線)を入れる
    fc2: float
        周波数応答のグラフにカットオフ周波数などの印(縦線)を入れる
    '''
    # ナイキスト周波数計算
    fn = fs / 2

    # 周波数応答計算
    w, h = signal.freqz(b, a, worN)
    x_freq_rspns = w / np.pi * fn
    y_freq_rspns = db(abs(h))  # 複素数→デシベル変換

    # 群遅延計算
    w, gd = signal.group_delay([b, a], worN)
    x_gd = w / np.pi * fn
    y_gd = gd

    # グラフ表示
    plt.figure(figsize=(8, 6))
    # 周波数応答プロット
    plt.subplot(2, 1, 1)
    plt.plot(x_freq_rspns, y_freq_rspns)
    if fc1 is not None:
        plt.plot([fc1, fc1], [y_freq_rspns.min(), y_freq_rspns.max()])
    if fc2 is not None:
        plt.plot([fc2, fc2], [y_freq_rspns.min(), y_freq_rspns.max()])
    #plt.ylim(-70, 2)  # MATLAB fvtool仕様
    plt.ylabel('Amplitude [dB]')
    plt.grid()
    # 群遅延プロット
    plt.subplot(2, 1, 2)
    plt.plot(x_gd, y_gd)
    plt.ylim(0, len(b))  # MATALB fvtool仕様
    plt.xlabel('Frequency [Hz]')
    plt.ylabel('Group delay [samples]')
    plt.grid()
Exemple #25
0
    def calc_tau_g(self):
        """
        (Re-)Calculate the complex frequency response H(f)
        """
        bb = fb.fil[0]['ba'][0]
        aa = fb.fil[0]['ba'][1]

        # calculate H_cmplx(W) (complex) for W = 0 ... 2 pi:
        self.W, self.tau_g = group_delay((bb, aa), w=params['N_FFT'], whole = True)
            #verbose = self.verbose) # self.chkWarnings.isChecked())

        # Zero phase filters have no group delay (Causal+AntiCausal)
        if 'baA' in fb.fil[0]:
           self.tau_g = np.zeros(self.tau_g.size)
Exemple #26
0
 def rdgPlot(self, axes, canvas):
     for i in range(0, len(self.stages_list)):
         if self.stages_list[i]:
             temp_list = []
             temp_list.append(self.sos[i])
             b, a = ss.sos2tf(temp_list)
             w, gd = ss.group_delay((b, a))
             axes.plot(w / (2 * np.pi), gd, label=str(i))
     axes.set_xscale('log')
     axes.set_ylabel('Group delay [samples]')
     axes.set_xlabel('Frequency [Hz]')
     axes.minorticks_on()
     axes.legend(loc='best')
     canvas.draw()
Exemple #27
0
def grpdelay(system, worN:int=512, fs=2*np.pi)->Tuple:
    """
    Group delay of a digital filter.
    
    Parameters
    ----------
        system : a tuple of array_like describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:
            
                * (num, den)
                
        worN : {None, int, array_like}, optional
            If a single integer, then compute at that many frequencies 
            (default is N=512). This is a convenient alternative to:

                np.linspace(0, fs if whole else fs/2, N, endpoint=False)
            
            Using a number that is fast for FFT computations can result in 
            faster computations (see Notes).
            If an array_like, compute the response at the frequencies given. 
            These are in the same units as fs.
            
        fs : float, optional
            The sampling frequency of the digital system.
            Defaults to 2*pi radians/sample (so w is from 0 to pi).
            
    Returns
    -------
        w : ndarray
            The frequencies at which h was computed, in the same units as fs.
            By default, w is normalized to the range [0, pi) (radians/sample).
            
        gd : ndarray
            The group delay.
    """
    
    #デジタルフィルタの群遅延を計算
    w, gd = signal.group_delay(system, w = worN, fs = fs)
    
    #計算誤差を整数に丸める
    if system[1] == 1:
        # If filter is FIR, round the group_delay
        gd = np.round(gd)
    
    #周波数と対応する群遅延を返す
    return w, gd
Exemple #28
0
    def plot_filter(self,
                    xlim=None,
                    ylim=None,
                    label=False,
                    xlabel=False,
                    ylabel=False,
                    plot_group_delay=None):
        """ Visualize the prototype filter.
        """
        xlabel = True if label else xlabel
        ylabel = True if label else ylabel

        _w, _filts = self._create_prototype_filter(shift=True, output='freq')
        _fig, _ax = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
        _ax[0].plot(_w, np.abs(_filts))
        _ax[1].plot(_w, np.angle(_filts))
        if xlim is not None:
            _ax[0].set_xlim(xlim)
            _ax[1].set_xlim(xlim)

        if xlabel:
            _ax[1].set_xlabel('Frequencies [Hz]')
        if ylabel:
            _ax[0].set_ylabel('Magnitude')
            _ax[1].set_ylabel('Phases [rad]')

        if plot_group_delay is not None:
            _filt = self._create_prototype_filter(output='time')[1]
            _w, _gd = group_delay([_filt, 1])
            _w *= (self.sample_rate / (2 * np.pi))

            _fig1, _ax1 = plt.subplots(1, 1, figsize=(8, 3))
            _ax1.plot(_w, _gd)

            if xlim is not None:
                _ax1.set_xlim([0, xlim[-1]])

            _ax1.set_ylim([0, _gd.max() * 1.25])

            if xlabel:
                _ax1.set_xlabel('Frequencies [Hz]')
            if ylabel:
                _ax1.set_ylabel('Number of Samples')

            return [_fig, _fig1]
        else:
            return _fig
Exemple #29
0
 def rdgPlot(self, axes, canvas):
     for f in self.filter_list:
         if f.chk:
             w, gd = ss.group_delay((f.Filtro.b, f.Filtro.a), w=1024)
             if f.plotColor is not None:
                 axes.plot(w / (2 * np.pi),
                           gd,
                           label=f.name,
                           color=self.formatColor(f.plotColor))
             else:
                 axes.plot(w / (2 * np.pi), gd, label=f.name)
     axes.set_xscale('log')
     axes.set_ylabel('Group delay [samples]')
     axes.set_xlabel('Frequency [Hz]')
     axes.minorticks_on()
     axes.legend(loc='best')
     canvas.draw()
Exemple #30
0
def median_group_delay(ba, fs) -> float:
    """
    :return:  Median group delay of filter in `band`, in milliseconds. `nan` if
                filter poles lie so close to the unit circle that group delay
                cannot be reliably calculated.
    """
    f_nyq = fs / 2
    freqs = linspace(*band, num=1000) / f_nyq
    with ignore(BadCoefficients):
        _, p, _ = tf2zpk(*ba)
    if any(abs(p) > 0.97):
        return nan
    else:
        _, gd_samples = group_delay(ba, freqs)
        mgd_samples = median(gd_samples)
        mgd_seconds = mgd_samples / fs
        return mgd_seconds * 1000
Exemple #31
0
def plot_filter(h, sfreq, freq=None, gain=None, title=None, color='#1f77b4',
                flim=None, fscale='log', alim=_DEFAULT_ALIM, show=True,
                compensate=False):
    """Plot properties of a filter.

    Parameters
    ----------
    h : dict or ndarray
        An IIR dict or 1D ndarray of coefficients (for FIR filter).
    sfreq : float
        Sample rate of the data (Hz).
    freq : array-like or None
        The ideal response frequencies to plot (must be in ascending order).
        If None (default), do not plot the ideal response.
    gain : array-like or None
        The ideal response gains to plot.
        If None (default), do not plot the ideal response.
    title : str | None
        The title to use. If None (default), deteremine the title based
        on the type of the system.
    color : color object
        The color to use (default '#1f77b4').
    flim : tuple or None
        If not None, the x-axis frequency limits (Hz) to use.
        If None, freq will be used. If None (default) and freq is None,
        ``(0.1, sfreq / 2.)`` will be used.
    fscale : str
        Frequency scaling to use, can be "log" (default) or "linear".
    alim : tuple
        The y-axis amplitude limits (dB) to use (default: (-60, 10)).
    show : bool
        Show figure if True (default).
    compensate : bool
        If True, compensate for the filter delay (phase will not be shown).

        - For linear-phase FIR filters, this visualizes the filter coefficients
          assuming that the output will be shifted by ``N // 2``.
        - For IIR filters, this changes the filter coefficient display
          by filtering backward and forward, and the frequency response
          by squaring it.

        .. versionadded:: 0.18

    Returns
    -------
    fig : matplotlib.figure.Figure
        The figure containing the plots.

    See Also
    --------
    mne.filter.create_filter
    plot_ideal_filter

    Notes
    -----
    .. versionadded:: 0.14
    """
    from scipy.signal import freqz, group_delay, lfilter, filtfilt, sosfilt
    import matplotlib.pyplot as plt
    from matplotlib.ticker import FormatStrFormatter, NullFormatter
    sosfiltfilt = get_sosfiltfilt()
    sfreq = float(sfreq)
    _check_option('fscale', fscale, ['log', 'linear'])
    flim = _get_flim(flim, fscale, freq, sfreq)
    if fscale == 'log':
        omega = np.logspace(np.log10(flim[0]), np.log10(flim[1]), 1000)
    else:
        omega = np.linspace(flim[0], flim[1], 1000)
    omega /= sfreq / (2 * np.pi)
    if isinstance(h, dict):  # IIR h.ndim == 2:  # second-order sections
        if 'sos' in h:
            H = np.ones(len(omega), np.complex128)
            gd = np.zeros(len(omega))
            for section in h['sos']:
                this_H = freqz(section[:3], section[3:], omega)[1]
                H *= this_H
                if compensate:
                    H *= this_H.conj()  # time reversal is freq conj
                else:
                    # Assume the forward-backward delay zeros out, which it
                    # mostly should
                    with warnings.catch_warnings(record=True):  # singular GD
                        warnings.simplefilter('ignore')
                        gd += group_delay((section[:3], section[3:]), omega)[1]
            n = estimate_ringing_samples(h['sos'])
            delta = np.zeros(n)
            delta[0] = 1
            if compensate:
                delta = np.pad(delta, [(n - 1, 0)], 'constant')
                func = sosfiltfilt
                gd += (len(delta) - 1) // 2
            else:
                func = sosfilt
            h = func(h['sos'], delta)
        else:
            H = freqz(h['b'], h['a'], omega)[1]
            if compensate:
                H *= H.conj()
            with warnings.catch_warnings(record=True):  # singular GD
                warnings.simplefilter('ignore')
                gd = group_delay((h['b'], h['a']), omega)[1]
                if compensate:
                    gd += group_delay(h['b'].conj(), h['a'].conj(), omega)[1]
            n = estimate_ringing_samples((h['b'], h['a']))
            delta = np.zeros(n)
            delta[0] = 1
            if compensate:
                delta = np.pad(delta, [(n - 1, 0)], 'constant')
                func = filtfilt
            else:
                func = lfilter
            h = func(h['b'], h['a'], delta)
        if title is None:
            title = 'SOS (IIR) filter'
        if compensate:
            title += ' (forward-backward)'
    else:
        H = freqz(h, worN=omega)[1]
        with warnings.catch_warnings(record=True):  # singular GD
            warnings.simplefilter('ignore')
            gd = group_delay((h, [1.]), omega)[1]
        title = 'FIR filter' if title is None else title
        if compensate:
            title += ' (delay-compensated)'
    # eventually axes could be a parameter
    fig, (ax_time, ax_freq, ax_delay) = plt.subplots(3)
    t = np.arange(len(h))
    if compensate:
        n_shift = (len(h) - 1) // 2
        t -= n_shift
        assert t[0] == -t[-1]
        gd -= n_shift
    t = t / sfreq
    gd = gd / sfreq
    f = omega * sfreq / (2 * np.pi)
    ax_time.plot(t, h, color=color)
    ax_time.set(xlim=t[[0, -1]], xlabel='Time (s)',
                ylabel='Amplitude', title=title)
    mag = 10 * np.log10(np.maximum((H * H.conj()).real, 1e-20))
    sl = slice(0 if fscale == 'linear' else 1, None, None)
    # Magnitude
    ax_freq.plot(f[sl], mag[sl], color=color, linewidth=2, zorder=4)
    if freq is not None and gain is not None:
        plot_ideal_filter(freq, gain, ax_freq, fscale=fscale, show=False)
    ax_freq.set(ylabel='Magnitude (dB)', xlabel='', xscale=fscale)
    # Delay
    ax_delay.plot(f[sl], gd[sl], color=color, linewidth=2, zorder=4)
    # shade nulled regions
    for start, stop in zip(*_mask_to_onsets_offsets(mag <= -39.9)):
        ax_delay.axvspan(f[start], f[stop - 1], facecolor='k', alpha=0.05,
                         zorder=5)
    ax_delay.set(xlim=flim, ylabel='Group delay (s)', xlabel='Frequency (Hz)',
                 xscale=fscale)
    xticks, xticklabels = _filter_ticks(flim, fscale)
    dlim = np.abs(t).max() / 2.
    dlim = [-dlim, dlim]
    for ax, ylim, ylabel in ((ax_freq, alim, 'Amplitude (dB)'),
                             (ax_delay, dlim, 'Delay (s)')):
        if xticks is not None:
            ax.set(xticks=xticks)
            ax.set(xticklabels=xticklabels)
        ax.xaxis.set_major_formatter(FormatStrFormatter('%0.1f'))
        ax.xaxis.set_minor_formatter(NullFormatter())
        ax.set(xlim=flim, ylim=ylim, xlabel='Frequency (Hz)', ylabel=ylabel)
    adjust_axes([ax_time, ax_freq, ax_delay])
    tight_layout()
    plt_show(show)
    return fig
Exemple #32
0
def plot_filter(h, sfreq, freq=None, gain=None, title=None, color='#1f77b4',
                flim=None, fscale='log', alim=(-60, 10), show=True):
    """Plot properties of a filter.

    Parameters
    ----------
    h : dict or ndarray
        An IIR dict or 1D ndarray of coefficients (for FIR filter).
    sfreq : float
        Sample rate of the data (Hz).
    freq : array-like or None
        The ideal response frequencies to plot (must be in ascending order).
        If None (default), do not plot the ideal response.
    gain : array-like or None
        The ideal response gains to plot.
        If None (default), do not plot the ideal response.
    title : str | None
        The title to use. If None (default), deteremine the title based
        on the type of the system.
    color : color object
        The color to use (default '#1f77b4').
    flim : tuple or None
        If not None, the x-axis frequency limits (Hz) to use.
        If None, freq will be used. If None (default) and freq is None,
        ``(0.1, sfreq / 2.)`` will be used.
    fscale : str
        Frequency scaling to use, can be "log" (default) or "linear".
    alim : tuple
        The y-axis amplitude limits (dB) to use (default: (-60, 10)).
    show : bool
        Show figure if True (default).

    Returns
    -------
    fig : matplotlib.figure.Figure
        The figure containing the plots.

    See Also
    --------
    mne.filter.create_filter
    plot_ideal_filter

    Notes
    -----
    .. versionadded:: 0.14
    """
    from scipy.signal import freqz, group_delay
    import matplotlib.pyplot as plt
    sfreq = float(sfreq)
    _check_fscale(fscale)
    flim = _get_flim(flim, fscale, freq, sfreq)
    if fscale == 'log':
        omega = np.logspace(np.log10(flim[0]), np.log10(flim[1]), 1000)
    else:
        omega = np.linspace(flim[0], flim[1], 1000)
    omega /= sfreq / (2 * np.pi)
    if isinstance(h, dict):  # IIR h.ndim == 2:  # second-order sections
        if 'sos' in h:
            from scipy.signal import sosfilt
            h = h['sos']
            H = np.ones(len(omega), np.complex128)
            gd = np.zeros(len(omega))
            for section in h:
                this_H = freqz(section[:3], section[3:], omega)[1]
                H *= this_H
                with warnings.catch_warnings(record=True):  # singular GD
                    gd += group_delay((section[:3], section[3:]), omega)[1]
            n = estimate_ringing_samples(h)
            delta = np.zeros(n)
            delta[0] = 1
            h = sosfilt(h, delta)
        else:
            from scipy.signal import lfilter
            n = estimate_ringing_samples((h['b'], h['a']))
            delta = np.zeros(n)
            delta[0] = 1
            H = freqz(h['b'], h['a'], omega)[1]
            with warnings.catch_warnings(record=True):  # singular GD
                gd = group_delay((h['b'], h['a']), omega)[1]
            h = lfilter(h['b'], h['a'], delta)
        title = 'SOS (IIR) filter' if title is None else title
    else:
        H = freqz(h, worN=omega)[1]
        with warnings.catch_warnings(record=True):  # singular GD
            gd = group_delay((h, [1.]), omega)[1]
        title = 'FIR filter' if title is None else title
    gd /= sfreq
    fig, axes = plt.subplots(3)  # eventually axes could be a parameter
    t = np.arange(len(h)) / sfreq
    f = omega * sfreq / (2 * np.pi)
    axes[0].plot(t, h, color=color)
    axes[0].set(xlim=t[[0, -1]], xlabel='Time (sec)',
                ylabel='Amplitude h(n)', title=title)
    mag = 10 * np.log10(np.maximum((H * H.conj()).real, 1e-20))
    axes[1].plot(f, mag, color=color, linewidth=2, zorder=4)
    if freq is not None and gain is not None:
        plot_ideal_filter(freq, gain, axes[1], fscale=fscale,
                          title=None, show=False)
    axes[1].set(ylabel='Magnitude (dB)', xlabel='', xscale=fscale)
    sl = slice(0 if fscale == 'linear' else 1, None, None)
    axes[2].plot(f[sl], gd[sl], color=color, linewidth=2, zorder=4)
    axes[2].set(xlim=flim, ylabel='Group delay (sec)', xlabel='Frequency (Hz)',
                xscale=fscale)
    xticks, xticklabels = _filter_ticks(flim, fscale)
    dlim = [0, 1.05 * gd[1:].max()]
    for ax, ylim, ylabel in zip(axes[1:], (alim, dlim),
                                ('Amplitude (dB)', 'Delay (sec)')):
        if xticks is not None:
            ax.set(xticks=xticks)
            ax.set(xticklabels=xticklabels)
        ax.set(xlim=flim, ylim=ylim, xlabel='Frequency (Hz)', ylabel=ylabel)
    adjust_axes(axes)
    tight_layout()
    plt_show(show)
    return fig