; stack_panel.pro ; ; Authors: Lon Riesberg / James Everton ; ; Date: 5/26/06 ; ; PURPOSE: ; ; REFERENCES: ; ; NOTES: ; ; CONSTRAINTS: ; ; OTHER SERVERS/MODULES USED: ; ; RELATED MODULES / CLASSES: ; called by cips_data_analyzer.pro ; ; SUPPORTING DATABASE TABLES OR FILES: ; ; -------------------------------------------------------------------------- ; PROCEDURE stack_panel_callback ; -------------------------------------------------------------------------- ; PURPOSE: ; This procedure is called whenever a registered component generates a ; message. In this UI panel, there are no registered components, so this ; procedure is here simply for syntactical reasons. If components get ; registered later, this is where messages will be handled. ; ; INPUT PARAMETERS: (Automatically sent by the iTools environment) ; wPanel - the widget id of the panel widget ; strID - string identifying the source of the message ; messageIn - string that uniquely identifies the message being sent. ; component - a value that is associated with the message being sent. ; PRO stack_panel_callback, wPanel, strID, messageIn, component ; Make sure we have a valid widget ID IF ~WIDGET_INFO(wPanel, /VALID) THEN RETURN ; Retrieve the widget ID of the first child widget of the UI panel wChild = WIDGET_INFO(wPanel, /CHILD) ; Retrieve the state structure from the user value of the first child widget WIDGET_CONTROL, wChild, GET_UVALUE = state END ; -------------------------------------------------------------------------- ; PROCEDURE sensitize_stack_panel ; -------------------------------------------------------------------------- PRO sensitize_stack_panel COMMON CIPS_GLOBAL_STATE, cips_global_options COMMON STACK_WINDOW_STATE, stack_window_options COMMON STACK_PANEL_BTNS, stack_panel_buttons COMMON L1C_STACK_PANEL_BTNS, l1c_stack_panel_buttons COMMON RETRIEVED_CLOUD_BTNS, cloud_panel_buttons COMMON SCENES_PANEL_BTNS, scenes_panel_buttons clear_retrieved_cloud_panel clear_scenes_panel clear_l1c_stack_panel cips_global_options.curr_view = 'stack' WIDGET_CONTROL, stack_panel_buttons.option_btns, SENSITIVE=1 WIDGET_CONTROL, stack_panel_buttons.contour_btns, SENSITIVE=1 WIDGET_CONTROL, stack_panel_buttons.plot_base, SENSITIVE=1 WIDGET_CONTROL, stack_panel_buttons.export_base, SENSITIVE=1 WIDGET_CONTROL, stack_panel_buttons.animation_controls, SENSITIVE=1 WIDGET_CONTROL, stack_panel_buttons.contrast_sliders, SENSITIVE=1 if (stack_window_options.surf_view eq 0) then begin WIDGET_CONTROL, stack_panel_buttons.colorbar_btn, SENSITIVE=1 endif if (n_elements(cloud_panel_buttons) gt 0) and (cips_global_options.is_cloud ne 0) then begin WIDGET_CONTROL, cloud_panel_buttons.cld_props_btns, SENSITIVE=1 ; keep available WIDGET_CONTROL, cloud_panel_buttons.option_btns, SENSITIVE=0 WIDGET_CONTROL, cloud_panel_buttons.plot_base_cloud, SENSITIVE=0 WIDGET_CONTROL, cloud_panel_buttons.export_base, SENSITIVE=0 WIDGET_CONTROL, cloud_panel_buttons.unc_btn, SENSITIVE=0 WIDGET_CONTROL, cloud_panel_buttons.contour_btns, SENSITIVE=0 endif if (cips_global_options.is_l1c_stack ne 0) and (n_elements(l1c_stack_panel_buttons) gt 0) then begin WIDGET_CONTROL, l1c_stack_panel_buttons.option_btns, SENSITIVE=0 WIDGET_CONTROL, l1c_stack_panel_buttons.contour_btns, SENSITIVE=0 WIDGET_CONTROL, l1c_stack_panel_buttons.plot_base, SENSITIVE=0 WIDGET_CONTROL, l1c_stack_panel_buttons.export_base, SENSITIVE=0 WIDGET_CONTROL, l1c_stack_panel_buttons.contrast_sliders, SENSITIVE=0 WIDGET_CONTROL, l1c_stack_panel_buttons.animation_controls, SENSITIVE=0 ; if multiple views are showing (e.g. 1C coastline view), return to single view void = itgetcurrent(tool=oTool) layout_param = oTool->FindIdentifiers('*layout*') layout_obj = oTool->GetByIdentifier(layout_param) layout_props = layout_obj->QueryProperty() layout_obj->GetProperty, VIEW_COLUMNS=cols layout_obj->GetProperty, VIEW_ROWS=rows ; switch back to single panel layout if (rows gt 1) then begin result = oTool->DoSetProperty(layout_param, 'SHOW_EXECUTION_UI', 0) result = oTool->DoSetProperty(layout_param, 'LAYOUT_INDEX', 1) result = oTool->DoSetProperty(layout_param, 'VIEW_COLUMNS', 1) result = oTool->DoSetProperty(layout_param, 'VIEW_ROWS', 1) result = oTool->DoSetProperty(layout_param, 'AUTO_RESIZE', 1) result = oTool->DoAction(layout_param) oTool->CommitActions endif endif if (n_elements(scenes_panel_buttons) gt 0) and (cips_global_options.is_scenes ne 0) then begin WIDGET_CONTROL, scenes_panel_buttons.options_btns, SENSITIVE=0 WIDGET_CONTROL, scenes_panel_buttons.contours_btn, SENSITIVE=0 WIDGET_CONTROL, scenes_panel_buttons.plot_base, SENSITIVE=0 WIDGET_CONTROL, scenes_panel_buttons.export_base, SENSITIVE=0 WIDGET_CONTROL, scenes_panel_buttons.contrast_sliders, SENSITIVE=0 WIDGET_CONTROL, scenes_panel_buttons.animation_controls, SENSITIVE=0 endif END ; -------------------------------------------------------------------------- ; PROCEDURE plot_orbit_box ; -------------------------------------------------------------------------- ; PURPOSE: ; To create a red box on the coastlines plot that shows the range of ; all the images in the orbit PRO plot_orbit_box COMMON VIEW_CIPS_STACK, panel_stack, layers_tvs, is_surface_stack, layers_thumb_max, stack_max width = panel_stack.stack.bbox[2]-panel_stack.stack.bbox[0] height = panel_stack.stack.bbox[3]-panel_stack.stack.bbox[1] n_coords = width*2 + height*2 red_box_x = dblarr(n_coords) red_box_y = dblarr(n_coords) current=0 x=panel_stack.stack.bbox[0] ; left side of the box red_box_x[current:current+height] = panel_stack.stack.bbox[0] for y=panel_stack.stack.bbox[1], panel_stack.stack.bbox[3]-1 do begin red_box_y[current] = y current += 1 endfor ; top of the box red_box_y[current:current+width-1] = panel_stack.stack.bbox[3] for x=panel_stack.stack.bbox[0], panel_stack.stack.bbox[2]-1 do begin red_box_x[current] = x current += 1 endfor ; right side of the box red_box_x[current:current+height-1] = panel_stack.stack.bbox[2] for y=panel_stack.stack.bbox[3], panel_stack.stack.bbox[1]+1, -1 do begin red_box_y[current] = y current += 1 endfor ; bottom of the box red_box_y[current:current+width-1] = panel_stack.stack.bbox[1] for x=panel_stack.stack.bbox[2], panel_stack.stack.bbox[0]+1, -1 do begin red_box_x[current] = x current += 1 endfor iplot, red_box_x, red_box_y, view_number=2, color=[255,0,0], /OVERPLOT END ; -------------------------------------------------------------------------- ; PROCEDURE setup_for_stack_plot ; -------------------------------------------------------------------------- PRO setup_for_stack_plot, x_values, y_values, x_title, y_title, min_value, max_value, plot_title COMMON VIEW_CIPS_STACK, panel_stack, layers_tvs, is_surface_stack, layers_thumb_max, stack_max COMMON STACK_WINDOW_STATE, stack_window_options ; setup y-axis CASE stack_window_options.yplot OF 'albedo': BEGIN y_values = stack_window_options.scaling_min > (*((*panel_stack.stack.albedo)[stack_window_options.curr_image_idx]))[*] < $ stack_window_options.scaling_max y_title = 'Albedo' END ELSE: break ENDCASE ; setup x-axis CASE stack_window_options.xplot OF 'zenith_angle': BEGIN if panel_stack.stack.version le 3.00 then begin x_values = (*((*panel_stack.stack.zenith_angle)[stack_window_options.curr_image_idx]))[*] endif else begin x_values = (*((*panel_stack.stack.zenith_angle_ray_peak)[stack_window_options.curr_image_idx]))[*] endelse x_title = 'Solar Zenith Angle' END 'scattering_angle': BEGIN x_values = (*((*panel_stack.stack.scattering_angle)[stack_window_options.curr_image_idx]))[*] x_title = 'Scattering Angle' END 'view_angle': BEGIN if panel_stack.stack.version le 3.00 then begin x_values = (*((*panel_stack.stack.view_angle)[stack_window_options.curr_image_idx]))[*] endif else begin x_values = (*((*panel_stack.stack.view_angle_ray_peak)[stack_window_options.curr_image_idx]))[*] endelse x_title = 'Viewing Angle' END ELSE: break ENDCASE plot_title = panel_stack.layers[stack_window_options.curr_image_idx].info END ; -------------------------------------------------------------------------- ; PROCEDURE remove_stack_coastlines ; -------------------------------------------------------------------------- pro remove_stack_coastlines, oTool layout_param = oTool->FindIdentifiers('*layout*') layout_obj = oTool->GetByIdentifier(layout_param) layout_props = layout_obj->QueryProperty() layout_obj->GetProperty, VIEW_COLUMNS=cols layout_obj->GetProperty, VIEW_ROWS=rows idCoast = oTool->FindIdentifiers('*SPACE/PLOT*', /VISUALIZATIONS) for i=0, N_ELEMENTS(idCoast)-1 do begin if idCoast[i] ne '' then begin success = oTool->RemoveByIdentifier(idCoast[i]) endif endfor ; switch back to single panel layout if (rows gt 1) then begin result = oTool->DoSetProperty(layout_param, 'SHOW_EXECUTION_UI', 0) result = oTool->DoSetProperty(layout_param, 'LAYOUT_INDEX', 1) result = oTool->DoSetProperty(layout_param, 'VIEW_COLUMNS', 1) result = oTool->DoSetProperty(layout_param, 'VIEW_ROWS', 1) result = oTool->DoSetProperty(layout_param, 'AUTO_RESIZE', 1) result = oTool->DoAction(layout_param) oTool->CommitActions endif END ; -------------------------------------------------------------------------- ; PROCEDURE draw_stack_contours ; -------------------------------------------------------------------------- pro draw_stack_contours, oTool COMMON COLORS, R_orig, G_orig, B_orig, R_curr, G_curr, B_curr COMMON VIEW_CIPS_STACK, panel_stack, layers_tvs, is_surface_stack, layers_thumb_max, stack_max COMMON STACK_WINDOW_STATE, stack_window_options COMMON CIPS_GLOBAL_STATE, cips_global_options COMMON VIEW_CIPS_STACK, panel_stack, layers_tvs, is_surface_stack, layers_thumb_max, stack_max if (stack_window_options.surf_view eq 1) and (cips_global_options.black_bg eq 0) then begin linecolor=[0,0,0] endif else begin linecolor=[255,255,255] endelse ; clear any existing contours idCON = oTool->FindIdentifiers('*SPACE/CONTOUR*', /VISUALIZATIONS) for i=0, N_ELEMENTS(idCON)-1 do begin if idCON[i] ne '' then begin success = oTool->RemoveByIdentifier(idCON[i]) endif endfor ; draw SZA contours if (stack_window_options.show_solar_zenith_angles eq 1) then begin contour_values = indgen(60) * 3 if panel_stack.stack.version le 3.00 then begin zenith_angles = *((*panel_stack.stack.zenith_angle)[stack_window_options.curr_image_idx]) endif else begin zenith_angles = *((*panel_stack.stack.zenith_angle_ray_peak)[stack_window_options.curr_image_idx]) endelse icontour, zenith_angles, overplot=oTool, COLOR=linecolor, C_VALUE=contour_values, C_LABEL_SHOW=contour_values endif ; draw scattering angle contours if (stack_window_options.show_scattering_angles eq 1) then begin contour_values = indgen(30) * 6 icontour, *((*panel_stack.stack.scattering_angle)[stack_window_options.curr_image_idx]), $ overplot=oTool, COLOR=linecolor, C_VALUE=contour_values, C_LABEL_SHOW=contour_values endif ; draw viewing angle contours if (stack_window_options.show_view_angles eq 1) then begin contour_values = indgen(30) * 6 if panel_stack.stack.version le 3.00 then begin view_angles = *((*panel_stack.stack.view_angle)[stack_window_options.curr_image_idx]) endif else begin view_angles = *((*panel_stack.stack.view_angle_ray_peak)[stack_window_options.curr_image_idx]) endelse icontour,view_angles, overplot=oTool, COLOR=linecolor, C_VALUE=contour_values, C_LABEL_SHOW=contour_values endif ; draw albedo contours if (stack_window_options.show_albedo_contours eq 1) then begin contour_values = indgen(30) * 6 albedo = *panel_stack.layers[stack_window_options.curr_image_idx].image icontour, albedo, overplot=oTool, COLOR=linecolor, C_VALUE=contour_values, C_LABEL_SHOW=contour_values endif ; draw lat/lon contours if (stack_window_options.show_latlon_contours eq 1) then begin contour_values = indgen(60) * 3 lat = *((*panel_stack.stack.latitude)[stack_window_options.curr_image_idx]) lon = *((*panel_stack.stack.longitude)[stack_window_options.curr_image_idx]) icontour, lat, overplot=oTool, COLOR=linecolor, C_VALUE=contour_values, C_LABEL_SHOW=contour_values icontour, lon, overplot=oTool, COLOR=linecolor, N_LEVELS=0, C_LABEL_SHOW=contour_values endif ; overplot common volume if (stack_window_options.view_cvo eq 1) then begin if ptr_valid((panel_stack.stack).common_volume_map) then begin orbit_cv = dereference_single((panel_stack.stack).common_volume_map) ; cv_orbit_swath is bounding box for the entire orbit swath [x, y, w, h] cv_orbit_bbox = dereference_single((panel_stack.stack).bbox) ; for each stack layer, need to use the bounding box for that layer to ; determine the right offset to use for determining which part of the cv map to use curr_scene_bbox = (*panel_stack.stack.scene_bboxes)[stack_window_options.curr_image_idx, *] ; find cv map for just the current scene start_x = curr_scene_bbox[0] - cv_orbit_bbox[0] start_y = curr_scene_bbox[1] - cv_orbit_bbox[1] end_y = curr_scene_bbox[3] - curr_scene_bbox[1] end_x = curr_scene_bbox[2] - curr_scene_bbox[0] curr_cv = make_array(end_x-start_x+1, end_y-start_y+1, /byte) curr_cv[*,*] = orbit_cv[start_x:end_x, start_y:end_y] contour_values = indgen(2) icontour, curr_cv, overplot=1, COLOR=linecolor, C_VALUE=contour_values view_ID = oTool->FindIdentifiers('*VIEW_1') oView = oTool->GetByIdentifier(view_ID) oView->Select, 1 endif endif end ; -------------------------------------------------------------------------- ; PROCEDURE animation_handler ; -------------------------------------------------------------------------- ; PRO animation_handler, event WIDGET_CONTROL, /DESTROY, event.TOP end ; -------------------------------------------------------------------------- ; PROCEDURE stack_panel_event ; -------------------------------------------------------------------------- ; ; INPUT PARAMETERS: (Automatically sent by the iTools environment) ; event - a widget event generated by a widget ; PRO stack_panel_event, event COMMON COLORS, R_orig, G_orig, B_orig, R_curr, G_curr, B_curr COMMON VIEW_CIPS_STACK, panel_stack, layers_tvs, is_surface_stack, layers_thumb_max, stack_max COMMON SCENES_WINDOW_STATE, scenes_window_options COMMON STACK_WINDOW_STATE, stack_window_options COMMON CLOUD_WINDOW_STATE, cloud_window_options COMMON CIPS_GLOBAL_STATE, cips_global_options COMMON L1C_STACK_PANEL_BTNS, l1c_stack_panel_buttons COMMON STACK_PANEL_BTNS, stack_panel_buttons COMMON RETRIEVED_CLOUD_BTNS, cloud_panel_buttons COMMON SCENES_PANEL_BTNS, scenes_panel_buttons ; if the user closes the window before a selection is rendered, ; an invalid object error will occur... cancel the error. catch, status if status ne 0 then begin ; Note: -754 is an unrendered iImage call ; -255 is an unrendered iContour call if (status eq -754) or (status eq -255) then begin catch, /cancel return endif else begin if (get_debug_level() gt 1) then print, !Error_State.Msg return endelse endif ; Initialize exec_option and color variables exec_option = 0 replace_title = 0 redraw_coast = 0 colorbar_needs_updating = 0 if (cips_global_options.black_bg eq 1) then begin bg_color = [0, 0, 0] line_color = [255, 255, 255] endif else begin bg_color = [255, 255, 255] line_color = [0, 0, 0] endelse ; Retrieve widget ID of first child widget of the UI panel wChild = WIDGET_INFO(event.handler, /CHILD) ; Retrieve the state structure from the user value of the first child widget. WIDGET_CONTROL, wChild, GET_UVALUE = state ; Retrieve the user value of the widget that generated the event WIDGET_CONTROL, event.id, GET_UVALUE = uvalue ; Get the parameter set that contains the images oParamSet = state.oTool->GetByIdentifier("/DATA MANAGER/CIPS PARAMETERS") ; Get the main window in which to place the new image idImage = state.oTool->FindIdentifiers('*IMAGE', /VISUALIZATIONS) oImage = state.oTool->GetByIdentifier(idImage) ; Get the graphics view from the data manager view_ID = state.oTool->FindIdentifiers('*VIEW_1') oView = state.oTool->GetByIdentifier(view_ID) oView->Select, 1 oTool=state.oTool ; if the main window doesn't have a layers view already, ; erase the main window if (stack_window_options.view eq 'layers') then begin stack_window_options.view = 'layers' result = oTool->FindIdentifiers('*VISUALIZATION LAYER/DATA SPACE') for i=0, N_ELEMENTS(result)-1 do begin if result[i] ne '' then begin success = oTool->RemoveByIdentifier(result[i]) endif endfor endif ; NOTE: ; exec_option eq 0: nothing needs to be redrawn ; exec_option eq 1: redraw ; exec_option eq 2: redraw entire screen CASE WIDGET_INFO(event.id, /UNAME) OF 'SHOWBLACKBGBTN': BEGIN ; Set the black_bg variable and set up the color scheme cips_global_options.black_bg = WIDGET_INFO(event.id, /BUTTON_SET) if (cips_global_options.black_bg eq 1) then begin bg_color = [0, 0, 0] line_color = [255, 255, 255] font_param = oTool->FindIdentifiers('*STYLE/ANNOTATIONS/TEXT*') result = oTool->DoSetProperty(font_param, 'FONT_SIZE', 20) result = oTool->DoSetProperty(font_param, 'COLOR', line_color) oTool->CommitActions endif else begin bg_color = [255, 255, 255] line_color = [0, 0, 0] font_param = oTool->FindIdentifiers('*STYLE/ANNOTATIONS/TEXT*') result = oTool->DoSetProperty(font_param, 'FONT_SIZE', 20) result = oTool->DoSetProperty(font_param, 'COLOR', line_color) oTool->CommitActions endelse exec_option = 1 replace_title = 1 if (stack_window_options.show_coast eq 1) then redraw_coast=1 if n_elements(l1c_stack_panel_buttons) ne 0 then begin WIDGET_CONTROL, l1c_stack_panel_buttons.black_bg_btn, $ SET_BUTTON=cips_global_options.black_bg endif if n_elements(cloud_panel_buttons) ne 0 then begin WIDGET_CONTROL, cloud_panel_buttons.black_bg_btn, $ SET_BUTTON=cips_global_options.black_bg endif if n_elements(scenes_panel_buttons) ne 0 then begin WIDGET_CONTROL, scenes_panel_buttons.black_bg_btn, $ SET_BUTTON=cips_global_options.black_bg endif if cips_global_options.colorbar eq 1 then update_colorbar END 'SHOWSURFACEBTN':BEGIN stack_window_options.surf_view = WIDGET_INFO(event.id, /BUTTON_SET) ; if the surface button was unselected if (stack_window_options.surf_view eq 0) then begin ; re-enable colorbars WIDGET_CONTROL, stack_panel_buttons.colorbar_btn, SENSITIVE=1 ; clear screen result = [oTool->FindIdentifiers('*VIEW_*VISUALIZATION LAYER/DATA SPACE'), $ oTool->FindIdentifiers('*VIEW_*ANNOTATION LAYER/COLORBAR*')] if (cips_global_options.stack_split eq 1) then $ result = [result, oTool->FindIdentifiers('*VIEW_2*SPACE/IMAGE*')] for i=0, N_ELEMENTS(result)-1 do begin if result[i] ne '' then begin success = oTool->RemoveByIdentifier(result[i]) endif endfor ; surface view endif else begin ; disable colorbars WIDGET_CONTROL, stack_panel_buttons.colorbar_btn, SENSITIVE=0 cips_global_options.colorbar = 0 update_colorbar endelse ; setup to redraw exec_option = 1 END 'SHOWCVOBTN': BEGIN stack_window_options.view_cvo = WIDGET_INFO(event.id, /BUTTON_SET) draw_stack_contours, oTool END 'MAXCONTRASTSLIDER': BEGIN new_max = exp((event.value/100.0) * alog(stack_max)) WIDGET_CONTROL, stack_panel_buttons.max_value_label, set_value=' '+strtrim(string(new_max, format='(f7.1)'),1) stack_window_options.scaling_max = new_max if stack_window_options.view eq 'plot' then exec_option=2 else exec_option=1 END 'MINCONTRASTSLIDER': BEGIN new_min = exp((event.value/100.0) * alog(stack_max)) if new_min le 1 then new_min = 0 WIDGET_CONTROL, stack_panel_buttons.min_value_label, set_value=' '+strtrim(string(new_min, format='(f7.1)'),1) stack_window_options.scaling_min = new_min if stack_window_options.view eq 'plot' then exec_option=2 else exec_option=1 END 'ANIMATE': BEGIN WIDGET_CONTROL, uvalue, GET_VALUE=color_list color_scheme = color_list[WIDGET_INFO(uvalue, /DROPLIST_SELECT)] color_scheme = (STRSPLIT(color_scheme,':',/EXTRACT))[0] LOADCT, color_scheme animation_base = widget_base(TITLE=cips_global_options.title) dim = SIZE(*panel_stack.layers[0].image, /DIMENSIONS) for i=1, n_elements(panel_stack.layers)-1 do begin new_dim = SIZE(*panel_stack.layers[i].image, /DIMENSIONS) dim[0] = ( new_dim[0] gt dim[0] ? new_dim[0] : dim[0] ) dim[1] = ( new_dim[1] gt dim[1] ? new_dim[1] : dim[1] ) endfor animate = CIPS_CW_ANIMATE(animation_base, dim[0], dim[1], n_elements(panel_stack.layers), MAX_VAL=stack_max) for i=0, n_elements(panel_stack.layers)-1 do begin new_dim = SIZE(*panel_stack.layers[i].image, /DIMENSIONS) CIPS_CW_ANIMATE_LOAD, animate, FRAME=i, IMAGE=*panel_stack.layers[i].image, $ XOFFSET=dim[0]-new_dim[0], YOFFSET=dim[1]-new_dim[1], MAX_VAL=stack_max endfor WIDGET_CONTROL, animation_base, /REALIZE CIPS_CW_ANIMATE_RUN, animate, 5 XMANAGER, 'stack_panel_event', animation_base, EVENT_HANDLER='animation_handler', /NO_BLOCK LOADCT, 39 END ; Set the show_coast variable and draw/undraw the coast lines 'SHOWCOASTBTN': BEGIN stack_window_options.show_coast = WIDGET_INFO(event.id, /BUTTON_SET) cips_global_options.stack_split = WIDGET_INFO(event.id, /BUTTON_SET) layout_param = oTool->FindIdentifiers('*layout*') layout_obj = oTool->GetByIdentifier(layout_param) layout_props = layout_obj->QueryProperty() layout_obj->GetProperty, VIEW_COLUMNS=cols layout_obj->GetProperty, VIEW_ROWS=rows if (stack_window_options.show_coast eq 1) then begin ; Change to 2x1 view and draw in the coast lines if (rows lt 2) then begin oView->GetProperty, DIMENSIONS=view_dims result = oTool->DoSetProperty(layout_param, 'SHOW_EXECUTION_UI', 0) result = oTool->DoSetProperty(layout_param, 'LAYOUT_INDEX', 1) result = oTool->DoSetProperty(layout_param, 'VIEW_COLUMNS', 1) result = oTool->DoSetProperty(layout_param, 'VIEW_ROWS', 2) result = oTool->DoSetProperty(layout_param, 'AUTO_RESIZE', 1) result = oTool->DoAction(layout_param) oTool->CommitActions endif restore, !COMMON_INPUT_DATA + '/coast.sav' if strcmp(panel_stack.stack.hemisphere, 'S') eq 1 then south=1 else south=0 project_lambert, lat=coast[1,*], lon=coast[0,*], x=x, y=y, $ center_lon=panel_stack.stack.center_lon, _extra=extra, south=south iplot, x, y, view_number=2, color=line_color, background_color=bg_color iimage, *panel_stack.layers[stack_window_options.curr_image_idx].image, $ VIEW_NUMBER=2, RGB_TABLE=[[r_orig], [g_orig], [b_orig]], /OVERPLOT, $ IMAGE_LOCATION=[(*panel_stack.stack.scene_bboxes)[stack_window_options.curr_image_idx, 0], $ (*panel_stack.stack.scene_bboxes)[stack_window_options.curr_image_idx, 1]] oView->SetCurrentZoom, 1 view_ID2 = oTool->FindIdentifiers('*VIEW_2') oView2 = oTool->GetByIdentifier(view_ID2) oView2->SetCurrentZoom, 2 plot_orbit_box endif else begin remove_stack_coastlines, oTool endelse exec_option = 0 END ; Set the show_solar_zenith_angles variable and draw/undraw the contours 'SHOWSZACONTOURSBTN': BEGIN stack_window_options.show_solar_zenith_angles = WIDGET_INFO(event.id, /BUTTON_SET) draw_stack_contours, oTool exec_option = 0 END 'SHOWSSABTN': BEGIN stack_window_options.show_scattering_angles = WIDGET_INFO(event.id, /BUTTON_SET) draw_stack_contours, oTool exec_option = 0 END 'SHOWVIEWANGLEBTN': BEGIN stack_window_options.show_view_angles = WIDGET_INFO(event.id, /BUTTON_SET) draw_stack_contours, oTool exec_option = 0 END 'SHOWALBEDOCONTOURSBTN': BEGIN stack_window_options.show_albedo_contours = WIDGET_INFO(event.id, /BUTTON_SET) draw_stack_contours, oTool exec_option = 0 END 'SHOWLATLONCONTOURSBTN':BEGIN stack_window_options.show_latlon_contours = WIDGET_INFO(event.id, /BUTTON_SET) draw_stack_contours, oTool exec_option = 0 END 'CLEARCONTOURSBTN':BEGIN widget_control, stack_panel_buttons.contour_btns, set_button = 0 stack_window_options.show_solar_zenith_angles = 0 stack_window_options.show_scattering_angles = 0 stack_window_options.show_view_angles = 0 exec_option = 1 END 'SHOWCOLORBARBTN': BEGIN cips_global_options.colorbar = WIDGET_INFO(event.id, /BUTTON_SET) update_colorbar exec_option = 0 END 'SHOWPLOTBTN': BEGIN ; Return on a button-release event if (event.select eq 0) then return ; if in coastline view, remove and change to 1x1 view if (stack_window_options.show_coast eq 1) then remove_stack_coastlines, oTool ; clear panel buttons that cause problems when going back to image view if (stack_window_options.view eq 'layer') then clear_stack_panel WIDGET_CONTROL, stack_panel_buttons.option_btns, SENSITIVE=0 WIDGET_CONTROL, stack_panel_buttons.contour_btns, SENSITIVE=0 stack_window_options.view = 'plot' exec_option = 2 END 'STARTDROP': BEGIN WIDGET_CONTROL, uvalue, /SET_BUTTON END 'STOPDROP': BEGIN WIDGET_CONTROL, uvalue, /SET_BUTTON END 'EXPORTBTN': BEGIN filename = dialog_pickfile(DIALOG_PARENT=event.handler, /WRITE, /OVERWRITE_PROMPT, path=!USER_DATA_PATH) if(strtrim(filename, 2) eq '') then begin void = dialog_message('Invalid file selection', /ERROR)& return endif data = panel_stack.stack num_elem = n_elements(panel_stack.layers) if WIDGET_INFO(uvalue.main_scene_btn, /BUTTON_SET) then begin ;-- Create range only including current image start_range = stack_window_options.curr_image_idx stop_range = stack_window_options.curr_image_idx endif else if WIDGET_INFO(uvalue.range_scene_btn, /BUTTON_SET) then begin ;-- Calculate proper range start_range = WIDGET_INFO(uvalue.start_drop,/DROPLIST_SELECT) if (start_range ne 0) then start_range -= 1 stop_range = WIDGET_INFO(uvalue.stop_drop,/DROPLIST_SELECT) if (stop_range eq 0) then stop_range = num_elem-1 $ else stop_range -= 1 if (start_range gt stop_range) then begin temp=start_range & start_range=stop_range & stop_range=temp endif endif ;-- Redefine pointer arrays in struct to fit the range tags = tag_names(data) for i=0, n_elements(tags)-1 do begin if (size(data.(i),/type) ne 10) then continue if ~(ptr_valid(data.(i))) then continue if n_elements(*(data.(i))) lt num_elem then continue data.(i) = ptr_new((*data.(i))[start_range:stop_range]) endfor SAVE, data, filename=filename END 'TV': BEGIN ; If event is a mouse-button-down event on one of the draw_widgets... IF event.press eq 1 THEN BEGIN ; if coming from another panel or switching from plot to image view, update colorbar if (stack_window_options.view eq 'plot') or (cips_global_options.curr_view ne 'stack') then begin case cips_global_options.curr_view of 'scenes' : if (scenes_window_options.view eq 'plot') then colorbar_needs_updating = 1 'stack' : if (stack_window_options.view eq 'plot') then colorbar_needs_updating = 1 'clouds' : if (cloud_window_options.view eq 'plot') then colorbar_needs_updating = 1 else : message, cips_global_options.curr_view + ' not found', /info endcase endif sensitize_stack_panel ; clear the windows result = [oTool->FindIdentifiers('*VIEW_1*SPACE/IMAGE*'), $ oTool->FindIdentifiers('*VIEW_1*VISUALIZATION LAYER/DATA SPACE')] if (cips_global_options.stack_split eq 1) then $ result = [result, oTool->FindIdentifiers('*VIEW_2*SPACE/IMAGE*')] for i=0, N_ELEMENTS(result)-1 do begin if result[i] ne '' then begin success = oTool->RemoveByIdentifier(result[i]) endif endfor ; keep track of which image is in window stack_window_options.curr_image_idx = uvalue.num-1 stack_window_options.view = 'layer' ; update min scaling WIDGET_CONTROL, state.min_contrast_slider, get_value=min_slider_value new_min = exp((min_slider_value/100.0) * alog(stack_max)) if new_min le 1 then new_min = 0 WIDGET_CONTROL, stack_panel_buttons.min_value_label, set_value=' '+strtrim(string(new_min, format='(f7.1)'),1) stack_window_options.scaling_min = new_min ; update max scaling WIDGET_CONTROL, state.max_contrast_slider, get_value=max_slider_value new_max = exp((max_slider_value/100.0) * alog(stack_max)) WIDGET_CONTROL, stack_panel_buttons.max_value_label, set_value=' '+strtrim(string(new_max, format='(f7.1)'),1) stack_window_options.scaling_max = new_max exec_option = 1 replace_title=1 ENDIF ELSE RETURN END ELSE: ENDCASE ; If we want to redraw... if exec_option eq 1 then begin ; replace title? if replace_title eq 1 then begin new_title = panel_stack.layers[stack_window_options.curr_image_idx].info result = oTool->FindIdentifiers('*VIEW_1*TEXT*') for i=0, N_ELEMENTS(result)-1 do begin if result[i] ne '' then begin success = oTool->RemoveByIdentifier(result[i]) endif endfor endif else new_title='' ; Redraw in the globe plot if (redraw_coast eq 1) then begin if n_elements(coast) eq 0 then restore, !COMMON_INPUT_DATA + '/coast.sav' if strcmp(panel_stack.stack.hemisphere, 'S') eq 1 then south=1 else south=0 project_lambert, lat=coast[1,*], lon=coast[0,*], x=x, y=y, $ center_lon=panel_stack.stack.center_lon, _extra=extra, south=south iplot, x, y, view_number=2, color=line_color, background_color=bg_color view_ID2 = oTool->FindIdentifiers('*VIEW_2') oView2 = oTool->GetByIdentifier(view_ID2) oView2->SetCurrentZoom, 2 plot_orbit_box endif ; setup scaling image = stack_window_options.scaling_min > *panel_stack.layers[stack_window_options.curr_image_idx].image < $ stack_window_options.scaling_max ; surface view if (stack_window_options.surf_view eq 1) then begin oView->SetCurrentZoom, 1 isurface, image, VIEW_TITLE=new_title, VIEW_NUMBER=1, BACKGROUND_COLOR=bg_color, $ XTEXT_COLOR=line_color, YTEXT_COLOR=line_color, ZTEXT_COLOR=line_color ; image view endif else begin iimage, image, VIEW_TITLE=new_title, VIEW_NUMBER=1, RGB_TABLE=[[r_orig], [g_orig], [b_orig]], $ BACKGROUND_COLOR=bg_color endelse if (colorbar_needs_updating eq 1) then update_colorbar draw_stack_contours, oTool ; Load the globe-positioned image if (stack_window_options.show_coast eq 1) then begin iimage, *((panel_stack.layers)[stack_window_options.curr_image_idx]).image, $ VIEW_NUMBER=2, RGB_TABLE=[[r_orig], [g_orig], [b_orig]], OVERPLOT=1, $ IMAGE_LOCATION=[(*panel_stack.stack.scene_bboxes)[stack_window_options.curr_image_idx, 0], $ (*panel_stack.stack.scene_bboxes)[stack_window_options.curr_image_idx, 1]] endif endif else if exec_option eq 2 then begin ; Delete all images/surface plots/colorbars in the current window result = [oTool->FindIdentifiers('*VIEW_*VISUALIZATION LAYER/DATA SPACE'), $ oTool->FindIdentifiers('*VIEW_*ANNOTATION LAYER/COLORBAR*'), $ oTool->FindIdentifiers('*VIEW_1*TEXT*')] for i=0, N_ELEMENTS(result)-1 do begin if result[i] ne '' then begin success = oTool->RemoveByIdentifier(result[i]) endif endfor setup_for_stack_plot, x_values, y_values, x_title, $ y_title, min_value, max_value, plot_title min_max = filter_sigma(y_values, 5) if((n_elements(max_value) ne 0)and(n_elements(min_value) ne 0)) then begin iplot, x_values, min_max[0]> y_values y_values SetCurrentZoom, 1.0 oView->Select, 1 endif END ; -------------------------------------------------------------------------- ; PROCEDURE init_thumbs_stack ; -------------------------------------------------------------------------- pro init_thumbs_stack COMMON VIEW_CIPS_STACK, panel_stack, layers_tvs, is_surface_stack, layers_thumb_max, stack_max ; Get widget IDs for the draw widgets then output the thumbnails if is_surface_stack eq 1 then begin for i=0, N_ELEMENTS(panel_stack.layers)-1 do begin WIDGET_CONTROL, *layers_tvs[i], GET_VALUE = TVID WSET, TVID SURFACE, *layers_tvs[i].thumbnail, $ shade=bytscl(*layers_tvs[i].thumbnail), $ XSTYLE = 4, YSTYLE = 4, ZSTYLE = 4 endfor endif else begin for i=0, N_ELEMENTS(panel_stack.layers)-1 do begin WIDGET_CONTROL, *layers_tvs[i], GET_VALUE = TVID WSET, TVID & TV, (*panel_stack.layers[i].thumbnail/layers_thumb_max)*255 endfor endelse WSET, 0 WDELETE end ; -------------------------------------------------------------------------- ; PROCEDURE init_stack_panel ; -------------------------------------------------------------------------- PRO init_stack_panel, widgetID COMMON RETRIEVED_CLOUD_BTNS, cloud_panel_buttons COMMON L1C_STACK_PANEL_BTNS, l1c_stack_panel_buttons init_thumbs_stack ; highest level data products have precedence on startup... ; so only sensitize the stack panel if a retrieved cloud panel doesn't exist if (n_elements(cloud_panel_buttons) eq 0) and (n_elements(l1c_stack_panel_buttons) eq 0) then begin sensitize_stack_panel void = ITGetCurrent(tool=oTool) font_param = oTool->FindIdentifiers('*STYLE/ANNOTATIONS/TEXT*') result = oTool->DoSetProperty(font_param, 'FONT_SIZE', 20) result = oTool->DoSetProperty(font_param, 'COLOR', [0,0,0]) oTool->CommitActions endif END ; -------------------------------------------------------------------------- ; PROCEDURE set_x_axis_plot_stack ; -------------------------------------------------------------------------- pro set_x_axis_plot_stack, event COMMON STACK_WINDOW_STATE, stack_window_options CASE event.str OF 'Solar Zenith Angle': stack_window_options.xplot = 'zenith_angle' 'Scattering Angle': stack_window_options.xplot = 'scattering_angle' 'Viewing Angle': stack_window_options.xplot = 'view_angle' ELSE: print, 'x-axis value not implemented' ENDCASE return end ; -------------------------------------------------------------------------- ; PROCEDURE set_y_axis_plot_stack ; -------------------------------------------------------------------------- pro set_y_axis_plot_stack, event COMMON STACK_WINDOW_STATE, stack_window_options CASE event.str OF 'Albedo': stack_window_options.yplot = 'albedo' ELSE: print, 'y-axis value not implemented' ENDCASE return end ; -------------------------------------------------------------------------- ; PROCEDURE stack_panel_shutdown ; -------------------------------------------------------------------------- pro stack_panel_shutdown, base COMMON VIEW_CIPS_STACK, panel_stack, layers_tvs, is_surface_stack, layers_thumb_max, stack_max delete_var, panel_stack delete_var, layers_tvs delete_var, is_surface_stack delete_var, layers_thumb_max COMMON STACK_WINDOW_STATE, stack_window_options delete_var, stack_window_options COMMON STACK_PANEL_BTNS, stack_panel_buttons delete_var, stack_panel_buttons return end ; -------------------------------------------------------------------------- ; PROCEDURE stack_panel ; -------------------------------------------------------------------------- PRO stack_panel, wPanel, oUI COMMON VIEW_CIPS_STACK, panel_stack, layers_tvs, is_surface_stack, layers_thumb_max, stack_max ; Init the panel WIDGET_CONTROL, wPanel, BASE_SET_TITLE = panel_stack.panel_name WIDGET_CONTROL, wPanel, kill_notify='stack_panel_shutdown' WIDGET_CONTROL, wPanel, EVENT_PRO = "stack_panel_event" strObserverIdentifier = oUI->RegisterWidget(wPanel, "Panel", 'stack_panel_callback') ; Register to receive selection events on visualizations oUI->AddOnNotifyObserver, strObserverIdentifier, 'Visualization' ; Get reference to current iTool oTool = oUI->GetTool() ; Create base widget wBase = WIDGET_BASE(wPanel, /COLUMN, SPACE = 10, /BASE_ALIGN_CENTER, $ NOTIFY_REALIZE='init_stack_panel') ; options options_base_stack = WIDGET_BASE(wBase, /COLUMN, /FRAME, UNAME='WINDOWBASE', xsize=250, /align_left) label = widget_label(options_base_stack, value='-- Options --') options_check_base_stack = widget_base(options_base_stack, /NONEXCLUSIVE, /COLUMN) check_black_bg_base = widget_base(options_base_stack, /NONEXCLUSIVE, /COLUMN) show_black_bg_btn = widget_button(options_check_base_stack, value='Black Background', $ UNAME='SHOWBLACKBGBTN', /ALIGN_LEFT) show_colorbar_btn = widget_button(options_check_base_stack, value='Insert Colorbar', $ UNAME='SHOWCOLORBARBTN', /ALIGN_LEFT) show_surf_view_btn = widget_button(options_check_base_stack, value='Surface View', /ALIGN_LEFT, $ UNAME='SHOWSURFACEBTN') show_map_proj_btn = widget_button(options_check_base_stack, value='Show Coastlines', $ UNAME='SHOWCOASTBTN', /ALIGN_LEFT) show_cvo_btn = widget_button(options_check_base_stack, value='Show Common Volume', $ UNAME='SHOWCVOBTN', /ALIGN_LEFT) ; scaling contrast_base_stack = widget_base(wBase, /COLUMN, /FRAME, UNAME='CONTRASTBASE', xsize=250, /align_left) label = widget_label(contrast_base_stack, value='-- Scaling --') horiz_base = widget_base(contrast_base_stack, /ROW, UNAME='MAXCONTRASTBASE', xsize=250, /align_left) label = widget_label(horiz_base, value='Max Value: ') max_contrast_slider = widget_slider(horiz_base, /SUPPRESS_VALUE, minimum=0, maximum=100, uname='MAXCONTRASTSLIDER', value=100) max_value_label = widget_label(horiz_base, value=' '+strtrim(string(stack_max, format='(f7.1)'),1), xsize=70) horiz_base = widget_base(contrast_base_stack, /ROW, UNAME='MINCONTRASTBASE', xsize=250, /align_left) label = widget_label(horiz_base, value='Min Value: ') min_contrast_slider = widget_slider(horiz_base, /SUPPRESS_VALUE, minimum=0, maximum=100, uname='MINCONTRASTSLIDER', value=0) min_value_label = widget_label(horiz_base, value=' 0.0', xsize=70) ; animation animation_base_stack = widget_base(wBase, /COLUMN, /BASE_ALIGN_CENTER, /FRAME, xsize=250) animation_base = widget_base(animation_base_stack, /COLUMN) label = widget_label(animation_base, value='--- Animation ---') animation_btn = widget_button(animation_base, value=' Animate ', UNAME='ANIMATE') horiz_base = widget_base(animation_base, /ROW) label = widget_label(horiz_base, value='Color:') animation_droplist = widget_droplist(horiz_base, value=['0: B-W LINEAR','39: Rainbow + white']) WIDGET_CONTROL, animation_btn, SET_UVALUE=animation_droplist ; contour plot selection contours_base_stack = widget_base(wBase, /COLUMN, /FRAME, UNAME='CONTOURSBASE', xsize=250, /align_center) contours_label = widget_label(contours_base_stack, value='-- Contour Plots --') contours_opts = widget_base(contours_base_stack, /COLUMN, /ALIGN_LEFT, /EXCLUSIVE) clear_contours_btn = widget_button(contours_opts, value='None', $ UNAME='CLEARCONTOURSBTN', /ALIGN_LEFT) show_sza_contours_btn = widget_button(contours_opts, value='Solar Zenith Angles - Rayleigh Peak', $ UNAME='SHOWSZACONTOURSBTN', /ALIGN_LEFT) show_ssa_contours_btn = widget_button(contours_opts, value='Scattering Angles', $ UNAME='SHOWSSABTN', /ALIGN_LEFT) show_view_contours_btn = widget_button(contours_opts, value='Viewing Angles - Rayleigh Peak', $ UNAME='SHOWVIEWANGLEBTN', /ALIGN_LEFT) ;show_alb_contours_btn = widget_button(contours_opts, value='Albedo', $ ; UNAME='SHOWALBEDOCONTOURSBTN', /ALIGN_LEFT) show_latlon_contours_btn = widget_button(contours_opts, value='Lat/Lon', $ UNAME='SHOWLATLONCONTOURSBTN', /ALIGN_LEFT) ; scatter plot selection plot_base_stack = widget_base(wbase, /COLUMN, /FRAME, UNAME='PLOTBASE', /BASE_ALIGN_CENTER, xsize=250) plot_label = widget_label(plot_base_stack, value='-- Scatter Plots --') temp_base = widget_base(plot_base_stack, /ROW) x_label = widget_label(temp_base, value='x-axis ') xdroplist = widget_combobox(temp_base, UNAME='XDROP', EVENT_PRO='set_x_axis_plot_stack', $ value=['Solar Zenith Angle', 'Scattering Angle', 'Viewing Angle']) temp_base = widget_base(plot_base_stack, /ROW) y_label = widget_label(temp_base, value='y-axis ') ydroplist = widget_combobox(temp_base, UNAME='YDROP', EVENT_PRO='set_y_axis_plot_stack', $ value=['Albedo ']) y_label_geom = WIDGET_INFO(y_label, /geom, units=0) ydroplist_geom = WIDGET_INFO(ydroplist, /geom, units=0) showplot_btn = widget_button(plot_base_stack, value='Show Plot', UNAME='SHOWPLOTBTN', xsize=195) WIDGET_CONTROL, plot_base_stack, set_uvalue={xdroplist : xdroplist, ydroplist : ydroplist} ; Export data export_base_stack = widget_base(wBase, /COLUMN, /FRAME, UNAME='EXPORTBASE', /BASE_ALIGN_CENTER, xsize=250) export_label = widget_label(export_base_stack, value='--- Export Data ---') export_select_base = widget_base(export_base_stack, /ROW, /BASE_ALIGN_TOP) radio_base = widget_base(export_select_base, /COLUMN, /EXCLUSIVE) main_scene_btn = widget_button(radio_base, value=' ', UNAME='MAINSCENE') range_scene_btn = widget_button(radio_base, value=' ', UNAME='RANGESCENE') WIDGET_CONTROL, main_scene_btn, /SET_BUTTON scene_list = panel_stack.layers.info for i=0, n_elements(scene_list)-1 do begin temp_string = strsplit(scene_list[i], '- ', /EXTRACT) scene_list[i] = (strtrim(i+1,2)+' - '+temp_string[1]) endfor dropdown_base = widget_base(export_select_base, /COLUMN, /BASE_ALIGN_LEFT) label = widget_label(dropdown_base, value='Main Window Scene') start_drop = widget_droplist(dropdown_base, value=['Start Range',scene_list],$ UNAME='STARTDROP', UVALUE=range_scene_btn) stop_drop = widget_droplist(dropdown_base, value=['Stop Range',scene_list],$ UNAME='STOPDROP', UVALUE=range_scene_btn) export_var_btn = widget_button(export_base_stack, value='Export Data', UNAME='EXPORTBTN', $ xsize=195, /align_center, UVALUE={ main_scene_btn: main_scene_btn ,$ range_scene_btn: range_scene_btn ,$ start_drop: start_drop ,$ stop_drop: stop_drop }) ; Create an array of pointers to all the draw widgets in the panel thumbnail_base = WIDGET_BASE(wBase, /COLUMN, UNAME='THUMBSBASE', /BASE_ALIGN_CENTER, xsize=250) num_thumbs = N_ELEMENTS(panel_stack.layers) layers_tvs = ptrarr(num_thumbs, /allocate_heap) for i=0, num_thumbs-1 do begin dimensions = size(*panel_stack.layers[i].thumbnail, /DIMENSIONS) layers_tvs[i] = ptr_new(widget_draw(thumbnail_base, xsize=dimensions[0], $ ysize=dimensions[1], /BUTTON_EVENTS, RETAIN=2, $ /ALIGN_CENTER, UNAME='TV', UVALUE = {id:'TV', num:i+1})) void = widget_label(thumbnail_base, VALUE = panel_stack.layers[i].info) void = widget_label(thumbnail_base, VALUE = "") endfor ; Create state structure in first child state = { oTool:oTool, $ oUI:oUI, $ wPanel:wPanel, $ wBase:wBase, $ show_black_bg_btn:show_black_bg_btn, $ show_colorbar_btn:show_colorbar_btn, $ show_surf_view_btn:show_surf_view_btn, $ show_cvo_btn:show_cvo_btn, $ max_contrast_slider:max_contrast_slider, $ max_value_label:max_value_label, $ min_value_label:min_value_label, $ min_contrast_slider:min_contrast_slider, $ plot_base_stack:plot_base_stack, $ showplot_btn:showplot_btn, $ clear_contours_btn:clear_contours_btn, $ show_sza_contours_btn:show_sza_contours_btn, $ show_ssa_contours_btn:show_ssa_contours_btn, $ show_view_contours_btn:show_view_contours_btn, $ ; show_alb_contours_btn:show_alb_contours_btn, $ show_latlon_contours_btn:show_latlon_contours_btn, $ show_map_proj_btn:show_map_proj_btn, $ export_var_btn:export_var_btn, $ thumbnail_base:thumbnail_base, $ TVs:layers_tvs $ } wChild = WIDGET_INFO(wPanel, /CHILD) IF wChild NE 0 THEN $ WIDGET_CONTROL, wChild, SET_UVALUE = state, /NO_COPY ; Add the wPanel object to the data manager ; Create the IDLitDataObject oPanel = OBJ_NEW('IDLitData', wPanel, IDENTIFIER = 'PANELSTACK') ; Add the data object to the data manager oTool->AddByIdentifier, '/Data Manager', oData COMMON STACK_PANEL_BTNS, stack_panel_buttons stack_panel_buttons = {option_btns: options_base_stack, $ colorbar_btn: show_colorbar_btn, $ black_bg_btn: show_black_bg_btn, $ surf_view_btn: show_surf_view_btn, $ show_cvo_btn:show_cvo_btn, $ contrast_sliders:contrast_base_stack, $ animation_controls:animation_base_stack, $ max_value_label:max_value_label, $ min_value_label:min_value_label, $ contour_btns: contours_base_stack, $ map_proj_btn: show_map_proj_btn, $ plot_base: plot_base_stack, $ sza_contours_btn:show_sza_contours_btn, $ scattering_contours_btn:show_ssa_contours_btn, $ view_contours_btn:show_view_contours_btn, $ export_base:export_base_stack $ } END