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
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)
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)
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')
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' )
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