예제 #1
0
 def _gauss_norm(self, n: int):
     """ Returns zeros, poles and gain of Gauss normalized approximation """
     transfer_function = self._get_tf(n)
     trans_zpk = transfer_function.to_zpk()
     z, p, k = trans_zpk.zeros, trans_zpk.poles, trans_zpk.gain
     w, h = ss.freqs_zpk(z, p, k)
     norm_gd = -np.diff(np.unwrap(np.angle(h))) / np.diff(w)
     trans_zpk.poles = trans_zpk.poles * norm_gd[0]
     trans_zpk.gain = np.prod(abs(trans_zpk.poles))
     return trans_zpk.zeros, trans_zpk.poles, trans_zpk.gain
예제 #2
0
    def _gauss_des(self, z_n, p_n):
        """ Returns zeros, poles and gain of Gauss denormalized approximation """

        p = p_n / (self.group_delay * 1e-3)  # user's group delay in ms
        k = prod(abs(p))
        w, h = ss.freqs_zpk([], p, k)
        #norm_gd = -diff(unwrap(angle(h))) / diff(w)
        #f_n = w / (2 * pi)
        #plt.semilogx(f_n[:-1], norm_gd)
        #plt.show()
        return z_n, p, k
예제 #3
0
def plot_zpk(z, p, k, fp, fs, Amax, Amin):
    w, h = signal.freqs_zpk(z, p, k, 2 * np.pi * np.logspace(2, 4, 500))

    plt.plot(w / (2 * np.pi), 20 * np.log10(abs(h)))
    plt.xscale('log')
    plt.title('Lowpass filter fit to constraints')
    plt.xlabel('Frequency [Hz]')
    plt.ylabel('Amplitude [dB]')
    plt.grid(True, which='both', axis='both')
    plt.fill([1e2, 1e2, fp, fp], [-Amin, -Amax, -Amax, -Amin], '0.9',
             lw=0)  # pass
    plt.fill([fs, fs, 1e4, 1e4], [-Amin, 0, 0, -Amin], '0.9', lw=0)  # stop
    plt.axis([1e2, 1e4, -50, 1])
    def test_freq_resp(self):
        # Test that frequency response meets tolerance from ITU-R BS.468-4
        upper = responses + upper_limits
        lower = responses + lower_limits

        z, p, k = ITU_R_468_weighting_analog()
        w, h = signal.freqs_zpk(z, p, k, 2*pi*frequencies)
        levels = 20 * np.log10(abs(h))

        if mpl:
            plt.figure('468')
            plt.title('ITU 468 weighting limits')
            plt.semilogx(frequencies, levels, alpha=0.7, label='analog')
            plt.semilogx(frequencies, upper, 'r:', alpha=0.7)
            plt.semilogx(frequencies, lower, 'r:', alpha=0.7)
            plt.grid(True, color='0.7', linestyle='-', which='major')
            plt.grid(True, color='0.9', linestyle='-', which='minor')
            plt.legend()

        assert all(np.less_equal(levels, upper))
        assert all(np.greater_equal(levels, lower))
    def test_freq_resp(self):
        # Test that frequency response meets tolerance from ITU-R BS.468-4
        upper = responses + upper_limits
        lower = responses + lower_limits

        z, p, k = ITU_R_468_weighting_analog()
        w, h = signal.freqs_zpk(z, p, k, 2 * pi * frequencies)
        levels = 20 * np.log10(abs(h))

        if mpl:
            plt.figure('468')
            plt.title('ITU 468 weighting limits')
            plt.semilogx(frequencies, levels, alpha=0.7, label='analog')
            plt.semilogx(frequencies, upper, 'r:', alpha=0.7)
            plt.semilogx(frequencies, lower, 'r:', alpha=0.7)
            plt.grid(True, color='0.7', linestyle='-', which='major')
            plt.grid(True, color='0.9', linestyle='-', which='minor')
            plt.legend()

        assert all(np.less_equal(levels, upper))
        assert all(np.greater_equal(levels, lower))
