-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathgeco_irigb_midnight_bug_check.py
More file actions
executable file
·116 lines (102 loc) · 4.88 KB
/
geco_irigb_midnight_bug_check.py
File metadata and controls
executable file
·116 lines (102 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python
# (c) Stefan Countryman, 2017
# pylint: disable=superfluous-parens
"""
USAGE: geco_irigb_midnight_bug_check.py START END
Check +/- 30 seconds around midnight in the given date range. START and END
should both be something like 2018-10-03. All dates between these two dates
(endpoints inclusive) will be checked at 00:00:00 (the start of each date).
"""
import sys
# spit out help string before slow imports if necessary
if __name__ == "__main__" and {"-h", "--help"}.intersection(sys.argv):
print(__doc__)
exit(0)
# pylint: disable=wrong-import-position
from datetime import timedelta
from astropy.time import Time
from gwpy.timeseries import TimeSeries
from dateutil.parser import parse as parse_datetime
import geco_irig_decode
RED = '\033[91m'
CLEAR = '\033[0m'
BITRATE = 16384
IFOS = ['H1', 'L1']
ARMS = ['X', 'Y']
CHANS = ['{}:CAL-PCAL{}_IRIGB_OUT_DQ'.format(ifo, arm)
for ifo in IFOS for arm in ARMS]
TFORMAT = '%a %b %d %X %Y'
def get_leap_seconds(gps):
"""Find the number of leap seconds at a given gps time using astropy's time
module (by comparing UTC to TAI and subtracting 19, the base difference
between TAI and GPS scales)."""
t = Time(gps, format='gps')
t.format = 'iso'
return (t.tai.to_datetime() - t.utc.to_datetime()).seconds - 19
def check_decoded_times(start_time, timewindow=30):
"""Check the decoded IRIG-B times within a window of size timewindow
surrounding the event time and make sure the times are all correct (i.e.
they are either the correct UTC or GPS time; either one is considered
correct). Save the results of the check to a text file for upload to LIGO's
EVNT log."""
for chan in CHANS:
format_string = 'Decoding {}+/-{}s on channel {}.'
start_time = int(start_time)
msg = format_string.format(start_time, timewindow, chan)
print(msg)
# print a header, since output will be arranged tabularly, e.g.
# 1225152018 | 1225152018 | 18 | GPS | 0 | 0 | 0 | 306 | ...
# 2018 | Thu Nov 02 00:00:00 2018 | Fri Nov 02 23:59:42 2018
print("Actual GPS | Decode GPS | Leap | Scale | Sec | Min | Hr | Day "
"| Year | Decoded Date/Time | Actual UTC Date/Time")
print("-----------+------------+------+-------+-----+-----+----+-----"
"+------+--------------------------+-------------------------")
row_fmt = ("{gps_actual:>10d} | {gps_decoded:>10d} | {leap:>4d} | "
"{scale:<5} | {second:>3d} | {minute:>3d} | {hour:>2d} | "
"{day:>3d} | {year:>4d} | {datetime_decoded:<24} | "
"{datetime_actual:<24}")
timeseries = TimeSeries.fetch(chan, start_time-timewindow,
start_time+timewindow+1).value
# deal with one second at a time, writing results to file
for i in range(2*timewindow + 1):
timeseries_slice = timeseries[i*BITRATE:(i+1)*BITRATE]
gps_actual = (start_time - timewindow) + i
leap_seconds = get_leap_seconds(gps_actual)
t_actual = Time(gps_actual, format='gps', scale='utc')
decoded = geco_irig_decode.decode_timeseries(timeseries_slice)
t = decoded['datetime']
dt = (t - t_actual.to_datetime()).seconds
datetime_actual = t_actual.to_datetime().strftime(TFORMAT)
# check whether the times agree, or whether they are off by the
# current number of leap seconds
if dt == 0:
scale = "UTC"
elif dt == leap_seconds:
scale = "GPS"
else:
scale = "ERROR"
print(row_fmt.format(gps_actual=gps_actual,
# foo = dict(gps_actual=gps_actual,
gps_decoded=int(Time(t).gps),
leap=leap_seconds, scale=scale,
datetime_decoded=t.strftime(TFORMAT),
datetime_actual=datetime_actual,
**decoded))
# print(foo)
def main():
"""Check the specified date range; see module docstring."""
start = parse_datetime(sys.argv[1]).replace(hour=0, minute=0, second=0)
end = parse_datetime(sys.argv[2]).replace(hour=0, minute=0, second=0)
days = (end - start).days + 1
print('Processing {} days between {} and {}.'.format(days, start, end))
print('Times are allowed to be off by current number of leap')
print('seconds. This most likely indicates that the device')
print('producing the IRIG-B signal is outputting GPS time.')
if days < 1:
sys.stderr.write("end day cannot be earlier than start day.")
exit(1)
for day in (start + timedelta(d) for d in range(days)):
print("CHECKING DATE: {}".format(day.isoformat()))
check_decoded_times(Time(day).gps)
if __name__ == "__main__":
main()