;docformat = 'rst' ;+ ; This reads the spacecraft offset file and inserts data into ; the sc_offset common block. It also ensures that the time ; of each element in the array is unique and that the array ; is sorted in ascending order by time tag. ; ; :Author: ; Bill Barrett ; ; :Examples: ; IDL> read_spacecraft_offset_file ; ; :Params: ; offset file: string, optional ; A named complete path for a file to read rather than the ; default: !COMMON_INPUT_DATA + '/sc_offset.dat' ; ;- pro read_spacecraft_offset_file, offset_file=offset_file common sc_offset, clock_offset_data ; Define the data structure used for clock offset records dummy = {sc_clock_offset_record, year_day_of_year:0e, clock_offset:0e, clock_slope:0e} if ~keyword_set(offset_file) then $ offset_file = !COMMON_INPUT_DATA + '/sc_offset.dat' print, get_routine_name() + " loading space craft offsets from " + offset_file ; The valid data lines from the offset file should begin with the year and day of year, ; optionally followed by a fraction of a day ; That should be followed by the offset, a numeric signed number, that may or may ; not have a decimal point, and may have numbers either to right or left of the ; decimal point or both. ; In more recent years, there is also a third field, the slope, which has the same ; format as the offset. ; The two or three fields should be separated by one or more spaces year_doy_re = '(20[012][[:digit:]]{4}(\.[[:digit:]]*)?)' offset_slope_re = '( +(\-|\+)?' + $ ; optional sign '[[:digit:]]*' + $ ; digits to the left of the decimal point '(\.[[:digit:]]*(e(\-|\+)?[[:digit:]]+)?)?)' ; decimal point and digits to the right ; optionally followed by an exponent regex = '^' + year_doy_re + offset_slope_re + offset_slope_re +'?.*$' clock_offset_data = [] openr,lun, offset_file, /get_lun line = '' while not eof(lun) do begin readf, lun, line ; Skip any header or blank lines line = strtrim(line, 2) match = stregex(line, regex, /subexpr, /extract) ; match[1] is the year-day_of_year ; match[3] is the spacecraft clock offset for that date ; match[8] is if the offset slope for that date if strlen(match[1]) gt 0 && strlen(match[3]) gt 0 then begin time_tag = double(match[1]) ; Ensure that there are no duplicates if n_elements(clock_offset_data) gt 0 then begin dummy = where(abs(time_tag - clock_offset_data.year_day_of_year) lt 0.00001, $ duplicate_count) if duplicate_count gt 0 then begin print, get_routine_name() + 'duplicate time tag found: ' + match[1] continue endif endif ; The earliest records do not have a slope. ; -9999 is a fill value that indicates no data is present ; Clock offset and slope are converted from seconds to ; microseconds (by multiplying by 1e6) because all of the ; times coming from the database are in gps microseconds. clock_slope = strlen(match[8]) gt 0 ? double(match[8]) : -9999. clock_offset_data = [ clock_offset_data, $ {sc_clock_offset_record, time_tag, double(match[3]), clock_slope} ] endif endwhile free_lun, lun ; Ensure that the data is time ordered clock_offset_data = clock_offset_data(sort(clock_offset_data.year_day_of_year)) print, get_routine_name() + 'number of spacecraft clock offset records = ' + $ strtrim(string(n_elements(clock_offset_data)), 2) end