This is meant as a short tutorial on how to use the utc time in the SuperK data. More details about how the utc time is registered and put into the data stream can be found in additional documents on Jeff George's home page.
Each event has several time values stored in the anti-header bank SKHEADA. These include: LTCGPS, NSGPS, NUSGPS, and LTCTRG. Each is a 32bit integer. LTCTRG is the value of the 50MHz Local Clock at the time of the event trigger. LTCGPS is the value of the 50MHz Local Clock at the time of the last UTC update. NSGPS and NUSGPS are the UTC time. The date and time to seconds are in NSGPS, the more significant digits are stored in NUSGPS as microseconds. Details follow.
Note there is a problem with the way this was implemented. Attempts to read the time outside of JST will incur an offset of the time difference between your time zone and JST. Brett Viren points out that a simple, though ungainly way of handling this is to type 'setenv TZ = JST' before extracting data. Of course, this will mess up other programs which use the time zone information, such as 'date'. I am looking for a more suitable solution.
Note that the utc time is only updated about every 20 seconds. More accurate time is provided by the 50MHz local time clock. Each trigger has a timestamp from this clock in "ltctrg". The value of ltctrg is a number of bins, multiply by 20ns/bin to get time.
The gps update is triggered by the rollover of bit 29 (counting 0 to 31) of the local time clock. The time stamp of a nearby trigger is stored as ltcgps, or apparently also known as local_to_gps. (I'm not sure who came up with that name, it didn't go by me...) Since the gps is triggered by the leading edge of a known bit, all lower bits are irrelevant and that's why it doesn't have to be stamped precisely at the gps update. So only the uppermost 2 bits are significant, the 3rd highest is always set (because it triggered the update with its leading edge), and all the rest of the bits of the exact local time are 0 at the gps update.
example: the local_to_gps value is 0x5fbf5745.It's clear that this value happened to be just before the rollover of bit 29, but no matter. The local clock time at the gps update is: 0x60000000. Keep only the uppermost 2 bits from the local_to_gps and set the 3rd highest, regardless. That's the prescription. I think
real_ltcgps = ((local_to_gps & 0xa0000000) | 0x20000000)will do it, probably I'm overlooking the obvious logical simplification here.
To get the actual time of the event, use:actual time = gps_sec (converted to calendar time) + gps_usec + \ (ltctrg - real_ltcgps)*20ns
Note that the relative time between events is good to 20ns, the resolution of the 50MHz local time clock. The absolute time of any given event (UTC) is only good to 1us.
Sorry about the insanity of the local_to_gps value. I should have been making the conversion beforehand, and I will do so now, but you will need to know this if you want the gps time in current data.