def nbs14_1000_test(): fdata = nbs14_1000() print "nbs14 1000-point frequency data tests:" nbs14_tester( allan.adev, fdata, nbs14_1000_devs[0] ) print "nbs14_1000 adev OK" nbs14_tester( allan.oadev, fdata, nbs14_1000_devs[1] ) print "nbs14_1000 oadev OK" nbs14_tester( allan.mdev, fdata, nbs14_1000_devs[2] ) print "nbs14_1000 mdev OK" nbs14_tester( allan.totdev, fdata, nbs14_1000_devs[3] ) print "nbs14_1000 totdev OK" nbs14_tester( allan.hdev, fdata, nbs14_1000_devs[4] ) print "nbs14_1000 hdev OK" nbs14_tester( allan.tdev, fdata, nbs14_1000_devs[5] ) print "nbs14_1000 tdev OK" nbs14_tester( allan.ohdev, fdata, nbs14_1000_devs[6] ) print "nbs14_1000 ohdev OK" ######################################################### # now we test the same data, calling the _phase functions pdata = allan.frequency2phase(fdata, 1.0) print "nbs14 1000-point phase data tests:" nbs14_tester( allan.adev_phase, pdata, nbs14_1000_devs[0] ) print "nbs14_1000 adev_phase OK" nbs14_tester( allan.oadev_phase, pdata, nbs14_1000_devs[1] ) print "nbs14_1000 oadev_phase OK" nbs14_tester( allan.mdev_phase, pdata, nbs14_1000_devs[2] ) print "nbs14_1000 mdev_phase OK" nbs14_tester( allan.totdev_phase, pdata, nbs14_1000_devs[3] ) print "nbs14_1000 totdev_phase OK" nbs14_tester( allan.hdev_phase, pdata, nbs14_1000_devs[4] ) print "nbs14_1000 hdev_phase OK" nbs14_tester( allan.tdev_phase, pdata, nbs14_1000_devs[5] ) print "nbs14_1000 tdev_phase OK" nbs14_tester( allan.ohdev_phase, pdata, nbs14_1000_devs[6] ) print "nbs14_1000 ohdev_phase OK" print "nbs14_1000 all tests OK"
def test_noise_id(self): """ test for noise-identification """ s32_rows = testutils.read_stable32( 'mdev_octave.txt' , rate ) freq = testutils.read_datafile(data_file) y_freq = allan.frequency2fractional(freq, mean_frequency=1.0e7) phase = allan.frequency2phase(freq, rate) for s32 in s32_rows: s32_tau, s32_alpha, s32_AF = s32['tau'], s32['alpha'], int(s32['m']) # noise-ID from frequency if len(phase)/s32_AF > 20: alpha_int, alpha, d, rho = allan.autocorr_noise_id(freq, data_type='freq', af=s32_AF ) print( "y: ",s32_tau, s32_alpha, alpha_int, alpha, rho, d ) assert alpha_int == s32_alpha # noise-ID from phase if len(phase)/s32_AF > 20: alpha_int, alpha, d, rho = allan.autocorr_noise_id( phase, data_type='phase', af=s32_AF ) print( "x: ",s32_tau, s32_alpha, alpha_int, alpha, rho, d ) assert alpha_int == s32_alpha
# random number generator described in # http://www.ieee-uffc.org/frequency-control/learning-riley.asp # http://tf.nist.gov/general/pdf/2220.pdf page 107 # http://www.wriley.com/tst_suit.dat def nbs14_1000(): n = [0]*1000 n[0] = 1234567890 for i in range(999): n[i+1] = (16807*n[i]) % 2147483647 # the first three numbers are given in the paper, so check them: assert( n[1] == 395529916 and n[2] == 1209410747 and n[3] == 633705974 ) n = [x/float(2147483647) for x in n] # normalize so that n is in [0, 1] return n fdata = nbs14_1000() pdata = allan.frequency2phase(fdata, 1.0) class TestNBS14_1000Point(): def test_adev(self): self.nbs14_tester( allan.adev, None,fdata, nbs14_1000_devs[0] ) # test with frequency data self.nbs14_tester( allan.adev, pdata, None,nbs14_1000_devs[0] ) # test with phase data def test_oadev(self): self.nbs14_tester( allan.oadev, None,fdata, nbs14_1000_devs[1] ) self.nbs14_tester( allan.oadev, pdata, None,nbs14_1000_devs[1] ) def test_mdev(self): self.nbs14_tester( allan.mdev, None,fdata, nbs14_1000_devs[2] ) self.nbs14_tester( allan.mdev, pdata, None,nbs14_1000_devs[2] ) def test_totdev(self): self.nbs14_tester( allan.totdev, None,fdata, nbs14_1000_devs[3] ) self.nbs14_tester( allan.totdev, pdata, None,nbs14_1000_devs[3] ) def test_hdev(self):
def nbs14_1000(): """ 1000-point test dataset. data is fractional frequency """ n = [0]*1000 n[0] = 1234567890 for i in range(999): n[i+1] = (16807*n[i]) % 2147483647 # the first three numbers are given in the paper, so check them: assert( n[1] == 395529916 and n[2] == 1209410747 and n[3] == 633705974 ) n = [x/float(2147483647) for x in n] # normalize so that n is in [0, 1] return n nbs14_f = nbs14_1000() nbs14_phase = allan.frequency2phase(nbs14_f, 1.0) def check_dev(name, tau, a, b): print(name," tau=",tau, " ", a ," == ", b) assert( numpy.isclose( a, b) ) def test_oadev_rt_nbs14_1k(): oadev_rt = allan.realtime.oadev_realtime(afs=[1,10,100],tau0=1.0) for x in nbs14_phase: oadev_rt.add_phase(x) for n in range(3): check_dev('OADEV', oadev_rt.taus()[n], oadev_rt.dev[n], nbs14_1000_devs[1][n]) def test_ohdev_rt_nbs14_1k(): dev_rt = allan.realtime.ohdev_realtime(afs=[1,10,100],tau0=1.0) for x in nbs14_phase:
# AW 2015-07-29 # from the ieee1139 table # PSD_y(f) = h0 * f^0 fractional frequency PSD # PSD_fi(f) = h0 * vo^2 * f^-2 phase (radians) PSD # PSD_x(f) = h0 * (2 pi f)^-2 phase (time) PSD # ADEV_y(tau) = sqrt{ 1/2 * h0 * tau^-1 } Allan deviation 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)
# AW 2015-08-06 # from the ieee1139 table # PSD_y(f) = h2 * f^-2 fractional frequency PSD # PSD_fi(f) = h2 * vo^2 * f^-4 phase (radians) PSD # PSD_x(f) = h2 * (2 pi)^-2 * f^-4 phase (time) PSD # ADEV_y(tau) = sqrt{ 2*pi^2/3 * h2 * tau } Allan deviation fs=12.8 # sampling frequency in Hz (code should work for any non-zero value here) h2=2e-20 # PSD f^-2 coefficient N=10*4096 # number of samples v0 = 1.2345e6 # nominal oscillator frequency y = noise.brown(num_points=N, b2=h2, 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)) # time-series time axis # time-series figure plt.figure() 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