def main(close=True, show=True, save=False, file_names=("Fig9.pdf",)):
    """Plots to be used in the paper."""

    print(f"\nRunning module \"{__name__}\" ...")

    cases = c.get_data("cases", "US")
    cases_padded, pad_sz = c.extrapolate(cases)

    f0, f1 = 1/7.0, 1/8.0
    y_el_1 = ellip_bf(cases_padded, f0, f1)[pad_sz:-pad_sz]
    H = ellip_spec(f0, f1, 1024)
    y_fft_1 = c.apply_spectrum(cases_padded, H)[pad_sz:-pad_sz]

    start = 40
    print("plot #1 begins on date: %s" % c.ind2datetime(start))
    y_label = lambda x, p: "%.0fk" % (x/1000)
    x = np.arange(0, max(cases[start:].shape), 1)
    dz = np.zeros(len(x))

    num = c.next_fig_num(close)
    fig, (ax3) = plt.subplots(1, 1, figsize=(5, 3.294), num=num)
    ax3.fill_between(x, cases[start:], dz, alpha=0.1, color="#000000", label="daily cases")
    ax3.plot(x, y_el_1[start:], linewidth=1.25, label="elliptic high-pass #1", linestyle=(0,(2,1)))
    ax3.plot(x, y_fft_1[start:], linewidth=1.25, label="FFT high-pass #1", linestyle=(0,(9,9)))
    ax3.set(xlabel='time [days]', ylabel='daily new cases')
    ax3.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_label))
    ax3.grid(True, alpha=0.2)
    ax3.axis([min(x), max(x), -15000, 80000])
    ax3.legend(loc='upper left', prop={'size': 9}, handlelength=2)
    plt.tight_layout()

    if show:
        plt.show(block=False)
    if save:
        c.save_fig(fig, file_names[0])
def make_plot(phf,
              x,
              countries,
              close=False,
              show=True,
              save=False,
              file_name=None):
    """Create plot."""

    days = ["S", "M", "T", "W", "T", "F", "S"]
    xticks = np.arange(7.5, 21.5, 1.0)  # xticks at 12-noon
    labels = [days[int(n) % 7] for n in xticks]

    num = c.next_fig_num(close)
    fig = plt.figure(figsize=(10.25, 2), num=num)

    for n_co in range(len(countries)):
        co = countries[n_co]
        ax0 = plt.subplot2grid((1, 5), (0, n_co))

        ax0.plot(x,
                 phf['cases'][co],
                 linewidth=1.25,
                 label="cases",
                 linestyle=(0, ()))
        ax0.plot(x,
                 phf['deaths'][co],
                 linewidth=1.25,
                 label="deaths",
                 linestyle=(0, (6, 1)))
        for n in range(7, 21, 2):
            ax0.fill_between([n, n + 1], [-2, -2], [2, 2],
                             alpha=1.0,
                             color="#eeeeee")

        ax0.axis([7, 21, -1.5, 1.2])
        ax0.set_xticks(xticks)
        ax0.set_xticklabels(labels, fontsize=6)
        ax0.tick_params(axis="x", direction="in", pad=-10)
        ax0.set_yticklabels('')
        ax0.tick_params(axis=u'both', which=u'both', length=0)
        ax0.set(xlabel='day of the week', title=co)
        ax0.title.set_size(10)

        if n_co == 4:
            leg = ax0.legend(bbox_to_anchor=(1.11, 0.5),
                             loc='upper right',
                             prop={'size': 9},
                             handlelength=1.5,
                             framealpha=0.92)
            leg.set_in_layout(False)

    plt.tight_layout()

    if show:
        plt.show(block=False)
    if save:
        c.save_fig(fig, file_name)
Пример #3
0
def plot_signal_freqz(d, fs, filename):
    plt.clf()
    plt.plot(np.linspace(0, fs/1e3, len(d), endpoint=False), 20*np.log10(np.abs(np.fft.fft(d))))
    plt.xlabel('f (kHz)')
    plt.ylabel('Magnitude (dB)')
    plt.tight_layout()
    plt.grid('on', ls='dotted')
    if filename:
        save_fig(plt, filename)
Пример #4
0
def sync_phase_est_test():
    #### 1#hide
    alpna = np.linspace(0, np.pi/4, 10000)
    a = np.cos(alpha)
    b = np.sin(alpha)
    alpha_e = (b/a)/(1+0.2815*(b/a)**2)

    plt.clf()
    plt.plot(alpha*180/np.pi, (alpha-alpha_e)*180/np.pi)
    plt.grid('on', ls=':')
    plt.xlabel('angle (in degree)')
    plt.ylabel('estimation error (in degree)')
    save_fig(plt, '../doc/image/sync_clk_phase_est.png')#hide
Пример #5
0
    def sample_phase(smp, ofst, filename):
        fir_tx = rcosdesign(0.4, 5, 20, 'normal')
        fir_tx = fir_tx/max(fir_tx)
        plt.clf()
        D = (len(fir_tx)-1)/2
        x = np.arange(len(fir_tx)) - D - smp
        l1 = plt.plot(x/20., fir_tx)
        l3 = plt.plot(x/20.-1, fir_tx)
        xm = np.array([-ofst, 0])
        ym = [fir_tx[smp-ofst+D], fir_tx[smp+20+D]]
        m1 = plt.plot(xm/20.0, ym, 'bs')
        m1[0].set_color(l1[0].get_color())
        plt.plot([0, 0], [-0.2, 1.2], 'b-.')
        plt.plot([-ofst/20., -ofst/20.], [-0.2, 1.2], 'b-.')

        add_annotate(0, fir_tx[smp+D+20], (-20, 0))
        add_annotate(-ofst/20., fir_tx[smp+D-ofst], (-20, 0))
        plt.grid('on', ls=":")
        plt.xlabel('n (symbols)')
        plt.xlim([-3, 3])
        plt.ylim([-0.2, 1.2])
        save_fig(plt, filename)
Пример #6
0
def rx_src_test():
    #### 1#hide
    s = np.cos(2*np.pi*1e6/24e6*np.arange(10000))
    s2 = rx_src(s, 24e6, 24e6*(1+100e-6))
    #### 2#hide
    s3 = rx_src(s2, 24e6*(1+100e-6), 24e6)
    np.mean(np.abs(s[100:len(s3)]-s3[100:]))#eval
    #### 3#hide
    plt.clf()
    plt.subplot(121)
    x = np.arange(10, 40)
    plt.plot(x, s[x])
    plt.plot(x, s2[x])
    plt.xlabel('n')
    plt.grid('on', ls=':')
    plt.legend(['s', 's2'])
    plt.subplot(122)
    x = x + 9937
    plt.plot(x, s[x])
    plt.plot(x, s2[x])
    plt.xlabel('n')
    plt.grid('on', ls=':')
    plt.legend(['s', 's2'])
    save_fig(plt, '../doc/image/sync_rx_src_test.svg')
