Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.stsci.edu/spst/UnixTransition/doc/gyro_bias_update_check.py
Дата изменения: Fri Apr 8 12:46:11 2016
Дата индексирования: Mon Apr 11 05:56:07 2016
Кодировка:

Поисковые слова: п п п п п п п п
#
#MODULE gyro_bias_update_check
#
#***********************************************************************
"""

**PURPOSE** --
This module contains a class that checks that gyro bias updates on a given
calendar are not too far apart.

**DEVELOPER** --
Gary Bower

**MODIFICATION HISTORY** --

o Initial implementation 10/27/10
o Fix to allow running on a calendar without final 02968 - mdr 10/28/10
o Mods to account for spatial scans - mdr 11/3/11
o Change the error delta time due to G4 issues, PR 82286 - mdr 10/5/15
o Change MIN_GUIDING_TIME from 20m to 5m, PR 82467 - mdr 10/19/15
o code cleanup - drc 12/7/15
"""
#***********************************************************************
__version__ = '15.12.07'

from abstract_check import abstract_check
from checklist_init import UNKNOWN, PASS, FAIL
import time_util

MIN_GUIDING_TIME = time_util.delta_time('0:00:05:00')
MIN_GYRO_BIAS_UPDATE_TIME = time_util.delta_time('0:08:50:00')
PREF_GYRO_BIAS_UPDATE_TIME = time_util.delta_time('0:08:00:00')


class gyro_bias_update_check(abstract_check):
"""Verify separation of Gyro bias updates is not too long
"""
# Works with the current map files.

# This function checks a calendar/display file for the time between gyro bias
# updates. If this time is greater than both MIN_GYRO_BIAS_UPDATE_TIME and
# PREF_GYRO_BIAS_UPDATE_TIME, then this is an error. If this time is less than
# MIN_GYRO_BIAS_UPDATE_TIME and greater than PREF_GYRO_BIAS_UPDATE_TIME,
# then a warning is issued.
#
# A gyro bias update opportunity is defined
# by a total of at least MIN_GUIDING_TIME with HST under the control of a
# guide star pair. This interval can be interrupted by small angle manuevers
# and moving target tracking.

def run(self):
abstract_check.run(self)
file_pointer = open(self.outfile, "w")
cal_disp = self.my_checklist.cal_display

# Define a window using the calendar start and end times.
start = cal_disp.get_begin_time()
end = cal_disp.get_end_time()
calendar_window = time_util.window(start, end)
# Get the requisite data from the calendar display.
pcs_acqs = cal_disp.get_fgs_acq_list()
slew_list = cal_disp.get_slew_list()
saa02 = cal_disp.get_saa_list('02')
display_command = "calendar -display -slew_fgs -noboundary"
fgs_slew_list = cal_disp.parse_calendar_display(display_command=display_command,
search_string='F/S_AVD',
regex=0)
# Keep only the FGS slews for earth avoidance entry.
fgs_ea_entry = []
for fgs_slew in fgs_slew_list:
if fgs_slew['data_string'].find('ENT') != -1:
t1 = fgs_slew['begin_time']
t2 = fgs_slew['end_time']
fgs_ea_entry.append(time_util.window(t1, t2))

# Find SAM, TRK51, SCAN and FGS Pause windows. Note that MRSAM's are not included
# in this tool because they occur only under gyro control.
sam_list = self.my_checklist.cal_display.parse_calendar_display(display_command=display_command,
search_string='M SAM',
regex=0)
sam_windows = time_util.window_list()
for sam in sam_list:
sam_windows.append(time_util.window(sam['begin_time'], sam['end_time']))
trk51_list = self.my_checklist.cal_display.parse_calendar_display(
display_command=display_command, search_string='M TRK51', regex=0)
trk51_windows = time_util.window_list()
for trk51 in trk51_list:
trk51_windows.append(time_util.window(trk51['begin_time'], trk51['end_time']))
fgs_pause_list = self.my_checklist.cal_display.parse_calendar_display(display_command=display_command,
search_string='FGS PAUSE',
regex=0)
fgs_pause_windows = time_util.window_list()
for fgs in fgs_pause_list:
t1 = fgs['begin_time']
t2 = fgs['end_time']
fgs_pause_windows.append(time_util.window(t1, t2))
scan_list = cal_disp.get_spatial_scans()
scan_windows = time_util.window_list()
for scan in scan_list:
# Only interested in scans under FGS-control
if (scan['mustusegyro'] != 'Y'):
scan_windows.append(time_util.window(scan['begin_time'], scan['end_time']))

# There must be at least one PC ACQ and at least one slew.
if not pcs_acqs:
self.pf_status = UNKNOWN
file_pointer.write(">>> No ACQs or REACQs found on this calendar!\n")
return self.pf_status

if not slew_list:
self.pf_status = UNKNOWN
file_pointer.write(">>> No Slews found on this calendar!\n")
return self.pf_status

