;------------------------------------------------------------------------------- ; ; Unit Name : l_SunPulseRtns.pro ; ; ; Purpose : This file contains all routines related to reading, processing, ; and calculating the location (the sectors) of the sun pulse data. ; ; ; Development History: ; Author Date Build Description of Change ; -------------- --------- -------- ------------------------- ; ELH 04/23/03 v1.0.11 Original implementation ; ; ; File Revision Number: %I% ; File Last Modified : %E% %T% ; ;------------------------------------------------------------------------------- ;------------------------------------------------------------------------------- ; Procedure: l_CalcSunPulse ; ; Description: This program reads in an orbit file and calculates the angle ; between the Sun and Earth for IMAGE and the LENA Sun sector ; ; Return Value: type = ; Value Description ; ------------------------- ------------------------------ ; None ; ; Argument List: ; Name Type Use Description ; ----------------- ------ --- --------------------------- ; l_oa struct * I pointer to OA data ; lena_sector float[] I sector location of sun pulse ; angle_zero long I sector location of angle zero ; ; ; External Variables: ; Source Name Type Use Description ; --------------- --------- ---- ---- -------------------- ; None ; ; ; Development History: ; Author Date Build Description of Change ; -------------- --------- -------- ------------------------- ; Michael Collier 10/22/00 v1.0 Original implementation ; ELH 11/02/00 v1.0 Converted original C ; program to IDL ;------------------------------------------------------------------------------- PRO l_CalcSunPulse, l_oa, lena_sector , angle_zero sc_spin = fltarr(3) sc_spin[0] = 0.229 sc_spin[1] = -0.974 sc_spin[2] = -0.005 RAD_TO_DEG = 180.0/3.14159265 if (angle_zero eq 'S') then begin nitems = n_elements ((*l_oa.gci_x_solar_pos_ptr)[*]) endif else begin if (angle_zero eq 'M') then begin nitems = n_elements ((*l_oa.gci_x_lunar_pos_ptr)[*]) endif else begin if (angle_zero eq 'R') then begin nitems = n_elements ((*l_oa.gci_x_vel_ptr)[*]) endif else begin if (angle_zero eq 'B') then begin nitems = n_elements ((*l_oa.gsm_x_pos_ptr)[*]) endif endelse endelse endelse sun_pos = fltarr (3) sc_pos = fltarr (3) s_hat_cross_p_hat = fltarr (3) lena_sector = fltarr (nitems) for i = 0, nitems - 1L do begin ;---------------------------------------------- ; grab sun and s/c vectors ;---------------------------------------------- if (angle_zero eq 'S') then begin sun_pos[0] = (*l_oa.gci_x_solar_pos_ptr)[i] sun_pos[1] = (*l_oa.gci_y_solar_pos_ptr)[i] sun_pos[2] = (*l_oa.gci_z_solar_pos_ptr)[i] endif else begin if (angle_zero eq 'M') then begin sun_pos[0] = (*l_oa.gci_x_lunar_pos_ptr)[i] sun_pos[1] = (*l_oa.gci_y_lunar_pos_ptr)[i] sun_pos[2] = (*l_oa.gci_z_lunar_pos_ptr)[i] endif else begin if (angle_zero eq 'R') then begin sun_pos[0] = (*l_oa.gci_x_vel_ptr)[i] sun_pos[1] = (*l_oa.gci_y_vel_ptr)[i] sun_pos[2] = (*l_oa.gci_z_vel_ptr)[i] endif else begin if (angle_zero eq 'B') then begin sun_pos[0] = (*l_oa.mag_field)[i,0] sun_pos[1] = (*l_oa.mag_field)[i,1] sun_pos[2] = (*l_oa.mag_field)[i,2] endif endelse endelse endelse sun_pos_mag = SQRT(sun_pos[0]*sun_pos[0] + sun_pos[1]*sun_pos[1] + $ sun_pos[2]*sun_pos[2]) sun_pos = sun_pos/sun_pos_mag sc_pos[0] = (*l_oa.gci_x_pos_ptr)[i] sc_pos[1] = (*l_oa.gci_y_pos_ptr)[i] sc_pos[2] = (*l_oa.gci_z_pos_ptr)[i] sc_pos_mag = SQRT(sc_pos[0]*sc_pos[0] + sc_pos[1]*sc_pos[1] + $ sc_pos[2]*sc_pos[2]) sc_pos = sc_pos/sc_pos_mag ;--------------------------------------------------------- ; determine component of Sun Vector along s/c spin axis ;--------------------------------------------------------- spin_dot_sun = 0 for j = 0, 2 do begin spin_dot_sun = spin_dot_sun + sun_pos[j] * sc_spin[j] endfor ;--------------------------------------------------------- ; subtract off component of Sun vector along spin axis ;--------------------------------------------------------- sun_proj = sun_pos for j = 0, 2 do begin sun_proj[j] = sun_proj[j] - spin_dot_sun * sc_spin[j] endfor ;--------------------------------------------------------- ; normalize the projected Sun vector ;--------------------------------------------------------- sun_proj_mag = SQRT(sun_proj[0]*sun_proj[0] + sun_proj[1]*sun_proj[1] + $ sun_proj[2]*sun_proj[2]) sun_proj = sun_proj / sun_proj_mag ;------------------------------------------------------------- ; determine angle between projected Sun vector and the Earth ;------------------------------------------------------------- sun_proj_dot_p = 0.0D for j = 0, 2 do begin sun_proj_dot_p = sun_proj_dot_p + sun_proj[j] * sc_pos[j] endfor earth_sun_angle = ACOS(sun_proj_dot_p)*RAD_TO_DEG ;------------------------------------------------------------- ; determine s hat cros p hat ;------------------------------------------------------------- s_hat_cross_p_hat[0] = sun_pos[1]*sc_pos[2] - sun_pos[2]*sc_pos[1] s_hat_cross_p_hat[1] = -(sun_pos[0]*sc_pos[2] - sun_pos[2]*sc_pos[0]) s_hat_cross_p_hat[2] = sun_pos[0]*sc_pos[1] - sun_pos[1]*sc_pos[0] ;------------------------------------------------------------- ; determine s hat cross p hat dotted into the spin direction ;------------------------------------------------------------- z_dot_s_cross_p = 0.0D for j = 0, 2 do begin z_dot_s_cross_p = z_dot_s_cross_p + s_hat_cross_p_hat[j]*sc_spin[j] endfor ;------------------------------------------------------------- ; correct angle for rotation towards/away from Earth ;------------------------------------------------------------- if (z_dot_s_cross_p le 0.0) then begin earth_sun_angle = earth_sun_angle - 180.0 endif if (z_dot_s_cross_p gt 0.0) then begin earth_sun_angle = 180.0 - earth_sun_angle endif ;------------------------------------------------------------- ; calculate LENA sun sector ;------------------------------------------------------------- lena_sector[i] = earth_sun_angle + 135.0 if (lena_sector[i] le 0.0) then begin lena_sector[i] = lena_sector[i] + 360.0 endif else begin if (lena_sector[i] ge 360.0) then begin lena_sector[i] = lena_sector[i] - 360.0 endif endelse format="(2(e12.5, TR4))" ;------------------------------------------------------------- ; converts to spin sector value else the value is in degrees ;------------------------------------------------------------- ;lena_sector[i] = lena_sector[i]/8.0 endfor RETURN END ;------------------------------------------------------------------------------- ; Procedure: l_DetermineSunDir ; ; Description: Calculates the sun direction. ; ; Return Value: type = ; Value Description ; ------------------------- ------------------------------ ; None ; ; Argument List: ; Name Type Use Description ; ----------------- ------ --- --------------------------- ; sun_markers float[] I sun sector location, filled data gaps ; sun_dir float[] O sun sector location, after any other ; trace adjustments ; l_setup struct I general setup parameters ; l_oa struct * I pointers to OA data ; ; ; External Variables: ; Source Name Type Use Description ; --------------- --------- ---- ---- -------------------- ; None ; ; ; Development History: ; Author Date Build Description of Change ; -------------- --------- -------- ------------------------- ; ELH 09/26/01 v1.0.7 Original Implementation ;------------------------------------------------------------------------------- PRO l_DetermineSunDir, sun_markers, sun_dir, l_setup, l_oa sun_dir = sun_markers sectors = l_setup.l_num_spinsec - 1L if (l_setup.l_angle_zero eq 'E') then begin ;--------------------------------------------------------- ; find the distance the earth was moved to center position ;--------------------------------------------------------- diff = (l_setup.l_earth_center - l_setup.l_spin_ang_zero) ;--------------------------------------------------------- ; subtract from the sun position the amount earth moved ;--------------------------------------------------------- gt_indx = where (sun_markers ge diff, gtcnt) if (gtcnt gt 0) then begin sun_dir[gt_indx] = sun_markers[gt_indx] - diff endif ;--------------------------------------------------------- ; position of sun when readjusted, crosses over the ; 44, 0 boundary ;--------------------------------------------------------- lt_indx = where (sun_markers lt diff, ltcnt) if (ltcnt gt 0) then begin sun_dir[lt_indx] = sectors - (diff - sun_markers[lt_indx] - 1) endif indx = where (sun_dir ge 45, cnt) if (cnt gt 0) then begin sun_dir[indx] = sun_dir[indx] - l_setup.l_num_spinsec endif endif else begin if (l_setup.l_angle_zero eq 'M') then begin moon = (*l_oa.lena_moon_sectPtr) ;--------------------------------------------------------- ; subtract from the sun position the amount moon moved ; to be centered at zero spin angle ;--------------------------------------------------------- gt_indx = where (moon ge l_setup.l_spin_ang_zero, gtcnt) if (gtcnt gt 0) then begin moon_dist = moon[gt_indx] - l_setup.l_spin_ang_zero sun_dir[gt_indx] = sun_markers[gt_indx] - moon_dist endif ;--------------------------------------------------------- ; position of sun when readjusted, if sun sector is at ; 33 will cross the 44, 0 boundary ;--------------------------------------------------------- lt_indx = where (moon lt l_setup.l_spin_ang_zero, ltcnt) if (ltcnt gt 0) then begin moon_dist = l_setup.l_spin_ang_zero - moon[lt_indx] indx_gt33 = where (sun_dir[lt_indx] ge (sectors - l_setup.l_spin_ang_zero), $ gt33cnt) sun_dir[lt_indx] = sun_markers[lt_indx] + moon_dist if (gt33cnt gt 0) then begin sun_dir[lt_indx[indx_gt33]] = (sun_dir[lt_indx[indx_gt33]] - $ l_setup.l_num_spinsec) endif endif endif else begin if (l_setup.l_angle_zero eq 'S') then begin sun = (*l_oa.lena_sun_sectPtr) ;--------------------------------------------------------- ; subtract from the sun position the amount sun moved ; to be centered at zero spin angle ;--------------------------------------------------------- gt_indx = where (sun ge l_setup.l_spin_ang_zero, gtcnt) if (gtcnt gt 0) then begin sun_dist = sun[gt_indx] - l_setup.l_spin_ang_zero sun_dir[gt_indx] = sun_markers[gt_indx] - sun_dist endif ;--------------------------------------------------------- ; position of sun when readjusted, if sun sector is at ; 33 will cross the 44, 0 boundary ;--------------------------------------------------------- lt_indx = where (sun lt l_setup.l_spin_ang_zero, ltcnt) if (ltcnt gt 0) then begin sun_dist = l_setup.l_spin_ang_zero - sun[lt_indx] indx_gt33 = where (sun_dir[lt_indx] ge (sectors - l_setup.l_spin_ang_zero), $ gt33cnt) sun_dir[lt_indx] = sun_markers[lt_indx] + sun_dist if (gt33cnt gt 0) then begin sun_dir[lt_indx[indx_gt33]] = (sun_dir[lt_indx[indx_gt33]] - $ l_setup.l_num_spinsec) endif endif endif endelse endelse RETURN END ;------------------------------------------------------------------------------- ; Procedure: l_DrawSunDirection ; ; Description: Draws the sun direction on the plot. ; ; Return Value: type = ; Value Description ; ------------------------- ------------------------------ ; None ; ; Argument List: ; Name Type Use Description ; ----------------- ------ --- --------------------------- ; X array[] I X values, time ; Y array[] I Y values, sun sectors ; img_pos long[] I plot position ; ; External Variables: ; Source Name Type Use Description ; --------------- --------- ---- ---- -------------------- ; l_LenaPlot.pro ; PLOTDEFS MAX_PLOTS int G max # plots per page ; MAX_WEB_SPINS int G max # spins per plot ; when using web interface ; NO_CNTS double G no counts indicator ; NO_DATA double G no data indicator ; ; ; Development History: ; Author Date Build Description of Change ; -------------- --------- -------- ------------------------- ; ELH v1.0.7 Original implementation ;------------------------------------------------------------------------------- PRO l_DrawSunDirection, X, Y, img_pos COMMON PLOTDEFS, MAX_PLOTS, MAX_WEB_SPINS, NO_CNTS, NO_DATA blankticks = strarr (30) blankticks(*) = ' ' PLOT, X, Y, /normal, /noerase, $ xstyle=1, $ ystyle=1, $ xrange = [min(X), max(X)], $ yrange = [0, 44], $ ticklen = -0.05, $ xtickname = blankticks, $ ytickname = blankticks, $ position = img_pos, $ linestyle = 2, $ ; dashed line thick = 2, $ ; line thickness color = 0 ; white RETURN END ;------------------------------------------------------------------------------- ; Procedure: l_CalcSunDirection ; ; Description: Routine which calls the procedures to calculate and draw the sun pulse ; sectors. ; ; Return Value: type = ; Value Description ; ------------------------- ------------------------------ ; None ; ; Argument List: ; Name Type Use Description ; ----------------- ------ --- --------------------------- ; l_oa struct * I pointers to OA data ; l_setup struct I general setup parameters ; img_pos long[] I plot position ; ; ; External Variables: ; Source Name Type Use Description ; --------------- --------- ---- ---- -------------------- ; None ; ; Development History: ; Author Date Build Description of Change ; -------------- --------- -------- ------------------------- ; ELH 04/23/03 v1.0.11 Original implementation ;------------------------------------------------------------------------------- PRO l_CalcSunDirection, l_oa, l_setup, img_pos nspins = n_elements ((*l_oa.tme_ptr)) l_HndlMissOA, (*l_oa.tme_ptr), $ hmd_oa_tme, $ nspins, $ (*l_oa.lena_sun_sectPtr), $ sun_markers, $ l_setup.l_start_dtime, $ l_setup.l_stop_dtime, $ 1 l_DetermineSunDir, sun_markers, sun_dir, l_setup, l_oa l_DrawSunDirection, hmd_oa_tme, $ sun_dir, $ img_pos RETURN END