def mtem(i, j, dt):
    """
    multitaper estimation method
    Input:
    i      first time series
    j      second time series

    Output:
    fki    power spectral density i
    fkj    power spectral density j
    cij    cross-spectral density ij
    coh    coherence
    ph     phase spectrum between ij at input freq
    
    """
    print 'i size', i.shape
    print 'j size', j.shape
    
    # apply multi taper cross spectral density from nitime module
    f, pcsd_est = tsa.multi_taper_csd(np.vstack([i,j]), Fs=1/dt, low_bias=True, adaptive=True, sides='onesided')
    
    # output is MxMxN matrix, extract the psd and csd
    fki = pcsd_est.diagonal().T[0]
    fkj = pcsd_est.diagonal().T[1]
    cij = pcsd_est.diagonal(+1).T.ravel()
    
    # using complex argument of cxy extract phase component
    ph = np.angle(cij)
    
    # calculate coherence using csd and psd
    coh = np.abs(cij)**2 / (fki * fkj)   
    
    return f, fki, fkj, cij, ph, coh 
def mtem(x, y):
    """
    multitaper estimation method
    input:
    x  first time series
    y  second time series

    output:
    fkx  power spectral density x
    fky  power spectral density y
    cxy  cross-spectral density xy
    coh  coherence
    ph  phase between xy at input freq
    
    """
    print ('x size', x.shape)
    print ('y size', y.shape)
    
    # apply multi taper cross spectral density from nitime module
    f, pcsd_est = tsa.multi_taper_csd(np.vstack([x,y]), Fs=1., low_bias=True, adaptive=True, sides='onesided')
    
    # output is MxMxN matrix, extract the psd and csd
    fkx = pcsd_est.diagonal().T[0]
    fky = pcsd_est.diagonal().T[1]
    cxy = pcsd_est.diagonal(+1).T.ravel()
    
    # using complex argument of cxy extract phase component
    ph = np.angle(cxy)
    
    # calculate coherence using csd and psd
    coh = np.abs(cxy)**2 / (fkx * fky)   
    
    return f, fkx, fky, cxy, ph, coh 
def mtem_unct(x_, y_, cf, mc_no=20):
    """
    Uncertainty function using Monte Carlo analysis
    Input:
    x_ = timeseries x
    y_ = timeseries y
    cf = coherence function between x and y
    mc_no = number of iterations default is 20, minimum is 3
    
    Output:
    phif = phase uncertainty bounded between 0 and pi
    """
    print 'iteration no is', mc_no

    data = np.vstack([x_, y_])
    # number of iterations
    # flip coherence and horizontal stack
    cg = np.hstack((cf[:-1], np.flipud(cf[:-1])))

    # random time series fx
    mc_fx = np.random.standard_normal(size=(mc_no, len(data[0])))
    mc_fx = mc_fx / np.sum(abs(mc_fx), axis=1)[None].T

    # random time series fy
    mc_fy = np.random.standard_normal(size=(mc_no, len(data[0])))
    mc_fy = mc_fy / np.sum(abs(mc_fy), axis=1)[None].T

    # create semi random timeseries based on magnitude squared coherence
    # and inverse fourier transform for ys
    ys = np.real(np.fft.ifft(mc_fy * np.sqrt(1 - cg**2)))
    ys = ys + np.real(np.fft.ifft(mc_fx * cg))

    # inverse fourier transform for xs
    xs = np.real(np.fft.ifft(mc_fx))

    # spectral analysis
    f_s, pcsd_est = tsa.multi_taper_csd(np.vstack([xs, ys]),
                                        Fs=1.,
                                        low_bias=True,
                                        adaptive=True,
                                        sides='onesided')
    cxyi = pcsd_est.diagonal(+int(xs.shape[0])).T
    phi = np.angle(cxyi)

    # sort and average the highest uncertianties
    pl = int(round(0.975 * mc_no) + 1)
    phi = np.sort(phi, axis=0)
    phi = phi[((mc_no + 1) - pl):pl]
    phi = np.array([phi[pl - 2, :], -phi[pl - mc_no, :]])
    phi = phi.mean(axis=0)  #
    phi = np.convolve(phi, np.array([1, 1, 1]) / 3)
    phif = phi[1:-1]
    return phif