예제 #6
0
    def test_freq_resp(self):
        # Test that frequency response meets tolerance from ANSI S1.4-1983
        for curve in {'A', 'B', 'C'}:
            N = len(responses[curve])  # Number of frequencies in spec
            f_test = frequencies[:N]
            upper = responses[curve] + upper_limits[:N]
            lower = responses[curve] + lower_limits[:N]

            z, p, k = ABC_weighting(curve)
            w, h = signal.freqs_zpk(z, p, k, 2 * pi * f_test)
            levels = 20 * np.log10(abs(h))

            if mpl:
                plt.figure(curve)
                plt.title('{}-weighting limits (Type 0)'.format(curve))
                plt.semilogx(f_test, levels, alpha=0.7, label='analog')
                plt.semilogx(f_test, upper, 'r:', alpha=0.7)
                plt.semilogx(f_test, lower, 'r:', alpha=0.7)
                plt.grid(True, color='0.7', linestyle='-', which='major')
                plt.grid(True, color='0.9', linestyle='-', which='minor')
                plt.legend()

            assert all(np.less_equal(levels, upper))
            assert all(np.greater_equal(levels, lower))
예제 #7
0
                1, 0.7, 1, 1, 1, 1, 1, 1, 1.5, 1.5, 1.5, 2, 2, 2.5, 3])
low1 = np.array([np.inf, np.inf, 4, 2, 1.5, 1.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 0.7, 1, 1, 1, 1, 1, 1, 1.5, 2, 2.5, 3, 5, 8, np.inf])
up0 = np.array([2, 2, 2, 2, 1.5, 1, 1, 1, 1, 1, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7,
                0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 1, 1, 1, 2, 2, 2, 2])
low0 = np.array([5, 3, 3, 2, 1.5, 1, 1, 1, 1, 1, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7,
                0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 1, 1.5, 2, 3, 3, 3, 3])

# FS_list = [4]
for fs in FS_list:
    f = np.logspace(1, np.log10(30000), 1024)
    wn = f * 2 * np.pi/fs
    [ba, aa] = vf.awt_design(fs)
    [bc, ac] = vf.cwt_design(fs)
    # compute the frequency response of the analog weighting filter
    [wa, ha] = sg.freqs_zpk(Za, Pa, Ka, wn*fs)
    [wc, hc] = sg.freqs_zpk(Zc, Pc, Kc, wn*fs)

    [wza, hza] = sg.freqz(ba, aa, wn)
    [wzc, hzc] = sg.freqz(bc, ac, wn)
# end for fs in FS_list

    hadb = 20*np.log10(np.abs(ha))
    hcdb = 20*np.log10(np.abs(hc))
    hzadb = 20*np.log10(np.abs(hza))
    hzcdb = 20*np.log10(np.abs(hzc))

    diffa = hzadb - hadb
    diffc = hzcdb - hcdb

    plt.figure(figsize=[10, 6])
예제 #8
0
def splane_eval(s):
    """
    `s` is a value on the analog S plane.  The frequency response at 10 Hz
    would be s = 1j*2*pi*10, for instance.
    """
    return freqs_zpk(z, p, k, -1j * s)[1]
예제 #9
0

gs = gridspec.GridSpec(2, 3, width_ratios=[2.5, 1, 1], height_ratios=[2.5, 1])

fig = plt.figure(figsize=(9, 7))

ax_cplot = fig.add_subplot(gs[0, 0])
cplot(splane_eval, re=(-r, r), im=(-r, r), axes=ax_cplot)
ax_cplot.set_xlabel('$\sigma$')
ax_cplot.set_ylabel('$j \omega$')
ax_cplot.axhline(0, color='white', alpha=0.15)
ax_cplot.axvline(0.5, color='white', alpha=0.15)
ax_cplot.set_title('S plane')
ax_cplot.axis('equal')

w, h = freqs_zpk(z, p, k, np.linspace(-r, r, 500))

ax_fr = fig.add_subplot(gs[0, 1], sharey=ax_cplot)
ax_fr.plot(abs(h), w)
ax_fr.invert_xaxis()
ax_fr.tick_params(
    axis='y',
    left=False,
    right=True,
    labelleft=False,
)
ax_fr.set_xlabel('Magnitude')
ax_fr.grid(True, which='both')

