; ;----------------------------------------------------------------------- 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 lines_event,event widget_control,event.id,get_uvalue=widget widget_control,event.top,get_uvalue=pinfo info = *pinfo line = *info.pline fields = *info.fields field = fields[line.ifield] mag = 0 & if field.grid_type eq 'magnetic' then mag = 1 ; case widget of 'CLOSE': widget_control,event.top,/destroy 'SELECT_LAT': begin line.slat = event.value lats = *fields[line.ifield].lats ilat = ixfind_nearest(lats,line.slat) line.slat = lats[ilat] data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz ge 1 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data widget_control,line.wfsl_lat,set_value=line.slat fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax IF line.plotz GE 1 and line.plottype eq 'profile' THEN getzprof,info,line,'profile',fields,zalt *info.pline = line pltline,info end 'SELECT_LON': begin line.slon = event.value lons = *fields[line.ifield].lons ilon = ixfind_nearest(lons,line.slon) line.slon = lons[ilon] line.sslt = fslt(line.sslt,line.ut,line.slon,'getlt',mag=mag) widget_control,line.wfsl_slt,set_value=line.sslt data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data widget_control,line.wfsl_lon,set_value=line.slon fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax IF line.plotz GE 1 and line.plottype eq 'profile' THEN getzprof,info,line,'profile',fields,zalt *info.pline = line pltline,info end 'SELECT_LEV': begin line.slev = event.value ; levs = *fields[line.ifield].levs ; ilev = ixfind(levs,line.slev,1) ; line.slev = levs[ilev] data = *fields[line.ifield].data if line.plotz gt 0 then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data widget_control,line.wfsl_lev,set_value=line.slev fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax *info.pline = line pltline,info end 'SELECT_SLT': begin line.sslt = event.value line.slon = fslt(line.sslt,line.ut,line.slon,'getlon',mag=mag) if line.zonalmean eq 1 then line.zonalmean = 0 ; turn off zonal means if line.meridionalmean eq 1 then line.meridionalmean = 0 ; turn off meridional means lons = *fields[line.ifield].lons ; ; If exact lon corresponding to slt is not found in lons array, ; set it to nearest lon within lons: if ixfind(lons,line.slon,0.) lt 0 then begin lons = *fields[line.ifield].lons dlon = lons[1]-lons[0] ilon = ixfind(lons,line.slon,dlon) line.slon = lons[ilon] endif else begin endelse widget_control,line.wfsl_lon,set_value=line.slon data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax IF line.plotz GE 1 and line.plottype eq 'profile' THEN getzprof,info,line,'profile',fields,zalt *info.pline = line pltline,info end 'SELECT_WVN': begin line.wavenumber = event.value data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data IF line.plottype EQ 'profile' THEN fminmaxlev, line IF line.plottype EQ 'meridional' THEN BEGIN fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax ENDIF *info.pline = line pltline,info end 'LOG10': begin line.log10 = 'density fields' data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data ; ; Reset min,max and contour interval: fminmax,*line.data,fmin,fmax,line.missing_value ; cmin=0. & cmax=0. & cint=0. ; *line.clevels = mkclevels(fmin,fmax,cmin,cmax,cint) line.fmin=fmin & line.fmax=fmax IF line.plotz GE 1 THEN getzprof,info,line,'line',fields,zalt *info.pline = line print,'Will plot log10 of density fields' pltline,info end 'LOG10_ALLFIELDS': begin line.log10 = 'all fields' data = *fields[line.ifield].data if line.plotz gt 0 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data ; ; Reset min,max and contour interval: fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax IF line.plotz GE 1 THEN getzprof,info,line,'line',fields,zalt *info.pline = line print,'Will plot log10 of all fields' pltline,info end 'LINEAR': begin line.log10 = 'none' data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data ; ; Reset min,max and contour interval: fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax IF line.plotz GE 1 THEN getzprof,info,line,'line',fields,zalt *info.pline = line print,'Will plot linear fields (no log10)' pltline,info end 'ZONAL_MEAN_ON': begin print,'Plotting zonal mean..' line.zonalmean = 1 ; deflinedata and pltline will check for this IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_lon, sensitive=0 IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_slt, sensitive=0 data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax IF line.plotz GE 1 THEN getzprof,info,line,'line',fields,zalt *info.pline = line pltline,info end 'ZONAL_MEAN_OFF': begin print,'Turning zonal mean off..' line.zonalmean = 0 ; deflinedata and pltline will check for this IF (line.plottype EQ 'profile' OR line.plottype EQ 'meridional') AND line.amplitude EQ 0 $ THEN widget_control, line.wfsl_lon, sensitive=1 IF (line.plottype EQ 'profile' OR line.plottype EQ 'meridional') AND line.amplitude EQ 0 $ THEN widget_control, line.wfsl_slt, sensitive=1 data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax IF line.plotz GE 1 THEN getzprof,info,line,'line',fields,zalt *info.pline = line pltline,info end 'MERIDIONAL_MEAN_ON': begin print,'Plotting meridional mean..' line.meridionalmean = 1 ; deflinedata and pltline will check for this data = *fields[line.ifield].data if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax *info.pline = line pltline,info end 'MERIDIONAL_MEAN_OFF': begin print,'Turning meridional mean off..' line.meridionalmean = 0 ; deflinedata and pltline will check for this data = *fields[line.ifield].data if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax *info.pline = line pltline,info end 'AMPLITUDE_ON_LINEAR': begin print,'Plotting wavenumber amplitude..' line.amplitude = 1 ; deflinedata and pltline will check for this IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_lon, sensitive=0 IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_slt, sensitive=0 IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_wvn, sensitive=1 data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data *info.pline = line pltline,info end 'AMPLITUDE_ON_LOG': begin print,'Plotting log wavenumber amplitude..' line.amplitude = 2 ; deflinedata and pltline will check for this IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_lon, sensitive=0 IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_slt, sensitive=0 IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_wvn, sensitive=1 data = *fields[line.ifield].data print, 'line.plotz, line.plottype ', line.plotz, line.plottype if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data *info.pline = line pltline,info end 'AMPLITUDE_OFF': begin print,'Turning wavenumber amplitude off..' line.amplitude = 0 ; deflinedata and pltline will check for this IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_wvn, sensitive=0 IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_lon, sensitive=1 IF line.plottype EQ 'profile' OR line.plottype EQ 'meridional' THEN widget_control, line.wfsl_slt, sensitive=1 data = *fields[line.ifield].data line.fmax = 0.0 line.fmin = 0.0 line.lonmin = -180.0 line.lonmax = 180.0 if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs if line.plotz gt 0 and line.plottype ne 'profile' then getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data *info.pline = line pltline,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_lines,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_lines,info,'time_fixslt' endelse end 'ANIM_LON': begin animate_lines,info,'lon_fixut' end 'ANIM_LAT': begin line = *info.pline data = *line.data animate_lines,info,'lat_fixut' end 'SET_MINMAX': begin umin=line.fmin & umax=line.fmax setminmax,info,umin,umax line.fmin=umin & line.fmax=umax *info.pline = line end 'RESET_MINMAX': begin line.fmin=0. & line.fmax=0. print,'Line slices: reset image min,max to full range.' *info.pline = line end 'SET_ZPAXIS': begin ; sets vertical zp axis limits line.levmin,max and updates *info.pline setaxis_vert,info,info.pline line = *info.pline fminmaxlev,line *info.pline = line pltline,info line = *info.pline end 'GPZALT_ON_PRF': begin ; sets vertical zp axis limits line.levmin,max and updates *info.pline print, 'Plotting profile on geopotential height ' IF line.plotz EQ 0 THEN *line.levszp = *line.levs line.plotz = 1 data = *fields[line.ifield].data if line.ftype eq 'WACCM' then *line.levs = *field.levs deflinedata,line,data getzprof,info,line,'profile',fields,zalt *info.pline = line pltline,info line = *info.pline end 'GMZALT_ON_PRF': begin ; sets vertical zp axis limits line.levmin,max and updates *info.pline IF line.plotz EQ 0 THEN *line.levszp = *line.levs line.plotz = 2 getzprof,info,line,'profile',fields,zalt *info.pline = line pltline,info line = *info.pline end 'ZALT_OFF_PRF': begin ; sets vertical zp axis limits line.levmin,max and updates *info.pline line.plotz = 0 *line.levs = *line.levszp line.levmin = MIN(*line.levs) line.levmax = MAX(*line.levs) fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax *info.pline = line pltline,info line = *info.pline end 'SET_GPALT': begin ; ; Geopotential height level for line plot. Set flag, disable ZP slider, get current altitude ; from line structure, and update info line structure ; line.plotz = 1 widget_control, line.wfsl_lev, sensitive=0 alt = line.alt *info.pline = line ; ; Get user requested altitude and check for validity. ; ALTSETGP:setalt,info,line,alt,mode ; ; If no input altitude field found, quit altitude plotting ; IF alt EQ -2 THEN BEGIN line.plotz = 0 widget_control, line.wfsl_lev, sensitive=1 *info.pline = line pltline,info ENDIF ELSE BEGIN line.alt = alt data = *fields[line.ifield].data getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax *info.pline = line pltline,info ; ; If user hits 'APPLY' button, leave window up for next altitude entry ; IF mode EQ 'APPLY' THEN GOTO, ALTSETGP ENDELSE end 'SET_GMALT': begin ; ; Derive geometric height level for plot. Set flag, disable ZP slider, get current altitude ; from line structure, and update info line structure ; line.plotz = 2 widget_control, line.wfsl_lev, sensitive=0 alt = line.alt *info.pline = line ; ; Get user requested altitude and check for validity. ; ALTSETGM:setalt,info,line,alt,mode ; ; If no input altitude field found, quit altitude plotting ; IF alt EQ -2 THEN BEGIN line.plotz = 0 widget_control, line.wfsl_lev, sensitive=1 *info.pline = line pltline,info ENDIF ELSE BEGIN line.alt = alt data = *fields[line.ifield].data getaltzdata,info,line,data ;Need to get vertical data if plotting on altitude deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax *info.pline = line pltline,info ; ; If user hits 'APPLY' button, leave window up for next altitude entry ; IF mode EQ 'APPLY' THEN GOTO, ALTSETGM ENDELSE end 'SET_ZGALT': begin ; ; Geometric height level from input file for line. Set flag, disable ZP slider, get current ; altitude from line structure, and update info line structure ; line.plotz = 3 widget_control, line.wfsl_lev, sensitive=0 alt = line.alt *info.pline = line ; ; Get user requested altitude and check for validity. ; ALTSETZG:setalt,info,line,alt,mode ; ; If no input altitude field found, quit altitude plotting ; IF alt EQ -2 THEN BEGIN line.plotz = 0 widget_control, line.wfsl_lev, sensitive=1 *info.pline = line pltline,info ENDIF ELSE BEGIN line.alt = alt *info.pline = line pltline,info ; ; If user hits 'APPLY' button, leave window up for next altitude entry ; IF mode EQ 'APPLY' THEN GOTO, ALTSETZG ENDELSE end 'SET_ALT_OFF': begin line.plotz = 0 widget_control, line.wfsl_lev, sensitive=1 data = *fields[line.ifield].data *info.pline = line deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin & line.fmax=fmax *info.pline = line pltline,info end 'RESET_ZPAXIS': begin line.levmin = (*field.levs)[0] & line.levmax = (*field.levs)[field.nlev-1] print,'Line slices: reset y-axis (zp or ht) to full range.' data = *fields[line.ifield].data if line.plotz ge 1 and info.ftype eq 'WACCM' and line.plottype EQ 'profile' then *line.levs = *field.levs deflinedata,line,data line.fmin = MIN(*line.data) line.fmax = MAX(*line.data) IF line.plotz GE 1 THEN getzprof,info,line,'line',fields,zalt *info.pline = line pltline,info end 'SET_DATAAXIS': begin ; sets data axis limits line.fmin,max and updates *info.pline line = *info.pline setaxis_data,info,info.pline line = *info.pline pltline,info end 'RESET_DATAAXIS': begin data = *line.data ndata = N_ELEMENTS(data) line.fmin = MIN(data) & line.fmax = MAX(data) print,'Lines: reset data axis to full range.' *info.pline = line pltline,info end 'SET_1DDATAAXIS': begin ; sets data axis limits line.fmin,max and updates *info.pline line = *info.pline setaxis_1ddata,info,info.pline line = *info.pline pltline,info end 'RESET_1DDATAAXIS': begin data = *line.data ndata = N_ELEMENTS(data) line.fmin = MIN(data) & line.fmax = MAX(data) print,'Lines: reset data axis to full range.' *info.pline = line pltline,info end 'SET_LATAXIS': begin ; sets x-axis limits line.latmin,max and updates *info.pline setaxis_lat,info,info.pline pltline,info end 'RESET_LATAXIS': begin line.latmin = (*field.lats)[0] & line.latmax = (*field.lats)[field.nlat-1] print,'Line slices: reset x-axis (latitude) to full range.' *info.pline = line pltline,info end 'SET_LONAXIS': begin ; sets x-axis limits line.lonmin,max and updates *info.pline setaxis_lon,info,info.pline pltline,info end 'RESET_LONAXIS': begin line.lonmin = (*field.lons)[0] & line.lonmax = (*field.lons)[field.nlon-1] print, 'line.amplitude ', line.amplitude IF line.amplitude GT 0 THEN BEGIN line.lonmin = 0 line.lonmax = field.nlon ENDIF print,'Line slices: reset x-axis (longitude) to full range.' *info.pline = line pltline,info end 'SET_TIMEAXIS': begin ; sets time axis limits line.timemin,max and updates *info.pline IF info.ftype EQ 'WACCM' THEN setaxis_timew,info,info.pline $ ELSE setaxis_time,info,info.pline line = *info.pline times = *line.times data = *line.data timemin = line.timemin jmin = ixfind_nearest(times,timemin) line.fmin = data(jmin) timemax = line.timemax jmax = ixfind_nearest(times,timemax) line.fmax = data(jmax) line.fmin = MIN(data(jmin:jmax)) line.fmax = MAX(data(jmin:jmax)) print, 'Set data axis min,max = ', line.fmin, line.fmax *info.pline = line pltline,info end 'RESET_TIMEAXIS': begin times = *line.times ntimes = N_ELEMENTS(times) line.timemin = times[0] & line.timemax = times[ntimes-1] print,'Line slices: reset time axis to full range.' line.fmin = MIN(*line.data) line.fmax = MAX(*line.data) *info.pline = line pltline,info end 'ADD_YAX': begin line.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...' line.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...' line.rhyaxis = 0 endif else begin print,'Will add extra right-hand y-axis' endelse *info.pline = line pltline,info end 'RM_YAX': begin line.rhyaxis = 0 ; remove extra right-hand y-axis print,'Will remove extra right-hand y-axis' *info.pline = line pltline,info end 'CUSTOM_CONTOUR': begin line.setcontour = 'on' cmin=line.fmin & cmax=line.fmax & cint=line.cint & clineclr = line.clineclr custom_contour,info.tlb,cmin,cmax,cint,clineclr line.clineclr = clineclr data = *fields[line.ifield].data deflondata,line,data data = *line.data fminmax,data,fmin,fmax,line.missing_value levels = mkclevels(fmin,fmax,cmin,cmax,cint) line.fmin=cmin & line.fmax=cmax & line.cint=cint *line.clevels = levels *info.pline = line end 'RESET_CONTOUR': begin line.setcontour = 'off' cmin=0. & cmax=0. & cint=0. print,'Line slices: reset contour min,max to full range.' data = *fields[line.ifield].data deflinedata,line,data data = *line.data fminmax,data,fmin,fmax,line.missing_value levels = mkclevels(fmin,fmax,cmin,cmax,cint) line.fmin=cmin & line.fmax=cmax & line.cint=cint *line.clevels = levels *info.pline = line 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 pltline,info,/ps psoff widget_control,event.top,hourglass=0 endif end 'SAVE_PNG': begin windowsave = !d.window window,xsize=line.draw_xsize,ysize=line.draw_ysize,/pixmap windo = !d.window wset,windo setclrtab,info.colortab pltline,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 ; 'PROFILES': 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 line.plottype = 'profile' *info.pline = line print,'Set plot type to ',line.plottype pltline,info endelse end 'LATITUDE_SERIES': begin if mag eq 1 then begin print,'>>> WARNING: cannot make image of magnetic field because of ',$ 'irregular latitude grid. Staying with plot type ',line.plottype endif else begin line.plottype = 'latitude_series' data = *fields[line.ifield].data ; ; Set up sliders for this plot type ; line_sliders,line deflinedata,line,data *info.pline = line pltline,info endelse end 'LONGITUDE_SERIES': begin line.plottype = 'longitude_series' *info.pline = line widget_control,lon.minmaxmenu,sensitive=0 ; no image widget_control,lon.contourmenu,sensitive=1 ; doing contours end else: print,'>>> lines_event: unknown widget ',widget endcase *pinfo = info end ;----------------------------------------------------------------------- pro field_line_event,event ; ; User has selected a field. Read field from the file and update ; line structure. ; widget_control,event.id,get_uvalue=widget widget_control,event.top,get_uvalue=pinfo info = *pinfo line = *info.pline line.plotz = 0 line.levs = line.levszp line.levmin = MIN(*line.levs) line.levmax = MAX(*line.levs) fields = *info.fields gridtype_prev = fields[line.ifield].grid_type for i=0,info.nflds-1 do begin if (widget eq fields[i].name) then begin line.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) levs = *line.levs nlevs = N_ELEMENTS(levs) line.levmin = levs[0] line.levmax = levs[nLevs-1] line.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 line.field = field IF line.plottype EQ 'profile' THEN line.levs = line.field.levs ; ; Plotting levels are in a different location for WACCM ; IF (info.ftype EQ 'WACCM') AND (line.plottype EQ 'meridional' OR line.plottype EQ 'zonal') THEN BEGIN levs = *field.levsPlot line.levs = PTR_NEW(levs) nlevs = N_ELEMENTS(levs) ENDIF ELSE BEGIN levs = *line.levs nlevs = N_ELEMENTS(levs) ENDELSE line.levmin = levs[0] line.levmax = levs[nLevs-1] line.data = line.field.data fmin = min(*fields[i].data) & fmax = max(*fields[i].data) rpt_minmax,info,fields[i],fmin,fmax endelse data = *fields[line.ifield].data ; ; If this is a change in grid type, reset select-longitude slider: ; if fields[line.ifield].grid_type ne gridtype_prev then begin mag = 0 & if fields[line.ifield].grid_type eq 'magnetic' then mag = 1 base = widget_info(line.wfsl_lon,/parent) widget_control,line.wfsl_lon,/destroy lons = *fields[line.ifield].lons nlon = n_elements(lons) dlon = lons[1]-lons[0] ; new dlon ilon = ixfind(lons,line.slon,dlon) line.slon = lons(ilon) title = 'Select '+fields[line.ifield].grid_type+' Longitude' line.wfsl_lon = cw_fslide(base,minimum=lons[0],maximum=lons[nlon-1],$ delta=dlon,xsize=200,uvalue="SELECT_LON",format='(f7.2)',$ value=line.slon,title=title) ; ; If this is a change in grid type, reset select-longitude slider: ; base = widget_info(line.wfsl_lat,/parent) widget_control,line.wfsl_lat,/destroy lats = *fields[line.ifield].lats nlat = n_elements(lats) dlat = lats[1]-lats[0] ; new dlon ilat = ixfind(lats,line.slat,dlat) line.slat = lats(ilat) title = 'Select '+fields[line.ifield].grid_type+' Latitude' line.wfsl_lat = cw_fslide(base,minimum=lats[0],maximum=lats[nlat-1],$ delta=dlat,xsize=200,uvalue="SELECT_LAT",format='(f7.2)',$ value=line.slat,title=title) endif deflinedata,line,data if (not ptr_valid(line.data)) then begin print,'lines: invalid pointer returned from deflinedata -- returning' return endif ; ; Reset min,max and contour interval: ; data = *line.data fminmax,data,fmin,fmax,line.missing_value line.fmin=fmin line.fmax=fmax endif ; found field name endfor if fields[line.ifield].grid_type eq 'magnetic' and $ ((line.plottype eq 'image_only') or (line.plottype eq 'image+contours')) then begin print,'>>> WARNING: cannot make image of magnetic field because of ',$ 'irregular latitude grid. Switching to color-fill contour..' line.plottype = 'profile' widget_control,line.minmaxmenu,sensitive=0 widget_control,line.contourmenu,sensitive=1 endif ; ; Update state info: ; *info.fields = fields *info.pline = line *pinfo = info pltline,info end ;----------------------------------------------------------------------- ;----------------------------------------------------------------------- pro field1D_line_event,event ; ; User has selected a field. Read field from the file and update ; line structure. ; widget_control,event.id,get_uvalue=widget widget_control,event.top,get_uvalue=pinfo info = *pinfo line = *info.pline line.plotz = 0 ;line.levs = line.levszp ;line.levmin = MIN(*line.levs) ;line.levmax = MAX(*line.levs) fields1D = *info.fields1D for i=0,info.nflds1D-1 do begin if (widget eq fields1D[i].name) then begin line.ifield1D = i if ptr_valid(fields1D[i].data) then begin ; field has been read print,'Selected field ',fields1D[i].name fmin = min(*fields1D[i].data) & fmax = max(*fields1D[i].data) times = *line.times ntimes = N_ELEMENTS(times) line.timemin = times[0] line.timemax = times[ntimes-1] line.field1D = fields1D[i] endif else begin widget_control,/hourglass varget,info,fields1D[i],ncdata fields1D[i].data = ptr_new(ncdata) field1D = fields1D[i] line.field1D = field1D ; print, 'Number of line.field.levs in lines.pro ', n_elements(*line.field.levs) times = *line.times nTimes = N_ELEMENTS(times) line.timemin = times[0] line.timemax = times[nTimes-1] line.data = line.field1D.data fmin = min(*fields1D[i].data) & fmax = max(*fields1D[i].data) rpt_minmax,info,fields1D[i],fmin,fmax endelse data = *fields1D[line.ifield1D].data line.data = ptr_new(data) if (not ptr_valid(line.data)) then begin print,'lines: invalid pointer for chosen 1D field data -- returning' return endif ; ; Reset min,max and contour interval: ; fminmax,data,fmin,fmax,line.missing_value line.fmin=fmin line.fmax=fmax endif ; found field name endfor ; ; Update state info: ; *info.fields1D = fields1D *info.pline = line *pinfo = info pltline,info end ;----------------------------------------------------------------------- pro mtime_line_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 line = *info.pline field = fields[line.ifield] line.plotz = 0 line.levs = line.levszp line.levmin = MIN(*line.levs) line.levmax = MAX(*line.levs) 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_line_event: could not find index to model time ',$ mtime_request return found: line.imtime = imtime line.mtime = file.mtimes[*,imtime] ; ; Reset slt slider from new ut and current selected line: ; line.ut = line.mtime[1]+line.mtime[2]/60. line.sslt = fslt(line.sslt,line.ut,line.slon,"getlt",mag=mag) ; ; Define line slice data: ; data = *fields[line.ifield].data deflinedata,line,data fminmax,*line.data,fmin,fmax,line.missing_value line.fmin=fmin line.fmax=fmax ; *info.pline = line pltline,info end ; mtime_line_event ;----------------------------------------------------------------------- pro lines,info,linetype ; ; Set up line slice widget: ; file = *info.pfile ; file info structure fields = *info.fields ; fields info structure fields1D = *info.fields1D ; fields1D info structure ; title = 'Lines: '+linetype tlb = widget_base(column=1,mbar=mbar, title=title) ; line_ids = *info.pline_ids for i=0,n_elements(line_ids)-1 do begin if (line_ids(i) le 0) then begin line_ids(i) = tlb ; print,'lines: added tlb ',tlb,' to line_ids at i=',i goto,done endif endfor done: linebase = tlb missing_value = file.missing_value ; ; Handle 1D time plot type ; IF linetype eq 'time' THEN BEGIN fieldsmenu = fields_menu(mbar,fields1D,'field1D_line_event') ENDIF ELSE BEGIN ; ; Fields menu: ; fieldsmenu = fields_menu(mbar,fields,'field_line_event') ; ; Model times menu: ; mtimesmenu = mtime_menu(mbar,file.mtimes,'mtime_line_event') ENDELSE ;linetype mtime = file.mtimes[*,0] imtime = 0 ; ; ------------------------- Plot options menus ----------------- ; optsmenu = widget_button(mbar,value='PlotOptions') IF linetype NE 'time' THEN BEGIN 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') ENDIF ; ; Set up plot options menu based on linetype ; ; 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)(Profiles only): ; IF linetype eq 'profile' THEN BEGIN 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 amplitude: ; 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 (LOG10)',uvalue='AMPLITUDE_ON_LOG') button = widget_button(spmenu,value='Wavenumber Amplitude Off',uvalue='AMPLITUDE_OFF') ; ; User set zp axis range: ; zpaxismenu = widget_button(optsmenu,value='Set vertical axis range',/menu) button = widget_button(zpaxismenu,value='Reset to full range',$ uvalue='RESET_ZPAXIS') button = widget_button(zpaxismenu,value='Set vertical axis min,max...',$ uvalue='SET_ZPAXIS') ; ; User set data axis range (species/parameter): ; dataaxismenu = widget_button(optsmenu,value='Set data axis range',/menu) button = widget_button(dataaxismenu,value='Reset to full range',$ uvalue='RESET_DATAAXIS') button = widget_button(dataaxismenu,value='Set data axis min,max...',$ uvalue='SET_DATAAXIS') ; ; Plot profiles on altitude in the vertical ; zaltmenu = widget_button(optsmenu,value='Set y-axis to Altitude',/menu) button = widget_button(zaltmenu,value='Geopotential Altitude',uvalue='GPZALT_ON_PRF') button = widget_button(zaltmenu,value='Geometric Altitude',uvalue='GMZALT_ON_PRF') button = widget_button(zaltmenu,value='Altitude As Vertical Axis Off',uvalue='ZALT_OFF_PRF') ENDIF ELSE IF linetype eq 'meridional' THEN BEGIN ; ; 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 amplitude: ; 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 (LOG10)',uvalue='AMPLITUDE_ON_LOG') button = widget_button(spmenu,value='Wavenumber Amplitude Off',uvalue='AMPLITUDE_OFF') ; ; User set data axis range (species/parameter): ; dataaxismenu = widget_button(optsmenu,value='Set data axis range',/menu) button = widget_button(dataaxismenu,value='Reset to full range',$ uvalue='RESET_DATAAXIS') button = widget_button(dataaxismenu,value='Set data axis min,max...',$ uvalue='SET_DATAAXIS') ; ; User set lat axis range: ; lataxismenu = widget_button(optsmenu,value='Set latitude axis range',/menu) button = widget_button(lataxismenu,value='Reset to full range',$ uvalue='RESET_LATAXIS') button = widget_button(lataxismenu,value='Set latitude axis min,max...',$ uvalue='SET_LATAXIS') ; ; Altitude selection ; altmenu = widget_button(optsmenu,value='Altitude Level',/menu) button = widget_button(altmenu,value='Set Geopotential Altitude',$ uvalue='SET_GPALT') button = widget_button(altmenu,value='Set Geometric Altitude',$ uvalue='SET_GMALT') ; ; Put ZG altitude option in menu if found in input file field list ; fields = *info.fields ixz = -1 for i=0,n_elements(fields)-1 do begin if strcompress(fields[i].name,/remove_all) eq 'ZG' then ixz = i endfor if ixz ne -1 then begin button = widget_button(altmenu,value='Set Geometric Altitude ZG',$ uvalue='SET_ZGALT') endif button = widget_button(altmenu,value='Set Altitude Off',$ uvalue='SET_ALT_OFF') ENDIF ELSE IF linetype eq 'zonal' THEN BEGIN ; ; Plot meridional means: ; mmmenu = widget_button(optsmenu,value='Meridional Mean',/menu) button = widget_button(mmmenu,value='Meridional Mean On',uvalue='MERIDIONAL_MEAN_ON') button = widget_button(mmmenu,value='Meridional Mean Off',uvalue='MERIDIONAL_MEAN_OFF') ; ; Plot wavenumber amplitude: ; 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 (LOG10)',uvalue='AMPLITUDE_ON_LOG') button = widget_button(spmenu,value='Wavenumber Amplitude Off',uvalue='AMPLITUDE_OFF') ; ; User set data axis range (species/parameter): ; dataaxismenu = widget_button(optsmenu,value='Set data axis range',/menu) button = widget_button(dataaxismenu,value='Reset to full range',$ uvalue='RESET_DATAAXIS') button = widget_button(dataaxismenu,value='Set data axis min,max...',$ uvalue='SET_DATAAXIS') ; ; User set lon axis range: ; lonaxismenu = widget_button(optsmenu,value='Set longitude axis range',/menu) button = widget_button(lonaxismenu,value='Reset to full range',$ uvalue='RESET_LONAXIS') button = widget_button(lonaxismenu,value='Set longitude axis min,max...',$ uvalue='SET_LONAXIS') ; ; Altitude selection ; altmenu = widget_button(optsmenu,value='Altitude Level',/menu) button = widget_button(altmenu,value='Set Geopotential Altitude',$ uvalue='SET_GPALT') button = widget_button(altmenu,value='Set Geometric Altitude',$ uvalue='SET_GMALT') ; ; Put ZG altitude option in menu if found in input file field list ; fields = *info.fields ixz = -1 for i=0,n_elements(fields)-1 do begin if strcompress(fields[i].name,/remove_all) eq 'ZG' then ixz = i endfor if ixz ne -1 then begin button = widget_button(altmenu,value='Set Geometric Altitude ZG',$ uvalue='SET_ZGALT') endif button = widget_button(altmenu,value='Set Altitude Off',$ uvalue='SET_ALT_OFF') ENDIF ELSE IF linetype eq 'time' THEN BEGIN ; ; User set data axis range (species/parameter): ; dataaxismenu = widget_button(optsmenu,value='Set data axis range',/menu) button = widget_button(dataaxismenu,value='Reset to full range',$ uvalue='RESET_DATAAXIS') button = widget_button(dataaxismenu,value='Set data axis min,max...',$ uvalue='SET_1DDATAAXIS') ; ; User set time axis range: ; timeaxismenu = widget_button(optsmenu,value='Set time axis range',/menu) button = widget_button(timeaxismenu,value='Reset to full range',$ uvalue='RESET_TIMEAXIS') button = widget_button(timeaxismenu,value='Set time axis min,max...',$ uvalue='SET_TIMEAXIS') ENDIF ;plot options depending on linetype ; ; ------------------------- Animation menus -------------------------- ; IF linetype NE 'time' THEN animmenu = widget_button(mbar,value='Animate') IF linetype EQ 'profile' OR linetype EQ 'meridional' THEN BEGIN 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') ENDIF IF linetype eq 'zonal' OR linetype EQ 'profile' THEN BEGIN animlon = widget_button(animmenu,value='Animate in latitude (fixed ut)',$ uvalue='ANIM_LAT') ENDIF IF linetype NE 'zonal' AND linetype NE 'time' THEN BEGIN animlon = widget_button(animmenu,value='Animate in longitude (fixed ut)',$ uvalue='ANIM_LON') ENDIF ; ; ------------------------- 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') ; ; Base for sliders that select latitude/longitude/time/level: ; sliderbase = widget_base(tlb,column=2,/frame) *info.pline_ids = line_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] slat = lats[0] lons = *fields[0].lons lonmin = lons[0] & lonmax = lons[n_elements(lons)-1] slon = lons[0] ; ; Vertical levels handled different for each line plot type ; IF (info.ftype EQ 'WACCM') AND (linetype EQ 'meridional' OR linetype EQ 'zonal') THEN BEGIN levs = *fields[0].levsPlot nlevs = size(levs,/n_elements) levmin = levs[0] levmax = levs[nlevs-1] ENDIF ELSE IF linetype eq 'time' THEN BEGIN times = *fields1D[0].times ntimes = n_elements(times) levmin = 0 levmax = 0 ENDIF ELSE BEGIN if ptr_valid(fields[0].levs) then $ levs = *fields[0].levs else levs = fields[1].levs levmin = levs[0] ;nlev = fields[0].nlev nlev = size(levs,/n_elements) levmax = levs[nlev-1] ENDELSE ; ; Set zp levels to levels at start ; if linetype ne 'time' then levszp = levs ; ; Get local time: ; mag = 0 & if fields[0].grid_type eq 'magnetic' then mag = 1 ut = mtime[1]+mtime[2]/60. sslt = fslt(sslt,ut,slon,"getlt",mag=mag) ; ; -------------------------- Line slice structure --------------------- ; line = {linestruct, $ field:fields[0], $ ; current field structure field1D:fields1D[0], $ ; current 1D field structure ifield:0, $ ; index to current field ifield1D:0, $ ; index to current field slon:slon, $ ; selected longitude slat:slat, $ ; selected latitude slev:levmin, $ ; selected level ilon:0, $ ; selected longitude ilat:0, $ ; selected latitude ilev:0, $ ; selected level ut:ut, $ ; ut(hrs) sslt:sslt, $ ; selected local time line_type:'line', $ ; 'line','slt', or 'zm' mtime:mtime, $ ; model time (default first time on file) imtime:imtime, $ ; index to mtime (file.mtimes[imtime]) missing_value:missing_value, $ ; missing data value linebase:linebase, $ ; widget id of cw lev slider base sliderbase:sliderbase, $ ; widget id of cw lev slider base rhyaxis:1, $ ; if > 0 then add extra right-hand y-axis wfsl_lon:0L, $ ; widget id of lon selection slider wfsl_lat:0L, $ ; widget id of lat selection slider wfsl_lev:0L, $ ; widget id of lev selection slider wfsl_slt:0L, $ ; widget id of slt selection slider wfsl_wvn:0L, $ ; widget id of amplitude wavenumber selection slider 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 ftype:info.ftype, $ ; Type of input file (TIME-GCM or WACCM presently) plottype:linetype, $ ; 4 options (see plottype_menu) zonalmean:0, $ ; plot zonal mean if zonalmean==1 meridionalmean:0, $ ; plot meridional mean if meridionalmean==1 amplitude:0, $ ; plot wavenumber amplitude if == 1 and log if == 2 wavenumber:1, $ ; wavenumber for amplitude plotz:0, $ ; plot altitude as vertical axis(profiles) if = 1 alt:0, $ ; altitude level to plot in km (default zero) fmin:0.,fmax:0., $ ; field min,max 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 lats:ptr_new(/allocate_heap), $ ; latitudes latmin:latmin,latmax:latmax, $ ; min,max latitude lons:ptr_new(/allocate_heap), $ ; latitudes lonmin:lonmin,lonmax:lonmax, $ ; min,max latitude times:ptr_new(/allocate_heap), $ ; times timemin:0.,timemax:0., $ ; min,max of lev y-axis data:ptr_new(/allocate_heap) $ ; 1d data (levs) } ; ; For time plot, set min/max ; IF linetype EQ 'time' THEN BEGIN line.timemin = times[0] line.timemax = times[ntimes-1] ENDIF ; ; Update state info ; line.lats = ptr_new(lats) line.lons = ptr_new(lons) line.levs = ptr_new(levs) line.levszp = ptr_new(levszp) line.times = ptr_new(times) *info.fields = fields info.pline = ptr_new(line) end