def mtem_unct(i_, j_, dt_, cf, mc_no=20):
    """
    Uncertainty function using Monte Carlo analysis
    Input:
    i_     timeseries i
    j_     timeseries j
    cf     coherence function between i and j
    mc_no  number of iterations default is 20, minimum is 3
    
    Output:
    phif   phase uncertainty bounded between 0 and pi
    """
    print 'iteration no is', mc_no
    
    data = np.vstack([i_,j_])
    # number of iterations
    # flip coherence and horizontal stack    
    cg = np.hstack((cf[:-1], np.flipud(cf[:-1])))
    
    # random time series fi
    mc_fi = np.random.standard_normal(size=(mc_no,len(data[0])))
    mc_fi = mc_fi / np.sum(abs(mc_fi),axis=1)[None].T
    
    # random time series fj
    mc_fj = np.random.standard_normal(size=(mc_no,len(data[0])))
    mc_fj = mc_fj / np.sum(abs(mc_fj),axis=1)[None].T
    
    # create semi random timeseries based on magnitude squared coherence
    # and inverse fourier transform for js
    js = np.real(np.fft.ifft(mc_fj * np.sqrt(1 - cg ** 2))) 
    js_ = js + np.real(np.fft.ifft(mc_fi *cg))
    
    # inverse fourier transform for xs
    is_ = np.real(np.fft.ifft(mc_fi))
    
    # spectral analysis
    f_s, pcsd_est = tsa.multi_taper_csd(np.vstack([is_,js_]), Fs=1/dt_, low_bias=True, adaptive=True, sides='onesided')
    cijx = pcsd_est.diagonal(+int(is_.shape[0])).T
    phi = np.angle(cijx)
    
    # sort and average the highest uncertianties
    pl = int(round(0.95*mc_no)+1)
    phi = np.sort(phi,axis=0)        
    phi = phi[((mc_no+1)-pl):pl]
    phi = np.array([phi[pl-2,:],-phi[pl-mc_no,:]])
    phi = phi.mean(axis=0)#
    phi = np.convolve(phi, np.array([1,1,1])/3)
    phif = phi[1:-1]
    return phif
示例#5
0
def test_multi_taper_psd_csd():
    """

    Test the multi taper psd and csd estimation functions.
    Based on the example in
    doc/examples/multi_taper_spectral_estimation.py

    """

    N = 2**10
    n_reps = 10

    psd = []
    est_psd = []
    est_csd = []
    for jk in [True, False]:
        for k in range(n_reps):
            for adaptive in [True, False]:
                ar_seq, nz, alpha = utils.ar_generator(N=N, drop_transients=10)
                ar_seq -= ar_seq.mean()
                fgrid, hz = tsa.freq_response(1.0,
                                              a=np.r_[1, -alpha],
                                              n_freqs=N)
                psd.append(2 * (hz * hz.conj()).real)
                f, psd_mt, nu = tsa.multi_taper_psd(ar_seq,
                                                    adaptive=adaptive,
                                                    jackknife=jk)
                est_psd.append(psd_mt)
                f, csd_mt = tsa.multi_taper_csd(np.vstack([ar_seq, ar_seq]),
                                                adaptive=adaptive)
                # Symmetrical in this case, so take one element out:
                est_csd.append(csd_mt[0][1])

        fxx = np.mean(psd, axis=0)
        fxx_est1 = np.mean(est_psd, axis=0)
        fxx_est2 = np.mean(est_csd, axis=0)

        # Tests the psd:
        psd_ratio1 = np.mean(fxx_est1 / fxx)
        npt.assert_array_almost_equal(psd_ratio1, 1, decimal=-1)
        # Tests the csd:
        psd_ratio2 = np.mean(fxx_est2 / fxx)
        npt.assert_array_almost_equal(psd_ratio2, 1, decimal=-1)
