; ;----------------------------------------------------------------------- pro anim_event,event ; ; Event handler for animation window: ; case event.action of "DONE": begin widget_control,event.top,/destroy return end else: print,'anim_event: Unknown action: ',event.action endcase return end ;----------------------------------------------------------------------- pro lons_event,event widget_control,event.id,get_uvalue=widget widget_control,event.top,get_uvalue=pinfo info = *pinfo lon = *info.plon fields = *info.fields field = fields[lon.ifield] mag = 0 & if field.grid_type eq 'magnetic' then mag = 1 ; case widget of 'CLOSE': widget_control,event.top,/destroy 'SELECT_LON': begin lon.slon = event.value lon.sslt = fslt(lon.sslt,lon.ut,lon.slon,'getlt',mag=mag) widget_control,lon.wfsl_slt,set_value=lon.sslt if lon.zonalmean eq 1 then lon.zonalmean = 0 ; turn off zonal means data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'SELECT_SLT': begin lon.sslt = event.value lon.slon = fslt(lon.sslt,lon.ut,lon.slon,'getlon',mag=mag) if lon.zonalmean eq 1 then lon.zonalmean = 0 ; turn off zonal means lons = *fields[lon.ifield].lons ; ; If exact lon corresponding to slt is not found in lons array, ; set it to nearest lon within lons: if ixfind(lons,lon.slon,0.) lt 0 then begin lons = *fields[lon.ifield].lons dlon = lons[1]-lons[0] ilon = ixfind(lons,lon.slon,dlon) lon.slon = lons[ilon] endif else begin endelse widget_control,lon.wfsl_lon,set_value=lon.slon data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'COLOR': begin clrtab = xcolor(info.colortab,event.top) info.colortab = clrtab pltlon,info end 'SELECT_WVN': begin lon.wavenumber = event.value print, 'Setting wavenumber to ', lon.wavenumber *info.plon = lon end 'SELECT_FRQ': begin lon.frequency = event.value print, 'Setting frequency to ', lon.frequency *info.plon = lon end 'SELECT_WVN_FRQ': begin lon.ampphs = 0 widget_control,event.top,hourglass=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate widget_control,event.top,hourglass=0 *info.plon = lon pltlon,info end 'LOG10': begin lon.log10 = 'density fields' data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate ; ; Reset min,max and contour interval: fminmax,*lon.data,fmin,fmax,lon.missing_value cmin=0. & cmax=0. & cint=0. *lon.clevels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint *info.plon = lon print,'Will plot log10 of density fields' pltlon,info end 'LOG10_ALLFIELDS': begin lon.log10 = 'all fields' data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate ; ; Reset min,max and contour interval: fminmax,*lon.data,fmin,fmax,lon.missing_value cmin=0. & cmax=0. & cint=0. *lon.clevels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint *info.plon = lon print,'Will plot log10 of all fields' pltlon,info end 'LINEAR': begin lon.log10 = 'none' data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate ; ; Reset min,max and contour interval: fminmax,*lon.data,fmin,fmax,lon.missing_value cmin=0. & cmax=0. & cint=0. *lon.clevels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint *info.plon = lon print,'Will plot linear fields (no log10)' pltlon,info end 'ZONAL_MEAN_ON': begin print,'Plotting zonal mean..' lon.zonalmean = 1 ; deflondata and pltlon will check for this data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'ZONAL_MEAN_OFF': begin print,'Turning zonal mean off..' lon.zonalmean = 0 ; deflondata and pltlon will check for this data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'AMPLITUDE_ON_LINEAR': begin print,'Plotting wavenumber amplitude..' lon.zonalfreq = 0 ; Make sure 2D amplitude/phase is off lon.amplitude = 1 ; deflondata and pltlon will check for this widget_control, lon.wfsl_lon, sensitive=0 widget_control, lon.wfsl_slt, sensitive=0 widget_control, lon.wfsl_wvn, sensitive=0 widget_control, lon.wfsl_frq, sensitive=0 widget_control, lon.wfsl_wvn1, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'AMPLITUDE_ON_LOG': begin print,'Plotting log wavenumber amplitude..' lon.zonalfreq = 0 ; deflondata and pltlon will check for this lon.amplitude = 2 ; deflondata and pltlon will check for this widget_control, lon.wfsl_lon, sensitive=0 widget_control, lon.wfsl_slt, sensitive=0 widget_control, lon.wfsl_wvn, sensitive=0 widget_control, lon.wfsl_frq, sensitive=0 widget_control, lon.wfsl_wvn1, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'AMPLITUDE_OFF': begin print,'Turning wavenumber amplitude off..' lon.amplitude = 0 ; deflondata and pltlon will check for this widget_control, lon.wfsl_wvn1, sensitive=0 widget_control, lon.wfsl_lon, sensitive=1 widget_control, lon.wfsl_slt, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN BEGIN getzlatlonut,info,lon,'lon',fields,zalt fminmax,*lon.data,fmin,fmax,lon.missing_value cmin=0. & cmax=0. & cint=0. *lon.clevels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint ENDIF *info.plon = lon pltlon,info end '2D_AMPLITUDE_ON_LINEAR': begin if field.ntime gt 1 then begin print,'Plotting 2D wavenumber amplitude..' widget_control,event.top,hourglass=1 lon.zonalfreq = 1 ; deflondata and pltlon will check for this lon.amplitude = 0 ; Make sure 1D amplitude off widget_control, lon.wfsl_lon, sensitive=0 widget_control, lon.wfsl_slt, sensitive=0 widget_control, lon.wfsl_wvn1, sensitive=0 widget_control, lon.wfsl_wvn, sensitive=1 widget_control, lon.wfsl_frq, sensitive=1 widget_control, lon.wfb_wvnfrq, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate widget_control,event.top,hourglass=0 *info.plon = lon pltlon,info endif else begin print, 'Input file has one time - no 2D analysis possible' endelse end '2D_AMPLITUDE_ON_LOG': begin if field.ntime gt 1 then begin print,'Plotting log 2D wavenumber amplitude..' widget_control,event.top,hourglass=1 lon.zonalfreq = 2 ; deflondata and pltlon will check for this lon.amplitude = 0 ; Make sure 1D amplitude off widget_control, lon.wfsl_lon, sensitive=0 widget_control, lon.wfsl_slt, sensitive=0 widget_control, lon.wfsl_wvn1, sensitive=0 widget_control, lon.wfsl_wvn, sensitive=1 widget_control, lon.wfsl_frq, sensitive=1 widget_control, lon.wfb_wvnfrq, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate widget_control,event.top,hourglass=0 *info.plon = lon pltlon,info endif else begin print, 'Input file has one time - no 2D analysis possible' endelse end '2D_AMPLITUDE_OFF': begin print,'Turning 2D wavenumber amplitude off..' lon.zonalfreq = 0 ; deflondata and pltlon will check for this lon.ampphs = 0 ; deflondata will check for this widget_control, lon.wfsl_wvn, sensitive=0 widget_control, lon.wfsl_frq, sensitive=0 widget_control, lon.wfb_wvnfrq, sensitive=0 widget_control, lon.wfsl_lon, sensitive=1 widget_control, lon.wfsl_slt, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN BEGIN getzlatlonut,info,lon,'lon',fields,zalt fminmax,*lon.data,fmin,fmax,lon.missing_value cmin=0. & cmax=0. & cint=0. *lon.clevels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint ENDIF *info.plon = lon pltlon,info end '2D_PHASE_ON_LINEAR': begin if field.ntime gt 1 then begin print,'Plotting 2D wavenumber phase..' widget_control,event.top,hourglass=1 lon.zonalfreq = 3 ; deflondata and pltlon will check for this lon.amplitude = 0 ; Make sure 1D amplitude off widget_control, lon.wfsl_lon, sensitive=0 widget_control, lon.wfsl_slt, sensitive=0 widget_control, lon.wfsl_wvn1, sensitive=0 widget_control, lon.wfsl_wvn, sensitive=1 widget_control, lon.wfsl_frq, sensitive=1 widget_control, lon.wfb_wvnfrq, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt widget_control,event.top,hourglass=0 *info.plon = lon pltlon,info endif else begin print, 'Input file has one time - no 2D analysis possible' endelse end '2D_PHASE_ON_LOG': begin if field.ntime gt 1 then begin print,'Plotting log 2D wavenumber phase..' widget_control,event.top,hourglass=1 lon.zonalfreq = 4 ; deflondata and pltlon will check for this lon.amplitude = 0 ; Make sure 1D amplitude off widget_control, lon.wfsl_lon, sensitive=0 widget_control, lon.wfsl_slt, sensitive=0 widget_control, lon.wfsl_wvn1, sensitive=0 widget_control, lon.wfsl_wvn, sensitive=1 widget_control, lon.wfsl_frq, sensitive=1 widget_control, lon.wfb_wvnfrq, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate widget_control,event.top,hourglass=0 *info.plon = lon pltlon,info endif else begin print, 'Input file has one time - no 2D analysis possible' endelse end '2D_PHASE_OFF': begin print,'Turning 2D wavenumber phase off..' lon.zonalfreq = 0 ; deflondata and pltlon will check for this lon.ampphs = 0 ; deflondata will check for this widget_control, lon.wfsl_frq, sensitive=0 widget_control, lon.wfsl_wvn, sensitive=0 widget_control, lon.wfb_wvnfrq, sensitive=0 widget_control, lon.wfsl_lon, sensitive=1 widget_control, lon.wfsl_slt, sensitive=1 data = *fields[lon.ifield].data deflondata,lon,data ; For altitude as vertical coordinate need to reset contour levels IF lon.plotz GE 1 THEN BEGIN getzlatlonut,info,lon,'lon',fields,zalt fminmax,*lon.data,fmin,fmax,lon.missing_value cmin=0. & cmax=0. & cint=0. *lon.clevels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint ENDIF *info.plon = lon pltlon,info end 'ANIM_TIME_FIXLON': begin if field.ntime eq 1 then begin print,'>>> Cannot animate in time: there is only one time on the file!' widget_control,event.id,sensitive=0 endif else begin widget_control,event.id,/sensitive animate_lons,info,'time_fixlon' endelse end 'ANIM_TIME_FIXSLT': begin if field.ntime eq 1 then begin print,'>>> Cannot animate in time: there is only one time on the file!' widget_control,event.id,sensitive=0 endif else begin widget_control,event.id,/sensitive animate_lons,info,'time_fixslt' endelse end 'ANIM_LON': begin animate_lons,info,'lon_fixut' end 'SET_MINMAX': begin umin=lon.fmin & umax=lon.fmax setminmax,info,umin,umax lon.fmin=umin & lon.fmax=umax lon.setcontour = 'on' *info.plon = lon pltlon,info end 'RESET_MINMAX': begin lon.fmin=0. & lon.fmax=0. print,'Lon slices: reset image min,max to full range.' *info.plon = lon pltlon,info end 'SET_YAXIS': begin ; sets y-axis limits lon.levmin,max and updates *info.plon lon = *info.plon ; For altitude as vertical coordinate, need to set min/max vertical levels to altitude values IF lon.plotz GE 1 THEN BEGIN lon.levmin = lon.levminz lon.levmax = lon.levmaxz ENDIF *info.plon = lon setaxis_vert,info,info.plon lon = *info.plon IF lon.plotz GE 1 THEN BEGIN lon.levminz = lon.levmin lon.levmaxz = lon.levmax ENDIF data = *fields[lon.ifield].data lon.field = fields[lon.ifield] deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'RESET_YAXIS': begin lon.levmin = (*field.levs)[0] & lon.levmax = (*field.levs)[field.nlev-1] print,'Lon slices: reset y-axis (zp or ht) to full range.' data = *fields[lon.ifield].data deflondata,lon,data ; For altitude as vertical coordinate, need to reset min/max vertical levels IF lon.plotz GE 1 THEN BEGIN lon.levminz = 0 lon.levmaxz = 0 getzlatlonut,info,lon,'lon',fields,zalt ENDIF *info.plon = lon pltlon,info end 'SET_XAXIS': begin ; sets x-axis limits lon.latmin,max and updates *info.plon setaxis_lat,info,info.plon lon = *info.plon data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'RESET_XAXIS': begin lon.latmin = (*field.lats)[0] & lon.latmax = (*field.lats)[field.nlat-1] print,'Lon slices: reset x-axis (latitude) to full range.' data = *field.data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate *info.plon = lon pltlon,info end 'ADD_YAX': begin lon.rhyaxis = 1 ; add extra right-hand y-axis if field.difftype ne '' then begin print,'>>> WARNING: this is a difference fields file: right-hand',$ ' axis in height is not available...' lon.rhyaxis = 0 endif else if mag eq 1 then begin print,'>>> WARNING: this is a magnetic gridded field: right-hand',$ ' axis in height is not available...' lon.rhyaxis = 0 endif else begin print,'Will add extra right-hand y-axis' endelse *info.plon = lon pltlon,info end 'RM_YAX': begin lon.rhyaxis = 0 ; remove extra right-hand y-axis print,'Will remove extra right-hand y-axis' IF lon.plotz GE 1 THEN BEGIN data = *fields[lon.ifield].data deflondata,lon,data getzlatlonut,info,lon,'lon',fields,zalt ENDIF *info.plon = lon pltlon,info end 'GPZALT_ON': begin ; Saves current zp levels and data and define and plot new data on geopotential altitude print, 'Plotting on geopotential altitude in vertical' ; Save current zp levels and data and define and plot new data on geopotential altitude IF lon.plotz EQ 0 THEN *lon.levszp = *lon.levs IF lon.plotz EQ 0 THEN *lon.datazp = *lon.data lon.plotz = 1 data = *fields[lon.ifield].data deflondata,lon, data getzlatlonut,info,lon,'lon',fields,zalt *info.plon = lon pltlon,info lon = *info.plon end 'GMZALT_ON': begin ; Saves current zp levels and data and define and plot new data on geometric altitude print, 'Plotting on geometric altitude in vertical' IF lon.plotz EQ 0 THEN *lon.levszp = *lon.levs IF lon.plotz EQ 0 THEN *lon.datazp = *lon.data lon.plotz = 2 data = *fields[lon.ifield].data deflondata,lon, data getzlatlonut,info,lon,'lon',fields,zalt *info.plon = lon pltlon,info lon = *info.plon end 'ZALT_OFF': begin ; Resets vertical zp axis and data from altitude vertical print, 'Plotting on altitude in vertical off' lon.plotz = 0 lfield = lon.field if info.ftype ne 'WACCM' then *lfield.levs = *lon.levszp lon.field = lfield *lon.levs = *lon.levszp *lon.data = *lon.datazp lon.levmin = MIN(*lon.levs) lon.levmax = MAX(*lon.levs) fminmax,*lon.data,fmin,fmax,lon.missing_value lon.fmin=fmin & lon.fmax=fmax *info.plon = lon pltlon,info lon = *info.plon end 'CUSTOM_CONTOUR': begin lon.setcontour = 'on' cmin=lon.fmin & cmax=lon.fmax & cint=lon.cint & clineclr = lon.clineclr custom_contour,info.tlb,cmin,cmax,cint,clineclr lon.clineclr = clineclr data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate data = *lon.data fminmax,data,fmin,fmax,lon.missing_value levels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint *lon.clevels = levels *info.plon = lon pltlon,info end 'RESET_CONTOUR': begin lon.setcontour = 'off' cmin=0. & cmax=0. & cint=0. print,'Lon slices: reset contour min,max to full range.' data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate data = *lon.data fminmax,data,fmin,fmax,lon.missing_value levels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint *lon.clevels = levels *info.plon = lon pltlon,info end ; ; Save images in ps or bitmap file for export: ; 'SAVE_PS': begin title='Select File for Postscript' psfile = dialog_pickfile(path=info.openpath,title=title,$ group=event.top) if (psfile ne '') then begin widget_control,event.top,hourglass=1 pson,filename=psfile,margin=1.0 setclrtab,info.colortab,/ps pltlon,info,/ps psoff widget_control,event.top,hourglass=0 endif end 'SAVE_PNG': begin windowsave = !d.window window,xsize=lon.draw_xsize,ysize=lon.draw_ysize,/pixmap windo = !d.window wset,windo setclrtab,info.colortab pltlon,info,/png writeimage,info.openpath,event.top,'PNG' wset,windowsave end 'SAVE_GIF': begin version = float(!version.release) if version le 5.3 then begin writeimage,info.openpath,event.top,'GIF' endif else begin print,'>>> NEED IDL version 5.3 to make GIF' endelse end 'SAVE_BMP': writeimage,info.openpath,event.top,'BMP' 'SAVE_JPEG': writeimage,info.openpath,event.top,'JPEG' 'SAVE_TIFF': writeimage,info.openpath,event.top,'TIFF' ; ; Plot types ; 'IMAGE_ONLY': begin if mag eq 1 then begin print,'>>> WARNING: cannot make image of magnetic field because of ',$ 'irregular latitude grid. Staying with plot type ',lon.plottype endif else begin lon.plottype = 'image_only' ; Need to get data again for altitude vertical axis IF lon.plotz GE 1 THEN BEGIN data = *fields[lon.ifield].data deflondata,lon,data getzlatlonut,info,lon,'lon',fields,zalt ENDIF *info.plon = lon print,'Set plot type to ',lon.plottype pltlon,info widget_control,lon.minmaxmenu,sensitive=1 ; can set image min,max widget_control,lon.contourmenu,sensitive=0 ; not doing contours endelse end 'IMAGE+CONTOURS': begin if mag eq 1 then begin print,'>>> WARNING: cannot make image of magnetic field because of ',$ 'irregular latitude grid. Staying with plot type ',lon.plottype endif else begin lon.plottype = 'image+contours' ; Need to get data again for altitude vertical axis IF lon.plotz GE 1 THEN BEGIN data = *fields[lon.ifield].data deflondata,lon,data getzlatlonut,info,lon,'lon',fields,zalt ENDIF *info.plon = lon print,'Set plot type to ',lon.plottype pltlon,info widget_control,lon.minmaxmenu,sensitive=0 ; image minmax will be fmin,fmax widget_control,lon.contourmenu,sensitive=1 ; doing contours endelse end 'MONOCHROME_CONTOURS': begin lon.plottype = 'monochrome_contours' ; Need to get data again for altitude vertical axis IF lon.plotz GE 1 THEN BEGIN data = *fields[lon.ifield].data deflondata,lon,data getzlatlonut,info,lon,'lon',fields,zalt ENDIF *info.plon = lon print,'Set plot type to ',lon.plottype pltlon,info widget_control,lon.minmaxmenu,sensitive=0 ; no image widget_control,lon.contourmenu,sensitive=1 ; doing contours end 'COLORFILL_CONTOURS': begin lon.plottype = 'colorfill_contours' ; Need to get data again for altitude vertical axis IF lon.plotz GE 1 THEN BEGIN data = *fields[lon.ifield].data deflondata,lon,data getzlatlonut,info,lon,'lon',fields,zalt ENDIF *info.plon = lon print,'Set plot type to ',lon.plottype pltlon,info widget_control,lon.minmaxmenu,sensitive=0 ; no image widget_control,lon.contourmenu,sensitive=1 ; doing contours end else: print,'>>> lons_event: unknown widget ',widget endcase *pinfo = info end ;----------------------------------------------------------------------- pro field_lon_event,event ; ; User has selected a field. Read field from the file and update ; lon structure. ; widget_control,event.id,get_uvalue=widget widget_control,event.top,get_uvalue=pinfo info = *pinfo lon = *info.plon lon.setcontour = 'off' lon.ampphs = 0 ;Make sure if doing 2D FFT that it is recalculated for new field fields = *info.fields gridtype_prev = fields[lon.ifield].grid_type for i=0,info.nflds-1 do begin if (widget eq fields[i].name) then begin lon.ifield = i if ptr_valid(fields[i].data) then begin ; field has been read print,'Selected field ',fields[i].name fmin = min(*fields[i].data) & fmax = max(*fields[i].data) lon.field = fields[i] endif else begin widget_control,/hourglass varget,info,fields[i],ncdata field = fields[i] procfield,info,ncdata,field,info.z_hist fields[i] = field lon.field = field lon.levs = lon.field.levs lon.data = lon.field.data ; Need to return to original levels when plotting on altitude in vertical IF lon.plotz GT 0 AND lon.ftype EQ 'WACCM' THEN *lon.levszp = *lon.field.levs IF lon.plotz GT 0 AND lon.ftype EQ 'WACCM' THEN *lon.datazp = *lon.field.data fmin = min(*fields[i].data) & fmax = max(*fields[i].data) rpt_minmax,info,fields[i],fmin,fmax endelse data = *fields[lon.ifield].data ; ; If this is a change in grid type, reset select-longitude slider: ; if fields[lon.ifield].grid_type ne gridtype_prev then begin mag = 0 & if fields[lon.ifield].grid_type eq 'magnetic' then mag = 1 base = widget_info(lon.wfsl_lon,/parent) widget_control,lon.wfsl_lon,/destroy lons = *fields[lon.ifield].lons nlon = n_elements(lons) dlon = lons[1]-lons[0] ; new dlon ilon = ixfind(lons,lon.slon,dlon) lon.slon = lons(ilon) title = 'Select '+fields[lon.ifield].grid_type+' Longitude' lon.wfsl_lon = cw_fslide(base,minimum=lons[0],maximum=lons[nlon-1],$ delta=dlon,xsize=200,uvalue="SELECT_LON",format='(f7.2)',$ value=lon.slon,title=title) ; ; Now reset select-localtime slider lon.wfsl_slt: ; base = widget_info(lon.wfsl_slt,/parent) widget_control,lon.wfsl_slt,/destroy title = 'Select '+fields[lon.ifield].grid_type+' Local time' sslt = fslt(sslt,lon.ut,lon.slon,'getlt',mag=mag) dslt = dlon/15. ; ; Set lon.slon to longitude nearest current local time: ; if ixfind(lons,lon.slon,0.) < 0 then begin ; lon.slon not in lons ilon = ixfind(lons,lon.slon,dlon) lon.slon = lons[ilon] print,'select_field: sslt=',sslt,' nearest lon.slon=',lon.slon endif else begin print,'select_field: found exact lon.slon=',lon.slon,' for slt=',sslt widget_control,lon.wfsl_lon,set_value=lon.slon endelse ; lon.wfsl_slt = cw_fslide(base,minimum=0.,maximum=24.,$ delta=dslt,xsize=200,uvalue="SELECT_SLT",format='(f5.2)',$ value=sslt,title=title) endif deflondata,lon,data if (not ptr_valid(lon.data)) then begin print,'lons: invalid pointer returned from deflondata -- returning' return endif IF lon.plotz GE 1 AND lon.ftype NE 'WACCM' THEN *fields[lon.ifield].data = data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate ; ; Reset min,max and contour interval: ; data = *lon.data fminmax,data,fmin,fmax,lon.missing_value cmin=0. & cmax=0. & cint=0. levels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint *lon.clevels = levels endif ; found field name endfor if fields[lon.ifield].grid_type eq 'magnetic' and $ ((lon.plottype eq 'image_only') or (lon.plottype eq 'image+contours')) then begin print,'>>> WARNING: cannot make image of magnetic field because of ',$ 'irregular latitude grid. Switching to color-fill contour..' lon.plottype = 'colorfill_contours' widget_control,lon.minmaxmenu,sensitive=0 widget_control,lon.contourmenu,sensitive=1 endif ; ; Update state info: ; *info.fields = fields *info.plon = lon *pinfo = info pltlon,info end ;----------------------------------------------------------------------- pro mtime_lon_event,event ; ; Respond to user selection of a model time: ; widget_control,event.top,get_uvalue=pinfo widget_control,event.id,get_uvalue=mtime_request info = *pinfo fields = *info.fields lon = *info.plon field = fields[lon.ifield] mag = 0 & if field.grid_type eq 'magnetic' then mag = 1 file = *info.pfile imtime = -1 for i=0,file.ntimes-1 do begin mtime_string = $ strcompress(string(file.mtimes[0,i]),/remove_all)+','+ $ strcompress(string(file.mtimes[1,i]),/remove_all)+','+ $ strcompress(string(file.mtimes[2,i]),/remove_all) if mtime_string eq mtime_request then begin imtime = i goto, found endif endfor print,'>>> WARNING mtime_lon_event: could not find index to model time ',$ mtime_request return found: lon.imtime = imtime lon.mtime = file.mtimes[*,imtime] ; ; Reset slt slider from new ut and current selected lon: ; lon.ut = lon.mtime[1]+lon.mtime[2]/60. lon.sslt = fslt(lon.sslt,lon.ut,lon.slon,"getlt",mag=mag) widget_control,lon.wfsl_slt,set_value=lon.sslt ; ; Define longitude slice data: ; data = *fields[lon.ifield].data deflondata,lon,data IF lon.plotz GE 1 THEN getzlatlonut,info,lon,'lon',fields,zalt ; For altitude as vertical coordinate ; ; Reset contour levels: ; if lon.setcontour eq 'off' then begin data = *lon.data fminmax,data,fmin,fmax,lon.missing_value cmin=0. & cmax=0. & cint=0. levels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint *lon.clevels = levels endif ; *info.plon = lon pltlon,info end ; mtime_lon_event ;----------------------------------------------------------------------- pro lons,info ; ; Set up longitude slice widget: ; file = *info.pfile ; file info structure fields = *info.fields ; fields info structure ; title = 'Lon Slices: '+info.file tlb = widget_base(column=1,mbar=mbar, title=title) ; lon_ids = *info.plon_ids for i=0,n_elements(lon_ids)-1 do begin if (lon_ids(i) le 0) then begin lon_ids(i) = tlb goto,done endif endfor done: lonbase = tlb missing_value = file.missing_value ; ; Fields menu: ; fieldsmenu = fields_menu(mbar,fields,'field_lon_event') ; ; Model times menu: ; mtimesmenu = mtime_menu(mbar,file.mtimes,'mtime_lon_event') mtime = file.mtimes[*,0] imtime = 0 ; ; ------------------------- Plot options menus ----------------- ; optsmenu = widget_button(mbar,value='PlotOptions') ; ; Plot types (submenu under plot options): ; plottype = widget_button(optsmenu,value='Plot Type',/menu) button = widget_button(plottype,$ value='Image Only',uvalue='IMAGE_ONLY') button = widget_button(plottype,$ value='Image plus Contours',uvalue='IMAGE+CONTOURS') button = widget_button(plottype,$ value='Monochrome Contours',uvalue='MONOCHROME_CONTOURS') button = widget_button(plottype,$ value='Color-fill Contours',uvalue='COLORFILL_CONTOURS') ; ; Plotting log10 of the fields: there are 3 options: ; lon.log10 = 'density fields' -> plot log10 of density fields only ; lon.log10 = 'all fields' -> always plot log10 ; lon.log10 = 'none' -> never plot log10 ; (See pro lons_event above, and deflondata.pro and pltlon.pro) ; Log10 submenu under PlotOptions: ; log10menu = widget_button(optsmenu,value='Plot log10 of field:',/menu) button = widget_button(log10menu,value='Plot log10 (density fields only)',$ uvalue='LOG10') button = widget_button(log10menu,value='Plot log10 (all fields)',$ uvalue='LOG10_ALLFIELDS') button = widget_button(log10menu,value='Plot linear (all fields)',$ uvalue='LINEAR') ; ; Add or remove extra right-hand y-axis (if left-hand y-axis is linear ; Zp then add non-linear right y-axis in height): ; yaxmenu = widget_button(optsmenu,value='Extra right-hand y-axis:',/menu) button = widget_button(yaxmenu,value='Add Right-hand Y-axis in Height',$ uvalue='ADD_YAX') button = widget_button(yaxmenu,value='Remove Right-hand Y-axis in Height',$ uvalue='RM_YAX') ; ; Plot zonal means: ; zmmenu = widget_button(optsmenu,value='Zonal Mean',/menu) button = widget_button(zmmenu,value='Zonal Mean On',uvalue='ZONAL_MEAN_ON') button = widget_button(zmmenu,value='Zonal Mean Off',uvalue='ZONAL_MEAN_OFF') ; ; Plot wavenumber amplitudes: ; spmenu = widget_button(optsmenu,value='Wavenumber Amplitude',/menu) button = widget_button(spmenu,value='Wavenumber Amplitude On (Linear)',uvalue='AMPLITUDE_ON_LINEAR') button = widget_button(spmenu,value='Wavenumber Amplitude On (Log)',uvalue='AMPLITUDE_ON_LOG') button = widget_button(spmenu,value='Wavenumber Amplitude Off',uvalue='AMPLITUDE_OFF') ; ; Plot 2D wavenumber amplitude: ; spmenu = widget_button(optsmenu,value='2D Wavenumber Amplitude/Phase',/menu) button = widget_button(spmenu,value='Wavenumber Amplitude On (Linear)',uvalue='2D_AMPLITUDE_ON_LINEAR') button = widget_button(spmenu,value='Wavenumber Amplitude On (Log)',uvalue='2D_AMPLITUDE_ON_LOG') button = widget_button(spmenu,value='Wavenumber Amplitude Off',uvalue='2D_AMPLITUDE_OFF') button = widget_button(spmenu,value='Wavenumber Phase On (Linear)',uvalue='2D_PHASE_ON_LINEAR') button = widget_button(spmenu,value='Wavenumber Phase On (Log)',uvalue='2D_PHASE_ON_LOG') button = widget_button(spmenu,value='Wavenumber Phase Off',uvalue='2D_PHASE_OFF') ; ; User set y-axis range (zp): ; yaxismenu = widget_button(optsmenu,value='Set y-axis range (zp or ht)',/menu) button = widget_button(yaxismenu,value='Reset to full range',$ uvalue='RESET_YAXIS') button = widget_button(yaxismenu,value='Set vertical min,max...',$ uvalue='SET_YAXIS') ; ; User set x-axis range (latitude): ; xaxismenu = widget_button(optsmenu,value='Set x-axis range (latitude)',/menu) button = widget_button(xaxismenu,value='Reset to full range',$ uvalue='RESET_XAXIS') button = widget_button(xaxismenu,value='Set latitude min,max...',$ uvalue='SET_XAXIS') ; ; Custom Contour: ; contourmenu = widget_button(optsmenu,value='Custom Contour',/menu) button = widget_button(contourmenu,value='Reset to full range',$ uvalue='RESET_CONTOUR') button = widget_button(contourmenu,value='Set min,max,interval...',$ uvalue='CUSTOM_CONTOUR') ; ; User set field min,max of image: ; minmaxmenu = widget_button(optsmenu,value='Fix Image min,max',/menu) button = widget_button(minmaxmenu,value='Reset to full range',$ uvalue='RESET_MINMAX') button = widget_button(minmaxmenu,value='Set Image min,max...',$ uvalue='SET_MINMAX') ; ; Change color tables: ; button = widget_button(optsmenu,value='Color...',uvalue='COLOR') ; ; Plot profiles on altitude as the vertical y-axis ; zaltmenu = widget_button(optsmenu,value='Set y-axis to Altitude',/menu) button = widget_button(zaltmenu,value='Geopotential Altitude as y-axis On',uvalue='GPZALT_ON') button = widget_button(zaltmenu,value='Geometric Altitude as y-axis On',uvalue='GMZALT_ON') button = widget_button(zaltmenu,value='Altitude as y-axis Off',uvalue='ZALT_OFF') ; ; ------------------------- Animation menus -------------------------- ; animmenu = widget_button(mbar,value='Animate') button = widget_button(animmenu,value='Animate in time (fixed longitude)',$ uvalue='ANIM_TIME_FIXLON') button = widget_button(animmenu,value='Animate in time (fixed local time)',$ uvalue='ANIM_TIME_FIXSLT') animlon = widget_button(animmenu,value='Animate in longitude (fixed ut)',$ uvalue='ANIM_LON') ; ; ------------------------- Save output files -------------------------- ; savemenu = widget_button(mbar,value='SaveFiles') button = widget_button(savemenu,value='Postscript...',uvalue='SAVE_PS') button = widget_button(savemenu,value='PNG...',uvalue='SAVE_PNG') button = widget_button(savemenu,value='GIF...',uvalue='SAVE_GIF') button = widget_button(savemenu,value='BMP...',uvalue='SAVE_BMP') button = widget_button(savemenu,value='JPEG...',uvalue='SAVE_JPEG') button = widget_button(savemenu,value='TIFF...',uvalue='SAVE_TIFF') ; ; ------------------ Sliders for selected lons, slt ------------------- ; ; Base for 3 sliders that select longitude, local time, and wavenumber: ; sliderbase = widget_base(tlb,column=2,/frame) ; ; Select longitude: ; lons = *fields[0].lons nlon = n_elements(lons) dlon = lons[1]-lons[0] slon = lons[0] slonbase = widget_base(sliderbase) title = 'Select '+fields[0].grid_type+' Longitude' wfsl_slon = cw_fslide(slonbase,minimum=lons[0],maximum=lons[nlon-1],$ delta=dlon,xsize=230,uvalue="SELECT_LON",format='(f7.2)',value=slon,$ title=title) ; ; Select local time: ; mag = 0 & if fields[0].grid_type eq 'magnetic' then mag = 1 sltbase = widget_base(sliderbase) ut = mtime[1]+mtime[2]/60. ;sslt = fslt(sslt,ut,slon,1) sslt = fslt(sslt,ut,slon,"getlt",mag=mag) dslt = dlon/15. title='Select '+fields[0].grid_type+' Local Time' wfsl_slt = cw_fslide(sltbase,minimum=0.,maximum=24.,$ delta=dslt,xsize=230,uvalue="SELECT_SLT",format='(f5.2)',value=sslt,$ title=title) ; ; Select wavenumber slider: ; swvn1base = widget_base(sliderbase) wavenumber = 1 ; initial wavenumber value is 1 dwvn = 1 title='Select Wavenumber' wfsl_wvn1 = cw_fslide(swvn1base,minimum=0,maximum=nlon/2,$ delta=dwvn,xsize=230,uvalue="SELECT_WVN",format='(i2)',value=wavenumber,$ title=title) ; ; Select wavenumber slider: ; swvnbase = widget_base(sliderbase) wavenumber = -1 ; initial wavenumber value is -1 dwvn = 1 title='Select WN (-W/+E cycles/360 degs lon)' wfsl_wvn = cw_fslide(swvnbase,minimum=-nlon/2,maximum=nlon/2,$ delta=dwvn,xsize=230,uvalue="SELECT_WVN",format='(i3)',value=wavenumber,$ title=title) ; ; Select frequency slider: ; sfrqbase = widget_base(sliderbase) frequency = 1 ; initial frequency value is 1 dfrq = 1 title='Select Frequency' ; ; Need to handle case where input file has only one time ; IF file.ntimes GT 1 THEN BEGIN ; ; Set frequency slider range based on input file time range ; ftimelengthdays = info.mtime_end[0] - info.mtime_beg[0] ftimelengthhours = info.mtime_end[1] - info.mtime_beg[1] ftimelengthmins = info.mtime_end[2] - info.mtime_beg[2] totaltimehours = ftimelengthdays * 24. + ftimelengthhours + ftimelengthmins / 60. mtime_files = *info.mtime_files fdeltimehours = mtime_files[1,1,0] - mtime_files[1,0,0] if fdeltimehours eq 0 then fdeltimehours = 24 title='Select Frequency (cycles/' + strtrim(totaltimehours+fdeltimehours,2) + ' hrs) ; ; If input time range is one day, calculate fraction of day as input file time length ; if ftimelengthdays eq 1 then ftimelengthdays = $ (mtime_files[1,*info.ntime_files[info.ifile_end]-1,info.ifile_end] + fdeltimehours) / 24. freqmax = file.ntimes / 2 freqmin = 0 wfsl_frq = cw_fslide(sfrqbase,minimum=freqmin,maximum=freqmax,$ delta=dfrq,xsize=230,uvalue="SELECT_FRQ",format='(i3)',value=frequency,$ title=title) ENDIF ELSE BEGIN wfsl_frq = cw_fslide(sfrqbase,minimum=-1,maximum=1,$ delta=dfrq,xsize=230,uvalue="SELECT_FRQ",format='(i3)',value=frequency,$ title=title) widget_control, wfsl_frq, sensitive=0 ENDELSE ; ; Display amplitude or phase for 2D spectral analysis ; wfb_wvnfrq = widget_button(sliderbase,value="OK",uvalue="SELECT_WVN_FRQ") *info.plon_ids = lon_ids draw_xsize = 500 & draw_ysize = 500 draw = widget_draw(tlb,xsize=draw_xsize,ysize=draw_ysize,uvalue='DRAW_LONS') button = widget_button(tlb,value='Close',uvalue='CLOSE') ; lats = *fields[0].lats latmin = lats[0] & latmax = lats[n_elements(lats)-1] levs = *fields[0].levs levmin = levs[0] ;nlev = fields[0].nlev nlev = size(levs,/n_elements) levmax = levs[nlev-1] ; ; -------------------------- Lon slice structure --------------------- ; lon = {lonstruct, $ field:fields[0], $ ; current field structure ifield:0, $ ; index to current field slon:slon, $ ; selected longitude sslt:sslt, $ ; selected local time lon_type:'lon', $ ; 'lon','slt', or 'zm' mtime:mtime, $ ; model time (default first time on file) imtime:imtime, $ ; index to mtime (file.mtimes[imtime]) ut:ut, $ ; ut (hrs) missing_value:missing_value, $ ; missing data value lonbase:lonbase, $ ; widget id of cw lev slider base rhyaxis:1, $ ; if > 0 then add extra right-hand y-axis wfsl_lon:wfsl_slon, $ ; widget id of lon selection slider wfsl_slt:wfsl_slt, $ ; widget id of slt selection slider wfsl_wvn1:wfsl_wvn1, $ ; widget id of amplitude wavenumber 1D selection slider wfsl_wvn:wfsl_wvn, $ ; widget id of amplitude wavenumber 2D selection slider wfsl_frq:wfsl_frq, $ ; widget id of frequency 2D selection slider wfb_wvnfrq:wfb_wvnfrq, $ ; widget id of amplitude/phase wavenumber/frequency 2D selection button log10:'density fields', $ ; plot log10 (densities, current field, on none) draw:draw, $ ; draw widget id draw_xsize:draw_xsize, $ ; x size of draw widget draw_ysize:draw_ysize, $ ; y size of draw widget minmaxmenu:minmaxmenu, $ ; menu widget for setting image min,max contourmenu:contourmenu, $ ; menu widget for custom contour ftype:info.ftype, $ ; Type of input file (TIME-GCM or WACCM presently) plottype:'image+contours', $ ; 4 options (see plottype_menu) clineclr:!d.table_size-1, $ ; contour line color zonalmean:0, $ ; plot zonal mean if zonalmean==1 amplitude:0, $ ; plot wavenumber amplitude linear if == 1 and log if == 2 wavenumber:wavenumber, $ ; wavenumber of wave zonalfreq:0, $ ; plot wavenumber amplitude/phase - linear amplitude if == 1 and log amplitude if == 2 linear phase if == 3 log phase if == 4 frequency:frequency, $ ; frequency of wave ampphs:0, $ ; wavenumber amplitude/phase calculated if == 1 and not if == 0 plotz:0, $ ; plot altitude as vertical axis(profiles) if = 1 setcontour:'off', $ ; tracks if contours have been set fmin:0.,fmax:0.,cint:0., $ ; field min,max and contour interval clevels:ptr_new(/allocate_heap),$ ; contour levels lats:ptr_new(/allocate_heap), $ ; latitudes for x-axis latmin:latmin,latmax:latmax, $ ; optional latitude range for x-axis levs:ptr_new(/allocate_heap), $ ; vertical levels for y axis levszp:ptr_new(/allocate_heap), $ ; vertical levels in zp for y axis levmin:levmin,levmax:levmax, $ ; min,max of lev y-axis levminz:0.,levmaxz:0., $ ; min,max of lev y-axis altitude amp:ptr_new(/allocate_heap), $ ; amplitude from 2D FFT phs:ptr_new(/allocate_heap), $ ; phase from 2D FFT data:ptr_new(/allocate_heap), $ ; 2d data (lats,levs) datazp:ptr_new(/allocate_heap) $ ; 2d data (lats,levs) on zp vertical grid } ; ; Initially turn off wavenumber slider: ; IF lon.amplitude EQ 0 THEN widget_control, wfsl_wvn1, sensitive=0 IF lon.amplitude EQ 0 THEN widget_control, wfsl_wvn, sensitive=0 IF lon.zonalfreq EQ 0 THEN widget_control, wfsl_frq, sensitive=0 IF lon.amplitude EQ 0 THEN widget_control, wfb_wvnfrq, sensitive=0 ; ; Read data from first field: ; if ptr_valid(fields[0].data) then begin ; field has been read deflondata,lon,*fields[0].data endif else begin widget_control,/hourglass varget,info,fields[0],ncdata field = fields[0] procfield,info,ncdata,field,info.z_hist fields[0] = field lon.levmin = (*field.levs)[0] & lon.levmax = (*field.levs)[field.nlev-1] deflondata,lon,*fields[0].data lon.field = field lon.levs = lon.field.levs endelse ; ; Set min,max for first field: ; fminmax,*lon.data,fmin,fmax,lon.missing_value rpt_minmax,info,fields[0],fmin,fmax widget_control,lon.minmaxmenu,sensitive=0 ; because default plottype is image+contour ; ; Set min,max and contour interval: ; cmin=0. & cmax=0. & cint=0. levels = mkclevels(fmin,fmax,cmin,cmax,cint) lon.fmin=cmin & lon.fmax=cmax & lon.cint=cint *lon.clevels = levels ; ; Update state info, realize the widgets, plot the first slice: ; *info.fields = fields info.plon = ptr_new(lon) widget_control,tlb,/realize pinfo = ptr_new(info) pltlon,info widget_control,tlb,set_uvalue=pinfo xmanager,'lons',tlb,/no_block end