ax_ph = fig.add_subplot(gs[0, 2], sharey=ax_cplot)
ax_ph.plot(np.rad2deg(np.angle(h)), w)
예제 #10
0
def s2z_zpk(s_zeros, s_poles, s_gain, s2z, fs, f0):
    z_zeros, z_poles, z_gain = s2z(s_zeros, s_poles, s_gain, fs=fs)
    z_gain *= _np.abs(_sig.freqs_zpk(s_zeros, s_poles, s_gain, worN=[2*_np.pi*f0])[1])\
        / _np.abs(_sig.freqz_zpk(z_zeros, z_poles, z_gain, worN=[f0], fs=fs)[1])
    return z_zeros, z_poles, z_gain
from scipy.signal import freqs_zpk, iirfilter

z, p, k = iirfilter(4, [1, 10],
                    1,
                    60,
                    analog=True,
                    ftype='cheby1',
                    output='zpk')

w, h = freqs_zpk(z, p, k, worN=np.logspace(-1, 2, 1000))

import matplotlib.pyplot as plt
plt.semilogx(w, 20 * np.log10(abs(h)))
plt.xlabel('Frequency')
plt.ylabel('Amplitude response [dB]')
plt.grid()
plt.show()
예제 #12
0
    return z * wc, p * wc, k


# 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
from scipy import signal
import matplotlib.pyplot as plt

fs = 100
bf = 2 * np.pi * np.array([7, 13])
filts = signal.lti(*signal.butter(4, bf, btype='bandpass', analog=True, output='zpk'))
filtz = signal.lti(*signal.bilinear_zpk(filts.zeros, filts.poles, filts.gain, fs))
wz, hz = signal.freqz_zpk(filtz.zeros, filtz.poles, filtz.gain)
ws, hs = signal.freqs_zpk(filts.zeros, filts.poles, filts.gain, worN=fs*wz)
plt.semilogx(wz*fs/(2*np.pi), 20*np.log10(np.abs(hz).clip(1e-15)), label=r'$|H(j \omega)|$')
plt.semilogx(wz*fs/(2*np.pi), 20*np.log10(np.abs(hs).clip(1e-15)), label=r'$|H_z(e^{j \omega})|$')
plt.legend()
plt.xlabel('Frequency [Hz]')
plt.ylabel('Magnitude [dB]')
plt.grid()
예제 #14
0
def hoge(exc, hor):
    fname = './OSTM_TM_{0}_EXC.xml'.format(exc)
    data = DiagAccess(fname)
    hor1 = data.xfer('K1:VIS-OSTM_TM_DAMP_L_IN1',
                     'K1:VIS-OSTM_TM_TEST_{0}_EXC'.format(exc)).xfer
    hor2 = data.xfer('K1:VIS-OSTM_TM_DAMP_P_IN1',
                     'K1:VIS-OSTM_TM_TEST_{0}_EXC'.format(exc)).xfer
    hor3 = data.xfer('K1:VIS-OSTM_TM_DAMP_Y_IN1',
                     'K1:VIS-OSTM_TM_TEST_{0}_EXC'.format(exc)).xfer
    w = data.xfer('K1:VIS-OSTM_TM_DAMP_L_IN1',
                  'K1:VIS-OSTM_TM_TEST_{0}_EXC'.format(exc)).FHz

    #
    def p(w0, Q):
        p1 = -w0 / (2 * Q) + 1j * np.sqrt((w0)**2 - w0**2 / (4 * Q**2))
        p2 = -w0 / (2 * Q) - 1j * np.sqrt((w0)**2 - w0**2 / (4 * Q**2))
        return [p1, p2]

    # for H1_EXC
    if hor == 'L':
        w0, Q0, k0 = 1.3, 4, 1.0e-0  # Len
        w1, Q1, k1 = 8, 5, 1.0e-1  #
        w2, Q2, k2 = 15, 50, -1.0e-0  # Len
        w3, Q3, k3 = 20, 20, 1.0e-4  #
        w4, Q4, k4 = 15, 20, 3.0e-4  #
        w5, Q5, k5 = 17, 20, 2.0e-4  #
    elif hor == 'P':
        w0, Q0, k0 = 1.3, 4, 1.5e-0
        w1, Q1, k1 = 8, 5, -1.0e-4
        w2, Q2, k2 = 20, 7, 2.0e-4
        w3, Q3, k3 = 20, 20, 2.0e-4  #
        w4, Q4, k4 = 15, 20, 1.0e-4  #
        w5, Q5, k5 = 17, 20, -1.0e-4  #
    elif hor == 'Y':
        w0, Q0, k0 = 1.3, 4, 1.0e-0
        w1, Q1, k1 = 8, 5, -8.0e-4
        w2, Q2, k2 = 20, 7, 1.5e-4
        w3, Q3, k3 = 20, 20, -1.0e-4  #
        w4, Q4, k4 = 15, 20, 1.0e-4  #
        w5, Q5, k5 = 17, 20, -7.0e-4  #
    else:
        pass

    _w1, h1 = freqs_zpk([], p(w0, Q0), k0, w)
    _w2, h2 = freqs_zpk([], p(w1, Q1), k1, w)
    _w3, h3 = freqs_zpk([], p(w2, Q2), k2, w)
    _w4, h4 = freqs_zpk([], p(w3, Q3), k3, w)
    _w5, h5 = freqs_zpk([], p(w4, Q4), k4, w)
    _w6, h6 = freqs_zpk([], p(w5, Q5), k5, w)

    # unknown Delay
    if hor == 'L':
        _w1, delay = freqs_zpk([-0.46], [-12.3], -7, w)  # de-white
        _w1, delay = freqs_zpk(
            [-0.1], [-10], -8,
            w)  # de-white and minus sign caused from dtt2hdf
    else:
        _w1, delay = freqs_zpk([-0.46], [-12.3], -7, w)  # de-white
        _w1, delay = freqs_zpk([-0.1], [-10], -8, w)  # de-white

    _w, h = _w1, (h1 + h2 + h3 + h4 + h5 + h6) * delay
    _w, h = _w1, (h1 + h2 + h3) * delay

    if hor == 'L':
        hor1 = hor1
        coh = data.xfer('K1:VIS-OSTM_TM_DAMP_L_IN1',
                        'K1:VIS-OSTM_TM_TEST_{0}_EXC'.format(exc)).coh
    elif hor == 'P':
        hor1 = hor2
        coh = data.xfer('K1:VIS-OSTM_TM_DAMP_P_IN1',
                        'K1:VIS-OSTM_TM_TEST_{0}_EXC'.format(exc)).coh
    elif hor == 'Y':
        hor1 = hor3
        coh = data.xfer('K1:VIS-OSTM_TM_DAMP_Y_IN1',
                        'K1:VIS-OSTM_TM_TEST_{0}_EXC'.format(exc)).coh
    else:
        pass

    return w, hor1, w1, _w1, h1, _w2, h2, _w3, h3, _w4, h4, _w5, h5, _w6, h6, _w, h, coh
