;;File Version: 2.0 ;;Last Modified: June 26, 2018 ;;By: JEC PRO ROCCDAT ;;This program computes a ring optical depth profile, with uncertainties, ;;from UVIS HSP data of a ring stellar occultation. ROCCDAT = Ring Occultation ;;Data Analysis Tool. ;; The user will be able to click on the data at spots where the star is ;; unobstructed by ring material to derive a profile for the unobstructed ;; star count rate. The user will be able to click on the data at spots ;; where there is no signal from the star to derive a profile for the background ;; count rate. ;; Inputs: ;; HSP data. Data files may be selected by the user at run time. ;; ;; A file with background count rates as a function of ring radius ;; position. ;; ;; History: ;; July 18, 2003: Start programming and widget design. ;; Joshua Colwell, Univ. of Colorado, UVIS team. ;; July 31, 2003: Calls HSP_CONCAT and loads and plots raw data. ;; August 4, 2003: Enable binning of data within this program. ;; August 5, 2003: Enable postscript output and logarithmic Y axis. ;; August 7, 2003: Dead time correction. Modify calling to hsp_concat. Display ;; integration period. Allow interactive readout of data values from plot. ;; August 12, 2003: Add Replot button. Enable Save button. Enable plotting connected ;; points. ;; August 15, 2003: Add statistics calculation. Cosmetic improvements. ;; September 11, 2003: Modify postscript style output. ;; September 12, 2003: Allow calls to hsp_concat to have binning. Additional ;; displays on GUI. ;; November 7, 2003: Update for new versions of HSP_BINNER and HSP_CONCAT with ;; improved time handling. ;; November 8, 2003: Increase sig figs displayed with track function. ;; February 24, 2004: Display data start time in widget. ;; October 15, 2004: Fix precision with binned data. Calculate ring plane ;; radii with geometer_engine. ;; February 3, 2005: compile_opt idl2. Fix stats bug. ;; May 23, 2005: Update for new OCCRAD program. ;; November 6, 2006: Smaller plot window to reduce overall widget size. ;; May 7, 2008: Correct proper motion correction. ;; January 5, 2009: More output. ;; April 3, 2009: Make OCCRAD do GR correction automatically, so ;; eliminate keyword in call. ;; November 25, 2009: Update for new OCCRAD (get ringoccphi). ;; January 20, 2010: Automatically load the reconstructed SP kernel ;; for the time period of the occultation, then find in a ;; compatibility table of SP and PC kernels the corresponding PC ;; kernel and load it. This is to have the right pole for the ;; particular SP kernel used. ;; January 5, 2013: add "are you sure" to Quit. ;; June 6, 2014: Add shortcut save button for standard ring occ geometry save. ;; June 26, 2018: Now that the mission is over we have a full merged SPK for ;; the entire mission. No longer necessary to have the software go off and retrieve ;; a particular SPK. So that part of the program is removed. COMPILE_OPT IDL2 COMMON HSPCOMMON, data, et, radius, lon, tau, dbin, etbin, radeg, dtor, $ ringoccphi radeg = 180D0/!DPI dtor = !DPI/180D0 true = 1B false = 0B !FANCY=2 version = 'V2.0 June 26, 2018' mainbase = WIDGET_BASE(TITLE = 'HSP Ring Occultation Data Analysis Tool '+$ version, /COLUMN) toprow = WIDGET_BASE(mainbase, /ROW) buval = {id:'Load Data', type:'BUTTON'} button = WIDGET_BUTTON(toprow, VALUE = buval.id, UVALUE = buval) buval.id = 'Save' button = WIDGET_BUTTON(toprow, VALUE = buval.id, UVALUE = buval) buval.id = 'SaveOcc' button = WIDGET_BUTTON(toprow, VALUE = buval.id, UVALUE = buval) buval.id = 'Reset' button = WIDGET_BUTTON(toprow, VALUE = buval.id, UVALUE = buval) buval.id = 'Replot' button = WIDGET_BUTTON(toprow, VALUE = buval.id, UVALUE = buval) buval.id = 'Quit' button = WIDGET_BUTTON(toprow, VALUE = buval.id, UVALUE = buval) buval.id = 'Stop' button = WIDGET_BUTTON(toprow, VALUE = buval.id, UVALUE = buval) label = WIDGET_LABEL(toprow, VALUE = 'Last Loaded File:') tuval = {id:'', type:'TEXT'} filenamewidget = WIDGET_TEXT(toprow, VALUE = 'None', UVALUE = tuval, $ XSIZE = 59) ;;Create the area for the draw window and its associated controls. drawbase = WIDGET_BASE(mainbase, /COLUMN) plotparambase = WIDGET_BASE(drawbase, /COLUMN, /FRAME) rangebase = WIDGET_BASE(plotparambase, /ROW) label = WIDGET_LABEL(rangebase, VALUE = 'X Data Range Min: ') tuval.id = 'XMIN' xmintext = WIDGET_TEXT(rangebase, VALUE = '0', UVALUE = tuval, $ /EDITABLE, XSIZE = 6) label = WIDGET_LABEL(rangebase, VALUE = ' Max: ') tuval.id = 'XMAX' xmaxtext = WIDGET_TEXT(rangebase, VALUE = '0', UVALUE = tuval, $ /EDITABLE, XSIZE = 6) yrangebase = WIDGET_BASE(plotparambase, /ROW) label = WIDGET_LABEL(rangebase, VALUE = 'Y Data Range Min: ') tuval.id = 'YMIN' ymintext = WIDGET_TEXT(rangebase, VALUE = '0', UVALUE = tuval, $ /EDITABLE, XSIZE = 6) label = WIDGET_LABEL(rangebase, VALUE = ' Max: ') tuval.id = 'YMAX' ymaxtext = WIDGET_TEXT(rangebase, VALUE = '0', UVALUE = tuval, $ /EDITABLE, XSIZE = 6) label = WIDGET_LABEL(rangebase, VALUE = 'Plot Symbol') duval = {id:'psym', type:'DROP'} psymdrop = WIDGET_DROPLIST(rangebase, UVALUE = duval, VALUE = $ ['Points','Asterisks','Diamonds','Triangles','Squares','Plus','Line']) stylebase = WIDGET_BASE(rangebase, /ROW, /NONEXCLUSIVE) buval.id = 'Connect Points' button = WIDGET_BUTTON(stylebase, VALUE = buval.id, UVALUE = buval) timebase = WIDGET_BASE(plotparambase, /ROW) label = WIDGET_LABEL(timebase, VALUE = 'Bin Size: ') tuval = {id:'bin', type:'TEXT'} tbin = WIDGET_TEXT(timebase, UVALUE = tuval, VALUE = '1', /EDITABLE, XSIZE = 12) label = WIDGET_LABEL(timebase, VALUE = 'Unbinned Int. Period (sec): ') tuval.id = 'ip' tip = WIDGET_TEXT(timebase, UVALUE = tuval, VALUE = 'N/A', XSIZE = 8) label = WIDGET_LABEL(timebase, VALUE = 'Number of points: ') tuval.id = 'npoints' tnumpoints = WIDGET_TEXT(timebase, UVALUE = tuval, VALUE = 'N/A', XSIZE = 12) label = WIDGET_LABEL(timebase, VALUE = 'Start: ') tuval.id = 'starttime' tstarttime = WIDGET_TEXT(timebase, UVALUE = tuval, VALUE = 'N/A', XSIZE = 24) titlebase = WIDGET_BASE(plotparambase, /ROW) label = WIDGET_LABEL(titlebase, VALUE = 'X Title: ') tuval.id = 'XTITLE' xtitle = WIDGET_TEXT(titlebase, VALUE = 'Default', /EDITABLE, XSIZE = 24, $ UVALUE = tuval) label = WIDGET_LABEL(titlebase, VALUE = 'Y Title: ') tuval.id = 'YTITLE' ytitle = WIDGET_TEXT(titlebase, VALUE = 'Default', /EDITABLE, XSIZE = 24, $ UVALUE = tuval) label = WIDGET_LABEL(titlebase, VALUE = 'Main Title: ') tuval.id = 'MTITLE' mtitle = WIDGET_TEXT(titlebase, VALUE = 'Default', /EDITABLE, XSIZE = 30, $ UVALUE = tuval) fringbase = WIDGET_BASE(titlebase, /ROW, /EXCLUSIVE) buval.id = 'RINGPLANE' ringplanebutton = WIDGET_BUTTON(fringbase, VALUE = 'Eq. Plane', $ UVALUE = buval) buval.id = 'FRING' fringbutton = WIDGET_BUTTON(fringbase, VALUE = 'F Ring', $ UVALUE = buval) WIDGET_CONTROL, ringplanebutton, /SET_BUTTON plotcontrolbase = WIDGET_BASE(plotparambase, /ROW) label = WIDGET_LABEL(plotcontrolbase, VALUE = 'X Axis') duval = {id:'xaxisdrop', type:'DROP'} xaxisdrop = WIDGET_DROPLIST(plotcontrolbase, UVALUE = duval, VALUE = $ ['ET', 'Index','Elapsed Hours','Elapsed Minutes','Elapsed Seconds',$ 'Ring Plane Radius']) label = WIDGET_LABEL(plotcontrolbase, VALUE = 'Y Axis: ') duval = {id:'yaxisdrop', type:'DROP'} yaxisdrop = WIDGET_DROPLIST(plotcontrolbase, UVALUE = duval, VALUE = $ ['Counts','Optical Depth','Background','I0']) label = WIDGET_LABEL(plotcontrolbase, VALUE = 'Control: ') duval = {id:'actiondrop', type:'DROP'} actiondrop = WIDGET_DROPLIST(plotcontrolbase, UVALUE = duval, VALUE = $ ['Plot', 'Compute Radii']) ; 'Set I0', 'Set Background','Dead Time Correction','Track',$ ; 'Numbers for Table','Compute Stats','Trend Correction',$ ; 'Compute Radii']) optionsbase = WIDGET_BASE(plotcontrolbase, /ROW, /NONEXCLUSIVE) buval.id = 'POSTSCRIPT' psbutton = WIDGET_BUTTON(optionsbase, VALUE = 'PostScript', $ UVALUE = buval) buval.id = 'YLOG' ylog = WIDGET_BUTTON(optionsbase, VALUE = 'Log. Y Axis', $ UVALUE = buval) drawuval = {id:'draw1',type:'DRAW'} draw = WIDGET_DRAW(drawbase, UVALUE = drawuval, SCR_XSIZE = 700, $ SCR_YSIZE = 400, $ /BUTTON_EVENTS, EVENT_PRO = 'ROCCDAT_DRAW_EVENT') status_base = WIDGET_BASE(mainbase, /ROW) label = WIDGET_LABEL(status_base, VALUE = 'Status:') status = WIDGET_TEXT(status_base, XSIZE = 113) WIDGET_CONTROL, mainbase, /REALIZE CASE !VERSION.OS OF ;;Need to add Mac to this list.' 'Win32': devname = 'win' ELSE: devname = 'X' ENDCASE WIDGET_CONTROL, draw, GET_VALUE = drawwin mainuval = {yaxisdrop:yaxisdrop, actiondrop:actiondrop, drawwin:drawwin, $ xaxisdrop:xaxisdrop, data:false, et:false, radius:false, tau:false, draw:draw, $ status:status, psym:3, xmintext:xmintext, xmaxtext:xmaxtext, ymintext:ymintext, $ ymaxtext:ymaxtext, xtitle:xtitle, ytitle:ytitle, mtitle:mtitle, bin:1, $ ylog:false, psbutton:false, devname:devname, tbin:tbin, ip:0., dtc:false, $ tip:tip, connect:false, filenamewidget:filenamewidget, tnumpoints:tnumpoints, $ tstarttime:tstarttime, fring:false, nfiles:0} WIDGET_CONTROL, mainbase, SET_UVALUE = mainuval SET_PLOT, mainuval.devname XMANAGER, "ROCCDAT", mainbase, EVENT_HANDLER = "ROCCDAT_EVENT" END PRO ROCCDAT_EVENT, event COMMON HSPCOMMON, data, et, radius, lon, tau, dbin, etbin, radeg, dtor, $ ringoccphi true = 1B false = 0B ;; Event handler for all but draw widget events generated by ROCCDAT. WIDGET_CONTROL, event.id, GET_UVALUE = uval WIDGET_CONTROL, event.top, GET_UVALUE = mainuval CASE uval.type OF 'BUTTON': BEGIN CASE uval.id OF 'Quit': BEGIN result = DIALOG_MESSAGE("Are you sure you want to quit?", /QUESTION) IF result EQ "Yes" THEN WIDGET_CONTROL, event.top, /DESTROY RETURN END 'Stop': STOP,'Stopping program. Use .c to continue.' 'Reset': BEGIN mainuval.dtc = false WIDGET_CONTROL, mainuval.xmintext, SET_VALUE = '0' WIDGET_CONTROL, mainuval.xmaxtext, SET_VALUE = '0' WIDGET_CONTROL, mainuval.ymintext, SET_VALUE = '0' WIDGET_CONTROL, mainuval.ymaxtext, SET_VALUE = '0' END 'Save': BEGIN sfile = DIALOG_PICKFILE(TITLE = 'Enter name of IDL save file') SAVE, dbin, etbin, data, et, filename = sfile WIDGET_CONTROL, mainuval.status, SET_VALUE = 'Data saved to IDL save file.' END 'SaveOcc': BEGIN sfile = DIALOG_PICKFILE(TITLE = 'Enter name of IDL save file for ring occ data', $ FILE = '/users/colwell/documents/cassini/uvis/data/RingStellarOccsHSP/') SAVE, data, et, radius, ringoccphi, lon, filename = sfile WIDGET_CONTROL, mainuval.status, SET_VALUE = 'Ring occultation data saved to IDL save file.' END 'Replot': BEGIN fakeevent = {WIDGET_DROPLIST, mainuval.actiondrop, event.top, $ event.handler, 0L} ROCCDAT_EVENT, fakeevent RETURN END 'Load Data': BEGIN HSP_CONCAT, data, et, /NOBIN, ip, lastfile, nfiles ;; Assuming that full merged SPK for the mission is loaded, so no additional ;; kernels loaded. ;; Get the year and day of year to identify the SP and PC ;; kernels that match this time period, and load them. ; CSPICE_ET2UTC, et[0], 'ISOD', 0L, utc0 ; year_str = STRMID(utc0, 2, 2) ; day_str = STRMID(utc0, 5, 3) ;; For ease of comparison, convert the date to a decimal year. ; IF year_str EQ '2004' OR year_str EQ '2008' OR 'year_str' EQ $ ; '2012' OR year_str EQ '2016' THEN ndays = 366. ELSE ndays = 365. ; datatime = FLOAT(year_str)+FLOAT(day_str)/ndays ; spkernelpath = '/users/colwell/documents/cassini/kernels/spkernels/' ; tkernelpath = '/users/colwell/documents/cassini/kernels/tkernels/' ; spklist = FILE_SEARCH(spkernelpath+'*R_SCPSE*.bsp', COUNT = nspk) ;; Loop through all SP kernels to find the right ;; reconstructed kernel for this time period ; foundspkernel = 0B ; index = 1 ; WHILE NOT foundspkernel AND index LT nspk DO BEGIN ; checktheoneopskernel = STRMID(spklist[index], STRPOS(spklist[index], $ ; 'SCPSE')+5,3) ; IF checktheoneopskernel EQ 'ops' THEN offset=4 ELSE offset=1 ; startyear = STRMID(spklist[index], STRPOS(spklist[index], $ ; 'SCPSE')+5+offset,2) ; startday = STRMID(spklist[index], STRPOS(spklist[index], $ ; 'SCPSE')+7+offset,3) ; starttime = FLOAT(startyear)+FLOAT(startday)/ndays ; IF startyear GT 17 THEN staryear = '01' ;; there is one kernel that ;;is for the whole mission and has a different naming scheme. It also starts ;;in 1997, so the year for it (97) is greater than the end year. That ;;screws things up, and we have no data at Saturn before 2000, so if this ;;is our kernel, just set the year to 01. ; endyear = STRMID(spklist[index], $ ; STRPOS(spklist[index], '_', /REVERSE_SEARCH) + $ ; 1, 2) ; endday = STRMID(spklist[index], $ ; STRPOS(spklist[index], '_', /REVERSE_SEARCH) + $ ; 3, 3) ; endtime = FLOAT(endyear)+FLOAT(endday)/ndays ; IF datatime GT starttime AND datatime LT endtime THEN $ ; foundspkernel = 1B ELSE index++ ; ENDWHILE ; IF index EQ nspk THEN BEGIN ; spkernel = DIALOG_PICKFILE(TITLE = 'Select the SP kernel', $ ; FILTER = '*.bsp', PATH = spkernelpath) ; ENDIF ELSE spkernel = spklist[index] ; PRINT,'Loaded: ',spkernel ; CSPICE_FURNSH, spkernel ;; Now find and load the PC kernel that is compatible with ;; this SP kernel: ; RESTORE, tkernelpath+'pcktospk_template.sav' ; pckmap = READ_ASCII(tkernelpath+'pcktospk_mapping.txt', $ ; TEMPLATE = pcktospk_template) ; nlist = N_ELEMENTS(pckmap.field1) ; foundpckernel = 0B ; index = 0 ; lastslashpos = STRPOS(spkernel, '/', /REVERSE_SEARCH) ; lastdotpos = STRPOS(spkernel, '.', /REVERSE_SEARCH) ; spkcore = STRMID(spkernel, lastslashpos+1, lastdotpos-lastslashpos-1) ; WHILE NOT foundpckernel AND index LE nlist DO $ ; IF pckmap.field2[index] EQ spkcore THEN $ ; foundpckernel = 1B ELSE index++ ; IF index GT nlist THEN PRINT,'Could not find PC kernel to load.' $ ; ELSE BEGIN ; CSPICE_FURNSH, tkernelpath+pckmap.field1[index] ; PRINT,'Loaded: ',pckmap.field1[index] ; ENDELSE mainuval.bin = 1 mainuval.nfiles = nfiles dbin = data ;;initialize binned data with data from HSP_CONCAT etbin = et mainuval.data = true mainuval.et = true mainuval.ip = ip*mainuval.bin WIDGET_CONTROL, mainuval.tip, SET_VALUE = STRCOMPRESS(STRING(ip)) mainuval.dtc = false WIDGET_CONTROL, mainuval.tbin, SET_VALUE = STRING(mainuval.bin) WIDGET_CONTROL, mainuval.status, SET_VALUE = 'Data loaded. '+$ STRCOMPRESS(STRING(N_ELEMENTS(data)))+' data points.' WIDGET_CONTROL, mainuval.tnumpoints, SET_VALUE = $ STRCOMPRESS(STRING(N_ELEMENTS(data))) WIDGET_CONTROL, mainuval.filenamewidget, SET_VALUE = lastfile CSPICE_ET2UTC, et[0], 'ISOD', 3L, utc WIDGET_CONTROL, mainuval.tstarttime, SET_VALUE = utc END 'Connect Points': BEGIN IF NOT mainuval.connect THEN BEGIN mainuval.connect = true mainuval.psym = -mainuval.psym ENDIF ELSE BEGIN mainuval.connect = false mainuval.psym = ABS(mainuval.psym) ENDELSE END 'POSTSCRIPT': BEGIN IF mainuval.psbutton THEN BEGIN !X.THICK = 1 !Y.THICK = 1 !P.CHARTHICK = 1 mainuval.psbutton = false ENDIF ELSE BEGIN !X.THICK = 2 !Y.THICK = 2 !P.CHARTHICK = 1.5 mainuval.psbutton = true ENDELSE END 'YLOG': BEGIN IF mainuval.ylog EQ 1 THEN $ mainuval.ylog = 0 ELSE mainuval.ylog = 1 END 'RINGPLANE': mainuval.fring = false 'FRING': mainuval.fring = true ELSE: ENDCASE END ;;end of button selections 'DROP': BEGIN CASE uval.id OF 'psym': BEGIN psymselect = WIDGET_INFO(event.id, /DROPLIST_SELECT) CASE psymselect OF 0: mainuval.psym = 3 ;points are symbol #3 1: mainuval.psym = 2 ;asterisks are symbol #2 2: mainuval.psym = 4 ;diamonds are symbol #4 3: mainuval.psym = 5 ;triangles are symbol #5 4: mainuval.psym = 6 ;squares are symbol #6 5: mainuval.psym = 1 ;plus signs are symbol #1 6: mainuval.psym = 0 ;line ENDCASE IF mainuval.connect THEN mainuval.psym = -mainuval.psym END ;psym selection 'xaxisdrop': BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = 'Selection registered.' CASE event.index OF 0: IF mainuval.et THEN BEGIN WIDGET_CONTROL, mainuval.xtitle, SET_VALUE = 'ET' ENDIF ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'ET data not available for plotting.' WIDGET_CONTROL, event.id, SET_DROPLIST_SELECT = 5 RETURN ENDELSE 1: BEGIN WIDGET_CONTROL, mainuval.xtitle, SET_VALUE = $ 'Index Number' END 2: IF mainuval.et THEN BEGIN WIDGET_CONTROL, mainuval.xtitle, SET_VALUE = $ 'Time from Observation Start (Hours)' ENDIF ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'ET data not available for plotting.' WIDGET_CONTROL, event.id, SET_DROPLIST_SELECT = 5 RETURN ENDELSE 3: IF mainuval.et THEN BEGIN WIDGET_CONTROL, mainuval.xtitle, SET_VALUE = $ 'Time from Observation Start (Minutes)' ENDIF ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'ET data not available for plotting.' WIDGET_CONTROL, event.id, SET_DROPLIST_SELECT = 5 RETURN ENDELSE 4: IF mainuval.et THEN BEGIN WIDGET_CONTROL, mainuval.xtitle, SET_VALUE = $ 'Time from Observation Start (Seconds)' ENDIF ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'ET data not available for plotting.' WIDGET_CONTROL, event.id, SET_DROPLIST_SELECT = 5 RETURN ENDELSE 5: IF mainuval.radius THEN BEGIN WIDGET_CONTROL, mainuval.xtitle, SET_VALUE = $ 'Ring Radius (km)' ENDIF ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Radius data not available for plotting.' RETURN ENDELSE ELSE: WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Impossible error: unrecognized X axis droplist selection.' ENDCASE ;;selection of x axis data. END 'yaxisdrop': BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = 'Selection registered.' CASE event.index OF 0: IF mainuval.data THEN $ WIDGET_CONTROL, mainuval.ytitle, SET_VALUE = 'Counts' $ ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Raw data are not available for plotting.' RETURN ENDELSE 1: IF mainuval.tau THEN $ WIDGET_CONTROL, mainuval.ytitle, SET_VALUE = 'Optical Depth' $ ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Optical depth not available for plotting.' WIDGET_CONTROL, event.id, SET_DROPLIST_SELECT = 0 RETURN ENDELSE ELSE: WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Unhandled selection.' ENDCASE ;;selection of y axis data. END 'actiondrop': BEGIN actionselect = WIDGET_INFO(event.id, /DROPLIST_SELECT) CASE actionselect OF 0: BEGIN ;;plot the current data selections. WSET, mainuval.drawwin xselect = WIDGET_INFO(mainuval.xaxisdrop, /DROPLIST_SELECT) CASE xselect OF 0: xdata = etbin 1: xdata = FINDGEN(N_ELEMENTS(dbin)) 2: xdata = (etbin-MIN(etbin))/3600D0 3: xdata = (etbin-MIN(etbin))/60D0 4: xdata = etbin-MIN(etbin) 5: xdata = radius ELSE: WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Impossible error: unrecognized X axis droplist selection.' ENDCASE ;;selection of x axis data. yselect = WIDGET_INFO(mainuval.yaxisdrop, /DROPLIST_SELECT) CASE yselect OF 0: ydata = dbin 1: ydata = tau ELSE: WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Unhandled selection.' ENDCASE ;;selection of y axis data. ;;Get ready to plot. ;;PLOTINFO procedure parses the values in the text widgets. PLOTINFO, mainuval, xmin, xmax, ymin, ymax, xtitle, ytitle, mtitle xrange = [xmin, xmax] yrange = [ymin, ymax] IF xmin EQ xmax THEN xrange = [MIN(xdata), MAX(xdata)] IF ymin EQ ymax THEN yrange = [MIN(ydata), MAX(ydata)] IF mainuval.psbutton THEN BEGIN SET_PLOT,'ps' plotfile = DIALOG_PICKFILE() DEVICE, FILENAME = plotfile, /ENCAPSULATED ENDIF PLOT, xdata, ydata, PSYM = mainuval.psym, XRANGE = xrange, $ YRANGE = yrange, YLOG = mainuval.ylog, XTITLE = xtitle, $ YTITLE = ytitle, TITLE = mtitle, POS = [0.18,0.1,0.92,0.92] IF mainuval.psbutton THEN BEGIN DEVICE, /CLOSE SET_PLOT, mainuval.devname ENDIF WIDGET_CONTROL, mainuval.status, SET_VALUE = 'Data plotted.' END ;;of 'Plot' selection of this drop widget. 3: BEGIN ;;Dead time correction block: IF mainuval.dtc THEN BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Dead time correction was previously applied to data.' RETURN ENDIF deadtime = 60.E-9 ;;Per Bill McClintock, +/- 5 nsec, ;;August 6, 2003. datarate = data/mainuval.ip data = datarate/(1.-datarate*deadtime) data = data*mainuval.ip datarate = dbin/mainuval.ip/mainuval.bin dbin = datarate/(1.-datarate*deadtime)*mainuval.ip*mainuval.bin WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Dead time correction has been applied to data.' mainuval.dtc = true END 4: ;;Do nothing. This setting will be recognized in the draw event handler. 5: BEGIN junk = MIN(radius,minloc) radin = radius[0:minloc] radout = radius[minloc:*] phiin = ringoccphi[0:minloc] phiout = ringoccphi[minloc:*] etin = etbin[0:minloc] etout = etbin[minloc:*] PRINT, 'Ingress:' PRINT, 'Phi: ',phiin[0], phiin[minloc] PRINT, 'Radius: ',radius[0], radius[minloc] PRINT, 'Duration: ',etin[minloc]-etin[0] PRINT, 'Egress:' PRINT, 'Phi: ',phiout[0], ringoccphi[N_ELEMENTS(ringoccphi)-1] PRINT,' Radius: ',radout[0], MAX(radout) PRINT,' Duration: ', MAX(et)-etout[0] PLOT, radius, ringoccphi, XTITLE = 'Radius (km)', YTITLE = $ 'ringoccphi (deg)' PRINT,'Total Duration: ',MAX(et)-MIN(et) END 6: BEGIN ;;Compute statistical measures for the data range selected in the ;;X Data Range windows. Use PLOTINFO to get the values of xmin, xmax: PLOTINFO, mainuval, xmin, xmax, ymin, ymax, xtitle, ytitle, mtitle xselect = WIDGET_INFO(mainuval.xaxisdrop, /DROPLIST_SELECT) missingx = 0B CASE xselect OF 0: IF mainuval.et THEN xdata = etbin ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'ET data not available for plotting.' missingx = 1B END 1: xdata = FINDGEN(N_ELEMENTS(dbin)) 2: xdata = (etbin-MIN(etbin))/3600D0 3: xdata = (etbin-MIN(etbin))/60D0 4: xdata = etbin-MIN(etbin) 5: IF mainuval.radius THEN xdata = radius ELSE BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Radius data not available for plotting.' missingx = 1B END ELSE: WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Impossible error: unrecognized X axis droplist selection.' ENDCASE ;;selection of x axis data. IF NOT missingx THEN BEGIN temp = MIN(ABS(xdata-xmin),xminloc) temp = MIN(ABS(xdata-xmax),xmaxloc) IF xminloc EQ xmaxloc THEN BEGIN xminloc = 0 xmaxloc = N_ELEMENTS(dbin)-1 xmin = xdata[xminloc] xmax = xdata[xmaxloc] ENDIF IF xminloc LT xmaxloc THEN dsub = dbin[xminloc:xmaxloc] ELSE $ dsub = dbin[xmaxloc:xminloc] ENDIF ELSE BEGIN xmin = 0. xmax = 0. dsub = dbin ENDELSE statistics = MOMENT(dsub, mdev = mdev, sdev = sdev) rootmean = SQRT(statistics[0]) ;;Create a message for the status window: statmessage = 'Data range: '+STRCOMPRESS(STRING(xmin))+' to '+$ STRCOMPRESS(STRING(xmax))+'. Mean: '+$ STRCOMPRESS(STRING(statistics[0]))+' S.Dev.: '+$ STRCOMPRESS(STRING(sdev))+' Root Mean: '+$ STRCOMPRESS(STRING(rootmean))+' Skewness: '+$ STRCOMPRESS(STRING(statistics[2]))+' Kurtosis: '+$ STRCOMPRESS(STRING(statistics[3])) WIDGET_CONTROL, mainuval.status, SET_VALUE = statmessage WIDGET_CONTROL, mainuval.tbin, GET_VALUE = binsize binsize = FLOAT(binsize[0]) WIDGET_CONTROL, mainuval.tstarttime, GET_VALUE = start_utc CSPICE_UTC2ET, start_utc[0], start_et WIDGET_CONTROL, mainuval.filenamewidget, GET_VALUE = lastfile statmessage2 = 'Count rate: '+$ STRCOMPRESS(STRING(statistics[0]/mainuval.ip/$ binsize))+$ ' Hz. Total counts: '+STRING(TOTAL(dbin))+$ ' ET: '+STRCOMPRESS(STRING(start_et))+$ ' UTC: '+start_utc[0] statmessage3 = 'Last file: '+lastfile[0]+' Number of files: '+$ STRCOMPRESS(STRING(mainuval.nfiles)) infomessage = [statmessage, statmessage2, statmessage3] junk = DIALOG_MESSAGE(infomessage, /INFORMATION) END 7: BEGIN ;;Trend correction block, for long-term trend modeling. END 1: BEGIN ;; Compute ring plane radii IF NOT mainuval.et THEN BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Need times to get radii.' RETURN ENDIF ntimes = N_ELEMENTS(etbin) ;; Get star position: starfile = FILE_WHICH('GeometerStars.txt') IF STRLEN(starfile) EQ 0 THEN BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'GeometerStars.txt not found.' starfile = DIALOG_PICKFILE(TITLE = $ 'Select GeometerStars.txt') ENDIF WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Star file located' starbase = WIDGET_BASE(/COLUMN, TITLE = "Enter Star Name") starname = CW_FIELD(starbase, TITLE = "Star Name: ", $ /RETURN_EVENTS) staruval = {starname:starname,$ rdtrue:0B, $ ra:0D0, $ dec:0D0, $ mura:0D0, $ mudec:0D0, $ parallax:0D0} WIDGET_CONTROL, starbase, SET_UVALUE = staruval WIDGET_CONTROL, starbase, /REALIZE, GROUP = $ event.top, /MODAL REPEAT BEGIN GETSTAR, staruval, starname, starfile ENDREP UNTIL staruval.rdtrue WIDGET_CONTROL, starbase, /DESTROY ;; Correct the star position for proper motion and for ;; parallax. ;; Get number of years since 1991.25 epoch of Hipparcos ;; star catalog position: time_since_epoch = etbin[0]/3.155D7+8.75 decstar = staruval.dec+staruval.mudec*$ time_since_epoch/3.6D6 rastar = staruval.ra+staruval.mura/COS(staruval.dec*DTOR)*$ time_since_epoch/3.6D6 dist_to_star = 1D0/(staruval.parallax*1D-3)*3.086D13 CSPICE_RADREC, dist_to_star, rastar*DTOR, decstar*DTOR, $ starpos CSPICE_SPKEZR, 'CASSINI', etbin[0], 'J2000', $ 'NONE', 'SSB', scstate, lt_corr scpos = scstate[0:2] starpos-=scpos starunit = starpos/CSPICE_VNORM(starpos) CSPICE_RECRAD, starunit, unitdist, rastar, decstar rastar = rastar*RADEG decstar = decstar*RADEG print,rastar,format="(F20.10)" print,decstar,format="(F20.10)" WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Computed Star Position: '+ STRING(rastar)+ $ ' '+STRING(decstar) IF mainuval.fring THEN BEGIN radius = DBLARR(ntimes) lon = DBLARR(ntimes) tt = 0L REPEAT BEGIN OCCRAD, rastar, decstar, etbin[tt], rr, ll, /FRING radius[tt] = rr lon[tt] = rr tt++ ENDREP UNTIL tt EQ ntimes ENDIF ELSE $ OCCRAD, rastar, decstar, etbin, radius, lon, ringoccphi WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Ring plane radii computed.' mainuval.radius = 1B END ELSE: ENDCASE ;;End of selections for the actiondrop widget. END ;;of actiondrop droplist selection. ELSE: ENDCASE ;;end of droplist IDs. END ;;end of droplist type. 'TEXT': BEGIN MESSAGE,/RESET_ERROR_STATE ;;reset the !ERROR_STATE variable so we can check ;;for type conversion errors below. WIDGET_CONTROL, event.id, GET_VALUE = value CASE uval.id OF 'bin': BEGIN ;;number of points to bin data by. IF NOT mainuval.data THEN BEGIN WIDGET_CONTROL, mainuval.status, SET_VALUE = $ 'Data have not been loaded. Cannot bin until data are loaded.' RETURN ENDIF enter_val = FIX(STRTRIM(STRCOMPRESS(value[0]),2)) IF (!ERROR_STATE.NAME EQ 'IDL_M_TYPCNVERR') THEN BEGIN WIDGET_CONTROL, event.id, SET_VALUE = '0.002' temp = DIALOG_MESSAGE(["There was an error in the format",$ "of the value you entered.",$ "Data will not be binned."], /ERROR) ENDIF ELSE BEGIN WIDGET_CONTROL, event.id, SET_VALUE = $ STRTRIM(STRING(enter_val),2) mainuval.bin = enter_val ;;Now bin the data and recast the time vector: nbin = N_ELEMENTS(data)/mainuval.bin dbin = LONARR(nbin) etbin = DBLARR(nbin) i = 0L REPEAT BEGIN dbin[i] = TOTAL(data[mainuval.bin*i:mainuval.bin*(i+1)-1]) etbin[i] = et[i*mainuval.bin] i = i+1 ENDREP UNTIL i EQ nbin ENDELSE WIDGET_CONTROL, mainuval.tnumpoints, SET_VALUE = $ STRCOMPRESS(STRING(N_ELEMENTS(dbin))) END 'XMIN': BEGIN enter_val = FLOAT(STRTRIM(STRCOMPRESS(value[0]),2)) IF (!ERROR_STATE.NAME EQ 'IDL_M_TYPCNVERR') THEN BEGIN WIDGET_CONTROL, event.id, SET_VALUE = '0.0' temp = DIALOG_MESSAGE(["There was an error in the format",$ "of the value you entered.",$ "XMIN value reset to 0."], /ERROR) ENDIF ELSE BEGIN WIDGET_CONTROL, event.id, SET_VALUE = $ STRTRIM(STRING(enter_val),2) ENDELSE END 'XMAX': BEGIN enter_val = FLOAT(STRTRIM(STRCOMPRESS(value[0]),2)) IF (!ERROR_STATE.NAME EQ 'IDL_M_TYPCNVERR') THEN BEGIN WIDGET_CONTROL, event.id, SET_VALUE = '0.0' temp = DIALOG_MESSAGE(["There was an error in the format",$ "of the value you entered.",$ "XMAX value reset to 0."], /ERROR) ENDIF ELSE BEGIN WIDGET_CONTROL, event.id, SET_VALUE = $ STRTRIM(STRING(enter_val),2) ENDELSE END 'YMIN': BEGIN enter_val = FLOAT(STRTRIM(STRCOMPRESS(value[0]),2)) IF (!ERROR_STATE.NAME EQ 'IDL_M_TYPCNVERR') THEN BEGIN WIDGET_CONTROL, event.id, SET_VALUE = '0.0' temp = DIALOG_MESSAGE(["There was an error in the format",$ "of the value you entered.",$ "YMIN value reset to 0."], /ERROR) ENDIF ELSE BEGIN WIDGET_CONTROL, event.id, SET_VALUE = $ STRTRIM(STRING(enter_val),2) ENDELSE END 'YMAX': BEGIN enter_val = FLOAT(STRTRIM(STRCOMPRESS(value[0]),2)) IF (!ERROR_STATE.NAME EQ 'IDL_M_TYPCNVERR') THEN BEGIN WIDGET_CONTROL, event.id, SET_VALUE = '0.0' temp = DIALOG_MESSAGE(["There was an error in the format",$ "of the value you entered.",$ "YMAX value reset to 0."], /ERROR) ENDIF ELSE BEGIN WIDGET_CONTROL, event.id, SET_VALUE = $ STRTRIM(STRING(enter_val),2) ENDELSE END ELSE: ;;Do nothing for other text widgets. ENDCASE ;;IDs of text widgets. END ;;Text type of widget event. ELSE: ENDCASE WIDGET_CONTROL, event.top, SET_UVALUE = mainuval RETURN END PRO ROCCDAT_DRAW_EVENT, event WIDGET_CONTROL, event.top, GET_UVALUE = mainuval actionselect = WIDGET_INFO(mainuval.actiondrop, /DROPLIST_SELECT) ;; Event handler for draw widget events generated by ROCCDAT. CASE actionselect OF 4: BEGIN ;; Display the X-Y coordinates in the status window: datapos = CONVERT_COORD([event.x, event.y], /DEVICE, /TO_DATA) xpos = STRCOMPRESS(STRING(datapos[0],FORMAT = '(8E16)')) ypos = STRCOMPRESS(STRING(datapos[1],FORMAT = '(8E16)')) WIDGET_CONTROL, mainuval.status, SET_VALUE = 'X: '+xpos+' Y: '+ypos END ELSE: ENDCASE RETURN END