; Helper function ; Checks if input from text widget is a valid number, returns NaN if not ; (imitates check done within spinner) function thm_ui_part_getspec_check_num, num compile_opt idl2, hidden if is_numeric(num) then begin on_ioerror, fail return, double(num) fail: return, !values.D_NAN endif else begin return,!values.D_NAN endelse end ; Helper function to reset one or more widgets' value(s) ; pro thm_ui_part_getspec_reset_widget, state, uname compile_opt idl2, hidden for i=0, n_elements(uname)-1 do begin id = widget_info(state.tab_id, find_by_uname=uname[i]) str_element, state, uname[i], value if size(/type,value) gt 0 then begin widget_control, id, set_value=value endif else begin ;throw error? endelse endfor end ;+ ; Purpose: ; Helper function to check if strings from user input ; contain valid numbers. ; -returns 1 if widget contains a valid number, 0 otherwise ; -if the input is invalid or out of range then a pop-up ; message will be generated to notify the user ; ; Arguments: ; state: state data structure ; uname: uname of the widget to check ; namestring: string used to indentify quantity in the ; error message, e.g "phi min", "maximum energy" ; ; Keywords (optional): ; min: the minimum valid value for the quantity in question ; max: the maximum valid value for the quantity in question ; value: set to names keyword to return the numeric value ; of the widget ; ;- function thm_ui_part_getspec_check_input, state, uname, namestring, $ min=min, max=max, value=value compile_opt idl2, hidden tlb = state.tab_id ;get value id = widget_info(tlb, find_by_uname=uname) widget_control, id, get_value=value ;convert to numerical if string is passed in if size(/type,value) eq 7 then begin value = thm_ui_part_getspec_check_num(value) endif ;if number is valid check against min & max values if finite(value,/nan) then begin msg = 'Invalid '+strlowcase(namestring)+' entered; value reset.' endif else if size(/type,min) gt 0 && value lt min then begin msg = namestring+' must be greater than or equal to ' + $ strtrim(string(min),1) + '; value reset.' endif else if size(/type,max) gt 0 && value gt max then begin msg = namestring+' must be less than or equal to ' + $ strtrim(string(min),1) + '; value reset.' endif else begin ;if we made it here then we're good to go return, 1 endelse ;report an issues with input x=dialog_message(msg,/center) ;return previous (valid) value if requested ;this will ensure a valid value is always passed back if arg_present(value) then begin str_element, state, uname, value endif return, 0 end ; Helper function to copy a widget's value into the ; appropriate variable ; pro thm_ui_part_getspec_set_value, state, uname compile_opt idl2, hidden for i=0, n_elements(uname)-1 do begin id = widget_info(state.tab_id, find_by_uname=uname[i]) widget_control, id, get_value=value ;strings from widget_control are often single-element arrays if n_elements(value) eq 1 then value=value[0] str_element, state, uname[i], value, /add endfor end ; Helper procedure to be called when ready to load spectra. ; -This procedure will check the applicable widgets for ; valid input and stores valid entries. ; -If the input is invalid the widgets will be reset ; pro thm_ui_part_getspec_set_values, state compile_opt idl2, hidden tlb = state.tab_id ;Check phi input ; first check in inputs are valid, next check that min < max ; if either chack fails then reset the widgets, otherwise store the valid entries a0 = thm_ui_part_getspec_check_input(state,'phi_min','Phi min',min=0,max=360,value=pmin) a1 = thm_ui_part_getspec_check_input(state,'phi_max','Phi max',min=0,max=360,value=pmax) if ~a0 || ~a1 || pmin ge pmax then begin if a0 && a1 && pmin ge pmax then x=dialog_message('Phi minimum must be less than maximum; values reset.',/center) thm_ui_part_getspec_reset_widget, state,['phi_min','phi_max','start_angle'];start angle could be out of bounds endif else begin thm_ui_part_getspec_set_value, state, ['phi_min','phi_max'] endelse ;check start angle against given phi limits ;the reasoning behind this check is not clear (it was copied) ps = double([state.phi_min,state.phi_max]) ps += (ps[1]-ps[0])/2 * [-1,0] a3 = thm_ui_part_getspec_check_input(state,'start_angle','Start_angle',min=ps[0],max=ps[1],value=sa) if a3 then begin thm_ui_part_getspec_set_value, state, 'start_angle' endif else begin thm_ui_part_getspec_reset_widget, state, 'start_angle' endelse ;check theta input a0 = thm_ui_part_getspec_check_input(state,'theta_min','Theta min',min=-90,max=90,value=tmin) a1 = thm_ui_part_getspec_check_input(state,'theta_max','Theta max',min=-90,max=90,value=tmax) if ~a0 || ~a1 || tmin ge tmax then begin if a0 && a1 && tmin ge tmax then x=dialog_message('Theta minimum must be less than maximum; values reset.',/center) thm_ui_part_getspec_reset_widget, state,['theta_min','theta_max'] endif else begin thm_ui_part_getspec_set_value, state, ['theta_min','theta_max'] endelse ;check pitch angle input a0 = thm_ui_part_getspec_check_input(state,'pa_min','Pitch Angle min',min=0,max=180,value=pamin) a1 = thm_ui_part_getspec_check_input(state,'pa_max','Pitch Angle max',min=0,max=180,value=pamax) if ~a0 || ~a1 || pamin ge pamax then begin if a0 && a1 && pamin ge pamax then x=dialog_message('Pitch angle minimum must be less than maximum; values reset.',/center) thm_ui_part_getspec_reset_widget, state,['pa_min','pa_max'] endif else begin thm_ui_part_getspec_set_value, state, ['pa_min','pa_max'] endelse ;check gyrovelocity input a0 = thm_ui_part_getspec_check_input(state,'gyro_min','Gyrovelocity min',min=0,max=360,value=gvmin) a1 = thm_ui_part_getspec_check_input(state,'gyro_max','Gyrovelocity max',min=0,max=360,value=gvmax) if ~a0 || ~a1 || gvmin ge gvmax then begin if a0 && a1 && gvmin ge gvmax then x=dialog_message('Gyrovelocity minimum must be less than maximum; values reset.',/center) thm_ui_part_getspec_reset_widget, state,['gyro_min','gyro_max'] endif else begin thm_ui_part_getspec_set_value, state, ['gyro_min','gyro_max'] endelse ;check energy limit input e0 = thm_ui_part_getspec_check_input(state,'energy_min','Energy min',min=0,value=emin) e1 = thm_ui_part_getspec_check_input(state,'energy_max','Energy max',min=0,value=emax) if ~e0 || ~e1 || emin ge emax then begin if e0 && e1 && emin ge emax then x=dialog_message('Phi minimun must be less than maximum; values reset.',/center) thm_ui_part_getspec_reset_widget, state,['energy_min','energy_max'] endif else begin thm_ui_part_getspec_set_value, state, ['energy_min','energy_max'] endelse ;check regrid input r0 = thm_ui_part_getspec_check_input(state,'regrid_phi','Regrid dimension (phi)',min=0) r1 = thm_ui_part_getspec_check_input(state,'regrid_theta','Regrid dimension (theta)',min=0) if r0 then begin thm_ui_part_getspec_set_value, state, 'regrid_phi' endif else begin thm_ui_part_getspec_reset_widget, state, 'regrid_phi' endelse if r1 then begin thm_ui_part_getspec_set_value, state, 'regrid_theta' endif else begin thm_ui_part_getspec_reset_widget, state, 'regrid_theta' endelse ;check maximum data gap input m0 = thm_ui_part_getspec_check_input(state,'max_gap','Maximum data gap',min=0) if m0 then begin thm_ui_part_getspec_set_value, state, 'max_gap' endif else begin thm_ui_part_getspec_reset_widget, state, 'max_gap' endelse ;check sst mast input & sunpulse limit s0 = thm_ui_part_getspec_check_input(state,'mask_value','SST mask proportion',min=0) s1 = thm_ui_part_getspec_check_input(state,'sunpulse_limit','Sunpulse limit',min=0) if s0 then begin thm_ui_part_getspec_set_value, state, 'mask_value' endif else begin thm_ui_part_getspec_reset_widget, state, 'mask_value' endelse if s1 then begin thm_ui_part_getspec_set_value, state, 'sunpulse_limit' endif else begin thm_ui_part_getspec_reset_widget, state, 'sunpulse_limit' endelse end ;Procedure to control sensitization for regrid widgets ;Regrid options will only be used for: ;-Pitch Angle/Gyro spectra ;-Energy spectra where PA or Gyro is limited or distribution is single-angle ; ;*no easy way to determine if distribution is single angle, so leave ; sensitized whenever energy spectra are returned pro thm_ui_part_getspec_rgcheck, state compile_opt idl2, hidden if state.angle EQ 'PA' or state.angle EQ 'GYRO' or state.energy_set eq 1 then sens=1 $ else sens = 0 id=widget_info(state.tab_id, find_by_uname='RGBASE') widget_control, id, sensitive=sens id=widget_info(state.tab_id, find_by_uname='ODBASE') widget_control, id, sensitive=sens end ; reset all pro thm_ui_part_getspec_options_reset, state compile_opt idl2, hidden ;reset values in state structure ;once set here widget can be easily updated state.suffix = '' state.angle = 'PHI' state.phi_min = '0' state.phi_max = '360' state.theta_min = '-90' state.theta_max = '90' state.pa_min = '0' state.pa_max = '180' state.gyro_min = '0' state.gyro_max = '360' state.start_angle = '0' state.energy_min = '0' state.energy_max = '1e7' state.energy_set = 0b state.normalize = 0b state.regrid_phi = '16' state.regrid_theta = '8' state.max_gap = '0' state.remove_mask = 0b state.mask_value = '0.99' state.remove_sp = 0b state.sunpulse_limit = '2.0' widget_control, state.probeList , set_list_select=-1 widget_control, state.dataTypeList, set_list_select=-1 id=widget_info(state.tab_id, find_by_uname='SUFFIX') widget_control, id, set_value='' state.suffix='' widget_control, state.angle_combobox, set_combobox_select=0 ;list of widgets than can be updated (reset) with general procedure widget_list = [ 'phi_min', 'phi_max', 'theta_min', 'theta_max', $ 'pa_min', 'pa_max', 'gyro_min', 'gyro_max', $ 'start_angle', 'energy_min', 'energy_max', $ 'regrid_phi', 'regrid_theta', 'max_gap', $ 'mask_value', 'sunpulse_limit' ] thm_ui_part_getspec_reset_widget, state, widget_list ; id=widget_info(state.tab_id, find_by_uname='phi_min') ; widget_control, id, set_value=state.angle_values[0, 0] ; id=widget_info(state.tab_id, find_by_uname='phi_max') ; widget_control, id, set_value=state.angle_values[1, 0] ; id=widget_info(state.tab_id, find_by_uname='theta_min') ; widget_control, id, set_value=state.angle_values[0, 1] ; id=widget_info(state.tab_id, find_by_uname='theta_max') ; widget_control, id, set_value=state.angle_values[1, 1] ; id=widget_info(state.tab_id, find_by_uname='pa_min') ; widget_control, id, set_value=state.angle_values[0, 2] ; id=widget_info(state.tab_id, find_by_uname='pa_max') ; widget_control, id, set_value=state.angle_values[1, 2] ; id=widget_info(state.tab_id, find_by_uname='gyro_min') ; widget_control, id, set_value=state.angle_values[0, 3] ; id=widget_info(state.tab_id, find_by_uname='gyro_max') ; widget_control, id, set_value=state.angle_values[1, 3] ; id=widget_info(state.tab_id, find_by_uname='start_angle') ; widget_control, id, set_value=state.start_angle ; id=widget_info(state.tab_id, find_by_uname='energy_min') ; widget_control, id, set_value=state.erange_values[0] ; id=widget_info(state.tab_id, find_by_uname='energy_max') ; widget_control, id, set_value=state.erange_values[1] id=widget_info(state.tab_id, find_by_uname='ENERGY:SET') widget_control, id, set_button=state.energy_set id=widget_info(state.tab_id, find_by_uname='NORM:SET') widget_control, id, set_button=state.normalize id=widget_info(state.tab_id, find_by_uname='RGBASE') widget_control, id, set_button=1 ; id=widget_info(state.tab_id, find_by_uname='regrid_phi') ; widget_control, id, set_value=state.regrid_values[0] ; id=widget_info(state.tab_id, find_by_uname='regrid_theta') ; widget_control, id, set_value=state.regrid_values[1] ; id=widget_info(state.tab_id, find_by_uname='max_gap') ; widget_control, id, set_value=state.max_gap id=widget_info(state.tab_id, find_by_uname='SST:MASKSET') widget_control, id, set_button=state.remove_mask id=widget_info(state.tab_id, find_by_uname='SSTBASE') widget_control, id, sensitive=state.remove_mask ; id=widget_info(state.tab_id, find_by_uname='mask_value') ; widget_control, id, set_value=state.mask_value id=widget_info(state.tab_id, find_by_uname='SP:SET') widget_control, id, set_button=state.remove_sp id=widget_info(state.tab_id, find_by_uname='SPBASE') widget_control, id, sensitive=state.remove_sp ; widget_control, state.sp_combobox, set_combobox_select=0 ; id=widget_info(state.tab_id, find_by_uname='sunpulse_limit') ; widget_control, id, set_value=state.sunpulse_limit widget_control, state.fill_combobox, set_combobox_select=0 sst_cal_id=widget_info(state.tab_id, find_by_uname='SST_CALIBRATE') widget_control,sst_cal_id,set_button=0 state.statusBar->update, 'Window reset to default settings.' state.historyWin->update, 'Window reset to default settings.' end ;event handler Pro thm_ui_part_getspec_options_event, event err_xxx = 0 Catch, err_xxx IF (err_xxx NE 0) THEN BEGIN Catch, /Cancel Help, /Last_Message, Output = err_msg thm_ui_sbar_hwin_update, state, err_msg, /error, err_msgbox_title='Error in THM_UI_PART_GETSPEC' if widget_valid(stash) then begin Widget_Control, stash, Set_UValue=state, /No_Copy endif Widget_Control, event.TOP, Set_UValue=state, /No_Copy widget_control, event.top,/destroy RETURN ENDIF ;widget_control, event.top, get_uvalue = state, /no_copy base = event.handler stash = widget_info(base,/child) widget_control, stash, Get_UValue=state, /no_copy ;Options apply = 0b ;local flag for the 'apply' process. widget_control, event.id, get_uvalue = uval state.historyWin->Update,'THM_UI_PART_GETSPEC_OPTIONS: User value: '+uval,/dontshow Case uval of 'SUFFIX': Begin widget_control, event.id, get_value = temp_string ;anything can be a suffix, as long as there are no spaces state.suffix = strcompress(/remove_all, temp_string) state.statusbar -> update, uval+' = '+state.suffix End 'ANGLE:COMBOBOX': Begin temp = strsplit(widget_info(state.angle_combobox, /combobox_gettext),':',/extract) state.angle = strupcase(strcompress(/remove_all, temp[0])) state.statusbar -> update, 'ANGLE = '+state.angle thm_ui_part_getspec_rgcheck, state ; id=widget_info(state.tab_id, find_by_uname='RGBASE') ; if state.angle EQ 'PHI' or state.angle EQ 'THETA' then sens=0 else sens=1 ; widget_control, id, sensitive=sens End 'phi_min': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) && double(temp_string) ge 0 && double(temp_string) lt 360 Then Begin ; state.angle_values[0, 0] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.angle_values[0, 0] = '0' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.angle_values[0, 0] + ' when you hit Apply.' ; endelse End 'phi_max': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) && double(temp_string) gt 0 && double(temp_string) le 360 Then Begin ; state.angle_values[1, 0] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.angle_values[1, 0] = '360' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.angle_values[1, 0] + ' when you hit Apply.' ; endelse End 'theta_min': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) && double(temp_string) ge -90 && double(temp_string) lt 90 Then Begin ; state.angle_values[0, 1] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.angle_values[0, 1] = '-90' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.angle_values[0, 1] + ' when you hit Apply.' ; endelse End 'theta_max': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) && double(temp_string) gt -90 && double(temp_string) le 90 Then Begin ; state.angle_values[1, 1] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.angle_values[1, 1] = '90' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.angle_values[1, 1] + ' when you hit Apply.' ; endelse End 'pa_min': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) && double(temp_string) ge 0 && double(temp_string) lt 180 Then Begin ; state.angle_values[0, 2] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.angle_values[0, 2] = '0' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.angle_values[0, 2] + ' when you hit Apply.' ; endelse End 'pa_max': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) && double(temp_string) gt 0 && double(temp_string) le 180 Then Begin ; state.angle_values[1, 2] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.angle_values[1, 2] = '180' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.angle_values[1, 2] + ' when you hit Apply.' ; endelse End 'gyro_min': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) && double(temp_string) ge 0 && double(temp_string) lt 360 Then Begin ; state.angle_values[0, 3] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.angle_values[0, 3] = '0' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.angle_values[0, 3] + ' when you hit Apply.' ; endelse End 'gyro_max': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) && double(temp_string) gt 0 && double(temp_string) le 360 Then Begin ; state.angle_values[1, 3] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.angle_values[1, 3] = '360' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.angle_values[1, 3] + ' when you hit Apply.' ; endelse End 'start_angle': Begin ; widget_control, event.id, get_value = temp_string ; If (is_numeric(temp_string)) then begin ; ps_lim = double(state.angle_values[*,0]) ; ps_lim += (ps_lim[1]-ps_lim[0])/2 * [-1,0] ; start_angle = double(temp_string) ; if start_angle ge ps_lim[0] and start_angle le ps_lim[1] then begin ; state.start_angle = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; endif else begin ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.start_angle + ' when you hit Apply.' ; endelse ; Endif Else begin ;; state.start_angle = '0' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.start_angle + ' when you hit Apply.' ; endelse End 'energy_min': Begin ; maxid = widget_info(state.tab_id, find_by_uname='energy_max') ; widget_control, maxid, get_value = max_string ; widget_control, event.id, get_value = temp_string ; If is_numeric(temp_string) Then Begin ; test_value = float(temp_string) ; If test_value Ge 0 Then Begin ; ; ;check against valid maximum ; If is_numeric(max_string) Then Begin ; max_value = float(max_string) ; If test_value ge max_value Then Begin ; state.statusbar -> update, uval+' Minimum energy must be less than maximum'+ $ ; '. Will be reset to ' + state.erange_values[0] + ' when you hit Apply.' ; break ; Endif ; Endif ; ; state.erange_values[0] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else Begin ;; state.erange_values[0] = '0' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.erange_values[0] + ' when you hit Apply.' ; Endelse ; Endif Else Begin ;; state.erange_values[0] = '0' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.erange_values[0] + ' when you hit Apply.' ; Endelse End 'energy_max': Begin ; minid = widget_info(state.tab_id, find_by_uname='energy_min') ; widget_control, minid, get_value = min_string ; widget_control, event.id, get_value = temp_string ; If is_numeric(temp_string) Then Begin ; test_value = float(temp_string) ; If test_value Ge 0 Then Begin ; ; ;check against valid minimum ; If is_numeric(min_string) Then Begin ; min_value = float(min_string) ; If test_value le min_value Then Begin ; state.statusbar -> update, uval+' Maximum energy must be greater than minimum'+ $ ; '. Will be reset to ' + state.erange_values[1] + ' when you hit Apply.' ; break ; Endif ; Endif ; ; state.erange_values[1] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.erange_values[1] = '1e7' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.erange_values[1] + ' when you hit Apply.' ; endelse ; Endif Else begin ;; state.erange_values[1] = '1e7' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.erange_values[1] + ' when you hit Apply.' ; endelse End 'ENERGY:SET': Begin state.energy_set = event.select If(event.select Eq 1) Then state.statusbar -> update, 'Return Energy Spectrum Option Set' $ Else state.statusbar -> update, 'Return Energy Spectrum Option Not Set' thm_ui_part_getspec_rgcheck, state ; id=widget_info(state.tab_id, find_by_uname='RGBASE') ; if state.energy_set then sens=0 else sens=1 ; widget_control, id, sensitive=sens End 'NORM:SET': Begin state.normalize = event.select If(event.select Eq 1) Then state.statusbar -> update, 'Normalize Option Set' $ Else state.statusbar -> update, 'Normalize Option Not Set' End 'regrid_phi': Begin ; widget_control, event.id, get_value = temp_string ; If(is_numeric(temp_string)) Then Begin ; test_value = float(temp_string) ; If(test_value Gt 0) Then Begin ; state.regrid_values[0] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.regrid_values[0] = '16' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.regrid_values[0] + ' when you hit Apply.' ; endelse ; Endif Else begin ;; state.regrid_values[0] = '16' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.regrid_values[0] + ' when you hit Apply. ; endelse End 'regrid_theta': Begin ; widget_control, event.id, get_value = temp_string ; If(is_numeric(temp_string)) Then Begin ; test_value = float(temp_string) ; If(test_value Gt 0) Then Begin ; state.regrid_values[1] = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.regrid_values[1] = '8' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.regrid_values[1] + ' when you hit Apply.' ; endelse ; Endif Else begin ;; state.regrid_values[1] = '8' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.regrid_values[1] + ' when you hit Apply. ; endelse End 'OD:COMBOBOX': Begin state.other_dim = widget_info(state.od_combobox, /combobox_gettext) state.statusbar -> update, 'OTHER_DIM = '+state.other_dim End 'max_gap': Begin ; widget_control, event.id, get_value = temp_string ; If(is_numeric(temp_string)) Then Begin ; test_value = float(temp_string) ; If(test_value Ge 0) Then Begin ; state.max_gap = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.max_gap = '0' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.max_gap + ' when you hit Apply.' ; endelse ; Endif Else begin ;; state.max_gap = '0' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.max_gap + ' when you hit Apply.' ; endelse End 'CLEARDATA': Begin widget_control, state.dataTypeList, set_list_select=-1 End 'CLEARPROBE': Begin widget_control, state.probeList , set_list_select=-1 End 'SST:MASKSET': Begin state.remove_mask = event.select If(event.select Eq 1) Then state.statusbar -> update, 'Remove Mask Option Set' $ Else state.statusbar -> update, 'Remove Mask Option Not Set' id=widget_info(state.tab_id, find_by_uname='SSTBASE') widget_control, id, sensitive=state.remove_mask End 'mask_value': Begin ; widget_control, event.id, get_value = temp_string ; If(is_numeric(temp_string)) Then Begin ; test_value = float(temp_string) ; If(test_value Ge 0 And test_value Le 1.0) Then Begin ; state.mask_value = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.mask_value = '0.99' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.mask_value + ' when you hit Apply.' ; endelse ; Endif Else begin ;; state.mask_value = '0.99' ; state.statusbar -> update, uval+' Invalid Input: '+temp_string+ $ ; '. Will be reset to ' + state.mask_value + ' when you hit Apply.' ; endelse End 'SP:SET': Begin state.remove_sp = event.select If(event.select Eq 1) Then state.statusbar -> update, 'SunPulse Removal Option Set' $ Else state.statusbar -> update, 'SunPulse Removal Option Not Set' id=widget_info(state.tab_id, find_by_uname='SPBASE') widget_control, id, sensitive=state.remove_sp End 'sunpulse_limit': Begin ; widget_control, event.id, get_value = temp_string ; If(is_numeric(temp_string)) Then Begin ; test_value = float(temp_string) ; If(test_value Ge 0) Then begin ; state.sunpulse_limit = temp_string ; state.statusbar -> update, uval+' = '+temp_string ; Endif Else begin ;; state.sunpulse_limit = '2.0' ; state.statusbar -> update, 'Invalid Input'+ $ ; '. Will be reset to ' + state.sunpulse_limit + ' when you hit Apply.' ; endelse ; Endif Else begin ;; state.sunpulse_limit = '2.0' ; state.statusbar -> update, 'Invalid Input'+ $ ; '. Will be reset to ' + state.sunpulse_limit + ' when you hit Apply.' ; endelse End 'SST_CALIBRATE':BEGIN ;if beta calibrations are requested, don't let user select invalid data types.(ESA or SST reduced) use_new_sst_calibrations = widget_info(event.id,/button_set) data_type_list_id = widget_info(state.tab_id,find_by_uname='data_type_list') if use_new_sst_calibrations then begin widget_control,data_type_list_id,set_value=state.validBetaTypes endif else begin widget_control,data_type_list_id,set_value=state.validDataTypes endelse end 'HELP':BEGIN gethelppath,path xdisplayfile, path+'thm_ui_part_getspec_options.txt', group=state.tab_id, /modal, done_button='Done', $ title='HELP: Getspec Options' END 'RESET':BEGIN thm_ui_part_getspec_options_reset, state END 'APPLY':Begin apply = 1b ;this is here to be checked if the catch is triggered widget_control, /hourglass ;Check editable widget values and copy into appropriate variables ;in the state structure. Widgets with invalid entries will be reset ;with the last applied value. thm_ui_part_getspec_set_values, state probe_idx = widget_info(state.probeList,/list_select) if probe_idx[0] eq -1 then begin state.statusbar->update, 'Please select a probe.' break endif if in_set(probe_idx,0) then begin probe = state.validProbes[1:n_elements(state.validProbes)-1] endif else begin probe = state.validProbes[probe_idx] endelse data_idx = widget_info(state.dataTypeList,/list_select) if data_idx[0] eq -1 then begin state.statusbar->update, 'Please select a datatype.' break endif sst_cal_id=widget_info(state.tab_id, find_by_uname='SST_CALIBRATE') use_new_sst_calibrations=widget_info(sst_cal_id,/button_set) ;list of acceptable data types is different if user is using new SST calibrations if use_new_sst_calibrations then begin if in_set(data_idx,0) then begin dtype = state.validBetatypes[1:n_elements(state.validBetatypes)-1] endif else begin dtype = state.validBetatypes[data_idx] endelse endif else begin if in_set(data_idx,0) then begin dtype = state.validDatatypes[1:n_elements(state.validDatatypes)-1] endif else begin dtype = state.validDatatypes[data_idx] endelse endelse ; setup array of requested probe + data types for i=0,n_elements(probe)-1 do begin for j=0,n_elements(dtype)-1 do begin IF n_elements(dtype_arr) EQ 0 then dtype_arr = ['th' + probe[i] + '_' + dtype[j]] $ ELSE dtype_arr = [dtype_arr, 'th' + probe[i] + '_' + dtype[j]] endfor endfor ;the rest of this section is tabbed over for no reason state.tr->getproperty, starttime=start_obj state.tr->getproperty, endtime=stop_obj start_obj->getProperty,tstring=startText stop_obj->getProperty,tstring=stopText trange = time_double([startText, stopText]) ;Check that start and end times are not out of order/equal if trange[0] ge trange[1] then begin state.statusbar->update, 'Error: End time less than/equal to Start time.' widget_control, stash, set_uvalue = state, /no_copy return endif ;Check that start and end times are not in the future if (trange[0] gt systime(/sec)) AND (trange[1] gt systime(/sec)) then begin state.statusbar->Update, "Error: Start and end times are later than today's date. " widget_control, stash, set_uvalue = state, /no_copy return endif x = state.loadeddata ; h = state.historywin ;Find active data, get datatypes, run thm_part_getspec separately for each uniq ;probe_datatype combination vars=dtype_arr sv = strmid(vars, 0, 8) usv = uniq(sv) sv = sv[usv] sun_clean_id = widget_info(state.tab_id,find_by_uname='SUN_CLEAN_METHOD') sun_clean_select = widget_info(sun_clean_id,/combobox_gettext) sun_fill_id = widget_info(state.tab_id,find_by_uname='SUN_FILL_METHOD') sun_fill_select = widget_info(sun_fill_id,/combobox_gettext) ;record options in history window history_arr = ['INPUT PARAMETERS FOR PART_GETSPEC:', $ 'TIME RANGE: '+startText+', '+stopText, $ 'START ANGLE: '+state.start_angle, $ 'SUFFIX: "'+state.suffix+'"', $ 'ANGLE: '+state.angle, $ 'PHI LIMITS: ['+state.phi_min+', '+state.phi_max+']', $ 'THETA LIMITS: ['+state.theta_min+', '+state.theta_max+']', $ 'PA LIMITS: ['+state.pa_min+', '+state.pa_max+']', $ 'GYRO LIMITS: ['+state.gyro_min+', '+state.gyro_max+']', $ 'ENERGY RANGE: ['+state.energy_min+', '+state.energy_max+']', $ 'ENERGY SPECTROGRAM OPTION: '+(state.energy_set ? 'True':'False'), $ 'PHI REGRID: '+state.regrid_phi, $ 'THETA REGRID: '+state.regrid_theta, $ 'OTHER_DIM: '+state.other_dim, $ 'NORMALIZE OPTION: '+(state.normalize ? 'True':'False'), $ 'DATAGAP VALUE: '+state.max_gap, $ 'SST MASK REMOVAL OPTION: '+(state.remove_mask ? 'True':'False'), $ 'SST MASK VALUE: '+state.mask_value, $ 'SST SUNPULSE REMOVAL OPTION: '+(state.remove_sp ? 'True':'False'), $ 'SST SUNPULSE REMOVAL METHOD: '+sun_clean_select, $ 'SST SUNPULSE REMOVAL FILLIN METHOD: '+sun_fill_select, $ 'SST SUNPULSE REMOVAL TOLERANCE: '+state.sunpulse_limit] state.historyWin -> update, history_arr ;copy options out of state structure ;numerical values have already been checked trange = time_double([startText, stopText]) start_angle = float(state.start_angle) suffix = state.suffix angle = strlowcase(state.angle) phi = float([state.phi_min, state.phi_max]) theta = float([state.theta_min, state.theta_max]) pitch = float([state.pa_min, state.pa_max]) gyro = float([state.gyro_min, state.gyro_max]) erange = float([state.energy_min, state.energy_max]) energy = state.energy_set regrid = long([state.regrid_phi,state.regrid_theta]) other_dim = strlowcase(state.other_dim) normalize = state.normalize datagap = float(state.max_gap) ;Keep track of new created variables new_vars = '' ;Keep track of tplot data here tnames_in = tnames() all_sv_success = 1b ;check for all variables created or not created, set to 0 if a variable is missed clobber = '' ;needed for check for duplicate variables eclobber = clobber ;for energy spectra For j = 0, n_elements(sv)-1 Do Begin groupNames = state.loadedData->getGroupNames() test_new_spec = sv[j]+'_an_eflux'+'_'+angle+suffix clobberflag = 1b ;default is to do spectra in case of duplicate variables if is_string(groupNames) then dupNameInd = where(test_new_spec eq groupNames, ndup) else ndup=0 if ndup gt 0 then begin if clobber ne 'yestoall' AND clobber ne 'notoall' then begin ;prompt the user prompttext = 'The variable ' + strupcase(test_new_spec) + $ ' already exists. Do you want to ' + 'overwrite it? '+ $ 'Click "No" continue with the existing variable or "Cancel" to stop.' clobber = thm_ui_prompt_widget(state.tab_id, state.statusBar, state.historyWin, promptText = promptText,$ /no, /yes, /allno, /allyes, /cancel, title='PART_GETSPEC: Variable already exists.', $ defaultvalue = 'cancel') endif endif if clobber eq 'yes' OR clobber eq 'yestoall' then begin state.historyWin-> update, 'THM_PART_GETSPEC: replacing variable '+test_new_spec state.statusbar -> update, 'replacing variable '+test_new_spec endif if clobber eq 'no' OR clobber eq 'notoall' then begin state.historyWin-> update, 'THM_PART_GETSPEC: Not replacing variable '+test_new_spec state.statusbar -> update, 'Not replacing variable '+test_new_spec clobberflag=0b endif if clobber eq 'cancel' then begin ;stop if cancel selected canceled = 1b break endif ;try energy spectra separately, only do this test if energy spectra ;have been requested, and if clobberflag for the angular distribution ;is set -- if clobberflag is 0 then we cannot do energy spectra anyway. energy_really_do = energy test_new_espec = sv[j]+'_en_eflux'+suffix If(energy Gt 0 And clobberflag) Then begin eclobberflag = 1b if is_string(groupNames) then dupNameInd = where(test_new_espec eq groupNames, endup) else endup=0 if endup gt 0 then begin ;Only do this if I already have not said yestoall or notoall if clobber ne 'yestoall' AND clobber ne 'notoall' And $ eclobber ne 'yestoall' AND eclobber ne 'notoall' then begin ;prompt the user prompttext = 'The variable ' + strupcase(test_new_espec) + $ ' already exists. Do you want to ' + 'overwrite it? '+ $ 'Click "No" continue with the existing variable or "Cancel" to stop.' eclobber = thm_ui_prompt_widget(state.tab_id, state.statusBar, state.historyWin, promptText = promptText,$ /no, /yes, /allno, /allyes, /cancel, title='PART_GETSPEC: Variable already exists.', $ defaultvalue = 'cancel') ;once you have yes or no to all, you should not get any more prompts if eclobber eq 'yestoall' OR eclobber eq 'notoall' then clobber = eclobber endif else eclobber = clobber endif if eclobber eq 'yes' OR eclobber eq 'yestoall' then begin state.historyWin-> update, 'THM_PART_GETSPEC: replacing variable '+test_new_espec state.statusbar -> update, 'replacing variable '+test_new_espec endif if eclobber eq 'no' OR eclobber eq 'notoall' then begin state.historyWin-> update, 'THM_PART_GETSPEC: Not replacing variable '+test_new_espec state.statusbar -> update, 'Not replacing variable '+test_new_espec eclobberflag = 0b endif if eclobber eq 'cancel' then begin ;stop if cancel selected canceled = 1b break endif If(eclobberflag Eq 0) Then energy_really_do = 0 Endif ;thm_part_getspec accepts 'probe' and 'data_type' keywords, ;assuming that there aren't non-standard variable names If(clobberflag) Then Begin probe = strmid(sv[j], 2, 1) dtype = strmid(sv[j], 4, 4) state.historyWin-> update, 'THM_PART_GETSPEC: Processing Probe: '+probe+', Datatype: '+dtype state.statusbar -> update, 'Processing Probe: '+probe+', Datatype: '+dtype ;SST masking is an issue If(strmid(dtype, 1, 1) Eq 's') Then Begin If(state.remove_mask Eq 0) Then mask_remove = 0 $ Else mask_remove = state.mask_value ;Sun pulse cleanup? If(state.remove_sp Eq 0) Then Begin method_sunpulse_clean = 0 limit_sunpulse_clean = 0 method_clean=0 Endif Else Begin ;method_clean and method_sunpulse_clean are two separate keywords for historical reasons ;but there is no reason to separate them in the GUI if strlowcase(sun_clean_select) eq 'automatic' then begin method_clean = strlowcase(sun_clean_select) method_sunpulse_clean=0 limit_sunpulse_clean=0 endif else begin method_clean=0 method_sunpulse_clean=strlowcase(sun_clean_select) limit_sunpulse_clean = state.sunpulse_limit endelse Endelse fillin_method = strlowcase(sun_fill_select) Endif Else Begin mask_remove = 0 method_sunpulse_clean = 0 limit_sunpulse_clean = 0 fillin_method = 0 method_clean=0 Endelse tn_before = tnames('*',create_time=cn) thm_part_getspec, probe = probe, data_type = dtype, trange = trange, $ start_angle = start_angle, suffix = suffix, angle = angle, $ phi = phi, theta = theta, pitch = pitch, gyro = gyro, $ erange = erange, energy = energy_really_do, regrid = regrid, $ other_dim = other_dim, normalize = normalize, datagap = datagap, $ mask_remove = mask_remove, method_sunpulse_clean = method_sunpulse_clean,method_clean=method_clean, $ limit_sunpulse_clean = limit_sunpulse_clean, fillin_method = fillin_method, $ /gui_flag, gui_statusBar=state.statusBar, gui_historyWin=state.historyWin,$ sst_cal=use_new_sst_calibrations ;Now find the new variables thm_ui_cleanup_tplot,tn_before,create_time_before=cn,new_vars=found_vars,del_vars=to_delete call_added = 0 new_spec = ssl_set_intersection([test_new_spec],[found_vars]) If(is_string(new_spec) && new_spec[0] ne '') Then Begin success = x->add(new_spec) If(success) Then Begin call_added = 1 state.callSequence->addGetSpecOp,probe,dtype,trange,$ start_angle,suffix,angle,phi,theta,pitch,gyro,erange,$ energy,regrid,other_dim,normalize,datagap,mask_remove,method_sunpulse_clean,$ limit_sunpulse_clean,fillin_method state.statusBar->update, 'Added Variable: '+new_spec state.historyWin->update, 'Added Variable: '+new_spec new_vars = [new_vars, new_spec] Endif Else Begin state.statusBar->update, 'Failed to Add Variable: '+new_spec state.historyWin->update, 'Failed to Add Variable: '+new_spec all_sv_success = 0b Endelse Endif Else Begin state.statusBar->update, 'Failed to Add Variable: '+test_new_spec state.historyWin->update, 'Failed to Add Variable: '+test_new_spec all_sv_success = 0b Endelse If(energy Gt 0) Then Begin new_espec = ssl_set_intersection([test_new_espec],[found_vars]) If(is_string(new_espec) && new_espec[0] ne '') Then Begin success = x->add(new_espec) If(success) Then Begin if ~keyword_set(call_added) then begin call_added = 1 state.callSequence->addGetSpecOp,probe,dtype,trange,$ start_angle,suffix,angle,phi,theta,pitch,gyro,erange,$ energy,regrid,other_dim,normalize,datagap,mask_remove,method_sunpulse_clean,$ limit_sunpulse_clean,fillin_method endif state.statusBar->update, 'Added Variable: '+new_espec state.historyWin->update, 'Added Variable: '+new_espec new_vars = [new_vars, new_espec] Endif Else Begin state.statusBar->update, 'Failed to Add Variable: '+new_espec state.historyWin->update, 'Failed to Add Variable: '+new_espec all_sv_success = 0b Endelse Endif Else Begin state.statusBar->update, 'Failed to Add Variable: '+test_new_espec state.historyWin->update, 'Failed to Add Variable: '+test_new_espec all_sv_success = 0b Endelse Endif if to_delete[0] ne '' then begin store_data,to_delete,/delete endif Endif Else all_sv_success = 0b Endfor ;update status bar and history window if keyword_set(canceled) then begin state.historyWin-> update, 'THM_PART_GETSPEC: Load canceled by user.' state.statusbar -> update, 'Load canceled by user.' endif else If(all_sv_success) Then Begin state.statusBar->update, 'Getspec load finished.' state.historyWin->update, 'Getspec load finished.' Endif Else Begin state.statusBar->update, 'Getspec load finished. Some quantities were not processed. Check History window.' state.historyWin->update, 'Getspec load finished. Some quantities were not processed. Check History window.' Endelse End ; end APPLY section ELSE: Endcase widget_control, stash, set_uvalue=state, /NO_COPY Return End ;+ ;NAME: ; thm_ui_part_getspec_options ; ;PURPOSE: ; A interface to THM_PART_GETSPEC.PRO for creating and loading THEMIS energy/ ; angular particle spectra into the GUI. Intended to be called from ; THM_UI_INIT_LOAD_WINDOW.PRO. ; ;CALLING SEQUENCE: ; thm_ui_part_getspec_options, tab_id, loadedData, historyWin, statusText, $ ; trObj, timeWidget=timeWidget ;INPUT: ; tab_id: The widget id of the tab. ; loadedData: The loadedData object. ; historyWin: The history window object. ; statusText: The status bar object for the main Load window. ; trObj: The GUI timerange object. ; ;KEYWORDS: ; timeWidget = The time widget object. ; ;OUTPUT: ; No explicit output, new variables are created. For a given data ; type, one or two spectra are created. One is the angular spectrum ; for the full energy range. If the energy spectrum option is chosen, ; then another spectrum is created which is the energy spectrum for ; the full angular range. ; ;HISTORY: ; 5-jan-2009, jmm, jimm@ssl.berkeley.edu ; 14-jan-2009, jmm, added statusbar object ; 15-jan-2009, jmm, added external_state, so that the active data ; widget on the dproc panel can be updated. ; 23-jan-2009, jmm, deletes tplot variables created during processing, ; correctly updates active data ; 13-may-2009, bck, moved code from Data Processing window to Load window ; 16-jul-2012, aaf, rewrote error checking on input values to match the ; behavior of other GUI windows ; ;$LastChangedBy: egrimes $ ;$LastChangedDate: 2013-04-03 14:18:44 -0700 (Wed, 03 Apr 2013) $ ;$LastChangedRevision: 11947 $ ;$URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/thmsoc/tags/tdas_8_00/idl/themis/thm_ui_new/panels/thm_ui_part_getspec_options.pro $ ;- Pro thm_ui_part_getspec_options, tab_id, loadedData, historyWin, statusBar, $ trObj,callSequence,timeWidget=timeid widget_control, /hourglass mainBase = widget_base(tab_id, /col) topBase = widget_base(mainBase, /row) topCol1Base = widget_base(topBase, /col) instrLabelBase = widget_base(topcol1base, /row) instrumentBase = widget_base(topCol1Base, /col, /frame, xpad=5) timeBase = widget_base(instrumentBase) sstCalButtonBase = widget_base(instrumentBase, /col, /nonexclusive, xpad=5) dataBase = widget_base(instrumentBase, /row) suffixLabelBase = widget_base(topCol1Base,/col) suffixBase = widget_base(topCol1Base, /row, /frame, ypad=1, xpad=10) topCol2Base = widget_base(topBase, /col) energyLabelBase = widget_base(topCol2Base, /row, /align_left) energy_base = widget_base(topCol2Base, /col, /frame, /align_left, ypad=10, xpad=8, tab_mode=1) ;base widget for energy info angleLabelBase = widget_base(topCol2Base, /row, /align_left) angle_Base = widget_base(topCol2Base, /col, /frame, ypad=15, xpad=5, tab_mode=1) topCol3Base = widget_base(topBase, /col) advancedLabelBase = widget_base(topCol3Base, /row) advanced_base = widget_base(topCol3Base, /col, /frame, ypad=4, xpad=4, tab_mode=1, space=2) buttonBase = widget_base(mainBase, /row, /align_center) ;data input options dataLabel = widget_label(instrLabelBase, value='Data Selection: ', /align_left) ; Time widget tr = trObj timeid = thm_ui_time_widget(timeBase,$ statusBar,$ historyWin,$ timeRangeObj=tr,$ uvalue='TIME_WIDGET',$ uname='time_widget') sstButton = widget_button(sstCalButtonBase, value = 'Use Beta SST Calibrations?', $ uname = 'SST_CALIBRATE',UVAL='SST_CALIBRATE') ; Probe selection ;----------------- validProbesVisible = [' * (All)', ' A (P5)', ' B (P1)', ' C (P2)', ' D (P3)', $ ' E (P4)'] validProbes = ['*', 'a', 'b', 'c', 'd', $ 'e'] probeBase = Widget_Base(dataBase, /col) plBase = Widget_base(probeBase, /row) probeListBase = Widget_Base(plBase, /col) probeLabel = Widget_Label(probeListBase, Value='Probe: ', /align_left) probeList = Widget_List(probeListBase, Value=validProbesVisible, /multiple, uval='PROBE', XSize=16, YSize=11) probeButtonBase = Widget_Base(probeListBase, /row, /align_center) probeClearButton = Widget_Button(probeButtonBase, value=' Clear Probe ', uvalue='CLEARPROBE', /align_center) ; Data type selection ;----------------- ; Get valid datatypes, probes, etc for different data types validDataTypes = ['*','peif', 'peir', 'peib', 'peef', 'peer', 'peeb', 'psif', 'psir', $ 'psef', 'pser', 'pseb'] validBetaTypes = ['*','psif','psef','pseb'] ; dtype_ind = make_array(n_elements(validDataTypes)-1, /int) dataTypeBase = Widget_Base(DataBase, /col) dataL1Base = Widget_Base(dataTypeBase, /col) dataButtonBase = Widget_Base(dataTypeBase, /col, /align_center) dataTypeLabel = Widget_Label(dataL1Base, Value='Data Type:', /align_left) dataTypeList = Widget_List(dataL1Base, Value=validDataTypes, uval='DATATYPE', $ uname='data_type_list',$ /Multiple, XSize=16, YSize=11) dataClearButton = Widget_Button(dataButtonBase, value=' Clear Data Type ', uvalue='CLEARDATA', /align_center) ;suffix suffixlabel = widget_label(suffixLabelBase, value = 'Variable Name: ', /align_left) suffixlabel = widget_label(suffixBase, value = 'New suffix: ', /align_left) suffix = '' suffixid = widget_text(suffixBase, value = suffix, xsize = 22, ysize = 1, $ uvalue = 'SUFFIX', uname='SUFFIX', /editable, /all_events) ;Buttons for energy spectra ;----------------- energy_min = '0' energy_max = '1e7' erbase = widget_base(energy_base, /col) erlabel = widget_label(energyLabelbase, value = 'Energy Range:') erminmaxbase = widget_base(erbase, /row) erminbase = widget_base(erminmaxbase, /row) erminlabel = widget_label(erminbase, value = 'Min (eV): ') ermin = widget_text(erminbase, value = energy_min, xsize = 6, ysize = 1, $ uvalue = 'energy_min', uname='energy_min', /editable, /all_events) ermaxbase = widget_base(erminmaxbase, /row) ermaxlabel = widget_label(ermaxbase, value = 'Max (eV):') ermax = widget_text(ermaxbase, value = energy_max, xsize = 6, ysize = 1, $ uvalue = 'energy_max', uname='energy_max', /editable, /all_events) energy_set = 0b ebuttonbase = widget_base(energy_base, /col, /nonexclusive, xpad=5) ebutton = widget_button(ebuttonbase, value = 'Return Energy Spectrum', uvalue = 'ENERGY:SET', $ uname = 'ENERGY:SET', $ tooltip='Output tplot variables containing the energy spectrum of ' + $ 'the energy/angle ranges input above') ;Angle Options ;----------------- alabel = widget_label(angleLabelBase, value = 'Angular distribution:') angle_options = ['Phi', 'Theta', 'PA', 'Gyro'] angle = 'Phi' angle_description = ['probe-sun dir in spin plane (deg)', $ 'spin plane/az of pitch ang (deg)', $ 'pitch angle, magnetic field (deg)', $ 'gyrovelocity'] ;need to figure out gyrovelocity angle_combobox = widget_combobox(angle_base, value = angle_options+': '+$ angle_description, uvalue = 'ANGLE:COMBOBOX') nangles = n_elements(angle_options) ;set default angle limits phi_min = '0' phi_max = '360' theta_min = '-90' theta_max = '90' pa_min = '0' pa_max = '180' gyro_min = '0' gyro_max = '360' ;compensate for widgets being made in for loop angle_values = [ [phi_min, phi_max], $ [theta_min, theta_max],$ [pa_min, pa_max], $ [gyro_min, gyro_max] ] angle_values_base = widget_base(angle_base, /col) angle_values_label = widget_label(angle_values_base, value = 'Angular Limits') For j = 0, nangles-1 Do Begin uvalj = strlowcase(angle_options[j]) basej = widget_base(angle_values_base, /row) basejlabel = widget_label(basej, value = angle_options[j], xsize = 60) basejminbase = widget_base(basej, /row) basejminlabel = widget_label(basejminbase, value = 'Min') basejmin = widget_text(basejminbase, value = angle_values[0, j], xsize = 6, ysize = 1, $ uvalue = uvalj+'_min', uname = uvalj+'_min', /editable, /all_events) basejmaxbase = widget_base(basej, /row) basejmaxlabel = widget_label(basejmaxbase, value = 'Max') basejmax = widget_text(basejmaxbase, value = angle_values[1, j], xsize = 6, ysize = 1, $ uvalue = uvalj+'_max', uname = uvalj+'_max', /editable, /all_events) Endfor start_angle = '0' start_angle_base = widget_base(angle_values_base, /row) start_angle_label = widget_label(start_angle_base, value = 'Start Angle (Phi only)', xsize = 150) start_angle_id = widget_text(start_angle_base, value = start_angle, xsize = 6, ysize = 1, $ uvalue = 'start_angle', uname='start_angle', /editable, /all_events) ;Advanced Options ;----------------- advancedLabel = widget_label(advancedLabelBase, value='Advanced: ') ;normalize option normalize = 0b normbase = widget_base(advanced_base, /nonexclusive,xpad=3) ;padded to match sst widgets nbutton = widget_button(normbase, value = 'Normalize Time Samples', uvalue = 'NORM:SET', $ uname='NORM:SET', tooltip='Independently normalize the flux for each time sample.') ;maximum gap max_gap = '0' dgbase = widget_base(advanced_base, /row) dglabel = widget_label(dgbase, /align_left, value = 'Set Maximum Gap (sec): ') dg = widget_text(dgbase, xsize = 8, ysize = 1, value = max_gap, $ uvalue = 'max_gap', uname = 'max_gap', /editable, /all_events) annoyingbase = widget_base(advanced_base, xpad=0) ;allign label left w/o altering advanced_base fac_en_label = widget_label(annoyingbase, value = 'Energy/FAC Options') advanced_subbase = widget_base(advanced_base, /col, xpad=0, ypad=0, frame=3) ;regrid options regrid_phi = '16' regrid_theta = '8' rgbase = widget_base(advanced_subbase, /col, uname='RGBASE') rglabel = widget_label(rgbase, /align_left, value = 'Regrid = [m,n] for [phi, theta]') rgmnbase = widget_base(rgbase, /row, space=2) rgmlabel = widget_label(rgmnbase, value = 'M ') rgm = widget_text(rgmnbase, value = regrid_phi, xsize = 6, ysize = 1, $ uvalue = 'regrid_phi', uname='regrid_phi', /editable, /all_events) rgnlabel = widget_label(rgmnbase, value = 'N ') rgn = widget_text(rgmnbase, value = regrid_theta, xsize = 6, ysize = 1, $ uvalue = 'regrid_theta', uname='regrid_theta', /editable, /all_events) ;conversion to FAC other_dim = 'MPHIGEO' odbase = widget_base(advanced_subbase, /row, uname='ODBASE') odlabel = widget_label(odbase, /align_left, value = 'Conversion to FAC: ') od_options = ['MPHIGEO', 'PHIGEO', 'MPHISM', 'PHISM', 'MRGEO', 'RGEO', 'XGSE', 'YGSM'] od_combobox = widget_combobox(odbase, value = od_options, uvalue = 'OD:COMBOBOX') ; ;resize previous widget as this one is longer ; geo = widget_info(dglabel,/geo) ; widget_control, odlabel, xsize=geo.scr_xsize ;SST mask remove_mask = 0b mask_value = '0.99' maskbuttonbase = widget_base(advanced_base, /col, /nonexclusive) maskbutton = widget_button(maskbuttonbase, value = 'Remove SST mask', uvalue = 'SST:MASKSET', $ uname='SST:MASKSET', tooltip='Remove on-board SST mask') maskvaluebase = widget_base(advanced_base, /row, sensitive=0, uname='SSTBASE', frame=3) maskvaluelabelbase = widget_base(maskvaluebase, /col) maskvaluelabel1 = widget_label(maskvaluelabelbase, /align_left, value = 'Mask_remove proportion') maskvaluelabel2 = widget_label(maskvaluelabelbase, /align_left, value = 'of values that must be zero') maskremove = widget_text(maskvaluebase, value = mask_value, xsize = 6, ysize = 1, $ uvalue = 'mask_value', uname = 'mask_value', /editable, /all_events) ;SST Contamination remove_sp = 0b sunpulse_limit = '10' spbuttonbase = widget_base(advanced_base, /col, /nonexclusive) spbutton = widget_button(spbuttonbase, value = 'Remove SST Sun Contamination', uvalue = 'SP:SET', $ uname='SP:SET', tooltip='Removes sunlight contamination of SST data') spbase0 = widget_base(advanced_base, /col, sensitive=0, uname='SPBASE', frame=3) spbase1 = widget_base(spbase0, /row) splabelbase = widget_base(spbase1, /col) splabel1 = widget_label(splabelbase, value = 'Sun cleaning method ') sp_options = ['AUTOMATIC','SPIN_FIT', 'MEDIAN', 'Z_SCORE_MOD'] sp_combobox = widget_combobox(spbase1, value = sp_options, uvalue = 'SP:COMBOBOX',uname='SUN_CLEAN_METHOD') limbase = widget_base(spbase0, /row) limlabelbase = widget_base(limbase, /col) limlabel1 = widget_label(limlabelbase, value = 'Lim for sunpulse cleaning') limtxt = widget_text(limbase, value = sunpulse_limit, xsize = 6, ysize = 1, $ uvalue = 'sunpulse_limit', uname = 'sunpulse_limit', /editable, /all_events) fillbase = widget_base(spbase0, /row) filllabelbase = widget_base(fillbase, /col) filllabel1 = widget_label(filllabelbase, value = 'Fill method') fill_options = ['INTERPOLATION', 'SPIN_FIT'] fill_combobox = widget_combobox(fillbase, value = fill_options, uvalue = 'FILL:COMBOBOX',uname='SUN_FILL_METHOD') ;buttons apply_button = Widget_Button(buttonBase, Value = ' Apply ', XSize = 70, $ UValue = 'APPLY', tooltip='Create particle spectra from active data') resetButton = Widget_Button(buttonBase, value='Reset All', uvalue='RESET', $ tooltip='Reset all settings to their default value.') helpButton = Widget_Button(buttonBase, Value='Help', XSize=70, UValue='HELP', $ tooltip='Open Help Window.') state = {tab_id:tab_id, $ ; GUI objects & variables loadedData:loadedData, historyWin:historyWin, callSequence:callSequence, $ statusBar:statusBar, probeList:probeList, tr:tr, $ ; Widgets angle_combobox:angle_combobox, dataTypeList:dataTypeList, $ sp_combobox:sp_combobox, maskButton:maskButton, od_combobox:od_combobox,$ fill_combobox:fill_combobox, maskValueBase:maskValueBase, $ spButton:spButton, spBase0:spBase0, $ probeClearButton:probeClearButton, dataClearButton:dataClearButton, $ ; Widget support data (lists etc) angle_options:angle_options, validProbes:validProbes, $ validDataTypes:validDataTypes, validBetaTypes:validBetaTypes, $ ; Stored Data (to be passed to thm_part_getspec) phi_min:phi_min, phi_max:phi_max, $ theta_min:theta_min, theta_max:theta_max, $ pa_min:pa_min, pa_max:pa_max, $ gyro_min:gyro_min, gyro_max:gyro_max, $ angle:angle, start_angle:start_angle, $ energy_set:energy_set, $ energy_min:energy_min, energy_max:energy_max, $ regrid_phi:regrid_phi, regrid_theta:regrid_theta, $ normalize:normalize, max_gap:max_gap, $ other_dim:other_dim, $ remove_mask:remove_mask, mask_value:mask_value, $ remove_sp:remove_sp, sunpulse_limit:sunpulse_limit, $ suffix:suffix $ } thm_ui_part_getspec_rgcheck, state widget_control, widget_info(tab_id, /child), set_uvalue=state, /no_copy Return End