Пример #7
0
def sync_clk_bpsk_demo():
    #### 1#hide
    # parameters
    Fs = 152000 # sample frequency(Hz)
    Fd = 1187.5 # data rate(Hz)
    CLK_OFFSET = 200e-6 # (+/-200ppm)
    SNR = 7 # in dB
    #### 2#hide
    msg_bits = np.random.randint(0, 2, 1000)
    # add PN sequence for frame synchronization
    pn = sync_lfsr()
    msg_cyc = np.hstack((pn, msg_bits, np.zeros(5, dtype=int)))

    #### 3#hide
    # differential encoding
    bit_p = 0
    for i in range(len(msg_cyc)):
        msg_cyc[i] = np.bitwise_xor(bit_p, msg_cyc[i])
        bit_p = msg_cyc[i]

    #### 4#hide
    # BPSK modulation
    # in real case this may be replaced by a lookup table, rather than a filter
    # generate the shaping filter
    UP_SAMP = int(Fs/Fd)
    UP_BASE = UP_SAMP//2
    hf = np.zeros(np.ceil(UP_SAMP/2*UP_BASE/2).astype(int))
    hf[:UP_BASE] = np.cos(np.pi/4*np.linspace(0, 2, UP_BASE))
    hf = np.hstack((hf, hf[-1:0:-1]))
    ht = np.fft.ifft(hf)
    ht = np.hstack((ht[-1 - (len(ht)-1)//2-1-1:], ht[0:(len(ht)-1)//2]))
    # hard coded here, 401 taps around center, just for simulation
    ht = ht[2048-200:2048+201].real

    #### 5#hide
    # generate bi-phase symbol
    msg_biphase = np.kron(msg_cyc*2-1, [1, -1])
    # shaping filter
    u = np.zeros(UP_BASE)
    u[0] = 1
    msg_shaping = scipy.signal.lfilter(ht, 1, np.kron(msg_biphase, u))*UP_BASE

    #### 6#hide
    # add clock error
    msg_signal = rx_src(msg_shaping, Fs, Fs*(1+CLK_OFFSET))
    # add noise
    gain = 1.0/(np.sum(msg_signal*msg_signal)/len(msg_signal))/(Fs/Fd/4)
    msg_signal = np.sqrt(gain)*msg_signal
    noise = np.random.normal(0, 1, len(msg_signal))
    noise *= 10**(-SNR/20)*np.sqrt(np.mean(msg_signal*msg_signal))*np.sqrt(UP_BASE)
    msg_signal += noise

    #### 7#hide
    # BSKP demodulation
    # down sampling by factor 8
    rx_sig = msg_signal
    fir_ds8 = scipy.signal.firwin2(40, [0, 4750./(Fs), 14250./(Fs), 1], [1, 1, 0, 0])
    rx_sig = scipy.signal.lfilter(fir_ds8, 1, rx_sig)
    rx_sig = rx_sig[::8]
    #### 8#hide
    # generate the matching filter
    hf8 = np.zeros(int(UP_SAMP/8/2*UP_BASE/2))
    hf8[:UP_BASE] = np.cos(np.pi/4*np.linspace(0, 2, UP_BASE))
    hf8 = np.hstack((hf8, hf8[-1:0:-1]))
    ht8 = np.fft.ifft(hf8)
    ht8 = np.hstack((ht8[-1- (len(ht8)-1)//2-1-1:-1], ht8[:(len(ht8)-1)//2]))
    # filter the signal from bit '1'
    s = np.hstack((np.ones(8), -1*np.ones(8), np.zeros(len(ht8))))
    fir_match = scipy.signal.lfilter(ht8, 1, s)
    fir_match = fir_match[246:285].real
    # match filtering
    rx_sig = scipy.signal.lfilter(fir_match, 1, rx_sig)

    #### 9#hide
    # Timing recovery and BPSK demodulation
    rx_bits, smp_time = sync_clk_bpsk(rx_sig, UP_SAMP/8, 1)

    #### 10#hide
    # differential decoding
    rx_bits_diff = np.bitwise_xor(np.hstack(([0], rx_bits[:-1])), rx_bits)

    # frame synchronization
    sync_corr = scipy.signal.convolve(rx_bits_diff*2-1, np.flipud(pn)*2-1)
    start = np.where(sync_corr > 80)[0]
    if len(start) == 0:
        print('Frame Header error!')
    else:
        print('Frame Header: %d at %d'%(sync_corr[start[0]], start[0]))
        msg_rx = rx_bits_diff[start[0]+1:]
        lenmin = min(len(msg_bits), len(msg_rx))
        err = sum(abs(msg_bits[:lenmin] - msg_rx[:lenmin]))
        print('BER: %f (%d/%d)'%(float(err)/lenmin, err, lenmin))

    ####
    plt.clf()
    plt.subplot(121)
    plt.plot(ht)
    plt.grid('on', ls=":")
    plt.xlabel('n (samples)')
    plt.ylabel('$h_T(n)$')
    plt.subplot(122)
    plt.plot(np.linspace(0, Fs, len(hf)), hf)
    plt.grid('on', ls=":")
    plt.xlim([0, Fd*3])
    plt.xlabel('f (Hz)')
    plt.ylabel('$H_T(f)$')
    save_fig(plt, '../doc/image/sync_clk_bpsk_shaping.svg')

    plt.clf()
    s = np.hstack((np.ones(64), -1*np.ones(64), np.zeros(len(ht))))
    sym = scipy.signal.lfilter(ht, 1, s)
    x = np.arange(len(ht)/2-50, len(ht)/2+200)
    plt.plot(x-266, sym[x])
    plt.plot(x-266, -sym[x])
    plt.grid('on', ls=":")
    plt.legend(['bit 1', 'bit 0'])
    plt.xlabel('n (samples)')
    save_fig(plt, '../doc/image/sync_clk_bpsk_biphase.svg')

    plt.clf()
    plt.plot(rx_sig)
    plt.plot(smp_time, rx_sig[smp_time], 'o')
    plt.grid('on', ls=":")
    plt.xlim([0, 400])
    plt.xlabel('n (samples)')
    save_fig(plt, '../doc/image/sync_clk_bpsk_sampling.png')
Пример #8
0
def sync_clk_demo():
    #### 1#hide
    Fsym = 1e6 # symbol rate
    UPS = 8 # up sampling factor
    Fs = Fsym*UPS # tx sampling rate
    Fs_rx = Fs*(1+100e-6) # rx sampling rate with clock offset
    DECISION = False # True --> hard decision, False --> use true signal
    SNR = 30 # awgn (dB)
    # Modulation
    MODE = 4
    PHASE_OFFSET = np.pi/MODE
    # the maximum phase error without bit error
    PHASE_SPACE = 2*np.pi/MODE/2
    #mapping table for hard decision
    PHASE = 2*np.pi/8*np.array([1, 3, -3, -1])

    #### 2#hide
    symbol = np.floor(MODE*np.random.rand(10000))
    signal = np.exp(1j*(2*np.pi/MODE*symbol + PHASE_OFFSET))

    # tx shaping filter
    fir_tx = rcosdesign(0.4, 3, UPS)
    s = np.kron(signal, np.concatenate((np.ones([1]), np.zeros([UPS-1]))))
    s = scipy.signal.lfilter(fir_tx, 1, s)
    # remove the filter delay
    s = s[(len(fir_tx)-1)//2:]

    #### 3#hide
    # rx
    # add timing error
    r = rx_src(s, Fs, Fs_rx)
    # add AWGN
    noise = np.random.normal(0, 0.5, len(r)*2)
    noise = noise[::2] + 1j*noise[1::2]
    noise *= 10**(-SNR/20)*np.sqrt(np.mean(r*np.conj(r)).real)*np.sqrt(UPS)
    r += noise

    #### 3.1#hide
    # match filter
    fir_rx = rcosdesign(0.4, 3, UPS)
    z = scipy.signal.lfilter(fir_rx, 1, r)
    # remove the filter delay
    z = z[(len(fir_rx)-1)//2:]

    #### 4#hide
    # estimated error
    timing_err = 0.0
    timing_err_p = 0.0
    timing_err_i = 0.0
    # hard & soft values and phase error of previous symbol
    z_h_p, z_s_p, ph_e_p = 0, 0, 0

    # index & counter for down-sampling by a factor of UPS
    ds_idx, ds_cnt = 0, UPS-1

    # timing recovery parameters
    ORDER = 16 #the filter order in Fs sampling rate
    M = 20 # up sampling factor
    N = M # down sampling factor
    flt = scipy.signal.firwin2(ORDER*M+1, [0, 0.5/M, 1.0/M, 1], [1, 1, 0, 0])
    # only saving the right half coefficients
    flt = flt[ORDER*M//2:]
    flt = np.hstack((flt, np.zeros(M+1)))
    # timing recovery block initialize value
    alpha = 2*M
    z_buf = np.zeros(ORDER+1, dtype=z.dtype)
    for i in range(ORDER//2):
        z_buf[ORDER//2-1-i] = z[i]

    #### 5#hide
    # output from the timing recovery block
    z2 = np.zeros(np.ceil(len(z)*(1+200e-6)/N*M).astype(int), dtype=z.dtype)
    # error display
    ph_err = np.zeros(np.ceil(float(len(z))/UPS).astype(int), dtype=z.dtype)
    terr_est = np.zeros(np.ceil(len(ph_err)).astype(int))
    # symbol after timing recovery
    z_out = np.zeros(np.ceil(len(ph_err)).astype(int), dtype=z.dtype)

    # the current sample index from the timing recovery block
    idx_tr = 0
    # the index of next sample from the timing recovery block to be processed
    idx_tr_p = 0
    #### 6#hide
    for i in range(ORDER//2, len(z)):
        # shift in one data for timing recovery
        z_buf = np.roll(z_buf, 1)
        z_buf[0] = z[i]
        # update the alpha
        alpha -= M
        # timing recovery
        while alpha <= M:
            output = 0
            # left side
            delta = M - alpha
            for k in range(ORDER//2+1):
                delta_i = int(delta+k*M)
                delta_f = delta+k*M - delta_i
                coeff_k = flt[delta_i]*(1-delta_f) + flt[delta_i+1]*delta_f
                output += coeff_k*z_buf[ORDER//2-k]

            # right side
            delta2 = M-delta
            for k in range(ORDER//2):
                delta_i = int(delta2+k*M)
                delta_f = delta2+k*M - delta_i
                coeff_k = flt[delta_i]*(1-delta_f) + flt[delta_i+1]*delta_f
                output += coeff_k*z_buf[ORDER//2+1+k]

            #output
            z2[idx_tr] = output*M
            idx_tr += 1

            # next output position
            alpha += N
            # compensate the timing error
            alpha += timing_err

        # down sampling by factor UPS, calculate the timing error,
        while idx_tr_p < idx_tr:
            # new input from the sampling rate conversion block
            z_in = z2[idx_tr_p]
            idx_tr_p += 1
            ds_cnt += 1
            # sampling for hard decision and timing error estimation
            if ds_cnt >= UPS:
                ds_cnt -= UPS
                # hard decision
                if DECISION == 0:
                    z_h = signal[ds_idx]
                else:
                    ph = np.arctan2(z_in.imag, z_in.real)
                    b = np.argmin(np.abs(ph-PHASE))
                    z_h = np.exp(1j*PHASE[b])

                # timing error calculating
                e_c = z_in*np.conj(z_h)
                ph_e = np.arctan2(e_c.imag, e_c.real)
                # calibrate
                if abs(ph_e_p) > PHASE_SPACE or abs(ph_e) > PHASE_SPACE:
                    tmer = 0
                else:
                    tmerr = np.real(np.conj(z_h_p)*z_in - np.conj(z_h)*z_s_p)
                # for next symbol
                z_s_p, z_h_p, ph_e_p = z_in, z_h, ph_e
                # PI controller
                timing_err_i += tmerr*0.001
                timing_err_p = tmerr*0.09
                timing_err = timing_err_i + timing_err_p
                # for plot #hide
                terr_est[ds_idx] = timing_err #hide
                z_out[ds_idx] = z_in #hide
                ph_err[ds_idx] = e_c #hide
                ds_idx += 1

    #### figure
    plt.figure(1)
    plt.clf()
    plt.scatter(z[::UPS].real, z[::UPS].imag)
    plt.grid('on', ls=':')
    save_fig(plt, '../doc/image/sync_clk_demo_r.png')

    plt.figure(2)
    plt.clf()
    plt.plot(terr_est[:ds_idx])
    plt.plot([0, ds_idx-1], [100e-6*20, 100e-6*20])
    plt.grid('on', ls=':')
    plt.xlabel('symbol')
    plt.ylabel('timing err')
    plt.legend(['estimated timing err', 'timing err'])
    plt.ylim([-0.04, 0.04])
    save_fig(plt, '../doc/image/sync_clk_demo_err.png')
    ph_err = ph_err[:ds_idx] # remove the empty tail
    # measurement
    e = ph_err[1:] - ph_err[:-1]
    q = ph_err[1:]
    ##
    IGNORE = 300
    z_out = z_out[IGNORE:ds_idx]
    plt.figure(3)
    plt.clf()
    plt.scatter(z_out.real, z_out.imag)
    plt.grid('on', ls=':')
    save_fig(plt, '../doc/image/sync_clk_demo_sym.png')

    # devm parameters
    rms_devm_thrd = 0.2
    peak_devm_thrd = 0.35
    devm_99_thrd = 0.3

    ##
    e = e[IGNORE:]
    q = q[IGNORE:]
    hc = np.histogram(np.abs(e/q), [0, devm_99_thrd])
    devm_99 = hc[0][0]/len(q)*100
    rms_devm = np.sqrt(np.mean(e*np.conj(e))/np.mean(q*np.conj(q))).real
    peak_dvem = np.sqrt(np.max(e*np.conj(e)) /(np.mean(q*np.conj(q)))).real

    if rms_devm > rms_devm_thrd:
        print('RMS DEVEM:%f, failed'%rms_devm)
    else:
        print('RMS DEVEM:%f, passed'%rms_devm)

    if peak_dvem > peak_devm_thrd:
        print('PEAK DEVEM:%f failed'%peak_dvem)
    else:
        print('PEAK DEVEM:%f passed'%peak_dvem)

    if devm_99 < 99:
        print('99 DEVEM:%f failed'%devm_99)
    else:
        print('99 DEVEM:%f passed'%devm_99)
Пример #9
0
def plot_sync_clock():
    def add_annotate(x, y, offset, txt=None):
        ant = plt.gca().annotate("", xy=(x, y), xytext=offset,
                textcoords='offset points', ha='right', va='bottom',
                arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0'))
        if txt is None:
            txt = '%0.2f'%(y)
        ant.set_text(txt)

    def sample_phase(smp, ofst, filename):
        fir_tx = rcosdesign(0.4, 5, 20, 'normal')
        fir_tx = fir_tx/max(fir_tx)
        plt.clf()
        D = (len(fir_tx)-1)/2
        x = np.arange(len(fir_tx)) - D - smp
        l1 = plt.plot(x/20., fir_tx)
        l3 = plt.plot(x/20.-1, fir_tx)
        xm = np.array([-ofst, 0])
        ym = [fir_tx[smp-ofst+D], fir_tx[smp+20+D]]
        m1 = plt.plot(xm/20.0, ym, 'bs')
        m1[0].set_color(l1[0].get_color())
        plt.plot([0, 0], [-0.2, 1.2], 'b-.')
        plt.plot([-ofst/20., -ofst/20.], [-0.2, 1.2], 'b-.')

        add_annotate(0, fir_tx[smp+D+20], (-20, 0))
        add_annotate(-ofst/20., fir_tx[smp+D-ofst], (-20, 0))
        plt.grid('on', ls=":")
        plt.xlabel('n (symbols)')
        plt.xlim([-3, 3])
        plt.ylim([-0.2, 1.2])
        save_fig(plt, filename)

    fir_tx = rcosdesign(0.4, 5, 20, 'normal')
    fir_tx = fir_tx/max(fir_tx)
    plt.clf()
    D = (len(fir_tx)-1)/2
    smp = 5
    ofst = 20
    x = (np.arange(len(fir_tx)) - D - smp)
    l1 = plt.plot(x/20.0, fir_tx)
    l2 = plt.plot(x/20.0+1, fir_tx)
    l3 = plt.plot(x/20.0-1, fir_tx)
    xm = np.array([-ofst, 0, ofst])
    plt.plot(xm/20.0, fir_tx[smp+xm+D], 'bo')
    for x in xm:
        plt.plot([x/20., x/20.], [-0.2, 1.2], 'b-.')
    plt.plot([-smp/20., -smp/20.], [-0.2, 1.2], 'b-.')
    gca().annotate(r'', xy=(0, 1), xytext=(-smp/20.0, 1), arrowprops=dict(arrowstyle='<->'))
    gca().annotate(r'$\tau$', xy=(0, 1), xytext=(-smp/20.0, 1.05))
    plt.grid('on', ls=":")
    plt.xlabel('n (symbols)')
    xv = np.array([0, -20, 20, -40]) + smp + D
    add_annotate(0, fir_tx[smp+D], (-20, 0), r'$f(\tau)$')
    add_annotate(-ofst/20.0, fir_tx[smp+D-ofst], (-20, 0), r'$f(\tau-1)$')
    add_annotate(+ofst/20.0, fir_tx[smp+D+ofst], (50, 10), r'$f(\tau+1)$')
    plt.xlim([-3, 3])
    plt.ylim([-0.2, 1.2])
    save_fig(plt, '../doc/image/sync_clk_mm.svg')
    sample_phase(0, 20, '../doc/image/sync_clk_mm_optimal.svg')
    sample_phase(5, 20, '../doc/image/sync_clk_mm_late.svg')
    sample_phase(-5, 20, '../doc/image/sync_clk_mm_early.svg')
    sample_phase(-5, 15, '../doc/image/sync_clk_mm_fast.svg')
    sample_phase(5, 25, '../doc/image/sync_clk_mm_slow.svg')

    plt.clf()
    plt.stem(np.arange(-5, 5), np.random.rand(10), basefmt='b')
    plt.plot([smp/20., smp/20.], [-0.2, 1.2], 'r-.')
    add_annotate(smp/20., 0, (20, 0), r'$\tau$')
    plt.ylim([-0.2, 1.2])
    x = np.arange(len(fir_tx)) - D + smp
    plt.grid('on', ls=":")
    plt.xlabel('samples')
    save_fig(plt, '../doc/image/sync_clk_cmp.svg')
    l1 = plt.plot(x/20.0, fir_tx)
    save_fig(plt, '../doc/image/sync_clk_cmp2.svg')

    plt.clf()
    signal = np.ones(100)
    signal[::2] = -1
    # shaping filter
    fir_tx = rcosdesign(0.4, 3, 24, 'normal')
    fir_tx = fir_tx/max(fir_tx)
    s = np.kron(signal, np.concatenate((np.ones([1]), np.zeros([24-1]))))
    s = scipy.signal.lfilter(fir_tx, 1, s)
    # remove the filter delay
    s = s[(len(fir_tx)-1)/2:]
    plt.plot(np.arange(0, len(s))/24., s)
    plt.stem(np.arange(0, len(s), 24)/24., s[0::24], 'b-.', basefmt=' ')
    plt.stem(np.arange(5, len(s), 24)/24., s[5::24], 'r-.', basefmt=' ')
    plt.grid('on', ls=':')
    plt.xlim([1840/24., 1960/24.])
    plt.xlabel('symbols')
    save_fig(plt, '../doc/image/sync_clk_bpsk.svg')
    plt.clf()
    signal = np.floor(np.random.rand(100)+0.5)*2-1
    s = np.kron(signal, np.concatenate((np.ones([1]), np.zeros([24-1]))))
    s = scipy.signal.lfilter(fir_tx, 1, s)
    plt.plot(np.arange(0, len(s))/24., s, 'b-o')
    plt.plot(np.arange(12, len(s), 24)/24., s[12::24], 'ro')
    plt.stem(np.arange(0, len(s), 24)/24., s[0::24], 'b-.', basefmt=' ')
    plt.grid('on', ls=':')
    plt.xlabel('symbols')
    save_fig(plt, '../doc/image/sync_clk_bpsk_tr.svg')

    plt.clf()
    x = np.arange(len(fir_tx)) - len(fir_tx)/2
    plt.plot(x/24., fir_tx)
    x = np.array([-15, 0, 15])
    plt.stem(x/24., fir_tx[x+len(fir_tx)/2], 'b-.', basefmt=' ')
    add_annotate(x[0]/24., fir_tx[x[0]+len(fir_tx)/2], (40, -20), r'$r_{early}$')
    add_annotate(x[1]/24., fir_tx[x[1]+len(fir_tx)/2], (0, -20), r'$r_{on}$')
    add_annotate(x[2]/24., fir_tx[x[2]+len(fir_tx)/2], (-20, -20), r'$r_{late}$')
    plt.grid('on', ls=':')
    plt.xlabel('symbols')
    plt.xlim([-25/24., 25/24.])
    save_fig(plt, '../doc/image/sync_clk_bpsk_opt.svg')
    plt.clf()
    x = np.arange(len(fir_tx)) - len(fir_tx)/2
    plt.plot(x/24., fir_tx)
    x = np.array([-15, 0, 15])-5
    plt.stem(x/24., fir_tx[x+len(fir_tx)/2], 'b-.', basefmt=' ')
    add_annotate(x[0]/24., fir_tx[x[0]+len(fir_tx)/2], (40, -20), r'$r_{early}$')
    add_annotate(x[1]/24., fir_tx[x[1]+len(fir_tx)/2], (0, -20), r'$r_{on}$')
    add_annotate(x[2]/24., fir_tx[x[2]+len(fir_tx)/2], (-20, -20), r'$r_{late}$')
    plt.grid('on', ls=':')
    plt.xlabel('symbols')
    plt.xlim([-25/24., 25/24.])
    save_fig(plt, '../doc/image/sync_clk_bpsk_early.svg')

    plt.clf()
    x = np.arange(len(fir_tx)) - len(fir_tx)/2
    plt.plot(x/24., fir_tx)
    x = np.array([-15, 0, 15])+5
    plt.stem(x/24., fir_tx[x+len(fir_tx)/2], 'b-.', basefmt=' ')
    add_annotate(x[0]/24., fir_tx[x[0]+len(fir_tx)/2], (40, -20), r'$r_{early}$')
    add_annotate(x[1]/24., fir_tx[x[1]+len(fir_tx)/2], (0, -20), r'$r_{on}$')
    add_annotate(x[2]/24., fir_tx[x[2]+len(fir_tx)/2], (-20, -20), r'$r_{late}$')
    plt.grid('on', ls=':')
    plt.xlabel('symbols')
    plt.xlim([-25/24., 25/24.])
    save_fig(plt, '../doc/image/sync_clk_bpsk_late.svg')
Пример #10
0
def sync_error_plot():
    # plot tx signal
    plt.clf()
    signal = np.exp(1j*(2*np.pi/4*np.arange(4)+np.pi/4))
    plt.scatter(signal.real, signal.imag)
    plt.grid('on', ls=':')
    plt.xlabel('real')
    plt.ylabel('imag')
    save_fig(plt, '../doc/image/sync_rx_ideal.svg')

    plt.clf()
    signal = signal * np.exp(1j*np.pi/8)
    plt.scatter(signal.real, signal.imag)
    plt.grid('on', ls=':')
    plt.xlabel('real')
    plt.ylabel('imag')
    save_fig(plt, '../doc/image/sync_rx_phi.svg')

    plt.clf()
    symbol = np.floor(4*np.random.rand(100))
    signal = np.exp(1j*(2*np.pi/4*symbol+np.pi/4))
    signal = signal * np.exp(1j*np.pi*np.arange(100)/1000)
    plt.scatter(signal.real, signal.imag)
    plt.grid('on', ls=':')
    plt.xlabel('real')
    plt.ylabel('imag')
    save_fig(plt, '../doc/image/sync_rx_df.svg')

    plt.clf()
    signal = np.exp(1j*(np.pi/4))
    plt.scatter(signal.real, signal.imag)
    plt.gca().annotate(r'', xy=(0, 0), xytext=(signal.real, signal.imag),
                       arrowprops=dict(arrowstyle='<-'))
    plt.grid('on', ls=':')
    plt.xlabel('real')
    plt.ylabel('imag')
    rx = signal * np.exp(1j*np.pi/8)
    plt.gca().annotate(r'', xy=(0, 0), xytext=(rx.real, rx.imag),
                       arrowprops=dict(arrowstyle='<-'))
    plt.scatter(rx.real, rx.imag)
    plt.grid('on', ls=':')
    plt.xlabel('real')
    plt.ylabel('imag')
    plt.xlim([0, 1])
    plt.ylim([0, 1])
    plt.legend(['estimated signal', 'received signal'])
    angle_plot = get_angle_plot(signal, rx, 1)
    plt.gca().add_patch(angle_plot)
    plt.gca().text(0.3, 0.45, r'$\phi_e$')

    save_fig(plt, '../doc/image/sync_rx_phase_error.svg')

    angle_plot = get_angle_plot(signal, rx, 2)
    plt.gca().add_patch(angle_plot)
    k = signal.imag/signal.real
    x2 = (k*rx.imag+rx.real)/(1+k*k)
    y2 = k*x2
    plt.plot([rx.real, x2], [rx.imag, y2], 'b')
    x3 = x2 - 0.05
    y3 = y2

    x4 = (k*y3+x3)/(1+k*k)
    y4 = k*x4

    b = y2 + 1/k*x2
    x5 = (-1/k*y3+x3+(b*1/k))/(1+1/(k*k))
    y5 = b - 1/k*x5
    plt.plot([x3, x4], [y3, y4], 'b')
    plt.plot([x3, x5], [y3, y5], 'b')
    save_fig(plt, '../doc/image/sync_rx_phase_error_approx.svg')

    plt.clf()
    signal = np.exp(1j*(np.pi/4))
    plt.scatter(signal.real, signal.imag)
    signal2 = signal*np.exp(1j*(np.pi/2))
    plt.scatter(signal2.real, signal2.imag)
    plt.gca().annotate(r'', xy=(0, 0), xytext=(signal.real, signal.imag),
                       arrowprops=dict(arrowstyle='<-'))
    plt.gca().annotate(r'', xy=(0, 0), xytext=(signal2.real, signal2.imag),
                       arrowprops=dict(arrowstyle='<-'))
    plt.grid('on', ls=':')
    plt.xlabel('real')
    plt.ylabel('imag')
    rx = signal * np.exp(1j*(np.pi/8+np.pi/2))
    plt.gca().annotate(r'', xy=(0, 0), xytext=(rx.real, rx.imag),
                       arrowprops=dict(arrowstyle='<-'))
    plt.scatter(rx.real, rx.imag)
    plt.grid('on', ls=':')
    plt.xlabel('real')
    plt.ylabel('imag')
    plt.xlim([-1, 1])
    plt.ylim([0, 1])
    plt.legend(['true signal', 'estimated signal', 'received signal'])
    angle_plot = get_angle_plot(signal, rx, 0.5)
    plt.gca().add_patch(angle_plot)
    plt.gca().text(-0.1, 0.3, r'$\phi_e$')
    angle_plot = get_angle_plot(signal2, rx, 1)
    plt.gca().add_patch(angle_plot)
    plt.gca().text(-0.55, 0.3, r'$\hat{\phi}_e$')
    save_fig(plt, '../doc/image/sync_rx_phase_error_large.svg')
def main(close=True, show=True, save=False, file_names=("Fig6.pdf", "Fig7.pdf", "Fig8.pdf",)):
    """Plots to be used in the paper."""

    print(f"\nRunning module \"{__name__}\" ...")


    deaths = c.get_data("deaths", "US")
    deaths_padded, pad_sz = c.extrapolate(deaths)

    m_ave = seven_day_ave_manual(deaths_padded)[pad_sz-3:-(pad_sz-3)] # moving average

    wp, ws = 1/9, 1/8
    y_el_1 = ellip_bf(deaths_padded, wp, ws)[pad_sz:-pad_sz] # elliptic
    H = ellip_spec(wp, ws, 1024)
    y_fft_1 = c.apply_spectrum(deaths_padded, H)[pad_sz:-pad_sz] # FFT

    wp, ws = 1/21, 1/19
    y_el_2 = ellip_bf(deaths_padded, wp, ws)[pad_sz:-pad_sz] # elliptic
    H = ellip_spec(wp, ws, 1024)
    y_fft_2 = c.apply_spectrum(deaths_padded, H)[pad_sz:-pad_sz] # FFT


    start = 100
    print("plots #1, #2, and #3 begin on date: %s" % c.ind2datetime(start))

    y_lables = lambda x, p: "%.1fk" % (x/1000)
    x = np.arange(0, max(deaths[start:].shape), 1)
    dz = np.zeros(len(x))

    num = c.next_fig_num(close)
    fig1, (ax1) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax1.fill_between(x, deaths[start:], dz, alpha=0.1, color="#000000", label="daily deaths")
    ax1.plot(x, m_ave[start:], linewidth=1.25, label="moving average")
    ax1.set(xlabel='time [days]', ylabel='daily new deaths')
    ax1.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_lables))
    ax1.grid(True, alpha=0.2)
    ax1.axis([min(x), max(x), 0, 2500])
    ax1.legend(loc='upper right', prop={'size': 9}, handlelength=2)
    plt.tight_layout()

    y_lables = lambda x, p: "%.1fk" % (x/1000)
    x = np.arange(0, max(deaths[start:].shape), 1)
    dz = np.zeros(len(x))

    num += 1
    fig2, (ax2) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax2.fill_between(x, deaths[start:], dz, alpha=0.1, color="#000000", label="daily deaths")
    ax2.plot(x, y_el_1[start:], linewidth=1.25, label="elliptic low-pass #1", linestyle=(0,(2,1)))
    ax2.plot(x, y_fft_1[start:], linewidth=1.25, label="FFT low-pass #1", linestyle=(0,(9,9)))
    ax2.set(xlabel='time [days]', ylabel='daily new deaths')
    ax2.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_lables))
    ax2.grid(True, alpha=0.2)
    ax2.axis([min(x), max(x), 0, 2500])
    ax2.legend(loc='upper right', prop={'size': 9}, handlelength=2)
    plt.tight_layout()

    y_lables = lambda x, p: "%.1fk" % (x/1000)
    x = np.arange(0, max(deaths[start:].shape), 1)
    dz = np.zeros(len(x))

    num += 1
    fig4, (ax4) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax4.fill_between(x, deaths[start:], dz, alpha=0.1, color="#000000", label="daily deaths")
    ax4.plot(x, y_el_2[start:], linewidth=1.25, label="elliptic low-pass #2", linestyle=(0,(2,1)))
    ax4.plot(x, y_fft_2[start:], linewidth=1.25, label="FFT low-pass #2", linestyle=(0,(9,9)))
    ax4.set(xlabel='time [days]', ylabel='daily new deaths')
    ax4.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_lables))
    ax4.grid(True, alpha=0.2)
    ax4.axis([min(x), max(x), 0, 2500])
    ax4.legend(loc='upper right', prop={'size': 9}, handlelength=2)
    plt.tight_layout()

    if show:
        plt.show(block=False)
    if save:
        c.save_fig(fig1, file_names[0])
        c.save_fig(fig2, file_names[1])
        c.save_fig(fig4, file_names[2])
Пример #12
0
def main(close=True,
         show=True,
         save=False,
         file_names=(
             "Fig10.pdf",
             "Fig11.pdf",
             "FigUnused_BP.pdf",
         )):
    """Plots to be used in the paper."""

    print(f"\nRunning module \"{__name__}\" ...")

    cases = c.get_data("cases", "US")
    deaths = c.get_data("deaths", "US")

    # Extrapolation
    cases_padded, pad_sz = c.extrapolate(cases)
    deaths_padded, pad_sz = c.extrapolate(deaths)

    numPts = 1024

    # first plot
    wp, ws = [1 / 8.0, 1 / 6.0], [1 / 9.0, 1 / 5.0]
    y_el_1 = ellip_bf(cases_padded, wp, ws)[pad_sz:-pad_sz]  # elliptic
    H_1 = ellip_spec(wp, ws, numPts)
    y_fft_1 = c.apply_spectrum(cases_padded, H_1)[pad_sz:-pad_sz]  # FFT

    start1 = 40
    print("plot #1 begins on date: %s" % c.ind2datetime(start1))
    y1_lables = lambda x, p: "%.0fk" % (x / 1000)
    x1 = np.arange(0, max(cases[start1:].shape), 1)
    dz = np.zeros(len(x1))

    num = c.next_fig_num(close)
    fig1, (ax1) = plt.subplots(1, 1, figsize=(5, 3.294), num=num)
    ax1.fill_between(x1,
                     cases[start1:],
                     dz,
                     alpha=0.1,
                     color="#000000",
                     label="daily deaths")
    ax1.plot(x1,
             y_el_1[start1:],
             linewidth=1.25,
             label="elliptic band-pass #1",
             linestyle=(0, (2, 1)))
    ax1.plot(x1,
             y_fft_1[start1:],
             linewidth=1.25,
             label="FFT band-pass #1",
             linestyle=(0, (9, 9)))
    ax1.get_yaxis().set_major_formatter(ticker.FuncFormatter(y1_lables))
    ax1.grid(True, alpha=0.2)
    ax1.legend(loc='upper left', prop={'size': 9}, handlelength=2)
    ax1.set(xlabel='time [days]')
    ax1.set(ylabel='daily new cases')
    ax1.axis([0, max(y_fft_1[start1:].shape) - 1, -15000, 80000])
    plt.tight_layout()

    # second plot
    wp, ws = [1 / 19, 1 / 9.0], [1 / 21.0, 1 / 8.0]
    y_el_2 = ellip_bf(deaths_padded, wp, ws)[pad_sz:-pad_sz]  # elliptic
    H_2 = ellip_spec(wp, ws, numPts)
    y_fft_2 = c.apply_spectrum(deaths_padded, H_2)[pad_sz:-pad_sz]

    start3 = 100
    print("plot #2 begins on date: %s" % c.ind2datetime(start3))
    y3_lables = lambda x, p: "%.1fk" % (x / 1000)
    x3 = np.arange(0, max(deaths[start3:].shape), 1)
    dz = np.zeros(len(x3))

    num += 1
    fig3, (ax3) = plt.subplots(1, 1, figsize=(5, 3.3), num=num)
    ax3.fill_between(x3,
                     deaths[start3:],
                     dz,
                     alpha=0.1,
                     color="#000000",
                     label="daily deaths")
    ax3.plot(x3,
             y_el_2[start3:],
             linewidth=1.25,
             label="elliptic band-pass #2",
             linestyle=(0, (2, 1)))
    ax3.plot(x3,
             y_fft_2[start3:],
             linewidth=1.25,
             label="FFT band-pass #2",
             linestyle=(0, (9, 9)))
    ax3.get_yaxis().set_major_formatter(ticker.FuncFormatter(y3_lables))
    ax3.grid(True, alpha=0.2)
    ax3.legend(loc='upper right', prop={'size': 9}, handlelength=2)
    ax3.set(xlabel='time [days]')
    ax3.set(ylabel='daily new deaths')
    ax3.axis([0, max(y_fft_2[start3:].shape) - 1, -250, 2500])
    plt.tight_layout()

    # third plot - To check if second plot contains any energy leaking
    # in from bandwidth associated with the seven-day oscillation.
    f = np.arange(0, numPts) / numPts
    d_dt_deaths = c.deriv_fft(deaths)
    Z = np.abs(np.fft.fft(d_dt_deaths, n=int(numPts)) / numPts)
    norm_val = np.max(
        Z[int(numPts * 0.1 +
              0.5):int(numPts * 0.5 +
                       0.5)])  # normalize to max value above 0.1 and 0.5
    Z_deaths = Z / norm_val
    dz = np.zeros(len(f))

    num += 1
    sbStyle = (0, (1, 1))
    pbStyle = (0, (2, 1))
    fig4, (ax4) = plt.subplots(1, 1, figsize=(6, 3.3), num=num)
    ax4.plot(np.array([wp[0]] * 2),
             np.array([-999, 999]),
             '#666666',
             linewidth=1.25,
             linestyle=pbStyle,
             label="\"pass-band\"")
    ax4.plot(np.array([wp[1]] * 2),
             np.array([-999, 999]),
             '#666666',
             linewidth=1.25,
             linestyle=pbStyle)
    ax4.plot(np.array([ws[0]] * 2),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.25,
             linestyle=sbStyle,
             label="\"stop-band\"")
    ax4.plot(np.array([ws[1]] * 2),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.25,
             linestyle=sbStyle)
    ax4.fill_between(f,
                     Z_deaths,
                     dz,
                     label="full spectrum",
                     color="#555500",
                     alpha=0.1)
    ax4.plot(f,
             Z_deaths * np.abs(H_2),
             label="plotted spectrum",
             linewidth=1.25,
             linestyle=(0, ()))
    ax4.set(title="The spectrum plotted for \"Band-Pass #2\"",
            xlabel='frequency [1/day]',
            ylabel='magnitude [1]')
    ax4.title.set_size(10)
    ax4.axis([0, 0.5, -0.0, 1.05])
    ax4.legend(loc='upper right',
               prop={'size': 9},
               handlelength=2,
               framealpha=0.92)
    plt.tight_layout()

    if show:
        plt.show(block=False)

    if save:
        c.save_fig(fig1, file_names[0])
        c.save_fig(fig3, file_names[1])
        c.save_fig(fig4, file_names[2])
def main(close=True,
         show=True,
         save=False,
         file_names=(
             "Fig4.pdf",
             "Fig5.pdf",
             "FigUnused_FR.pdf",
         )):
    """Filter response plots used in the paper."""

    print(f"\nRunning module \"{__name__}\" ...")

    f, H = get_ellip_l1()
    H_lp1_x2 = H * H
    H_El_lp1_x2_db = 20 * np.log10(np.abs(H_lp1_x2))

    f, H = get_ellip_l2()
    H_lp2_x2 = H * H
    H_El_lp2_x2_db = 20 * np.log10(np.abs(H_lp2_x2))

    f, H = get_ellip_h1()
    H_hp1_x2 = H * H
    H_El_hp1_x2_db = 20 * np.log10(np.abs(H_hp1_x2))

    f, H = get_ellip_bp1()
    H_bp1_x2 = H * H
    H_El_bp1_x2_db = 20 * np.log10(np.abs(H_bp1_x2))

    f, H = get_ellip_bp2()
    H_bp2_x2 = H * H
    H_El_bp2_x2_db = 20 * np.log10(np.abs(H_bp2_x2))

    f, H_ma = get_7day_ave()
    H_ma_db = 20 * np.log10(np.abs(H_ma))
    ma_angles = np.unwrap(np.angle(H_ma))  # phase response

    def y_label(x, p):
        if x / np.pi == 0:
            s = r"       0"
        elif x / np.pi == 1:
            s = r"$\pi$"
        elif x / np.pi == -1:
            s = r"-$\pi$"
        else:
            s = r"%.1f$\pi$" % (x / np.pi)
        return s

    num = c.next_fig_num(close)

    fStyle = (0, (1, 1))

    num = c.next_fig_num(close)
    fig1, (ax1) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax1.plot(np.array([1 / 7, 1 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax1.plot(np.array([2 / 7, 2 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax1.plot(np.array([3 / 7, 3 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax1.plot(f, H_ma_db, label="moving average", linewidth=1.25)
    ax1.plot(f,
             H_El_lp2_x2_db,
             label="elliptic low-pass #2",
             linewidth=1.25,
             linestyle=(0, (7, 1)))
    ax1.plot(f,
             H_El_hp1_x2_db,
             label="elliptic high-pass #1",
             linewidth=1.25,
             linestyle=(0, (3, 1)))
    ax1.set(xlabel='frequency [1/day]', ylabel='magnitude [dB]')
    ax1.legend(loc='lower right', prop={'size': 9}, handlelength=2)
    ax1.axis([0.0, 0.5, -120, +5])
    plt.tight_layout()

    num += 1
    fig2, (ax2) = plt.subplots(1, 1, figsize=(5, 2), num=num)
    ax2.plot(np.array([1 / 7, 1 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax2.plot(np.array([2 / 7, 2 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax2.plot(np.array([3 / 7, 3 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax2.plot(f, ma_angles, label="moving average", linewidth=1.25)
    ax2.yaxis.set_major_locator(plt.MultipleLocator(np.pi / 1))
    ax2.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_label))
    ax2.set(xlabel='frequency [1/day]', ylabel='phase angle')
    ax2.legend(loc='upper center', prop={'size': 9}, handlelength=2)
    ax2.axis([0.0, 0.5, -np.pi * 1.2, np.pi * 1.2])
    plt.tight_layout()

    num += 1
    fig3, (ax3) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax3.plot(np.array([1 / 7, 1 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax3.plot(np.array([2 / 7, 2 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax3.plot(np.array([3 / 7, 3 / 7]),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.0,
             linestyle=fStyle)
    ax3.plot(f,
             H_El_lp2_x2_db,
             label="elliptic low-pass #1",
             linewidth=1.25,
             linestyle=(0, ()))
    ax3.plot(f,
             H_El_bp1_x2_db,
             label="elliptic band-pass #1",
             linewidth=1.25,
             linestyle=(0, (7, 1)))
    ax3.plot(f,
             H_El_bp2_x2_db,
             label="elliptic band-pass #2",
             linewidth=1.25,
             linestyle=(0, (3, 1)))
    ax3.legend(loc='lower right', prop={'size': 9}, handlelength=2)
    ax3.set(xlabel='frequency [1/day]', ylabel='magnitude [dB]')
    ax3.set(title="Elliptic filter frequency responses",
            xlabel='frequency [1/day]',
            ylabel='magnitude [1]')
    ax3.axis([0.0, 0.5, -50, +5])
    plt.tight_layout()

    if show:
        plt.show(block=False)

    if save:
        c.save_fig(fig1, file_names[0])
        c.save_fig(fig2, file_names[1])
        c.save_fig(fig3, file_names[2])
Пример #14
0
def main(close=True, show=True, save=False, file_names=("Fig1.pdf",)):
    """Create and save frequency spectrum plot for time series (deaths
    and cases)."""

    print(f"\nRunning module \"{__name__}\" ...")

    # some variables
    # countries = ["United Kingdom", "Brazil", "US", "Mexico", "South Africa", "Russia"]
    # countries = ["United Kingdom", "Brazil", "US", "Mexico", "Argentina", "Kenya"]
    countries = ["United Kingdom", "Brazil", "US", "Mexico", "Argentina", "Switzerland"]

    start = 65
    end = c.num_days()
    print("total days: %d, date range: %s, %s" % (end-start, c.ind2datetime(start), c.ind2datetime(end)))
    print("end-start/7 = %f, (end-start)/3.5 = %f" % ((end-start)/7.0, (end-start)/3.5))

    # Create the data
    p_data = dict()
    for country in countries:
        cases = c.get_data("cases", "global", country=country)
        deaths = c.get_data("deaths", "global", country=country)
        f, Z_cases = process_data(cases, start, end)
        f, Z_deaths = process_data(deaths, start, end)
        p_data[country] = {"cases": Z_cases, "deaths": Z_deaths, "f": f}

    # Plot the data
    axis = [0, 0.5, -0.0, 1.05]
    num = c.next_fig_num(close)
    fig = plt.figure(figsize=(10.25, 3), num=num)
    fStyle = (0,(1,1))
    for row in range(2):
        for col in range(3):
            country = countries[col + row*3]
            sub_p_data = p_data[country]
            Z_cases = sub_p_data["cases"]
            Z_deaths = sub_p_data["deaths"]
            f = sub_p_data["f"]

            ax0 = plt.subplot2grid((2, 3), (row, col), colspan=1)
            ax0.plot(np.array([1/7, 1/7]), np.array([-999, 999]), '#bbbbbb', linewidth=1.0, linestyle=fStyle)
            ax0.plot(np.array([2/7, 2/7]), np.array([-999, 999]), '#bbbbbb', linewidth=1.0, linestyle=fStyle)
            ax0.plot(np.array([3/7, 3/7]), np.array([-999, 999]), '#bbbbbb', linewidth=1.0, linestyle=fStyle)
            ax0.plot(f, Z_cases, label="cases", linewidth=1.25)
            ax0.plot(f, Z_deaths, label="deaths", linewidth=1.25, linestyle=(0,(7,1)))
            ax0.set(title=country)
            ax0.title.set_size(10)
            ax0.get_xaxis().set_tick_params(direction='in')
            ax0.get_yaxis().set_tick_params(direction='in')
            ax0.axis(axis)

            if row == 1:
                ax0.set(xlabel='frequency [1/day]')
            else:
                ax0.set_xticklabels('')

            if col == 0:
                ax0.set(ylabel='magnitude')
            else:
                ax0.set_yticklabels('')

            if (row, col) == (0, 2):
                ax0.legend(bbox_to_anchor=(1.05, 1.3), loc='upper right', prop={'size': 9}, handlelength=2, framealpha=0.92)

    plt.tight_layout()

    if show:
        plt.show(block=False)

    if save:
        c.save_fig(fig, file_names[0])
Пример #15
0
def main(close=True,
         show=True,
         save=False,
         file_names=(
             "Fig12.pdf",
             "Fig13.pdf",
         )):
    """Plot frequency and phase response of derivative algorithms."""

    print(f"\nRunning module \"{__name__}\" ...")

    f, H_cd = get_cent_diff()
    H_cda = np.abs(H_cd)
    H_cd_ph = np.angle(H_cd)

    f, H_fd = get_first_diff()
    H_fda = np.abs(H_fd)
    H_fd_ph = np.angle(H_fd)

    f, H_fft = get_fft_deriv()
    H_ffta = np.abs(H_fft)
    H_fft_ph = np.angle(H_fft)

    def y_label(x, p):
        ad = {1 / 2: r"$\pi/2$", 0: r"$0$", -1 / 2: r"$-\pi/2$"}
        try:
            s = ad[x / np.pi]
        except KeyError:
            s = r"%.1f$\pi$" % (x / np.pi)
        return s

    num = c.next_fig_num(close)
    fig2, (ax2) = plt.subplots(1, 1, figsize=(5, 2), num=num)
    ax2.plot(f, H_fft_ph, label="frequency domain", linewidth=1.25)
    ax2.plot(f,
             H_fd_ph,
             label="first difference",
             linewidth=1.25,
             linestyle=(0, (7, 1)))
    ax2.plot(f,
             H_cd_ph,
             label="central difference",
             linewidth=1.25,
             linestyle=(0, (3, 1)))
    ax2.set(xlabel='frequency [1/day]', ylabel='phase angle')
    ax2.legend(loc='center left',
               prop={'size': 9},
               handlelength=2,
               bbox_to_anchor=(0.0, 0.425))
    ax2.yaxis.set_major_locator(plt.MultipleLocator(np.pi / 2))
    ax2.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_label))
    ax2.axis([0.0, 0.5, -np.pi * 0.5 * 1.2, np.pi * 0.5 * 1.2])
    plt.tight_layout()

    num += 1
    fig1, (ax1) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax1.plot(f, H_ffta, label="frequency domain", linewidth=1.25)
    ax1.plot(f,
             H_fda,
             label="first difference",
             linewidth=1.25,
             linestyle=(0, (7, 1)))
    ax1.plot(f,
             H_cda,
             label="central difference",
             linewidth=1.25,
             linestyle=(0, (3, 1)))
    ax1.set(xlabel='frequency [1/day]', ylabel='magnitude [1]')
    ax1.legend(loc='upper left', prop={'size': 9}, handlelength=2)
    ax1.axis([0.0, 0.5, 0, np.pi])
    plt.tight_layout()

    if show:
        plt.show(block=False)

    if save:
        c.save_fig(fig2, file_names[0])
        c.save_fig(fig1, file_names[1])
Пример #16
0
def sync_freq_demo():
    #### 1#hide
    # parameters
    Fsym = 1e6 # symbol rate
    UPS = 8 # up-sampling factor
    Fif = 2e6 # IF frequency
    # IF frequency delta at receiver side with frequency error
    Fif_prime = Fif + 20e3
    Fif_phi = 0.1

    Fs = Fsym*UPS # sampling frequency
    SNR = 30 # awgn (dB)

    # Modulation
    MODE = 4
    PHASE_OFFSET = np.pi/MODE
    # the maximum phase error without bit error
    PHASE_SPACE = 2*np.pi/MODE/2
    #mapping table for hard decision
    PHASE = 2*np.pi/8*np.array([1, 3, -3, -1])

    # True --> hard decision; False --> use tx data
    DECISION = False

    #### 2#hide
    # generate the PSK signal
    symbol = np.floor(MODE*np.random.rand(10000))
    signal = np.exp(1j*(2*np.pi/MODE*symbol + PHASE_OFFSET))

    # tx shaping filter
    fir_tx = rcosdesign(0.4, 5, UPS)

    s = np.kron(signal, np.concatenate((np.ones([1]), np.zeros([UPS-1]))))
    s = scipy.signal.lfilter(fir_tx, 1, s)
    # remove the filter delay
    s = s[(len(fir_tx)-1)//2:]
    plot_signal_freqz(s, Fs, '../doc/image/sync_demo_tx.png')#hide
    #### 3#hide
    # rx
    # modulation with IF to simulate a received signal after ADC
    r = np.real(s*np.exp(1j*2*np.pi*Fif/Fs*np.arange(len(s)))+Fif_phi)
    # add AWGN
    noise = np.random.normal(0, 1, len(r))
    noise *= 10**(-SNR/20)*np.sqrt(np.mean(r*r))*np.sqrt(UPS)
    r += noise
    plot_signal_freqz(r, Fs, '../doc/image/sync_demo_rx.png')#hide

    #### 3.1#hide
    # match filter
    fir_rx = rcosdesign(0.4, 3, UPS)
    r_buf = np.zeros(len(fir_rx), dtype=complex)

    # frequency synchronization
    q = np.zeros(np.ceil(len(s)/float(UPS)).astype(int), dtype=complex)
    q_est = np.zeros(np.ceil(len(s)/float(UPS)).astype(int), dtype=complex)
    freq_est = np.zeros(np.ceil(len(q)).astype(int))

    # estimated error
    ph_nco = 2*np.pi*(Fif_prime)/Fs
    freq_err = 0.0
    freq_err_i = 0.0
    freq_err_d = 0.0

    #### 4#hide
    index = 0
    # down sampling by a factor of UPS, then estimate the frequency error,
    # assume no clock error and sampling at best phase
    for i in range(0, len(r)):
        # step 1: NCO for frequency synchronization & frequency error compensation
        ph_nco = ph_nco - freq_err - 2*np.pi*(Fif_prime)/Fs
        if ph_nco > np.pi:
            ph_nco -= 2*np.pi
        elif ph_nco < -np.pi:
            ph_nco += 2*np.pi
        # step 2: down shift
        r_b = 2*r[i]*np.exp(1j*ph_nco)
        # step 3: filtering
        r_buf = np.roll(r_buf, 1)
        r_buf[0] = r_b
        r_b = np.sum(r_buf*fir_rx)

        # step 4: down-sampling by a factor of 8
        if i >= (len(fir_rx)-1)/2 and i%UPS == 0:
            # step 5: received signal
            z_in = r_b
            q_est[index] = z_in
            # step 6: decision
            if DECISION == 0:
                q_h = signal[index]
            else:
                # find the closest point on constellation
                p = np.arctan2(q_est[index].imag, q_est[index].real)
                b = np.argmin(np.abs(p-PHASE))
                q_h = np.exp(1j*PHASE[b])

            # step 7: estimate frequency error
            # remove the signal phase
            q[index] = q_est[index]*np.conj(q_h)
            # phase error ~ [-pi, pi]
            phi_e = np.arctan2(q[index].imag, q[index].real)

            # step 8: PI controller
            freq_err_i = freq_err_i + phi_e*0.01/UPS
            freq_err_d = phi_e*0.2/UPS
            freq_err = freq_err_i + freq_err_d
            freq_est[index] = freq_err
            index += 1
    ####
    # plot received signal
    figure(1)
    clf()
    # down shift
    rd = 2*r*np.exp(1j*(2*np.pi*-(Fif_prime)/Fs*np.arange(len(s))))
    z = scipy.signal.lfilter(fir_rx, 1, rd)
    # remove the filter delay
    z = z[(len(fir_rx)-1)//2:]

    plt.scatter(z[::UPS].real, z[::UPS].imag)
    plt.scatter(q_est[50:].real, q_est[50:].imag)
    plt.grid('on', ls=':')
    plt.xlabel('real')
    plt.ylabel('imag')
    plt.legend(['without freq sync', 'with freq sync'])
    save_fig(plt, '../doc/image/sync_demo_scatter.png')
    # estimated phase error
    plt.figure(2)
    plt.clf()
    plt.plot(freq_est[:index])
    plt.xlabel('n (samples)')
    plt.ylabel('e[n]')
    plt.title('Estimated Phase Error')
    plt.grid('on', ls=':')
    save_fig(plt, '../doc/image/sync_demo_err.png')
Пример #17
0
def main(close=True,
         show=True,
         save=False,
         rt="deaths",
         region="global",
         country="Brazil",
         state=None,
         file_names=("Fig2.pdf", )):
    """time segment FFT analysis.

    keyword args
        close: close plots (boolean)
        show: show plots (boolean)
        save: save plots (boolean)
        rt: record type ("deaths" or "cases")
        region: global or US
        country: country name
        state: name of US State

    returns
        None
    """

    print(f"\nRunning module \"{__name__}\" ...")

    start = 35
    data = c.get_data(rt, region, country=country, state=state)
    data = data[start:]
    data_d_dt = c.deriv_fft(data)

    winSz = 25

    print("time-spectrum start date: %s" % (c.ind2datetime(start)))
    print("initial window center: %s" % (c.ind2datetime(start + winSz / 2)))
    print("final window center: %s" %
          (c.ind2datetime(start + len(data) - 1 - winSz / 2)))
    print("sliding window size: %d" % (winSz))

    N = 1024  # % pts in FFT
    numSamps = len(data)
    numHops = numSamps - winSz  # 1 sample hops (sliding window)

    # set frequency range used for plotting
    minFreq = 0.0
    maxFreq = 0.5
    minFreq_ind = int(N * minFreq + 0.5)
    maxFreq_ind = int(N * maxFreq + 0.5)

    # set frequency range used for normnalization
    normCutMinFreq = 0.1
    normCutMaxFreq = 0.5
    normCutMinFreq_ind = int(N * normCutMinFreq + 0.5)
    normCutMaxFreq_ind = int(N * normCutMaxFreq + 0.5)

    Z = np.zeros([numHops, maxFreq_ind - minFreq_ind])
    Z_hanning = np.zeros([numHops, maxFreq_ind - minFreq_ind])
    Z_d_dt = np.zeros([numHops, maxFreq_ind - minFreq_ind])

    b_start = 0
    b_stop = winSz

    for n in range(numHops):
        xr = data[b_start:b_stop]
        X = np.fft.fft(xr, n=N) / N
        X = np.abs(X[:N // 2])
        Z[n] = X[minFreq_ind:maxFreq_ind] / np.max(
            X[normCutMinFreq_ind:normCutMaxFreq_ind])

        xr = data[b_start:b_stop]
        X = np.fft.fft(xr * np.hanning(winSz), n=N) / N
        X = np.abs(X[:N // 2])
        Z_hanning[n] = X[minFreq_ind:maxFreq_ind] / np.max(
            X[normCutMinFreq_ind:normCutMaxFreq_ind])

        xr = data_d_dt[b_start:b_stop]
        X = np.fft.fft(xr, n=N) / N
        X = np.abs(X[:N // 2])
        Z_d_dt[n] = X[minFreq_ind:maxFreq_ind] / np.max(
            X[normCutMinFreq_ind:normCutMaxFreq_ind])

        b_start += 1
        b_stop += 1

    # clip values that exceed unity.
    Z = np.clip(Z, 0, 1)
    Z_hanning = np.clip(Z_hanning, 0, 1)
    Z_d_dt = np.clip(Z_d_dt, 0, 1)

    # interp = None # smallest size
    interp = 'sinc'
    colors = cm.Blues_r
    # colors = cm.magma # largest size, percetual color map
    # colors = cm.gray # smallest size

    xMin = winSz * 0.5
    xMax = winSz * 0.5 + Z.shape[0]

    num = c.next_fig_num(close)
    fig = plt.figure(figsize=(10.25, 2.3), num=num)

    # --------------------------------------------------------------
    ax0 = plt.subplot2grid((1, 3), (0, 0))
    ax0.imshow(np.flipud(Z.transpose(1, 0)),
               interpolation=interp,
               cmap=colors,
               extent=(xMin, xMax, minFreq, maxFreq),
               aspect='auto')
    ax0.set(xlabel='time [days]',
            title="Square Window",
            ylabel='frequency [1/day]')
    ax0.title.set_size(10)
    ax0.yaxis.set_major_locator(plt.MultipleLocator(0.1))

    # --------------------------------------------------------------
    ax1 = plt.subplot2grid((1, 3), (0, 1))
    ax1.imshow(np.flipud(Z_hanning.transpose(1, 0)),
               interpolation=interp,
               cmap=colors,
               extent=(xMin, xMax, minFreq, maxFreq),
               aspect='auto')
    ax1.set(xlabel='time [days]', title="Hanning Window")
    ax1.title.set_size(10)
    ax1.set_yticklabels('')
    ax1.tick_params(axis=u'y', which=u'both', length=0)

    # --------------------------------------------------------------
    ax2 = plt.subplot2grid((1, 3), (0, 2))
    ax2.imshow(np.flipud(Z_d_dt.transpose(1, 0)),
               interpolation=interp,
               cmap=colors,
               extent=(xMin, xMax, minFreq, maxFreq),
               aspect='auto')
    ax2.set(xlabel='time [days]', title="Square Window of Derivative")
    ax2.title.set_size(10)
    ax2.set_yticklabels('')
    ax2.tick_params(axis=u'y', which=u'both', length=0)

    plt.tight_layout()

    if show:
        plt.show(block=False)

    if save:
        c.save_fig(fig, file_names[0])