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