;+ ;PROCEDURE: tsnap ;PURPOSE: ; Tplot variables with two independent variables (time and some other ; parameter) are often displayed as color spectrograms, where the Y ; axis is the second independent variable and color represents the ; dependent variable (Z). Sometimes, the color scale does not ; accurately portray the variation in Z, or it is difficult to tell ; whether a color gradient is significant. ; ; This routine plots cuts of color spectrograms across the second ; independent variable at time(s) selected by the mouse. You can plot ; error bars if DY is provided as a tag in the tplot variable structure. ; This procedure can average in time (and propagate errors) to improve ; statistics. ; ; Unless keyword SUM is set, you can hold down the left mouse button ; and drag for a movie effect. Click the right mouse button at any time ; to exit. ; ;USAGE: ; tsnap, var ; ;INPUTS: ; var: Tplot variable name or number. If not specified, determine ; based on which panel the mouse is in when clicked. ; ; If specified, this must have two independent variables ; (time and some other parameter). This cannot be a compound ; variable (list of variables to be plotted in the same panel). ; You must specify which variable within the list. ; ;KEYWORDS: ; NAVG: Number of times to average centered on the selected time. ; This is forced to be an odd number. Default = 1. ; ; SUM: Average all times between two selected times. ; ; XSMO: Number of points to smooth in X. Default = 1 (no smoothing). ; ; KEEP: Do not close the snapshot window on exit. ; ; DYDX: Plot the first (DYDX=1) or second (DYDX=2) derivative. ; Default = 0 (just plot Y). ; ; ERR: If the tplot variable has a DY tag, then plot error bars for ; each point. Propagate uncertainties when NAVG or SUM is set. ; ; Passes many keywords to WIN (e.g. MONITOR, DX, DY, etc.). If WIN is ; enabled (win, /config), then by default the snapshot window will be ; placed in the secondary monitor. ; ; Passes many keywords to PLOT (e.g., XSIZE, YTITLE, etc.). If not set, ; TITLE becomes the time or time range of the snapshot. ; ; KEY: Alternate method for setting keywords. Structure containing ; keyword(s) for this routine, plus many keywords for WIN and ; PLOT. Unrecognized keywords can be added to the structure ; but will subsequently be ignored. Ambiguous keywords are also ; ignored, but they will generate error messages. ; ; {KEYWORD: value, KEYWORD: value, ...} ; ; This allows you to gather keywords into a single structure and ; use them multiple times without a lot of typing. In case of ; conflict, keywords set explicitly take precedence over KEY. ; ; $LastChangedBy: dmitchell $ ; $LastChangedDate: 2024-05-05 19:11:56 -0700 (Sun, 05 May 2024) $ ; $LastChangedRevision: 32550 $ ; $URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/spdsoft/tags/spedas_6_1/general/misc/tsnap.pro $ ; ;CREATED BY: David L. Mitchell ;- pro tsnap, var, navg=navg, sum=sum, xsmo=xsmo, keep=keep, dydx=dydx, err=err, key=key, $ ; WIN monitor=monitor, secondary=secondary, xsize=xsize, ysize=ysize, dx=dx, dy=dy, $ corner=corner, center=center, xcenter=xcenter, ycenter=ycenter, norm=norm, $ xpos=xpos, ypos=ypos, full=full, xfull=xfull, yfull=yfull, $ ; PLOT title=title, xtitle=xtitle, ytitle=ytitle, xlog=xlog, ylog=ylog, xrange=xrange, $ yrange=yrange, xstyle=xstyle, ystyle=ystyle, linestyle=linestyle, psym=psym, $ symsize=symsize, thick=thick, ticklen=ticklen, charsize=charsize, xmargin=xmargin, $ ymargin=ymargin, xminor=xminor, yminor=yminor, xthick=xthick, ythick=ythick, $ xtickformat=xtickformat, ytickformat=ytickformat, xtickinterval=xtickinterval, $ ytickinterval=ytickinterval, xticklen=xticklen, yticklen=yticklen, xticks=xticks, $ yticks=yticks ; Set keywords using the KEY structure if (size(key,/type) eq 8) then begin ktag = tag_names(key) tlist = ['NAVG','SUM','XSMO','KEEP','DYDX','ERR', $ 'MONITOR','SECONDARY','XSIZE','YSIZE','DX','DY','CORNER','CENTER','XCENTER','YCENTER', $ 'NORM','XPOS','YPOS','FULL','XFULL','YFULL', $ 'TITLE','XTITLE','YTITLE','XLOG','YLOG','XRANGE','YRANGE','XSTYLE','YSTYLE','LINESTYLE', $ 'PSYM','SYMSIZE','THICK','TICKLEN','CHARSIZE','XMARGIN','YMARGIN','XMINOR','YMINOR', $ 'XTHICK','YTHICK','XTICKFORMAT','YTICKFORMAT','XTICKINTERVAL','YTICKINTERVAL', $ 'XTICKLEN','YTICKLEN','XTICKS','YTICKS'] for j=0,(n_elements(ktag)-1) do begin i = strmatch(tlist, ktag[j]+'*', /fold) case (total(i)) of 0 : ; keyword not recognized -> do nothing 1 : begin kname = (tlist[where(i eq 1)])[0] ok = execute('kset = size(' + kname + ',/type) gt 0',0,1) if (not kset) then ok = execute(kname + ' = key.(j)',0,1) end else : print, "Keyword ambiguous: ", ktag[j] endcase endfor endif ; Set some defaults if (n_elements(navg) gt 0) then k = (round(navg[0]) - 1)/2 > 0 else k = 0 npts = keyword_set(sum) ? 2 : 1 keep = keyword_set(keep) xsmo = (n_elements(xsmo) gt 0) ? fix(xsmo[0]) > 1 : 1 if (size(dydx,/type) eq 0) then dydx = 0 else dydx = fix(dydx[0]) < 2 > 0 dx = (n_elements(dx) gt 0) ? fix(dx[0]) : 10 dy = (n_elements(dy) gt 0) ? fix(dy[0]) : 10 secondary = (n_elements(secondary) gt 0) ? keyword_set(secondary) : 1 tiny = 1.e-31 ; Make sure the tplot variable exists and has the standard tags and correct dimensions ctime,t,panel=p,npoints=npts,/silent if (npts eq 2) then cursor,cx,cy,/norm,/up ; make sure mouse button is released if (size(t,/type) eq 2) then return if (n_elements(var) eq 0) then begin tplot_options, get=topt var = topt.varnames[p[0]] endif get_data, var, data=dat, alim=lim, index=i if (i eq 0) then begin print,"Tplot variable not found: ",var return endif if (size(dat,/type) ne 8) then begin print,"Compound variable: ",var n = n_elements(dat) - 1 for i=0,n do print,i,dat[i],format='(" ",i2," : ",a)' read, i, prompt='Variable to plot [0-' + strtrim(string(n),2) + ']: ' var = dat[i > 0 < n] get_data, var, data=dat, alim=lim, index=i if (i eq 0) then begin print,"Tplot variable not found: ",var return endif endif str_element, dat, 'x', success=ok if (ok) then str_element, dat, 'y', success=ok if (ok) then begin if ((size(dat.y))[0] ne 2) then begin print,"Not a 2-D tplot variable: ",var return endif str_element, dat, 'v', success=ok endif if (not ok) then begin print,"Cannot interpret tplot variable: ",var return endif str_element, dat, 'dy', success=ok err = keyword_set(err) and ok ; Get the axis labels and ranges from the variable's limits structure (Y -> X, Z -> Y). ; Use these to set any keywords that are missing. str_element, lim, 'ytitle', msg, success=ok if (ok && n_elements(xtitle) eq 0) then xtitle = msg str_element, lim, 'yrange', rng, success=ok if (ok && n_elements(xrange) eq 0) then xrange = rng str_element, lim, 'ylog', i, success=ok if (ok && n_elements(xlog) eq 0) then xlog = i str_element, lim, 'ystyle', i, success=ok if (ok && n_elements(xstyle) eq 0) then xstyle = i str_element, lim, 'ztitle', msg, success=ok if (ok && n_elements(ytitle) eq 0) then ytitle = msg str_element, lim, 'zrange', rng, success=ok if (ok && n_elements(yrange) eq 0) then yrange = rng str_element, lim, 'zlog', i, success=ok if (ok && n_elements(ylog) eq 0) then ylog = i str_element, lim, 'zstyle', i, success=ok if (ok && n_elements(ystyle) eq 0) then ystyle = i ; Create a snapshot window Twin = !d.window win, /free, monitor=monitor, secondary=secondary, xsize=xsize, ysize=ysize, dx=dx, dy=dy, $ corner=corner, center=center, xcenter=xcenter, ycenter=ycenter, xpos=xpos, ypos=ypos, $ norm=norm, full=full, xfull=xfull, yfull=yfull Swin = !d.window ; Make snapshot(s) keepgoing = 1 while (keepgoing) do begin i = nn2(dat.x, t) if ((size(dat.v))[0] eq 2) then x = reform(dat.v[i,*]) else x = dat.v if (npts eq 1) then begin y = reform(dat.y[(i-k):(i+k),*]) if (err) then dy = reform(dat.dy[(i-k):(i+k),*]) endif else begin y = reform(dat.y[min(i):max(i),*]) if (err) then dy = reform(dat.dy[min(i):max(i),*]) endelse if ((size(y))[0] eq 2) then begin nrm = y nrm[*] = 1. bndx = where(~finite(y), count) if (count gt 0L) then begin nrm[bndx] = 0. dy[bndx] = !values.f_nan endif nrm = total(nrm,1) y = total(y, 1, /nan)/nrm if (err) then dy = sqrt(total(dy*dy, 1, /nan))/nrm endif y = smooth(y, xsmo, /nan, /edge_truncate) case dydx of 1 : y = deriv(x,y) 2 : y = deriv(x,deriv(x,y)) else : ; do nothing endcase wset, Swin if (size(title,/type) ne 7) then begin if (npts eq 1) then begin msg = time_string(dat.x[i-k]) if (k gt 0) then msg += ' - ' + strmid(time_string(dat.x[i+k]),11) endif else msg = time_string(dat.x[min(i)]) + ' - ' + strmid(time_string(dat.x[max(i)]),11) endif else msg = title[0] plot, x, y, title=msg, xtitle=xtitle, ytitle=ytitle, xrange=xrange, yrange=yrange, $ xlog=xlog, ylog=ylog, xstyle=xstyle, ystyle=ystyle, linestyle=linestyle, $ psym=psym, symsize=symsize, thick=thick, ticklen=ticklen, charsize=charsize, $ xmargin=xmargin, ymargin=ymargin, xminor=xminor, yminor=yminor, xthick=xthick, $ ythick=ythick, xtickformat=xtickformat, ytickformat=ytickformat, $ xtickinterval=xtickinterval, ytickinterval=ytickinterval, xticklen=xticklen, $ yticklen=yticklen, xticks=xticks, yticks=yticks if (err) then if (ylog) then errplot,x,(y-dy)>tiny,y+dy,width=0 else errplot,x,y-dy,y+dy,width=0 wset, Twin ctime,t,npoints=npts,/silent if (npts eq 2) then cursor,cx,cy,/norm,/up ; make sure mouse button is released if (size(t,/type) eq 2) then keepgoing = 0 endwhile if (~keep) then wdelete,Swin end