示例#6
0
def test_multi_taper_psd_csd():
    """

    Test the multi taper psd and csd estimation functions.
    Based on the example in
    doc/examples/multi_taper_spectral_estimation.py

    """

    N = 2 ** 10
    n_reps = 10

    psd = []
    est_psd = []
    est_csd = []
    for jk in [True, False]:
        for k in range(n_reps):
            for adaptive in [True, False]:
                ar_seq, nz, alpha = utils.ar_generator(N=N, drop_transients=10)
                ar_seq -= ar_seq.mean()
                fgrid, hz = tsa.freq_response(1.0, a=np.r_[1, -alpha],
                                              n_freqs=N)
                psd.append(2 * (hz * hz.conj()).real)
                f, psd_mt, nu = tsa.multi_taper_psd(ar_seq, adaptive=adaptive,
                                                    jackknife=jk)
                est_psd.append(psd_mt)
                f, csd_mt = tsa.multi_taper_csd(np.vstack([ar_seq, ar_seq]),
                                               adaptive=adaptive)
                # Symmetrical in this case, so take one element out:
                est_csd.append(csd_mt[0][1])

        fxx = np.mean(psd, axis=0)
        fxx_est1 = np.mean(est_psd, axis=0)
        fxx_est2 = np.mean(est_csd, axis=0)

        # Tests the psd:
        psd_ratio1 = np.mean(fxx_est1 / fxx)
        npt.assert_array_almost_equal(psd_ratio1, 1, decimal=-1)
        # Tests the csd:
        psd_ratio2 = np.mean(fxx_est2 / fxx)
        npt.assert_array_almost_equal(psd_ratio2, 1, decimal=-1)
示例#7
0
def test_hermitian_multitaper_csd():
    """
    Make sure CSD matrices returned by various methods have
    Hermitian symmetry.
    """

    sig = np.random.randn(4, 256)

    _, csd1 = tsa.multi_taper_csd(sig, adaptive=False)

    for i in range(4):
        for j in range(i + 1):
            xc1 = csd1[i, j]
            xc2 = csd1[j, i]
            npt.assert_equal(xc1, xc2.conj(), err_msg='MTM CSD not Hermitian')

    _, psd, _ = tsa.multi_taper_psd(sig, adaptive=False)
    for i in range(4):
        npt.assert_almost_equal(
            psd[i],
            csd1[i, i].real,
            err_msg='MTM CSD diagonal inconsistent with real PSD')
示例#8
0
def test_hermitian_multitaper_csd():
    """
    Make sure CSD matrices returned by various methods have
    Hermitian symmetry.
    """

    sig = np.random.randn(4,256)

    _, csd1 = tsa.multi_taper_csd(sig, adaptive=False)

    for i in range(4):
        for j in range(i+1):
            xc1 = csd1[i,j]
            xc2 = csd1[j,i]
            npt.assert_equal(
                xc1, xc2.conj(), err_msg='MTM CSD not Hermitian'
                )

    _, psd, _ = tsa.multi_taper_psd(sig, adaptive=False)
    for i in range(4):
        npt.assert_almost_equal(
            psd[i], csd1[i,i].real,
            err_msg='MTM CSD diagonal inconsistent with real PSD'
            )