예제 #15
0
def hoge(exc, hor):
    fname = './measurements/OSTM_TM_{0}_EXC.xml'.format(exc)
    data = DiagAccess(fname)
    hor1 = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H1_IN1_DQ',
                     'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).xfer
    hor2 = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H2_IN1_DQ',
                     'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).xfer
    hor3 = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H3_IN1_DQ',
                     'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).xfer
    hor4 = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H4_IN1_DQ',
                     'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).xfer
    w = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H1_IN1_DQ',
                  'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).FHz

    #
    def p(w0, Q):
        p1 = -w0 / (2 * Q) + 1j * np.sqrt((w0)**2 - w0**2 / (4 * Q**2))
        p2 = -w0 / (2 * Q) - 1j * np.sqrt((w0)**2 - w0**2 / (4 * Q**2))
        return [p1, p2]

    # for H1_EXC
    if hor == 'H1':
        w0, Q0, k0 = 1.3, 4, 1.5e-1  # Len
        w1, Q1, k1 = 8, 5, 3.0e-2  #
        w2, Q2, k2 = 15, 30, 1.0e-2  # Len
        w3, Q3, k3 = 20, 20, 1.0e-4  #
        w4, Q4, k4 = 15, 20, 3.0e-4  #
        w5, Q5, k5 = 17, 20, 2.0e-4  #
    elif hor == 'H2':
        w0, Q0, k0 = 1.3, 4, 1.5e-1
        w1, Q1, k1 = 8, 5, -1.0e-1
        w2, Q2, k2 = 20, 7, 2.0e-4
        w3, Q3, k3 = 20, 20, 2.0e-4  #
        w4, Q4, k4 = 15, 20, 1.0e-4  #
        w5, Q5, k5 = 17, 20, -1.0e-4  #
    elif hor == 'H3':
        w0, Q0, k0 = 1.3, 4, 1.5e-1
        w1, Q1, k1 = 8, 5, -8.0e-3
        w2, Q2, k2 = 20, 7, 1.5e-4
        w3, Q3, k3 = 20, 20, -1.0e-4  #
        w4, Q4, k4 = 15, 20, 1.0e-4  #
        w5, Q5, k5 = 17, 20, -7.0e-4  #
    elif hor == 'H4':
        w0, Q0, k0 = 1.3, 4, 1.5e-1  # Len
        w1, Q1, k1 = 8, 5, 1.5e-3  #
        w2, Q2, k2 = 20, 7, 3.5e-4  # Len
        w3, Q3, k3 = 20, 20, -3.0e-4  #
        w4, Q4, k4 = 15, 20, 3.5e-4  #
        w5, Q5, k5 = 17, 20, -4.5e-4  #
    else:
        pass

    _w1, h1 = freqs_zpk([], p(w0, Q0), k0, w)
    _w2, h2 = freqs_zpk([], p(w1, Q1), k1, w)
    _w3, h3 = freqs_zpk([], p(w2, Q2), k2, w)
    _w4, h4 = freqs_zpk([], p(w3, Q3), k3, w)
    _w5, h5 = freqs_zpk([], p(w4, Q4), k4, w)
    _w6, h6 = freqs_zpk([], p(w5, Q5), k5, w)

    # unknown Delay
    if hor == 'H3':
        _w1, delay = freqs_zpk([-0.46], [-12.3], -7, w)  # de-white
        #_w1,delay = freqs_zpk([-0.5],[-1],-8,w) # de-white and minus sign caused from dtt2hdf
    else:
        _w1, delay = freqs_zpk([-0.46], [-12.3], -7, w)  # de-white
        #_w1,delay = freqs_zpk([-0.5],[-1],-8,w) # de-white

    _w, h = _w1, (h1 + h2 + h3 + h4 + h5 + h6) * delay

    if hor == 'H1':
        hor1 = hor1
        coh = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H1_IN1_DQ',
                        'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).coh
    elif hor == 'H2':
        hor1 = hor2
        coh = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H2_IN1_DQ',
                        'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).coh
    elif hor == 'H3':
        hor1 = hor3
        coh = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H3_IN1_DQ',
                        'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).coh
    elif hor == 'H4':
        hor1 = hor4
        coh = data.xfer('K1:VIS-OSTM_TM_OSEMINF_H4_IN1_DQ',
                        'K1:VIS-OSTM_TM_COILOUTF_{0}_EXC'.format(exc)).coh
    else:
        pass

    return w, hor1, w1, _w1, h1, _w2, h2, _w3, h3, _w4, h4, _w5, h5, _w6, h6, _w, h, coh
