def many_psds(k=2,fs=1.0, b0=1.0, N=1024): """ compute average of many PSDs """ psd=[] for j in range(k): print j x = noise.white(N=2*4096,b0=b0,fs=fs) f, tmp = noise.numpy_psd(x,fs) if j==0: psd = tmp else: psd = psd + tmp return f, psd/k
def many_psds(k=2, fs=1.0, b0=1.0, N=1024): """ compute average of many PSDs """ psd = [] for j in range(k): print(j) x = noise.white(num_points=2 * 4096, b0=b0, fs=fs) f, tmp = noise.numpy_psd(x, fs) if j == 0: psd = tmp else: psd = psd + tmp return f, psd / k
fs=100 h0=2e-16 N=16*4096 v0 = 1e6 # nominal oscillator frequency y = noise.white(N=N,b0=h0,fs=fs) # fractional frequency x = allantools.frequency2phase(y,fs) # phase in seconds fi = [2*math.pi*v0*xx for xx in x] # phase in radians t = np.linspace(0, (1.0/fs)*N, len(y)) plt.figure() plt.plot(t,y) plt.xlabel('Time / s') plt.ylabel('Fractional frequency') f_y, psd_y = noise.numpy_psd(y,fs) f_fi, psd_fi = noise.numpy_psd(fi,fs) f_x, psd_x = noise.numpy_psd(x,fs) fxx, Pxx_den = noise.scipy_psd(y, fs) f_fi2, psd_fi2 = noise.scipy_psd(fi, fs) f_x2, psd_x2 = noise.scipy_psd(x, fs) plt.figure() plt.semilogy(f_y,psd_y,label='numpy.fft()') plt.semilogy(fxx,Pxx_den,label='scipy.signal.welch()') plt.semilogy(f_y,[h0]*len(f_y),label='h_0 = %.3g' % h0 ) plt.legend(framealpha=0.5) plt.title('PSD of fractional frequency') plt.xlabel('Frequeny / Hz') plt.ylabel('one-sided PSD / S_y(f)')
plt.ylabel('Count') plt.title('Frequency histogram') plt.subplot(2, 2, 4) phist, pbins = np.histogram([1e9 * yy for yy in x], bins=100, density=True) plt.plot(pbins[1:], phist, 'ro') plt.xlabel('Phase / ns') plt.ylabel('Count') plt.title('Phase histogram') rmsphase = 1e12 * np.std(x) print("RMS phase = ", rmsphase, " ps") plt.text(0, 0.01, 'RMS = %f ps' % rmsphase) # plt.show() f_y, psd_y = noise.numpy_psd(y, fs) f_fi, psd_fi = noise.numpy_psd(fi, fs) f_x, psd_x = noise.numpy_psd(x, fs) fxx, Pxx_den = noise.scipy_psd(y, fs) f_fi2, psd_fi2 = noise.scipy_psd(fi, fs) f_x2, psd_x2 = noise.scipy_psd(x, fs) print("PSD calc done.") # S_y plt.figure() plt.loglog(f_y, psd_y, label='numpy.fft()') plt.loglog(fxx, Pxx_den, label='scipy.signal.welch()') plt.loglog(f_y, [h2 * ff * ff for ff in f_y], label='h2 * f^2 ') plt.legend(framealpha=0.5) plt.title('PSD of fractional frequency')
# time-series figure plt.figure() plt.plot(t,y,label='y') plt.plot(t,x[1:],label='x') plt.legend() plt.xlabel('Time / s') plt.ylabel('Fractional frequency') # note: calculating the PSD of an 1/f^4 signal using fft seems to be difficult # the welch method returns a correct 1/f^4 shaped PSD, but fft often does not # things that may help # - using a longer time-series (increase N above) # - detrend using signal.detrend() # - calculate PSD for a short window of data, and average over windows (this is done in the Welch method) # - read the Welch code to see what is going on f_y, psd_y = noise.numpy_psd(y, fs) f_fi, psd_fi = noise.numpy_psd( signal.detrend( fi[:len(fi)/20] ),fs) f_x, psd_x = noise.numpy_psd(x[:len(x)/20], fs) fxx, Pxx_den = noise.scipy_psd(y, fs) f_fi2, psd_fi2 = noise.scipy_psd(fi, fs) f_x2, psd_x2 = noise.scipy_psd(x, fs) # Fractional frequency PSD plt.figure() plt.loglog(f_y,psd_y,label='numpy.fft()') plt.loglog(fxx,Pxx_den,label='scipy.signal.welch()') plt.loglog(f_y[1:],[h2/(ff*ff) for ff in f_y[1:]],label='h_2/f^2 with h_2 = %.3g' % h2 ) plt.legend(framealpha=0.5) plt.title('PSD of fractional frequency')
fig, ax1 = plt.subplots() ax1.plot(t, y, label='y') ax2 = ax1.twinx() ax2.plot(t, x[1:], label='x') plt.legend() plt.xlabel('Time / s') plt.ylabel('Fractional frequency') # note: calculating the PSD of an 1/f^4 signal using fft seems to be difficult # the welch method returns a correct 1/f^4 shaped PSD, but fft often does not # things that may help # - using a longer time-series (increase N above) # - detrend using signal.detrend() # - calculate PSD for a short window of data, and average over windows (this is done in the Welch method) # - read the Welch code to see what is going on f_y, psd_y = noise.numpy_psd(y, fs) f_fi, psd_fi = noise.numpy_psd( signal.detrend( fi[:len(fi)/20] ),fs) f_x, psd_x = noise.numpy_psd(x[:len(x)/20], fs) fxx, Pxx_den = noise.scipy_psd(y, fs) f_fi2, psd_fi2 = noise.scipy_psd(fi, fs) f_x2, psd_x2 = noise.scipy_psd(x, fs) # Fractional frequency PSD plt.figure() plt.loglog(f_y,psd_y,label='numpy.fft()') plt.loglog(fxx,Pxx_den,label='scipy.signal.welch()') plt.loglog(f_y[1:],[h2/(ff*ff) for ff in f_y[1:]],label='h_2/f^2 with h_2 = %.3g' % h2 ) plt.legend(framealpha=0.5) plt.title('PSD of fractional frequency')