示例#9
0
def PCA(arr,
        ncomp,
        verbose=True,
        sample_rate=488.28125,
        filename="",
        **keywords):

    pdf_pages = PdfPages('PCA_diag' + filename +
                         '.pdf')  # name of the pdf produced

    # do mean subration
    mean_vec_arr = np.mean(arr, axis=0)
    arr = arr - mean_vec_arr

    # normalize by the variance
    var = np.std(arr, axis=0)**2
    arr = arr / var

    covmat = np.dot(arr.T, arr)  #/data_arr.shape[0]

    #compute the eigvectors and eigenvalues
    evals, evects = np.linalg.eig(covmat)

    #sort the eigenvectors and values by largest to smallest
    idx = evals.argsort()[::-1]
    evals = evals[idx]
    evects = evects[:, idx]

    #make the eigenfunction array
    efuncarr = np.dot(arr, evects)
    # pick components to subtract
    efuncarr[:, 0:ncomp] = 0
    res_index_used = idx[0:ncomp]
    #transform back
    arr_clean = np.inner(efuncarr, evects)

    if verbose:
        print("the covariance matrix is")
        print(covmat)
        print("")
        print("the eigenvalues are")
        print(evals)
        print("")
        print("the eigenvectors are")
        print(evects)
        print("")
    fig = plt.figure(1, figsize=(12, 6))
    plt.subplot(1, 2, 1)
    plt.title("Eigenvalues")
    plt.plot(np.log10(np.abs(evals)), label="eigenvalues")
    plt.plot(np.log10(np.abs(evals[0:ncomp])), 'o', label="components removed")
    plt.xlabel("Eigenvalue index")
    plt.ylabel("Eigenvalue Magnitude")
    plt.legend()

    plt.subplot(1, 2, 2)
    plt.title("Log10(covariance matrix)")
    plt.imshow(np.log10(covmat), interpolation='nearest')
    plt.colorbar()

    pdf_pages.savefig(fig)
    plt.close()

    #need to unnormalize by the varaince
    arr = arr * var
    arr_clean = arr_clean * var

    #need to add the mean back in to get the right units
    arr = arr + mean_vec_arr
    arr_clean = arr_clean + mean_vec_arr

    #block for plotting the correlation between the two most corrrelated detectors
    fig = plt.figure(2, figsize=(12, 6))
    plt.title("Cross correlation of two most correlated detectors")
    # make a figure that show the correlation between the two most correlated detectors
    cov_matrix_2 = covmat
    for i in range(0, cov_matrix_2.shape[0]):
        cov_matrix_2[
            i,
            i] = 0  #zeros out diagonal obviously detecotrs are correlated with them selves
    max_corr_index1 = np.where(cov_matrix_2 == np.max(cov_matrix_2))[0][0]
    max_corr_index2 = np.where(cov_matrix_2 == np.max(cov_matrix_2))[0][1]

    # this is kind of a neat package for doing cross correlation on time streams
    # see this page for explanation
    # http://nbviewer.jupyter.org/github/mattijn/pynotebook/blob/master/ipynotebooks/Python2.7/2016/2016-05-25%20cross-spectral%20analysis.ipynb
    #calculate the cross correlation
    f, pcsd_est = tsa.multi_taper_csd(np.vstack(
        (arr[:, max_corr_index1], arr[:, max_corr_index2])),
                                      Fs=sample_rate,
                                      low_bias=True,
                                      adaptive=False,
                                      sides='onesided')
    fki = pcsd_est.diagonal().T[0]
    fkj = pcsd_est.diagonal().T[1]
    cij = pcsd_est.diagonal(+1).T.ravel()
    #calculate the coherene
    coh = np.abs(cij)**2 / (fki * fkj)

    plt.loglog(f, fki, label="Resonator psd index = " + str(max_corr_index1))
    plt.loglog(f, fkj, label="Resonator psd index = " + str(max_corr_index2))
    ylim = plt.ylim()
    plt.loglog(f, np.abs(cij), label="Cross psd")
    plt.ylim(ylim[0], ylim[1])
    plt.legend()

    pdf_pages.savefig(fig)
    plt.close()

    fig = plt.figure(3, figsize=(12, 6))
    plt.semilogx(f, np.abs(coh))
    plt.title("Coherence")
    plt.xlabel("Frequency Hz")
    plt.ylim(0, 1)

    pdf_pages.savefig(fig)
    plt.close()

    pdf_pages.close()

    PCA_dict = {
        'arr': arr,
        'cleaned': arr_clean,
        'ncomp': ncomp,
        'res_index_used': res_index_used,
        'cov_matrix': covmat
    }
    return PCA_dict