PRO HSI_ADVANCE_ROLL_SOLUTION, obs_time_interval, start_time, stop_time, $ TEST_TIME=test_time, LATENCY=latency, SC_SUN_OFFSET=sc_sun_offset, PA_CORR=pa_corr ; ; Analyses PMTRAS data for obs_time_interval and returns predicted clock angle at future_time ; ; ; If TEST_TIME is defined, start_time and stop_time inputs are not required and the interpolated "actual" ; PA at test_time is printed. ; ; sc_sun_offset = 2 element vector representing the s/c pointing offset (+W,+N) in degrees relative to sun center. ; pa_corr = an empirial position angle offset (degrees) that is added to THETAz0 to reflect recent biasses. ; ; 30-MAY-02 First version (ghurford@ssl.berkeley.edu) ; 31-May-02 Remove the !PI adjustment to PMTRAS_ANALYSIS output ; Express roll rate in radians/s, not rpm. ; 8-Jun-02 gh Use quadratic model of pa vs time to extrapolate to stop time, then linear fit back to target time. ; Add TEST_TIME keyword ; 10-JUn-02 gh Add PLOT keyword ; 11-Jun-02 gh Add optional inputs for comparing actual-predicted position angles. ; 12-jun-02 gh Use last instead of observed roll value as the msmt point. ; Correct trivial error in sign of actual-predicted position angles. ; Include the !PI adjustment to PMTRAS_ANALYSIS output. ; Destroy object after use. ; 16-Jun-02 gh/jm Zero the clock drift file so that all times are in terms of s/c clock, not UTC. ; gh Once again, remove the !PI adjustment to PMTRAS_ANALYSIS output. ; Add LATENCY keyword. ; 17-Jun-02 gh Include latency offset in displayed target time. ; Minor output format change. ; 18-Jun-02 gh Add SC_SUN_OFFSET keyword ; gh Change calculation of theta0Z by 180 degrees to match results of June 17 and 18. ; 19-Jun-02 gh Add display of sc_sun_offset input value. ; 22-Jun-02 gh Add TIMEBIN keyword. ; 24-Apr-03 gh Remove blipmin=150 argument in call to pmtras_analysis ; 18-May-03 gh Implement new default algorithm to base predictions on a quadratic fit to pa at ; specific times separated by integral orbital periods. ; Define OLD_METHOD keyword to retain ability to use previous algorithm. ; 16-Apr-04 gh Completely recoded to exploit fits to roll database. ; 17-Apr-04 gh Recode TEST_TIME keyword handling to work with roll database. ; 9-Jun-04 gh Eliminate printing of sc_sun_offset which has not been used since 16-april-04 version. ; Suppress printing of (irrelevant) latency when in TEST_TIME mode. ; Correct printing bug in TEST_TIME mode when exiting due to extrapolation. ; Add PA_CORR keyword. ; 13-May-05 gh Remove obsolete pred_pa_target and pred_period arguments ; ; latency = time delay (s) between the nominal time of the ATS load and the first execution of the offpointing software ; ; Zero clock drift file to force target time and solution to be in s/c units. ; Unless reversed, THIS APPLIES TO THE REMAINDER OF THE IDL SESSION !!!! hsi_clock_drift, /zero_init_drift ; IF N_ELEMENTS(latency) EQ 0 THEN latency = 0 ; default is no latency IF N_ELEMENTS(pa_corr) EQ 0 THEN pa_corr = 0. ; default is no empirical correction IF N_ELEMENTS(sc_sun_offset) EQ 0 THEN sc_sun_offset = FLTARR(2) ; default is [0,0] IF KEYWORD_SET (test_time) THEN BEGIN opmt = hsi_roll_db_full() dbsolution = opmt->getdata(obs_time_interval=obs_time_interval) IF N_ELEMENTS(dbsolution) EQ -1 THEN MESSAGE, 'HSI_ADVANCE_ROLL_SOLUTION could not find the roll database.' obj_destroy, opmt ; ok = WHERE(dbsolution.roll_quality GE 192, nok) solnok = hsi_pmtras_dbase_expand(dbsolution[ok]) ; convert to structure with monatonically increasing radians phaseok = solnok.posn_angle ; DOUBLE in radians t0 = dbsolution[0].sctime ; LONG in seconds trelok = dbsolution[ok].sctime - t0 ; LONG array test_time_st = hsi_any2sctime(test_time) test_time_rel = test_time_st.seconds - t0 pa_test_solar = INTERPOL(phaseok, trelok, test_time_rel, /QUAD) p_angle = pb0r(t0_target_s) ; p,b0,r in deg, deg, arcmin pa_test = pa_test_solar - p_angle[0]*!DTOR ; make position angles wrt celestial rather than solar N. PRINT, 'OBS_TIME: from: ', ANYTIM(obs_time_interval[0], /ECS) PRINT, ' to: ', ANYTIM(obs_time_interval[1], /ECS) ; PRINT, 'SC_SUN_OFFSET (deg) ', sc_sun_offset ; PRINT, 'LATENCY (s) = ', latency PRINT, 'TEST_TIME = ', ANYTIM(test_time, /ECS) IF test_time_rel GT trelok[nok-1] THEN BEGIN PRINT, 'LAST DATA TIME = ', ANYTIM(trelok[nok-1]+t0,/ECS) PRINT, 'Did not attempt extrapolation.' ENDIF ELSE PRINT, 'PA at test_time[rad]=', (pa_test + 2000*!DPI) MOD (2.*!DPI) RETURN ENDIF ; ; ; Calculate target time in sc clock units at integer seconds. target_sc_time = hsi_any2sctime(start_time) ; convert nominal future_time to sc clock target_sc_time.bmicro = 0 ; Truncate sc clock to integral seconds t0_target_s = hsi_sctime2any(target_sc_time) + latency ; Add ATS-to-execution latency t0_target_label = anytim(t0_target_s, /ECS) stop_sc_time = hsi_any2sctime(stop_time) stop_sct = DOUBLE(stop_sc_time.seconds) target_sct = DOUBLE(target_sc_time.seconds) + latency ; target time in sctime seconds PMTRAS_DBASE_MANAGER, TIME_RANGE=obs_time_interval, PRED_TIMES=[stop_sct, target_sct], PRED_ROLL=pred_roll p_angle_target = pb0r(t0_target_s) ; p,b0,r in deg, deg, arcmin p_angle_stop = pb0r(stop_time) pa_stop = pred_roll[0] - (p_angle_stop[0] *!DTOR) ; make position angles wrt celestial rather than solar N. pa_target = pred_roll[1] - (p_angle_target[0] *!DTOR) ; ; Determine average spin period and roll rate between target and stop times. ;spin_rate = (pa_stop - pa_target) / (t_stop_rel - t_target_rel) ; radians/s spin_rate = (pa_stop - pa_target) / (stop_sct - target_sct) ; radians/s avperiod = 2 * !PI / spin_rate ; seconds ; ; Determine target clock angle ; theta0z = (pa_target - !PI/2.) MOD (2.*!PI) ; convention used until June 18,2002 theta0z = (pa_target + pa_corr*!DTOR + !PI/2.) MOD (2.*!PI) ; convention used from June 19 ; Print results PRINT PRINT, 'OBS_TIME: from: ', ANYTIM(obs_time_interval[0], /ECS) PRINT, ' to: ', ANYTIM(obs_time_interval[1], /ECS) ; PRINT, 'SC_SUN_OFFSET (deg) ', sc_sun_offset PRINT, 'LATENCY (s) = ', latency PRINT, 'PA_corr (deg) = ', pa_corr IF KEYWORD_SET(timebin) THEN PRINT, 'TIMEBIN (s) = ', timebin IF KEYWORD_SET(old_method) NE 0 THEN $ PRINT, 'MEASUREMENT TIME = ', t_roll_msmt_label PRINT, 'TARGET TIME = ', t0_target_label PRINT, 'STOP TIME = ', ANYTIM(stop_time, /ECS) IF KEYWORD_SET(old_method) NE 0 THEN $ PRINT, 'PAmsmt [rad] = ', posn_angle_msmt MOD (2.*!PI) PRINT, 'PAtarget [rad] = ', pa_target MOD (2.*!PI) PRINT, 'PAstop [rad] = ', pa_stop MOD (2.*!PI) PRINT, ' [sec] = ', avperiod PRINT PRINT, 'TARGET SC TIME =', target_sc_time.seconds, '.000000 ' PRINT, 'SPIN RATE[rad/s] = ', spin_rate, ' <==============' PRINT, theta0z, FORMAT = "('THETAz0 [rad] =', F14.3, 10X, '<=============')" RETURN END