# Find the slew time windows.
last_slew_begin_time = slew_list[len(slew_list)-1]['begin_time']
slew_time_windows = []
for slew in slew_list:
slew_time_windows.append(time_util.window(slew['begin_time'],
slew['end_time']))

# Find the guide star pair acquisitions or reacquisitions.
# Note that the guide star (re)acq end time is the begin time of
# guiding.
acq_begin_times = []
acq_end_times = []
for acq in pcs_acqs:
if acq['mode'].find('BASE1') != -1:
acq_begin_times.append(acq['begin_time'])
acq_end_times.append(acq['end_time'])

# Assign (re)acq times into a list of windows.
# If n = len(acq_end_times)-1, then use the start of the slew
# to the ending 2968.
windows = time_util.window_list()
for n in range(len(acq_end_times)):
if (n < len(acq_end_times)-1):
windows.append(time_util.window(acq_end_times[n], acq_begin_times[n+1]))
else:
# Check if last_slew_begin_time is prior to the acq_end_times, ie no 2968
# If so, use the calendar end time instead
if (last_slew_begin_time < acq_end_times[n]):
windows.append(time_util.window(acq_end_times[n], end))
else:
windows.append(time_util.window(acq_end_times[n], last_slew_begin_time))

# Correct windows for slews, SAA model 02 entries, and FGS earth
# avoidance slews.

for window in windows:
for slew in slew_time_windows:
if window.overlaps(slew):
window.set_end_time(slew.starttime())

for passage in saa02:
saa02_win = time_util.window(passage['begin_time'], passage['end_time'])
if window.overlaps(saa02_win):
window.set_end_time(saa02_win.starttime())

for fgs_slew in fgs_ea_entry:
if window.overlaps(fgs_slew):
window.set_end_time(fgs_slew.starttime())

for fgs_pause in fgs_pause_windows:
if window.overlaps(fgs_pause):
window.set_end_time(fgs_pause.starttime())

# Convert each window to a delta time. If the window overlaps
# a SAM, TRK51, SCAN or FGS Pause window, then calculate its delta time and
# subtract from the original window's delta time.
delta_wins = time_util.window_list()
for window in windows:
delta_win = window.size()
for sam in sam_windows:
if window.overlaps(sam):
delta_win = delta_win - window.intersection(sam).size()
for trk in trk51_windows:
if window.overlaps(trk):
delta_win = delta_win - window.intersection(trk).size()
for scan in scan_windows:
if window.overlaps(scan):
delta_win = delta_win - window.intersection(scan).size()
delta_wins.append(delta_win)

# Find the gyro bias update opportunities.
gyro_bias_updates = time_util.window_list()
for i in range(len(windows)):
if delta_wins[i] >= MIN_GUIDING_TIME:
new_start = windows[i].starttime() + MIN_GUIDING_TIME
windows[i].set_begin_time(new_start)
gyro_bias_updates.append(windows[i])

# Find the complement of gyro_bias_updates.
not_gyro_bias_updates = gyro_bias_updates.complement(interval=calendar_window)

# Test the intervals where no gyro bias update is possible against
# the minimum and preferred gyro bias update time intervals.
n_error = 0
n_warning = 0
file_pointer.write('Intervals of no expected autonomous gyro bias updates:\n')
for no_update in not_gyro_bias_updates:
if (no_update.size() > MIN_GYRO_BIAS_UPDATE_TIME):
n_error = n_error + 1
file_pointer.write('%s = %s -- Error\n' % (no_update, str(no_update.size())[:-4]))
file_pointer.write(' Minimum gyro bias update time window ')
file_pointer.write('of %s' % str(MIN_GYRO_BIAS_UPDATE_TIME)[:-4])
file_pointer.write(' is not met.\n')
elif (no_update.size() > PREF_GYRO_BIAS_UPDATE_TIME):
n_warning = n_warning + 1
file_pointer.write('%s = %s -- Warning\n' % (no_update, str(no_update.size())[:-4]))
file_pointer.write(' Preferred gyro bias update time ')
file_pointer.write('window of %s' % str(PREF_GYRO_BIAS_UPDATE_TIME)[:-4])
file_pointer.write(' is not met.\n')
else:
file_pointer.write('%s = %s -- OK\n' % (no_update, str(no_update.size())[:-4]))

if (n_error > 0):
file_pointer.write('**** Check FAILS ****\n')
self.pf_status = FAIL
elif (n_warning > 0):
self.pf_status = UNKNOWN
elif (n_error == 0 and n_warning == 0):
self.pf_status = PASS
else:
self.pf_status = UNKNOWN

if self.pf_status == PASS:
file_pointer.write("No problems found -- check passes\n")

return self.pf_status


def run(calendar):
"""Run the check stand alone.
"""
import calchecklist
clist = calchecklist.cal(calendar, 'none', 1)
check = gyro_bias_update_check(clist)
print "\n Output sent to file " + check.outfile
check.run()


if __name__ == '__main__':
import sys
run(*sys.argv[1:])