; pro kill_bases,info,tlb=tlb ; ; Destroy base widgets if they exist. If tlb is set ; destroy it as well (it is top level base for the ; application). ; ; File info base: widget_control,info.finfo_id,/destroy,bad_id=badid ; ; Kill map bases: ; map_ids = *info.pmap_ids for i=0,n_elements(map_ids)-1 do begin widget_control,map_ids(i),/destroy,bad_id=badid endfor ; ; Kill lat and lon slice bases: ; lon_ids = *info.plon_ids for i=0,n_elements(lon_ids)-1 do begin widget_control,lon_ids(i),/destroy,bad_id=badid endfor lat_ids = *info.plat_ids for i=0,n_elements(lat_ids)-1 do begin widget_control,lat_ids(i),/destroy,bad_id=badid endfor ; ; Kill utvert bases: ; utvert_ids = *info.putvert_ids for i=0,n_elements(utvert_ids)-1 do begin widget_control,utvert_ids(i),/destroy,bad_id=badid endfor ; ; Kill line bases: ; line_ids = *info.pline_ids for i=0,n_elements(line_ids)-1 do begin widget_control,line_ids(i),/destroy,bad_id=badid endfor ; ; Kill animate bases: ; anim_ids = *info.panim_ids for i=0,n_elements(anim_ids)-1 do begin if anim_ids(i) gt 0 then begin animid = long(anim_ids(i)) validbase = widget_info(animid,/valid_id) if validbase gt 0 then begin animbase = widget_info(animid,/parent) widget_control,animbase,/destroy,bad_id=badid widget_control,anim_ids(i),/destroy,bad_id=badid anim_ids(i) = 0 endif endif endfor *info.panim_ids = anim_ids ; ; If tlb keyword is set, kill main app top level base: ; if keyword_set(tlb) then widget_control,tlb,/destroy end ;----------------------------------------------------------------------- function openfile,file ; ; Open netcdf file. If successful, return cdfid, ; otherwise return -1. ; on_ioerror,badfile print, 'file', file cdfid = ncdf_open(file) print,'Opened file ',file print, 'file id', cdfid return,cdfid badfile: print,' ' print,'>>> openfile: error opening file ',file print,' (may not be a netcdf file)' return,-1 end ; ; The following subroutines handle the top level events including input file ; and plotting types ; ;----------------------------------------------------------------------- function mtime_to_mins,mtime ; model time to integer minutes return,long(mtime(0))*24*60+long(mtime(1))*60+long(mtime(2)) end ;----------------------------------------------------------------------- ; ; The following subroutines handle the top level events including input file ; and plotting types ; ;----------------------------------------------------------------------- pro finfo_event,event ; ; Respond to file info request. Call pro fileinfo to display ; an ncdump of the file in a scrollable text widget. This pro ; will update info.finfo_id. ; widget_control,event.top,get_uvalue=infoptr info = *infoptr ; ; If a fileinfo base already exists, destroy it: widget_control,info.finfo_id,/destroy,bad_id=badid ; ; Make new (or first) file info base: fileinfo,*infoptr end ;----------------------------------------------------------------------- pro plotmaps_event,event widget_control,event.top,get_uvalue=infoptr info = *infoptr if (strlen(strcompress(info.file,/remove_all)) le 0) then begin print,'>>> maps: no file!' return endif maps,*infoptr end ;----------------------------------------------------------------------- pro lonslices_event,event widget_control,event.top,get_uvalue=infoptr info = *infoptr if (strlen(strcompress(info.file,/remove_all)) le 0) then begin print,'>>> lonslices: no file!' return endif lons,*infoptr end ;----------------------------------------------------------------------- pro latslices_event,event widget_control,event.top,get_uvalue=infoptr info = *infoptr if (strlen(strcompress(info.file,/remove_all)) le 0) then begin print,'>>> latslices: no file!' return endif lats,*infoptr end ;----------------------------------------------------------------------- ;added by Tom Freeston on 6/30/03 to add a ut vs. vertical plot pro utvertical_event,event widget_control,event.top,get_uvalue=infoptr info = *infoptr fields = *info.fields if (strlen(strcompress(info.file,/remove_all)) le 0) then begin print,'>>> utverticalslices: no file!' return endif if fields[0].ntime gt 1 then begin utverts,*infoptr endif else begin print,'>>> not enough to model times to plot' endelse end ;----------------------------------------------------------------------- ;Do profile line plots ; PRO profile_event,event ; ; Set up profile widget ; widget_control,event.top,get_uvalue=infoptr info = *infoptr fields = *info.fields ; ;Check for input file ; if (strlen(strcompress(info.file,/remove_all)) le 0) then begin print,'>>> profile: no file!' return endif ; ; Set variable to identify type of line plot ; linetype = 'profile' ; ; Get data for line plots and plot ; profs,*infoptr, linetype END ;----------------------------------------------------------------------- ;Do meridional line plots ; PRO meridional_event,event ; ; Set up meridional widget ; widget_control,event.top,get_uvalue=infoptr info = *infoptr fields = *info.fields ; ;Check for input file ; if (strlen(strcompress(info.file,/remove_all)) le 0) then begin print,'>>> profile: no file!' return endif ; ; Set variable to identify type of line plot ; linetype = 'meridional' ; ; Get data for line plots and plot ; meridional,*infoptr, linetype END ;----------------------------------------------------------------------- ;Do zonal line plots ; PRO zonal_event,event ; ; Set up zonal widget ; widget_control,event.top,get_uvalue=infoptr info = *infoptr fields = *info.fields ; ;Check for input file ; if (strlen(strcompress(info.file,/remove_all)) le 0) then begin print,'>>> profile: no file!' return endif ; ; Set variable to identify type of line plot ; linetype = 'zonal' ; ; Get data for line plots and plot ; zonal,*infoptr, linetype END ;----------------------------------------------------------------------- ;Do time line plots ; PRO times_event,event ; ; Set up time widget ; widget_control,event.top,get_uvalue=infoptr info = *infoptr ; ;Check for input file ; if (strlen(strcompress(info.file,/remove_all)) le 0) then begin print,'>>> profile: no file!' return endif ; ; Set variable to identify type of line plot ; linetype = 'time' ; ; Get data for line plots and plot ; times,*infoptr, linetype END ;----------------------------------------------------------------------- FUNCTION ncdf_isopen, ncid CATCH, ERR IF ERR NE 0 THEN BEGIN CATCH, /CANCEL MESSAGE, /RESET RETURN, 0 ENDIF !NULL = NCDF_INQUIRE( ncid ) return, 1 END ;----------------------------------------------------------------------- pro openfile_event,event ; ; Respond to open file request: ; ; Get state info: ; widget_control,event.top,get_uvalue=infoptr info = *infoptr ; ; Select file: ; files = dialog_pickfile(/must_exist,/read,/multiple_files,$ get_path=path,filter='*.nc',title='Please select one or more files') if files[0] eq '' then return ; user probably hit 'cancel' in pickfile file = files[0] info.nfiles = n_elements(files) info.openpath = path *info.files = files *infoptr = info ; ; Check if file is open and close before opening another file ; if info.cdfid ge 0 then begin ncfstat = ncdf_isopen(info.cdfid) if ncfstat ne 0 then begin print,'Closing file ',info.file,' (cdfid=',info.cdfid,')' ncdf_close,info.cdfid endif info.cdfid = -1 endif ; ; Call pro openfile to open (first) netcdf file: ; info.cdfid = openfile(file) ; if (info.cdfid lt 0) then begin info.cdfid = -1 widget_control,info.pmenu_id,sensitive=0 return ; open failed endif ; ; Use existence of mtime variable to confirm tgcm history file or nsteph variable ; to confirm waccm file: ; if (ncdf_varid(info.cdfid,'mtime') eq -1) AND (ncdf_varid(info.cdfid,'nsteph') eq -1) then begin print,' ' print,'>>> WARNING: This is apparently not a TGCM or WACCM history file',$ ' (mtime or nsteph var is missing)' print,' ' widget_control,info.pmenu_id,sensitive=0 info.cdfid = -1 return endif fileType = ' ' IF ncdf_varid(info.cdfid,'mtime') ne -1 THEN BEGIN fileType = 'TGCM' print, ' ' print, 'This is a TIME-GCM history file ' print, ' ' ENDIF ELSE if ncdf_varid(info.cdfid,'nsteph') ne -1 THEN BEGIN fileType = 'WACCM' print, ' ' print, 'This is a WACCM history file ' print, ' ' ENDIF ELSE BEGIN PRINT, 'This file is not supported ' RETURN ENDELSE info.ftype = fileType ; ; Update state info: info.file = file *infoptr = info ; ; Destroy any pre-existing bases: kill_bases,info ;widget_control,info.groupleader,/destroy ; ; Reset file label: ; flabel_text = 'File: '+file widget_control,info.flabel_id,set_value=flabel_text ; ; Plot menu is insenitive while reading the file: widget_control,info.pmenu_id,sensitive=0 ; ; Read the file (define array of field structures in info.fields, ; not including field data). Different read routines for TIME-GCM ; and WACCM and read vertical coordinate with Z for TIME-GCM and Z3 ; for WACCM: ; widget_control,event.top,hourglass=1 IF info.ftype eq 'TGCM' THEN BEGIN ; ; Read TGCM file ; readfile,info ; ; Save unprocessed Z from history (info.z_hist) for TGCM file: ; ixz = -1 fields = *info.fields for i=0,info.nflds-1 do begin if (fields[i].name eq 'Z') then ixz = i endfor if ixz eq -1 then begin print,'>>> WARNING tgcmproc: could not find field Z' endif else begin ncdf_varget,info.cdfid,fields[ixz].idvar,ncdata info.z_hist = ptr_new(ncdata) ;print,'tgcmproc: info.z_hist min,max=',min(*info.z_hist),max(*info.z_hist) endelse ENDIF ELSE BEGIN ; ; Read WACCM file ; readfilew,info ; ; Save unprocessed Z from history (info.z_hist): ; ixz = -1 fields = *info.fields for i=0,info.nflds-1 do begin if (fields[i].name eq 'Z3') then ixz = i endfor if ixz eq -1 then begin print,'>>> WARNING tgcmproc: could not find WACCM field Z3' endif else begin ncdf_varget,info.cdfid,fields[ixz].idvar,ncdata z3data = ncdata vertreverse, info, ncdata, z3data info.z_hist = ptr_new(z3data) ;print,'tgcmproc: info.z_hist min,max=',min(*info.z_hist),max(*info.z_hist) endelse ENDELSE ; ; Make Plot menu visible: ; widget_control,info.pmenu_id,/sensitive widget_control,event.top,hourglass=0 ; ; Save state: *infoptr = info return end ;----------------------------------------------------------------------- pro tgcmproc_event,event ; ; Main event handler for tgcmproc. ; widget_control,event.top,get_uvalue=infoptr info = *infoptr widget_control,event.id,get_uvalue=widget case widget of 'EXIT': begin kill_bases,info,tlb=event.top ; widget_control,info.groupleader,/destroy ; widget_control,event.top,/destroy end 'SUBMIT_F90': begin print,'Submit an f90 tgcmproc job..' submit_f90,info end else: begin print,'>>> tgcmproc_event: unknown widget ',widget end endcase done: ; ; Save state information: *infoptr = info end ;----------------------------------------------------------------------- pro tgcmproc ; ; Main pro: Create base window. ; ; Check for widget support: if ((!d.flags and 65536) eq 0) then $ message, 'Widgets are not supported on this device' ; device,decomposed=0,retain=2 ; 8-bit pseudocolor mode ; ; Check display: ;device,get_visual_name=name ;device,get_visual_depth=depth ;device,get_decomposed=mode ;print,'name,depth,mode=',name,depth,mode ;help,/device ; ; Top level base: ; tlb_width = 550 title = 'tgcmproc' tlb = widget_base(column=1,mbar=mbar,title=title,xsize=tlb_width) ; ; File menu: ; fmenu = widget_button(mbar,value='File(s)') butt1 = widget_button(fmenu,value='Select...',uvalue='SELECT',$ event_pro='openfile_event') ;openpath = '/vishnu/e/foster/tgcmproc' ;openpath = '/vishnu/e/foster/tiegcm1' ;openpath = '/vishnu/e/foster/tgcm24' ;openpath = '/vishnu/e/foster/tiegcm-hist-lbc' ;openpath = '/vishnu/e/foster/tiegcm1.8' openpath = '.' butt2 = widget_button(fmenu,value='Info...',uvalue='INFO',$ event_pro='finfo_event') ; ; Plots: ; ; Added a button for line plots and types ; pmenu = widget_button(mbar,value='Plot',sensitive=0) butt1 = widget_button(pmenu,value='Maps...',uvalue='MAPS',$ event_pro='plotmaps_event') map_ids = intarr(50) butt2 = widget_button(pmenu,value='Lon Slices...',uvalue='LONSLICES',$ event_pro='lonslices_event') butt3 = widget_button(pmenu,value='Lat Slices...',uvalue='LATSLICES',$ event_pro='latslices_event') ; added by Tom Freestone 6/30/03 butt4 = widget_button(pmenu,value='UT vs. Vertical...',uvalue='UTVERT',$ event_pro='utvertical_event') lmenu = widget_button(pmenu,value='Line Plots...',/MENU) lButt1 = widget_button(lmenu,value='Profiles',uvalue='PROFILES',$ event_pro='profile_event') lButt2 = widget_button(lmenu,value='Meridional Trace',uvalue='MERIDIONAL',$ event_pro='meridional_event') lButt3 = widget_button(lmenu,value='Zonal Trace',uvalue='ZONAL',$ event_pro='zonal_event') lButt4 = widget_button(lmenu,value='Time Trace',uvalue='TIMES',$ event_pro='times_event') lon_ids = intarr(50) lat_ids = intarr(50) utvert_ids = intarr(50) line_ids = intarr(50) anim_ids = intarr(100) ; ; Batch (submit f90 job): ; 5/15/03: this is not complete yet... ; ;batchmenu = widget_button(mbar,value='Batch') ;button = widget_button(batchmenu,value='Submit f90 tgcmproc job...',$ ; uvalue='SUBMIT_F90') ; ; Exit: exit = widget_button(mbar,value='Exit') butt6 = widget_button(exit,value='Exit',uvalue='EXIT') ; file = ' '+$ ' ' flabel_text = 'File: '+file ;flabel_id = widget_label(tlb,value=flabel_text,/dynamic_resize,$ ; /align_left,/frame) flabel_id = widget_label(tlb,value=flabel_text,xsize=tlb_width,$ /align_left,/frame) ftype = ' ' ; ; This does not appear to work as of 3/14/03 -- when either maps or ; lons try to use groupleader as a group_leader, idl stops with an ; invalid widget id error. ; ;groupleader = widget_base(tlb) ;print,'tgcmproc: groupleader=',groupleader ; ; Realize base: widget_control,tlb,/realize ; ; Create state information structure: info = { $ file:file, $ ; current open netcdf file openpath:openpath, $ ; path for diaglog_pickfile files:ptr_new(/allocate_heap), $ input files from pickfile nfiles:0, $ total number of files ntimes:0, $ total times on all files mtimes:ptr_new(/allocate_heap), $ mtimes from all files (3,ntimes) mtime_files:ptr_new(/allocate_heap), $ mtimes on each file (3,mxtimes_file,nfiles) ntime_files:ptr_new(/allocate_heap), $ number of times on each file mtime_beg:[0,0,0], $ starting mtime ifile_beg:0, $ index to file containing start mtime mtime_end:[0,0,0], $ ending mtime ifile_end:0, $ index to file containing end mtime flabel_id:flabel_id, $ ; file label widget id finfo_id:0, $ ; file info widget base id cdfid:-1L, $ ; netcdf file id ftype:ftype, $ ; netcdf file type diffs:0, $ ; > 0 if difference fields pmap_ids:ptr_new(map_ids), $ ; pointer to map widget base ids plon_ids:ptr_new(lon_ids), $ ; pointer to lon slice widget base ids plat_ids:ptr_new(lat_ids), $ ; pointer to lat slice widget base ids putvert_ids:ptr_new(utvert_ids), $ ; pointer to utvert widget base ids pline_ids:ptr_new(line_ids), $ ; pointer to line slice widget base ids panim_ids:ptr_new(anim_ids), $ pointer to animate widgets pmenu_id:pmenu, $ plot menu id nflds:0, $ number of fields on the file nflds1D:0, $ number of 1D fields on the file colortab:5, $ color table index tlb:tlb, $ widget id of top level base groupleader:-1, $ group leader of all tlb bases (maps, lons, etc) fields:ptr_new(/allocate_heap), $ ; ptr to field structures (see readfile.pro) fields1D:ptr_new(/allocate_heap), $ ; ptr to 1D field structures (see readfile.pro) z_hist:ptr_new(/allocate_heap), $ ; unprocessed 4d Z from history pfile:ptr_new(/allocate_heap), $ ; ptr to file structure (see readfile.pro) pmap:ptr_new(/allocate_heap), $ ; ptr to map structure plon:ptr_new(/allocate_heap), $ ; ptr to lon structure plat:ptr_new(/allocate_heap), $ ; ptr to lat structure putvert:ptr_new(/allocate_heap),$ ; ptr to utvert structure pline:ptr_new(/allocate_heap) $ ; ptr to line structure } ;utvert pointers added on 6/30/03 by Tom Freestone ; ; Load color table: setclrtab,info.colortab ; ; User value for main tlb is pointer to state info structure: infoptr = ptr_new(info) widget_control,tlb,set_uvalue=infoptr ; ; Start event manager: xmanager,'tgcmproc',tlb,/no_block end