;+ ;PROCEDURE: contour2d,data ;PURPOSE: ; Produces contour plots of pitch angle dist.s from 2D data structures. ;INPUTS: ; data - structure containing 2d data (obtained from get_fa_???() routine) ; e.g. "get_fa_ees, get_fa_ies, etc." ;KEYWORDS: ; LIMITS - A structure containing limits and display options. ; see: "options", "xlim" and "ylim", to change limits ; UNITS - convert to given data units before plotting ; MSEC - Subtitle will include milliseconds ; TITLE - Title to be plotted, ; - set title=' ' for NO Title! ; - set title='1' for just the time in the title ; XTITLE - xtitle to be plotted, ; - set xtitle=' ' for NO xtitle!, default determined by VEL keyword ; YTITLE - ytitle to be plotted, ; - set ytitle=' ' for NO ytitle!, default=data.units_name ; ZTITLE - ztitle to be plotted, ; - set ztitle=' ' for NO ytitle!, default='Log!D10!N('+y_units+')' ; RETRACE - set to number of retrace steps removed, ; - typically set to 1 for FAST esas ; - minus number will remove -(retrace) steps from end of sweep ; VEL - If set, x-axis is velocity km/s -- Default is Energy (eV) ; ; NCONT - Number of contours to be plotted, default = 8 ; LEVELS - Explicit contour levels, default levels spaced down ; from max by 10^.5 ; FILL - If set, contours are filled with solid color or gray scale ; BW - If set, contours are white, no affect on fill plots ; PURE - If set, 6 pure colors are cycled through for levels ; POLAR - Makes a polar plot ; ROTATE - Exchanges x and y axes for non-polar plots ; LABEL - Labels the contour levels ; LAB_0 - Puts 0 in center of plot (default is 90). Labels pitch angles with 90 degree increments. ; LAB_90 - Puts 90 in center of plot (default is 90). Labels pitch angles with 90 degree increments. ; LAB_180 - Puts 180 in center of plot (default is 90). Labels pitch angles with 90 degree increments. ; XMARGIN - Change xmargin from default ; YMARGIN - Change ymargin from default ; ;See "pitch2d" for another means of plotting data. ;See "conv_units" to change units. ; ; ;CREATED BY: J. McFadden 96-8-31 ;FILE: contour2d.pro ;VERSION 1. ;MODIFICATIONS: ; McFadden 96-9-3 More keywords added ; Delory Polar keyword ; McFadden 97-11-20 Lab_0,LAB_180 keywords ; McFadden 98-3-3 xmargin, ymargin keywords ; ;- pro contour2d,tempdat, $ LIMITS = limits, $ UNITS = units, $ MSEC = msec, $ TITLE = title, $ YTITLE = ytitle, $ XTITLE = xtitle, $ ZTITLE = ztitle, $ RETRACE = retrace, $ VEL = vel, $ NCONT = ncont, $ LEVELS = levels, $ FILL = fill, $ BW = bw, $ PURE = pure, $ POLAR = polar, $ ROTATE = rotate, $ LABEL = label, $ LAB_180 = lab_180, $ LAB_90 = lab_90, $ LAB_0 = lab_0, $ XMARGIN = xmargin, $ YMARGIN = ymargin, $ POINTS = points if data_type(tempdat) ne 8 or tempdat.valid eq 0 then begin print,'Invalid Data' return endif !y.omargin =[2,3] ; temporary fix if not keyword_set(units) then str_element,limits,'units',value=units ;cnt = conv_units(tempdat,'counts') ;cnt.data(*,*) = .5 ;err = conv_units(cnt,units) data3d = conv_units(tempdat,units) if ndimen(data3d.data) eq ndimen(data3d.bins) then data3d.data=data3d.data*data3d.bins if not keyword_set(title) then begin title = data3d.project_name+' '+data3d.data_name+' ' + $ data3d.units_name title = title + '!C'+trange_str(data3d.time, data3d.end_time, $ MSEC=msec) endif else if title eq '1' then begin title = '' + '!C'+trange_str(data3d.time, data3d.end_time, $ MSEC=msec) endif nenergy = data3d.nenergy nbins = data3d.nbins ydat = data3d.theta zdat = data3d.data str_element,limits,'velocity',value=vel if keyword_set(vel) then begin xdat = velocity(data3d.energy,data3d.mass) if keyword_set(polar) then begin if not keyword_set(ytitle) then ytitle = 'Perp. Velocity (km/s)' if not keyword_set(xtitle) then xtitle = 'Para. Velocity (km/s)' endif else begin if not keyword_set(ytitle) then ytitle = 'Pitch Angle (deg)' if not keyword_set(xtitle) then xtitle = 'Velocity (km/s)' endelse endif else begin xdat = data3d.energy if keyword_set(polar) then begin xdat = alog10(xdat) if not keyword_set(ytitle) then ytitle = 'Log Perp. Energy (eV)' if not keyword_set(xtitle) then xtitle = 'Log Para. Energy (eV)' endif else begin if not keyword_set(ytitle) then ytitle = 'Pitch Angle (deg)' if not keyword_set(xtitle) then xtitle = 'Energy (eV)' endelse endelse if keyword_set(retrace) then begin if retrace gt 0 then zdat(0:retrace-1,*)=0. $ else zdat(nenergy+retrace:nenergy-1,*)=0. endif if keyword_set(lab_0) then begin ydat = ((360.*(ydat/360.-floor(ydat/360.))) mod 360.) endif else if keyword_set(lab_180) then begin ydat = ((360.*(ydat/360.-floor(ydat/360.)) + 180.) mod 360.) -180. endif else begin ydat = ((360.*(ydat/360.-floor(ydat/360.)) + 90.) mod 360.) -90. endelse minvar = min(reform(ydat(0,*)),indminvar) if (indminvar gt 1) then begin if ydat(0,0) gt ydat(0,1) then indminvar=indminvar+1 endif else begin if ydat(0,2) gt ydat(0,3) then indminvar=indminvar+1 endelse if 1 then begin xdat=transpose(xdat) ydat=transpose(ydat) zdat=transpose(zdat) xdat = shift(xdat,-indminvar,0) ydat = shift(ydat,-indminvar,0) zdat = shift(zdat,-indminvar,0) xdat=transpose(xdat) ydat=transpose(ydat) zdat=transpose(zdat) endif else begin xdat = shift(xdat,0,-indminvar) ydat = shift(ydat,0,-indminvar) zdat = shift(zdat,0,-indminvar) endelse ; Use the following if array order matters ;if ydat(0,0) gt ydat(0,1) then begin ; xdat = reverse(xdat,1) ; ydat = reverse(ydat,1) ; ydat = reverse(ydat,1) ;endif ;if xdat(1,0) gt xdat(2,0) then begin ; xdat = reverse(xdat,0) ; ydat = reverse(ydat,0) ; ydat = reverse(ydat,0) ;endif if ydat(0,0) gt ydat(0,1) then begin if keyword_set(lab_0) then begin ydat(*,0) = ydat(*,0) + 360.*(ydat(*,0) lt 180.) ydat(*,1) = ydat(*,1) + 360.*(ydat(*,1) lt 180.) ydat(*,nbins-1) = ydat(*,nbins-1) - 360.*(ydat(*,nbins-1) gt 180.) ydat(*,nbins-2) = ydat(*,nbins-2) - 360.*(ydat(*,nbins-2) gt 180.) endif else if keyword_set(lab_180) then begin ydat(*,0) = ydat(*,0) + 360.*(ydat(*,0) lt 0.) ydat(*,1) = ydat(*,1) + 360.*(ydat(*,1) lt 0.) ydat(*,nbins-1) = ydat(*,nbins-1) - 360.*(ydat(*,nbins-1) gt 0.) ydat(*,nbins-2) = ydat(*,nbins-2) - 360.*(ydat(*,nbins-2) gt 0.) endif else begin ydat(*,0) = ydat(*,0) + 360.*(ydat(*,0) lt 0.) ydat(*,1) = ydat(*,1) + 360.*(ydat(*,1) lt 0.) ydat(*,nbins-1) = ydat(*,nbins-1) - 360.*(ydat(*,nbins-1) gt 0.) ydat(*,nbins-2) = ydat(*,nbins-2) - 360.*(ydat(*,nbins-2) gt 0.) endelse endif else begin if keyword_set(lab_0) then begin ydat(*,0) = ydat(*,0) - 360.*(ydat(*,0) gt 180.) ydat(*,1) = ydat(*,1) - 360.*(ydat(*,1) gt 180.) ydat(*,nbins-1) = ydat(*,nbins-1) + 360.*(ydat(*,nbins-1) lt 180.) ydat(*,nbins-2) = ydat(*,nbins-2) + 360.*(ydat(*,nbins-2) lt 180.) endif else if keyword_set(lab_180) then begin ydat(*,0) = ydat(*,0) - 360.*(ydat(*,0) gt 0.) ydat(*,1) = ydat(*,1) - 360.*(ydat(*,1) gt 0.) ydat(*,nbins-1) = ydat(*,nbins-1) + 360.*(ydat(*,nbins-1) lt 0.) ydat(*,nbins-2) = ydat(*,nbins-2) + 360.*(ydat(*,nbins-2) lt 0.) endif else begin ydat(*,0) = ydat(*,0) - 360.*(ydat(*,0) gt 0.) ydat(*,1) = ydat(*,1) - 360.*(ydat(*,1) gt 0.) ydat(*,nbins-1) = ydat(*,nbins-1) + 360.*(ydat(*,nbins-1) lt 0.) ydat(*,nbins-2) = ydat(*,nbins-2) + 360.*(ydat(*,nbins-2) lt 0.) endelse endelse ; Set plot limits if keyword_set(polar) then begin xmax=max(xdat(*,0)) xrange=[-xmax,xmax] yrange=[-xmax,xmax] xstyle=0 ystyle=0 ;r_excl = (xdat^2+ydat^2)^0.5 ;nan_data = where(r_excl LE 0.1*max(r_excl)) ;if nan_data(0) GE 0 then zdat(nan_data) = !values.f_nan endif else begin xmin=min(xdat(*,0))-1. > .1 xmax=max(xdat(*,0)) xrange=[xmin,xmax] xstyle=1 xlog=1 ystyle=1 ylog=0 endelse ind=where(zdat ne 0.) zmin=min(zdat(ind)) zmax=max(zdat) zrange=[zmin,zmax] zlog=1 if not keyword_set(polar) then begin if max(tempdat.theta) gt 200. then begin yrange=[-100,280] yticks = 4 ytickv = [-90,0,90,180,270] endif else begin yrange=[-10,190] yticks = 2 ytickv = [0,90,180] endelse endif else begin yticks = 0 ytickv = 0 endelse if keyword_set(limits) then begin str_element,limits,'xrange',index=index if index ge 0 then xrange=limits.xrange str_element,limits,'xstyle',index=index if index ge 0 then xstyle=limits.xstyle str_element,limits,'xlog',index=index if index ge 0 then xlog=limits.xlog str_element,limits,'yrange',index=index if index ge 0 then begin yrange=limits.yrange yticks=0 ytickv=0 endif str_element,limits,'ystyle',index=index if index ge 0 then ystyle=limits.ystyle str_element,limits,'ylog',index=index if index ge 0 then ylog=limits.ylog str_element,limits,'zrange',index=index if index ge 0 then begin zrange=limits.zrange if n_elements(limits.zrange) GT 1 then begin zmin = limits.zrange(0) zmax = limits.zrange(1) endif endif str_element,limits,'zlog',index=index if index ge 0 then zlog=limits.zlog endif if not keyword_set(levels) then begin if keyword_set(ncont) then begin if (ncont GT 29 or ncont LT 1) then begin print,'CONTOUR2D: Keyword NCONT must be in the range 1 to 29.' print,'Setting NCONT = 25' ncont=25 endif endif if not keyword_set(ncont) then ncont=25 if zlog eq 1 then begin ; levels=zrange(1)*10.^(-.5*findgen(ncont)) levels=zrange(1)*10.^(-(findgen(ncont)/ncont * (alog10(zmax) - $ alog10(zmin)))) levels=reverse(levels) endif else begin levels=(zrange(1)-zrange(0))*findgen(ncont)/ncont + zrange(0) endelse endif else ncont = dimen1(levels) if keyword_set(bw) and not keyword_set(fill) then c_colors=[1000] else $ begin ; if keyword_set(bw) then loadct2,42 else loadct2,39 if keyword_set(pure) then c_colors=bytescale(pure=ncont) else $ c_colors=bytescale(findgen(ncont)) endelse if keyword_set(polar) then begin if not keyword_set(fill) then fill=0 ydat=!pi*ydat/180. ; Add donut hole rmin = 0.8 * min(xdat(*,0)) thdim = dimen2(xdat) xdat = [fltarr(1,thdim),xdat] xdat(0,*) = rmin ydat = [fltarr(1,thdim),ydat] ydat(0,*) = ydat(1,*) zdat = [fltarr(1,thdim),zdat] zdat(0,*) = 0. if not keyword_set(xmargin) then xmargin=[12,12] if not keyword_set(ymargin) then ymargin=[5,5] polar_contour, zdat, ydat, xdat, title=title, xtitle=xtitle, $ ytitle=ytitle, c_colors=c_colors, levels=levels, fill=fill, $ xrange=xrange, yrange=yrange, ystyle=ystyle, xstyle=xstyle, $ xmargin=xmargin,ymargin=ymargin if keyword_set(points) then begin if keyword_set(xrange) and keyword_set(yrange) then begin ind=where(xdat*cos(ydat) gt xrange(0) and xdat*cos(ydat) lt xrange(1) and xdat*sin(ydat) gt yrange(0) and xdat*sin(ydat) lt yrange(1)) xyouts,xdat(ind)*cos(ydat(ind)),xdat(ind)*sin(ydat(ind)),'.' endif else if keyword_set(xrange) then begin ind=where(xdat*cos(ydat) gt xrange(0) and xdat*cos(ydat) lt xrange(1)) xyouts,xdat(ind)*cos(ydat(ind)),xdat(ind)*sin(ydat(ind)),'.' endif else if keyword_set(yrange) then begin ind=where(xdat*sin(ydat) gt yrange(0) and xdat*sin(ydat) lt yrange(1)) xyouts,xdat(ind)*cos(ydat(ind)),xdat(ind)*sin(ydat(ind)),'.' endif else xyouts,xdat,ydat,'.' endif endif else begin if not keyword_set(xmargin) then xmargin=[10,10] if not keyword_set(ymargin) then ymargin=[4,2] if keyword_set(rotate) then begin zdat=transpose(zdat) xdat=transpose(xdat) ydat=transpose(ydat) contour, zdat, ydat, xdat, title=title, xtitle=ytitle, ytitle=xtitle, $ c_colors=c_colors, levels=levels, yrange=xrange, ystyle=xstyle, $ ylog=xlog, xrange=yrange, xstyle=ystyle, xlog=ylog, $ fill=fill, xmargin=xmargin, ymargin=ymargin, xticks=yticks, xtickv=ytickv endif else begin contour, zdat, xdat, ydat, title=title, xtitle=xtitle, ytitle=ytitle, $ c_colors=c_colors, levels=levels, yrange=yrange, ystyle=ystyle, $ ylog=ylog, xrange=xrange, xstyle=xstyle, xlog=xlog, $ fill=fill, xmargin=xmargin, ymargin=ymargin, yticks=yticks, ytickv=ytickv endelse if keyword_set(points) then begin if keyword_set(xrange) and keyword_set(yrange) then begin ind=where(xdat gt xrange(0) and xdat lt xrange(1) and ydat gt yrange(0) and ydat lt yrange(1)) xyouts,xdat(ind),ydat(ind),'.' endif else if keyword_set(xrange) then begin ind=where(xdat gt xrange(0) and xdat lt xrange(1)) xyouts,xdat(ind),ydat(ind),'.' endif else if keyword_set(yrange) then begin ind=where(ydat gt yrange(0) and ydat lt yrange(1)) xyouts,xdat(ind),ydat(ind),'.' endif else xyouts,xdat,ydat,'.' endif endelse time_stamp if keyword_set(label) then begin bar_levels = [[c_colors],[c_colors]] bar_width = 0.03*(!x.window(1)-!x.window(0)) bar_start = 0.01 bar_pos1_norm = [!x.window(1)+bar_start, !y.window(0)] bar_height = !y.window(1) - !y.window(0) bar_pos1_dev = convert_coord(bar_pos1_norm(0), bar_pos1_norm(1), $ /norm, /to_device) bar_pos2_dev = convert_coord(bar_pos1_norm(0) + bar_width, $ bar_pos1_norm(1) + bar_height, /norm, $ /to_device) x_size = -(bar_pos1_dev(0) - bar_pos2_dev(0)) y_size = -(bar_pos1_dev(1) - bar_pos2_dev(1)) bar_pos2_norm = convert_coord(bar_pos1_dev(0)+x_size, $ bar_pos1_dev(1)+y_size, /device, $ /to_norm) bar_levels = transpose(congrid(bar_levels,y_size,x_size)) if !d.name EQ 'PS' then bar_levels = $ transpose(congrid([[c_colors],[c_colors]],200,50)) tv, bar_levels, bar_pos1_norm(0), bar_pos1_norm(1), $ xsize = bar_pos2_norm(0) - bar_pos1_norm(0), $ ysize = bar_pos2_norm(1) - bar_pos1_norm(1), /norm ; print,bar_pos1_norm ; print,bar_pos2_norm bar_min = alog10(levels(0)) bar_max = alog10(levels(ncont-1)) y_units = strlowcase(units) case y_units of 'eflux':y_units = 'eV/(cm!E2!N-s-sr-eV)' 'rate':y_units = '#/sec' 'crate':y_units = 'Deadtime Corrected #/sec' 'flux':y_units = '#/(cm!E2!N-s-sr-eV)' 'df':y_units = '#/(cm!E3!N-(km/sec)!E3!N)' else:y_units = units endcase if not keyword_set(ztitle) then ztitle='Log!D10!N('+y_units+')' if label eq 3 then ztitle=' ' axis, bar_pos2_norm(0),0,0, yaxis=1, yrange=[bar_min,bar_max], $ ystyle=1, yticks=4, ytitle=ztitle, $ yticklen = 0.02, /norm endif !y.omargin = [0,0] return end