xref: /freebsd-src/contrib/ntp/scripts/stats/clock.awk (revision cfe30d02adda7c3b5c76156ac52d50d8cab325d9)
1*c0b746e5SOllivier Robert# awk program to scan clockstat files and report errors/statistics
2*c0b746e5SOllivier Robert#
3*c0b746e5SOllivier Robert# usage: awk -f check.awk clockstats
4*c0b746e5SOllivier Robert#
5*c0b746e5SOllivier Robert# This program works for the following radios:
6*c0b746e5SOllivier Robert# PST/Traconex 1020 WWV reciever
7*c0b746e5SOllivier Robert# Arbiter 1088 GPS receiver
8*c0b746e5SOllivier Robert# Spectracom 8170/Netclock-2 WWVB receiver
9*c0b746e5SOllivier Robert# IRIG audio decoder
10*c0b746e5SOllivier Robert# Austron 2200A/2201A GPS receiver (see README.austron file)
11*c0b746e5SOllivier Robert#
12*c0b746e5SOllivier RobertBEGIN {
13*c0b746e5SOllivier Robert	etf_min = osc_vmin = osc_tmin = 1e9
14*c0b746e5SOllivier Robert	etf_max = osc_vmax = osc_tmax = -1e9
15*c0b746e5SOllivier Robert}
16*c0b746e5SOllivier Robert#
17*c0b746e5SOllivier Robert# scan all records in file
18*c0b746e5SOllivier Robert#
19*c0b746e5SOllivier Robert{
20*c0b746e5SOllivier Robert	#
21*c0b746e5SOllivier Robert	# select PST/Traconex WWV records
22*c0b746e5SOllivier Robert	# 00:00:37.234  96/07/08/190 O6@0:5281825C07510394
23*c0b746e5SOllivier Robert	#
24*c0b746e5SOllivier Robert	if (NF >= 4 && $3 == "127.127.3.1") {
25*c0b746e5SOllivier Robert		if (substr($6, 14, 4) > "0010")
26*c0b746e5SOllivier Robert			wwv_sync++
27*c0b746e5SOllivier Robert		if (substr($6, 13, 1) == "C")
28*c0b746e5SOllivier Robert			wwv_wwv++
29*c0b746e5SOllivier Robert		if (substr($6, 13, 1) == "H")
30*c0b746e5SOllivier Robert			wwv_wwvh++
31*c0b746e5SOllivier Robert		x = substr($6, 12, 1)
32*c0b746e5SOllivier Robert		if (x == "1")
33*c0b746e5SOllivier Robert			wwv_2.5++
34*c0b746e5SOllivier Robert		else if (x == "2")
35*c0b746e5SOllivier Robert			wwv_5++
36*c0b746e5SOllivier Robert		else if (x == "3")
37*c0b746e5SOllivier Robert			wwv_10++
38*c0b746e5SOllivier Robert		else if (x == "4")
39*c0b746e5SOllivier Robert			wwv_15++
40*c0b746e5SOllivier Robert		else if (x == "5")
41*c0b746e5SOllivier Robert			wwv_20++
42*c0b746e5SOllivier Robert		continue
43*c0b746e5SOllivier Robert	}
44*c0b746e5SOllivier Robert	#
45*c0b746e5SOllivier Robert	# select Arbiter GPS records
46*c0b746e5SOllivier Robert	# 96 190 00:00:37.000 0 V=08 S=44 T=3 P=10.6 E=00
47*c0b746e5SOllivier Robert	# N39:42:00.951 W075:46:54.880 210.55      2.50 0.00
48*c0b746e5SOllivier Robert	#
49*c0b746e5SOllivier Robert	if (NF >= 4 && $3 == "127.127.11.1") {
50*c0b746e5SOllivier Robert		if (NF > 8) {
51*c0b746e5SOllivier Robert			arb_count++
52*c0b746e5SOllivier Robert			if ($7 != 0)
53*c0b746e5SOllivier Robert				arb_sync++
54*c0b746e5SOllivier Robert			x = substr($10, 3, 1)
55*c0b746e5SOllivier Robert			if (x == "0")
56*c0b746e5SOllivier Robert				arb_0++
57*c0b746e5SOllivier Robert			else if (x == "1")
58*c0b746e5SOllivier Robert				arb_1++
59*c0b746e5SOllivier Robert			else if (x == "2")
60*c0b746e5SOllivier Robert				arb_2++
61*c0b746e5SOllivier Robert			else if (x == "3")
62*c0b746e5SOllivier Robert				arb_3++
63*c0b746e5SOllivier Robert			else if (x == "4")
64*c0b746e5SOllivier Robert				arb_4++
65*c0b746e5SOllivier Robert			else if (x == "5")
66*c0b746e5SOllivier Robert				arb_5++
67*c0b746e5SOllivier Robert			else if (x == "6")
68*c0b746e5SOllivier Robert			arb_6++
69*c0b746e5SOllivier Robert		} else if (NF == 8) {
70*c0b746e5SOllivier Robert			arbn++
71*c0b746e5SOllivier Robert			arb_mean += $7
72*c0b746e5SOllivier Robert			arb_rms += $7 * $7
73*c0b746e5SOllivier Robert			if (arbn > 0) {
74*c0b746e5SOllivier Robert				x = $7 - arb_val
75*c0b746e5SOllivier Robert				arb_var += x * x
76*c0b746e5SOllivier Robert			}
77*c0b746e5SOllivier Robert			arb_val = $7
78*c0b746e5SOllivier Robert		}
79*c0b746e5SOllivier Robert		continue
80*c0b746e5SOllivier Robert	}
81*c0b746e5SOllivier Robert	#
82*c0b746e5SOllivier Robert	# select Spectracom WWVB records
83*c0b746e5SOllivier Robert	# see summary for decode
84*c0b746e5SOllivier Robert	#   96 189 23:59:32.248  D
85*c0b746e5SOllivier Robert	#
86*c0b746e5SOllivier Robert	if (NF >= 4 && $3 == "127.127.4.1") {
87*c0b746e5SOllivier Robert		if ($4 == "SIGNAL" || NF > 7)
88*c0b746e5SOllivier Robert			printf "%s\n", $0
89*c0b746e5SOllivier Robert		else {
90*c0b746e5SOllivier Robert			wwvb_count++
91*c0b746e5SOllivier Robert			if ($4 ~ /\?/)
92*c0b746e5SOllivier Robert				wwvb_x++
93*c0b746e5SOllivier Robert			else if ($4 ~ /A/)
94*c0b746e5SOllivier Robert				wwvb_a++
95*c0b746e5SOllivier Robert			else if ($4 ~ /B/)
96*c0b746e5SOllivier Robert				wwvb_b++
97*c0b746e5SOllivier Robert			else if ($4 ~ /C/)
98*c0b746e5SOllivier Robert				wwvb_c++
99*c0b746e5SOllivier Robert			else if ($4 ~ /D/)
100*c0b746e5SOllivier Robert				wwvb_d++
101*c0b746e5SOllivier Robert		}
102*c0b746e5SOllivier Robert		continue
103*c0b746e5SOllivier Robert	}
104*c0b746e5SOllivier Robert	#
105*c0b746e5SOllivier Robert	# select IRIG audio decoder records
106*c0b746e5SOllivier Robert	# see summary for decode
107*c0b746e5SOllivier Robert	#
108*c0b746e5SOllivier Robert	if (NF >= 4 && $3 == "127.127.6.0") {
109*c0b746e5SOllivier Robert		irig_count++
110*c0b746e5SOllivier Robert		if ($5 ~ /\?/)
111*c0b746e5SOllivier Robert			irig_error++
112*c0b746e5SOllivier Robert		continue
113*c0b746e5SOllivier Robert	}
114*c0b746e5SOllivier Robert	#
115*c0b746e5SOllivier Robert	# select Austron GPS LORAN ENSEMBLE records
116*c0b746e5SOllivier Robert	# see summary for decode
117*c0b746e5SOllivier Robert	#
118*c0b746e5SOllivier Robert	else if (NF >= 13 && $6 == "ENSEMBLE") {
119*c0b746e5SOllivier Robert		ensemble_count++
120*c0b746e5SOllivier Robert		if ($9 <= 0)
121*c0b746e5SOllivier Robert			ensemble_badgps++
122*c0b746e5SOllivier Robert		else if ($12 <= 0)
123*c0b746e5SOllivier Robert			ensemble_badloran++
124*c0b746e5SOllivier Robert		else {
125*c0b746e5SOllivier Robert			if ($13 > 200e-9 || $13 < -200e-9)
126*c0b746e5SOllivier Robert				ensemble_200++
127*c0b746e5SOllivier Robert			else if ($13 > 100e-9 || $13 < -100e-9)
128*c0b746e5SOllivier Robert				ensemble_100++
129*c0b746e5SOllivier Robert			ensemble_mean += $13
130*c0b746e5SOllivier Robert			ensemble_rms += $13 * $13
131*c0b746e5SOllivier Robert		}
132*c0b746e5SOllivier Robert		continue
133*c0b746e5SOllivier Robert	}
134*c0b746e5SOllivier Robert	#
135*c0b746e5SOllivier Robert	# select Austron LORAN TDATA records
136*c0b746e5SOllivier Robert	# see summary for decode; note that signal quality log is simply
137*c0b746e5SOllivier Robert	# copied to output
138*c0b746e5SOllivier Robert	#
139*c0b746e5SOllivier Robert	else if (NF >= 7 && $6 == "TDATA") {
140*c0b746e5SOllivier Robert                tdata_count++
141*c0b746e5SOllivier Robert                for (i = 7; i < NF; i++) {
142*c0b746e5SOllivier Robert                        if ($i == "M" && $(i+1) == "OK") {
143*c0b746e5SOllivier Robert                                i += 5
144*c0b746e5SOllivier Robert                                m += $i
145*c0b746e5SOllivier Robert                		tdata_m++
146*c0b746e5SOllivier Robert		        }
147*c0b746e5SOllivier Robert                        else if ($i == "W" && $(i+1) == "OK") {
148*c0b746e5SOllivier Robert                                i += 5
149*c0b746e5SOllivier Robert                                w += $i
150*c0b746e5SOllivier Robert                        	tdata_w++
151*c0b746e5SOllivier Robert			}
152*c0b746e5SOllivier Robert                        else if ($i == "X" && $(i+1) == "OK") {
153*c0b746e5SOllivier Robert                                i += 5
154*c0b746e5SOllivier Robert                                x += $i
155*c0b746e5SOllivier Robert                        	tdata_x++
156*c0b746e5SOllivier Robert			}
157*c0b746e5SOllivier Robert                        else if ($i == "Y" && $(i+1) == "OK") {
158*c0b746e5SOllivier Robert                                i += 5
159*c0b746e5SOllivier Robert                                y += $i
160*c0b746e5SOllivier Robert                        	tdata_y++
161*c0b746e5SOllivier Robert			}
162*c0b746e5SOllivier Robert                        else if ($i == "Z" && $(i+1) == "OK") {
163*c0b746e5SOllivier Robert                                i += 5
164*c0b746e5SOllivier Robert                                z += $i
165*c0b746e5SOllivier Robert                        	tdata_z++
166*c0b746e5SOllivier Robert			}
167*c0b746e5SOllivier Robert		}
168*c0b746e5SOllivier Robert		continue
169*c0b746e5SOllivier Robert	}
170*c0b746e5SOllivier Robert	#
171*c0b746e5SOllivier Robert	# select Austron ITF records
172*c0b746e5SOllivier Robert	# see summary for decode
173*c0b746e5SOllivier Robert	#
174*c0b746e5SOllivier Robert	else if (NF >= 13 && $5 == "ITF" && $12 >= 100) {
175*c0b746e5SOllivier Robert		itf_count++
176*c0b746e5SOllivier Robert		if ($9 > 200e-9 || $9 < -200e-9)
177*c0b746e5SOllivier Robert			itf_200++
178*c0b746e5SOllivier Robert		else if ($9 > 100e-9 || $9 < -100e-9)
179*c0b746e5SOllivier Robert			itf_100++
180*c0b746e5SOllivier Robert		itf_mean += $9
181*c0b746e5SOllivier Robert		itf_rms += $9 * $9
182*c0b746e5SOllivier Robert		itf_var += $10 * $10
183*c0b746e5SOllivier Robert		continue
184*c0b746e5SOllivier Robert	}
185*c0b746e5SOllivier Robert	#
186*c0b746e5SOllivier Robert	# select Austron ETF records
187*c0b746e5SOllivier Robert	# see summary for decode
188*c0b746e5SOllivier Robert	#
189*c0b746e5SOllivier Robert	else if (NF >= 13 && $5 == "ETF" && $13 >= 100) {
190*c0b746e5SOllivier Robert		etf_count++
191*c0b746e5SOllivier Robert		if ($6 > etf_max)
192*c0b746e5SOllivier Robert			etf_max = $6
193*c0b746e5SOllivier Robert		else if ($6 < etf_min)
194*c0b746e5SOllivier Robert			etf_min = $6
195*c0b746e5SOllivier Robert		etf_mean += $6
196*c0b746e5SOllivier Robert		etf_rms += $6 * $6
197*c0b746e5SOllivier Robert		etf_var += $9 * $9
198*c0b746e5SOllivier Robert		continue
199*c0b746e5SOllivier Robert	}
200*c0b746e5SOllivier Robert	#
201*c0b746e5SOllivier Robert	# select Austron TRSTAT records
202*c0b746e5SOllivier Robert	# see summary for decode
203*c0b746e5SOllivier Robert	#
204*c0b746e5SOllivier Robert	else if (NF >= 5 && $5 == "TRSTAT") {
205*c0b746e5SOllivier Robert		trstat_count++
206*c0b746e5SOllivier Robert		j = 0
207*c0b746e5SOllivier Robert		for (i = 6; i <= NF; i++)
208*c0b746e5SOllivier Robert			if ($i == "T")
209*c0b746e5SOllivier Robert				j++
210*c0b746e5SOllivier Robert		trstat_sat[j]++
211*c0b746e5SOllivier Robert		continue
212*c0b746e5SOllivier Robert	}
213*c0b746e5SOllivier Robert	#
214*c0b746e5SOllivier Robert	# select Austron ID;OPT;VER records
215*c0b746e5SOllivier Robert	#
216*c0b746e5SOllivier Robert	# config GPS 2201A TTY1 TC1 LORAN IN OUT1 B.00 B.00 28-Apr-93
217*c0b746e5SOllivier Robert	#
218*c0b746e5SOllivier Robert	# GPS 2201A	receiver model
219*c0b746e5SOllivier Robert	# TTY1		rs232 moduel
220*c0b746e5SOllivier Robert	# TC1		IRIG module
221*c0b746e5SOllivier Robert	# LORAN		LORAN assist module
222*c0b746e5SOllivier Robert	# IN		input module
223*c0b746e5SOllivier Robert	# OUT1		output module
224*c0b746e5SOllivier Robert	# B.00 B.00	firmware revision
225*c0b746e5SOllivier Robert	# 28-Apr-9	firmware date3
226*c0b746e5SOllivier Robert        #
227*c0b746e5SOllivier Robert	else if (NF >= 5 && $5 == "ID;OPT;VER") {
228*c0b746e5SOllivier Robert		id_count++
229*c0b746e5SOllivier Robert		id_temp = ""
230*c0b746e5SOllivier Robert		for (i = 6; i <= NF; i++)
231*c0b746e5SOllivier Robert			id_temp = id_temp " " $i
232*c0b746e5SOllivier Robert		if (id_string != id_temp)
233*c0b746e5SOllivier Robert			printf "config%s\n", id_temp
234*c0b746e5SOllivier Robert		id_string = id_temp
235*c0b746e5SOllivier Robert		continue
236*c0b746e5SOllivier Robert	}
237*c0b746e5SOllivier Robert	#
238*c0b746e5SOllivier Robert	# select Austron POS;PPS;PPSOFF records
239*c0b746e5SOllivier Robert	#
240*c0b746e5SOllivier Robert	# position +39:40:48.425 -075:45:02.392 +74.09 Stored UTC 0 200 0
241*c0b746e5SOllivier Robert	#
242*c0b746e5SOllivier Robert	# +39:40:48.425	position north latitude
243*c0b746e5SOllivier Robert	# -075:45:02.392 position east longitude
244*c0b746e5SOllivier Robert	# +74.09	elevation (meters)
245*c0b746e5SOllivier Robert	# Stored	position is stored
246*c0b746e5SOllivier Robert	# UTC		time is relative to UTC
247*c0b746e5SOllivier Robert	# 0 200 0	PPS offsets
248*c0b746e5SOllivier Robert	#
249*c0b746e5SOllivier Robert	else if (NF >= 5 && $5 == "POS;PPS;PPSOFF") {
250*c0b746e5SOllivier Robert		pos_count++
251*c0b746e5SOllivier Robert		pos_temp = ""
252*c0b746e5SOllivier Robert		for (i = 6; i <= NF; i++)
253*c0b746e5SOllivier Robert			pos_temp = pos_temp " " $i
254*c0b746e5SOllivier Robert		if (pos_string != pos_temp)
255*c0b746e5SOllivier Robert			printf "position%s\n", pos_temp
256*c0b746e5SOllivier Robert		pos_string = pos_temp
257*c0b746e5SOllivier Robert	continue
258*c0b746e5SOllivier Robert	}
259*c0b746e5SOllivier Robert	#
260*c0b746e5SOllivier Robert	# select Austron OSC;ET;TEMP records
261*c0b746e5SOllivier Robert	#
262*c0b746e5SOllivier Robert	# loop 1121 Software Control Locked
263*c0b746e5SOllivier Robert	#
264*c0b746e5SOllivier Robert	# 1121		oscillator type
265*c0b746e5SOllivier Robert	# Software Control loop is under software control
266*c0b746e5SOllivier Robert	# Locked	loop is locked
267*c0b746e5SOllivier Robert	#
268*c0b746e5SOllivier Robert	else if (NF >= 5 && $5 == "OSC;ET;TEMP") {
269*c0b746e5SOllivier Robert		osc_count++
270*c0b746e5SOllivier Robert		osc_temp = $6 " " $7 " " $8 " " $9
271*c0b746e5SOllivier Robert		if (osc_status != osc_temp)
272*c0b746e5SOllivier Robert			printf "loop %s\n", osc_temp
273*c0b746e5SOllivier Robert		osc_status = osc_temp
274*c0b746e5SOllivier Robert		if ($10 > osc_vmax)
275*c0b746e5SOllivier Robert			osc_vmax = $10
276*c0b746e5SOllivier Robert		if ($10 < osc_vmin)
277*c0b746e5SOllivier Robert			osc_vmin = $10
278*c0b746e5SOllivier Robert		if ($11 > osc_tmax)
279*c0b746e5SOllivier Robert			osc_tmax = $11
280*c0b746e5SOllivier Robert		if ($11 < osc_tmin)
281*c0b746e5SOllivier Robert			osc_tmin = $11
282*c0b746e5SOllivier Robert	continue
283*c0b746e5SOllivier Robert	}
284*c0b746e5SOllivier Robert	#
285*c0b746e5SOllivier Robert	# select Austron UTC records
286*c0b746e5SOllivier Robert	# these ain't ready yet
287*c0b746e5SOllivier Robert	#
288*c0b746e5SOllivier Robert	else if (NF >= 5 && $5 == "UTC") {
289*c0b746e5SOllivier Robert		utc_count++
290*c0b746e5SOllivier Robert		utc_temp = ""
291*c0b746e5SOllivier Robert		for (i = 6; i <= NF; i++)
292*c0b746e5SOllivier Robert			utc_temp = utc_temp " " $i
293*c0b746e5SOllivier Robert		if (utc_string != utc_temp)
294*c0b746e5SOllivier Robert#			printf "utc%s\n", utc_temp
295*c0b746e5SOllivier Robert                utc_string = utc_temp
296*c0b746e5SOllivier Robert	continue
297*c0b746e5SOllivier Robert	}
298*c0b746e5SOllivier Robert} END {
299*c0b746e5SOllivier Robert#
300*c0b746e5SOllivier Robert# PST/Traconex WWV summary data
301*c0b746e5SOllivier Robert#
302*c0b746e5SOllivier Robert	if (wwv_wwv + wwv_wwvh > 0)
303*c0b746e5SOllivier Robert		printf "wwv %d, wwvh %d, err %d, MHz (2.5) %d, (5) %d, (10) %d, (15) %d, (20) %d\n", wwv_wwv, wwv_wwvh, wwv_sync, wwv_2.5, wwv_5, wwv_10, wwv_15, wwv_20
304*c0b746e5SOllivier Robert#
305*c0b746e5SOllivier Robert# Arbiter 1088 summary data
306*c0b746e5SOllivier Robert#
307*c0b746e5SOllivier Robert# gps		record count
308*c0b746e5SOllivier Robert# err		error count
309*c0b746e5SOllivier Robert# sats(0-6)	satellites tracked
310*c0b746e5SOllivier Robert# mean		1 PPS mean (us)
311*c0b746e5SOllivier Robert# rms		1 PPS rms error (us)
312*c0b746e5SOllivier Robert# var		1 PPS Allan variance
313*c0b746e5SOllivier Robert#
314*c0b746e5SOllivier Robert	if (arb_count > 0) {
315*c0b746e5SOllivier Robert		printf "gps %d, err %d, sats(0-6) %d %d %d %d %d %d %d", arb_count, arb_sync, arb_0, arb_1, arb_2, arb_3, arb_4, arb_5, arb_6
316*c0b746e5SOllivier Robert		if (arbn > 1) {
317*c0b746e5SOllivier Robert			arb_mean /= arbn
318*c0b746e5SOllivier Robert			arb_rms = sqrt(arb_rms / arbn - arb_mean * arb_mean)
319*c0b746e5SOllivier Robert			arb_var = sqrt(arb_var / (2 * (arbn - 1)))
320*c0b746e5SOllivier Robert			printf ", mean %.2f, rms %.2f, var %.2e\n", arb_mean, arb_rms, arb_var * 1e-6
321*c0b746e5SOllivier Robert		} else {
322*c0b746e5SOllivier Robert			printf "\n"
323*c0b746e5SOllivier Robert		}
324*c0b746e5SOllivier Robert	}
325*c0b746e5SOllivier Robert#
326*c0b746e5SOllivier Robert# ensemble summary data
327*c0b746e5SOllivier Robert#
328*c0b746e5SOllivier Robert# ensemble	record count
329*c0b746e5SOllivier Robert# badgps	gps data unavailable
330*c0b746e5SOllivier Robert# badloran	loran data unavailable
331*c0b746e5SOllivier Robert# rms		ensemble rms error (ns)
332*c0b746e5SOllivier Robert# >200		ensemble error >200 ns
333*c0b746e5SOllivier Robert# >100		100 ns < ensemble error < 200 ns
334*c0b746e5SOllivier Robert#
335*c0b746e5SOllivier Robert	if (ensemble_count > 0) {
336*c0b746e5SOllivier Robert		ensemble_mean /= ensemble_count
337*c0b746e5SOllivier Robert		ensemble_rms = sqrt(ensemble_rms / ensemble_count - ensemble_mean * ensemble_mean) * 1e9
338*c0b746e5SOllivier Robert		printf "ensemble %d, badgps %d, badloran %d, rms %.1f, >200 %d, >100 %d\n", ensemble_count, ensemble_badgps, ensemble_badloran, ensemble_rms, ensemble_200, ensemble_100
339*c0b746e5SOllivier Robert	}
340*c0b746e5SOllivier Robert#
341*c0b746e5SOllivier Robert# wwvb summary data
342*c0b746e5SOllivier Robert#
343*c0b746e5SOllivier Robert# wwvb		record count
344*c0b746e5SOllivier Robert# ?		unsynchronized
345*c0b746e5SOllivier Robert# >1		error > 1 ms
346*c0b746e5SOllivier Robert# >10		error > 10 ms
347*c0b746e5SOllivier Robert# >100		error > 100 ms
348*c0b746e5SOllivier Robert# >500		error > 500 ms
349*c0b746e5SOllivier Robert#
350*c0b746e5SOllivier Robert	if (wwvb_count > 0)
351*c0b746e5SOllivier Robert		printf "wwvb %d, ? %d, >1 %d, >10 %d, >100 %d, >500 %d\n", wwvb_count, wwvb_x, wwvb_a, wwvb_b, wwvb_c, wwvb_d
352*c0b746e5SOllivier Robert#
353*c0b746e5SOllivier Robert# irig summary data
354*c0b746e5SOllivier Robert#
355*c0b746e5SOllivier Robert# irig		record count
356*c0b746e5SOllivier Robert# err		error count
357*c0b746e5SOllivier Robert#
358*c0b746e5SOllivier Robert	if (irig_count > 0)
359*c0b746e5SOllivier Robert		printf "irig %d, err %d\n", irig_count, irig_error
360*c0b746e5SOllivier Robert#
361*c0b746e5SOllivier Robert# tdata summary data
362*c0b746e5SOllivier Robert#
363*c0b746e5SOllivier Robert# tdata		record count
364*c0b746e5SOllivier Robert# m		M master OK-count, mean level (dB)
365*c0b746e5SOllivier Robert# w		W slave OK-count, mean level (dB)
366*c0b746e5SOllivier Robert# x		X slave OK-count, mean level (dB)
367*c0b746e5SOllivier Robert# y		Y slave OK-count, mean level (dB)
368*c0b746e5SOllivier Robert# z		Z slave OK-count, mean level (dB)
369*c0b746e5SOllivier Robert#
370*c0b746e5SOllivier Robert	if (tdata_count > 0 ) {
371*c0b746e5SOllivier Robert		if (tdata_m > 0)
372*c0b746e5SOllivier Robert			m /= tdata_count
373*c0b746e5SOllivier Robert		if (tdata_x > 0)
374*c0b746e5SOllivier Robert			w /= tdata_count
375*c0b746e5SOllivier Robert		if (tdata_x > 0)
376*c0b746e5SOllivier Robert			x /= tdata_count
377*c0b746e5SOllivier Robert		if (tdata_y > 0)
378*c0b746e5SOllivier Robert			y /= tdata_count
379*c0b746e5SOllivier Robert		if (tdata_z > 0)
380*c0b746e5SOllivier Robert			z /= tdata_count
381*c0b746e5SOllivier Robert		printf "tdata %d, m %d %.1f, w %d %.1f, x %d %.1f, y %d %.1f, z %d %.1f\n", tdata_count, tdata_m, m, tdata_w, w, tdata_x, x, tdata_y, y, tdata_z, z
382*c0b746e5SOllivier Robert	}
383*c0b746e5SOllivier Robert#
384*c0b746e5SOllivier Robert# itf summary data
385*c0b746e5SOllivier Robert#
386*c0b746e5SOllivier Robert# itf		record count
387*c0b746e5SOllivier Robert# rms		itf rms error (ns)
388*c0b746e5SOllivier Robert# >200		itf error > 200 ns
389*c0b746e5SOllivier Robert# >100		itf error > 100 ns
390*c0b746e5SOllivier Robert# var		Allan variance
391*c0b746e5SOllivier Robert#
392*c0b746e5SOllivier Robert	if (itf_count > 1) {
393*c0b746e5SOllivier Robert		itf_mean /= itf_count
394*c0b746e5SOllivier Robert		itf_rms = sqrt(itf_rms / itf_count - itf_mean * itf_mean) * 1e9
395*c0b746e5SOllivier Robert		itf_var = sqrt(itf_var / (2 * (itf_count - 1)))
396*c0b746e5SOllivier Robert		printf "itf %d, rms %.1f, >200 %d, >100 %d, var %.2e\n", itf_count, itf_rms, itf_200, itf_100, itf_var
397*c0b746e5SOllivier Robert	}
398*c0b746e5SOllivier Robert#
399*c0b746e5SOllivier Robert# etf summary data
400*c0b746e5SOllivier Robert#
401*c0b746e5SOllivier Robert# etf		record count
402*c0b746e5SOllivier Robert# mean		etf mean (ns)
403*c0b746e5SOllivier Robert# rms		etf rms error (ns)
404*c0b746e5SOllivier Robert# max		etf maximum (ns)
405*c0b746e5SOllivier Robert# min		etf minimum (ns)
406*c0b746e5SOllivier Robert# var		Allan variance
407*c0b746e5SOllivier Robert#
408*c0b746e5SOllivier Robert	if (etf_count > 0) {
409*c0b746e5SOllivier Robert                etf_mean /= etf_count
410*c0b746e5SOllivier Robert		etf_rms = sqrt(etf_rms / etf_count - etf_mean * etf_mean)
411*c0b746e5SOllivier Robert		etf_var = sqrt(etf_var / (2 * (etf_count - 1)))
412*c0b746e5SOllivier Robert		printf "etf %d, mean %.1f, rms %.1f, max %d, min %d, var %.2e\n", etf_count, etf_mean, etf_rms, etf_max, etf_min, etf_var
413*c0b746e5SOllivier Robert	}
414*c0b746e5SOllivier Robert#
415*c0b746e5SOllivier Robert# trstat summary data
416*c0b746e5SOllivier Robert#
417*c0b746e5SOllivier Robert# trstat	record count
418*c0b746e5SOllivier Robert# sat		histogram of tracked satellites (0 - 7)
419*c0b746e5SOllivier Robert#
420*c0b746e5SOllivier Robert	if (trstat_count > 0)
421*c0b746e5SOllivier Robert		printf "trstat %d, sat %d %d %d %d %d %d %d %d\n", trstat_count, trstat_sat[0], trstat_sat[1], trstat_sat[2], trstat_sat[2], trstat_sat[3], trstat_sat[4], trstat_sat[5], trstat_sat[6], trstat_sat[7]
422*c0b746e5SOllivier Robert#
423*c0b746e5SOllivier Robert# osc summary data
424*c0b746e5SOllivier Robert#
425*c0b746e5SOllivier Robert# osc		record count
426*c0b746e5SOllivier Robert# control	control midrange (V) +/- deviation (mV)
427*c0b746e5SOllivier Robert# temp		oven temperature midrange +/- deviation (deg C)
428*c0b746e5SOllivier Robert#
429*c0b746e5SOllivier Robert	if (osc_count > 0)
430*c0b746e5SOllivier Robert		printf "osc %d, control %.3f+/-%.3f, temp %.1f+/-%.2f\n", osc_count, (osc_vmax + osc_vmin) / 2, (osc_vmax - osc_vmin) / 2 * 1e3, (osc_tmax + osc_tmin) / 2, (osc_tmax - osc_tmin) / 2
431*c0b746e5SOllivier Robert}
432