예제 #16
0

set_rcparams()
outdir = set_outdir()

wc = 2**0
Gd = -12
max_order = 6
orders = np.arange(1, max_order + 1)
wmin, wmax, num_w = 2**-9.5, 2**4.5, 1000
w = np.logspace(np.log10(wmin), np.log10(wmax), num=num_w)

H = np.zeros((max_order, len(w)), dtype='complex')
for i, M in enumerate(orders):
    zpk = higher_order_shelving_holters(Gd, M, wc=wc, normalize=True)
    H[i] = freqs_zpk(*zpk, worN=w)[1]
z, p, _ = zpk

wlim = w[0], w[-1]
wticks = 2**(np.arange(
    np.ceil(np.log2(w)[0] / 4) * 4,
    np.floor(np.log2(w[-1]) / 4) * 4 + 4, 4))
kw = dict(linewidth=2, alpha=1, basex=2)
kw_z = dict(c='C0', marker='o', ms=9, ls='none', mew=1, mfc='none', alpha=1)
kw_p = dict(c='k', marker='x', ms=9, ls='none', mew=1)
kw_artist = dict(edgecolor='gray', linestyle=':', linewidth=1)
colors = [
    cm.get_cmap('Oranges')(x)[:3]
    for x in np.linspace(0.33, 1, num=max_order, endpoint=False)
]