; file: movex.pro = = multi-file assoc movie player/blinker ; init: Sep 15 2010 Rob Rutten Deil as ximovie_rr.pro ; last: Jan 20 2021 Rob Rutten Deil ; note: main pro starts at ++++ MAIN PRO +++++ far below all subroutines ; todo: lots... ; options to reset intensity scaling ranges A and B ; options running difference, running mean difference, unsharp masking ; line center = profile min for Dopplergrams with asymmetric sampling ; add (optional?) bisector to profile plot (multiple lines?) ; options to integrate A and B wav ranges (eg line core) - or make cube? ; cghistoplot intensities current image ; showxslice: x_t greyscale slice (image = 2D version plotxtrace) ; showspectime: spec.vs.time current/marked pixel? Slow without .sp.? ; load SDO level1, level2 files ; option rotslider = rotate image with angle slider ; timeline plot y-axis scale must be set by max(A,B) ; add keyword duration = duration until exit (in blink mode) ; option set flatten as set smear ; display smear, flatten values ; option to place/remove a marker cross in all (right-mouse?) ;+ ; movex.pro = movie explorer to play/blink multiple image sequences ; in parallel using multi-assoc into files. ; Usually called though wrapper showex.pro which can also load ; (x,y,t) cubes or images in memory and/or png, jpg, mp4, ps files. ; Restrictions: ; - all images or sequences must have identical dimensions. ; - IDL quickly runs out of LUNs and must then be restarted ; ; DESCRIPTION: ; Image sequence player and blinker built on SSW ximovie.pro by ; Oyvind Vikstol and Viggo Hansteen, written in preparation for ; Solar-B (Hinode). That provides a widget interface to play and ; blink two image sequences in assocced files as movies, with a ; nice zoom option opening a new instance per mouse-drawn cutout. ; Using assoc permits any file size. ; ; This ximovie-clone accepts a large number of files of different types: ; - DOT cubefiles [nx,ny,nt] ; - fits cubefiles [nx,ny,nt], including co-aligned SDO sequences ; and IRIS slitjaw sequences ; - SST "La Palma" cubefiles [nx,ny,nt] ; - SST/CRISP multiwav "la Palma" files [nx,ny,nwav*nstokes*nt] ; - SST/CHROMIS multiwav files ; - DST/IBIS multiwav fits files [nx,ny,nwav*nt] ; - DST/MXIS multiwav fits files [nx,ny,nwav*nt] ; and can easily be extended to similar files in other formats by ; adding such into movex_loadfiles.pro. ; Use it to: ; - inspect movies and blink images for any pair of the sequences, with ; slider-selection of the two files and/or wavelengths within ; multiwav [x,y,wav*t] files ; - zoom in to detail by drawing a subframe starting a run on that ; - switch to abs, sqrt, log, reverse greyscaling ; - show and blink Dopplergrams (optionally colorcoded red-blue) ; - add live scatter contour plot for the current blink pair ; - show, blink, scatterplot temporal sequence averages ; - blink with slider-selected time delay ; - add live plot of spectral profiles ; - add live plot of timelines for the pixel under cursor ; - add live plot of trace along x for the pixel under cursor ; - add live power spectra for the pixel under cursor ; - add live color highlighting of pixels in given scatterblink ranges ; - get feature pixel location, full image size, and /tmp/*png screenshots ; of all active windows by clicking on a pixel in the image ; - mark the image center ; - save current image as fits file or ps plot ; ; This browser is less comprehensive and versatile than Gregal ; Vissers' crispex.pro for CRISP and IRIS files, but its display ; fits better on my small laptop screen, the addition of other than ; crispex files is easier, and the draw-out zoom option is very useful. ; ; Wrapper showex.pro calls movex.pro just as shown here, accepting ; all keyword options below, but can also accept variables in ; memory (one or more 2D image and 3D sequence arrays, up to 50) ; that then first get written as /tmp/showex_XXX.fits files for ; movex.pro to assoc into. Therefore use showex.pro habitually. ; ; CALL: ; movex,infiles,nt_mw=nt_mw,mwspectfiles=mwspectfiles,$ ; intscale=intscale,trimbox=trimbox,magnification=magnification,$ ; addlabels=addlabels,plotmax=plotmax,plotscale=plotscale,$ ; cadence=cadence,xrange=xrange,yrange=yrange,trange=trange,$ ; ; ----- special for SDO ; allsdo=allsdo,sdodirs=sdodirs,$ ; ; ----- special for SST ; allmwf=allmwf,mwfdirs=mwfdirs,allfits=allfits,fitsdirs=fitsdirs,$ ; allspect=allspect,spectdirs=spectdirs, ; ; ----- optional startup settings ; plotprofile=plotprofile,plottimeline=plottimeline,$ ; plotxtrace=plotxtrace,plotpower=plotpower,plotscatter=plotscatter,$ ; scatrangeA=scatrangeA,scatrangeB=scatrangeB,$ ; wavindA=wavindA,wavindB=wavindB,doppA=doppA,doppB=doppB,$ ; absA=absA,absB=absB,sqrA=sqrA,sqrB=sqrB,logA=logA,logB=logB,$ ; revA=revA,revB=revB,rundifA=rundifA,rundifB=rundifB,$ ; doppcol=doppcol,smear=smear,blink=blink,frame_speed=frame_speed,$ ; itthis=itthis,itfirst=itfirst,itlast=itlast,time_delay=time_delay,$ ; colorA=colorA,colorB=colorB,markcenter-markcenter,noblock=noblock,$ ; > ; ; INPUTS: ; infiles: string array with one or more path+filename strings ; may be set to '' when /allsdo or /allfits or /allmwf ; ; INPUT KEYWORD PARAMETERS: ; nt_mw = number ot time steps, MANDATORY when only crispex file(s) ; mwspectfiles: string array of files with multiwav wavelengths ; intscale = display intensity scaling (default = -0.2) ; = -0.2 etc: find min, max stepping fix(0.2*nt) images (default) ; = -N with N>2: find min, max stepping N images (OOPS?? wrong??) ; = 0: scale each movie to min and max of first frame (as ximovie) ; = -1: bytscale each image individually (then the mean flickers) ; = -2: scale each movie to its min and max (very slow for large movies) ; > 1: range intmax-intmin with intmin = first-image min ; (example: raw IRIS SLI's have zero level at integer limit -32767, ; typically counts of 1000s above that, cosmic rays far higher; ; use e.g., intscale=3000) ; = [multmin,multmax]: mulipliers to 1st image [min,max], eg [0.5,1.5] ; these choices also hold for Dopplergrams, but those are bytescaled ; to maintain zero Dopplershift midway at grey = 127 ; these scalings are determined for the full [nx,ny,nt] trimboxxed data, ; also when xrange,yrange,trange are set or used in zoom cutouts ; trimbox = [xmin,ymin,xmax,ymax]: define subframe for intscaling, scatter ; magnification: resize the widget window (default 0 = fit screen 90%) ; addlabels = 1/0: distill and insert wavelength labels ; NB: this delays the startup ; NB: when multiwav files but no mwspectfiles given, ; the wav indices are show instead and the Dopplergram mode ; [still] assumes that the central index is nominal line center. ; If this is not the case the Dopplergram displays are no good! ; plotmax: max value y-axis of profile, timeline, trace, default 150 ; plotscale: magnifier to change plot window size, default 1 ; cadence: in seconds, to get MHz units for power-spectrum frequencies ; xrange, yrange, trange: 2-elem arrays [min,max] to limit to a subcube ; smear = nr of px to smear over (default 0 = no smearing) (option on top) ; blink = 1/0: start in blinking mode ; frame_speed: startup blink or play frame rate (default 7 = fairly slow) ; noblock = 1/0: default=0, 1=return to command line so that you may ; call multiple movex's in parallel, but then display freezes at error ; ; ----- special keyword parameters for grouped file selection ; allsdo = 1/0: take all SDO files in dir(s) sdodirs and show in nice order ; sdodirs: string array paths to SDO cubefiles dirs ; defaults for /allsdo: 'sdo2sst/' or 'target/cubes/') ; allmwf = 1/0: take all recognized multiwav files in dir(s) mwfdirs ; mwfdirs: string array of paths to multiwav dirs, default 'crispex' ; my habit is to have SST database files in subdir 'crispex'; these ; I delete at analysis completion since renewable from their source ; allfits = 1/0: take all fitscube files except multiwav files in fitsdirs ; fitsdirs: string array of paths to dir(s) with fits files, default 'sst' ; my habit is to use this for tailored SST fitscube files I made myself ; SDO files and mwf multiwav files are excluded ; allspect = 1/0: use all files containing 'spect' in spectdirs ; assuming these are SST-style spect*.sav files with wavelengths ; spectdirs: string array paths dir(s) with spectfiles, default 'crispex' ; ; ----- optional startup settings ; NB: set/change per slider or via pull-down Options menu at the top ; plotprofile: plot profile at pixel under cursor marking A and B ; plottimeline: plot timelines for A and B at pixel under cursor ; plotxtrace: plot trace along x at cursor position ; plotpower: plot power spectra for A and B at pixel under cursor ; plotscatter: plot contour scatter diagram between A and B ; scatrangeA, scatrangeB: range scatterplot A,B; default intscale min, max ; wavindA, wavindB: startup wavelength index A, B ; absA, absB: start A, B in absolute-value display mode ; sqrA, sqrB: start A, B in sqrt display mode ; logA, logB: start A,B in log display mode ; revA, revB: start A,B reversed-intensity ; rundifA, rundifB: running-difference movie, value is number to skip ; doppA, doppB: start A,B in Doppler mode (if wavind in [x,y,wav*t] file) ; doppcol: use blue-red color instead of greyscale for Dopplergrams ; itthis: startup value for the it time slider ; itfirst: start value of the it time slider (default trange[0]) ; itlast: end value of the it time slider (default trange[1]) ; delay_time: startup value (in it units) for the time delay slider ; colorA, colorB: [value, value] range color pixels A,B in scatterblinking ; markcenter = 1/0: mark center of current image ; ----- the remaining keyword parameters (not specified here) serve to ; initialize new zoom instances, do not set these youself ; ; OUTPUT: ; Active widget to show and blink selected movies from the files list. ; Options (pull-down menu at the top): ; - save current image as /tmp/movex_image.fits or write as ; /tmp/movex_image.ps ; - select another color table ; - define or undo colored-pixel A and/or B ranges when scatterblinking ; - set smear value ; - set rundifA, rundifB (number to skip) ; - limit time range for movie playing ; - switch profile plot on/off (default: on for multiwav files) ; - switch timelines plot on/off (NB: all plots slow movie playing) ; - switch plotxtrace on/off ; - switch power spectra plot on/off ; - switch scatter contour plot on/off ; - mark frame center ; ; MOUSE OPTIONS: ; for cursor within main image: ; - move: refresh (x,y), A and B values shown at menu bottom ; refresh scatterplot marker of values under cursor ; refresh profile, timeline, trace, power spectrum plots per pixel ; - mouse-left click: print (x,y,t), A, B, (nx,ny,nt) in active terminal ; and write screenshots of all open windows as /tmp/movex_xxx.png ; - mouse-left draw: open new instance for zoom-in cutout frame ; For example, you can zoom in to isolate some feature for ; inspecting its contribution to the blinkscatter plot ; (but the cursor shows that too). Or to inspect co-alignment at ; large magnification. ; ; USAGE EXAMPLE: ; see end of this file and the comment block in showex.pro ; ; RESTRICTIONS: ; - all files must be synchronous and have the same (nx,ny,nt) dimensions ; (but they may differ in type and in nwav, nstokes for multiwavs) ; - when only crispex files specified nt_mw must be specified ; - keyword parameters are sticky when rerun from the same IDL session ; - movies play faster for data on internal solid-state disk ; - at multiple zoom-in's or calls IDL may run out of file units; restart ; ; MODIFICATION HISTORY: ; Jan xx 2004 Oyvind Wikstol & Viggo Hansteen (Oslo): ximovie.pro ; Jun 25 2017 RR: overhaul, renamed to movex.pro ; Jul 4 2017 RR: multifile input, /allsdo ; Jul 10 2017 RR: Doppler mode ; Jul 17 2017 RR: scatter plots ; Sep 25 2017 RR: color pixels in A,B scatterblink ranges ; Oct 24 2017 RR: cursor marker in scatterplot ; Nov 17 2017 RR: screen shots at cursor click ; Mar 20 2018 RR: button mean(t), option smear ; Apr 4 2018 RR: buttons abs, sqrt, log ; Apr 25 2020 RR: option plotxtrace ; Nov 17 2020 RR: buttons revA,revB; better movie playing ; Jan 16 2021 RR: magnetograms fixzero, log button twoside ;- ;RR ========== routines for window size, cursor motion, new-instance cutout ; resize main window ;------------------- pro ximovie_resize,event widget_control,event.top ,get_uvalue=q (*q).magscreen=(*q).magscreen*event.x/(*q).tlb_xsz (*q).d_xsz=event.x - (*q).menu_xsz > 1 (*q).d_ysz = (*q).d_xsz*(*q).aspect (*q).xscale=ptr_new((*q).d_xsz) (*q).yscale=ptr_new((*q).d_ysz) *(*q).xscale=interpol(indgen((*q).nxcut),(*q).d_xsz) *(*q).yscale=interpol(indgen((*q).nycut),(*q).d_ysz) widget_control,(*q).drawid,$ draw_xsize=(*q).d_xsz,draw_ysize=(*q).d_ysz,$ xsize=(*q).d_xsz,ysize=(*q).d_ysz pseudoevent={widget_button,id:(*q).action,$ top:(*q).tlb,handler:0l,select:1} movex_tvimage,pseudoevent end ; ----- of ximovie_resize.pro ; draw box in image = cutout for zoom in per new instance ; ------------------------------------------------------- pro ximovie_drawbox,event widget_control,event.top,get_uvalue=q ; refresh image movex_tvimage,event ; get size of parent image and define the cutout frame sz=size((*q).thisimage) xsz=sz[1] ysz=sz[2] if xsz ne (*q).nxfile or ysz ne (*q).nyfile then begin xresize=xsz/float((*q).nxfile) yresize=ysz/float((*q).nyfile) endif else begin xresize=1. yresize=1. endelse if (xresize ne 1 or yresize ne 1) then begin xcutmin=fix((*q).xcutmin*xresize) xcutmax=fix((*q).xcutmax*xresize) ycutmin=fix((*q).ycutmin*yresize) ycutmax=fix((*q).ycutmax*yresize) endif else begin xcutmin=(*q).xcutmin ycutmin=(*q).ycutmin xcutmax=(*q).xcutmax ycutmax=(*q).ycutmax endelse ; overplot the cutout frame ?? plots,[xcutmin,xcutmin,xcutmax,xcutmax,xcutmin],$ [ycutmin,ycutmax,ycutmax,ycutmin,ycutmin],$ color=255,/device end ; ----- of ximovie_drawbox.pro ; handle cursor motion and mouse-left action within image ; ------------------------------------------------------- pro ximovie_cursorevent,event widget_control,event.top,get_uvalue=q wset,(*q).mainwindow if event.type gt 2 then return events=['down','up','motion'] thisevent=events[event.type] if ((*q).run eq 1) then return ; Nov 15 2020 to make movie stop work ; undo green pixels that appeared out of nowhere if ((*q).streamA and (*q).colorA[1] eq -1) then $ tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig if ((*q).streamB and (*q).colorB[1] eq -1) then $ tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig window,/pixmap,/free,xsize=(*q).d_xsz,ysize=(*q).d_ysz if (*q).magscreen eq 1.0 then showimage=(*q).thisimage else $ showimage=congrid((*q).thisimage,(*q).d_xsz,(*q).d_ysz) ; display (without label) tv,showimage (*q).pixmapwindow=!d.window ; ----- mouse-left down case thisevent of 'down': begin ; stop blinking when blinking if ((*q).blink eq 1) then (*q).blink=0 ; start box drawing ; turn motion events on, set static corner (*q).sx=event.x (*q).sy=event.y (*q).drawbox=1B endcase ; ----- mouse-left up 'up': begin ; stationary click, or ready with box drawing = start new instance ; erase last box device,copy=[0,0,(*q).d_xsz,(*q).d_ysz,0,0,$ (*q).pixmapwindow] ; turn motion events off (*q).drawbox=0B ; get frame size sx=(*q).sx ; old (x,y) sy=(*q).sy dx=event.x ; new (,y) dy=event.y ; non-draw click ;RR cursor still (nearly within margin) at mouse-down location at button-up ; get full-frame cursor coordinates if (abs(dx-sx) lt 5 and abs(dy-sy) lt 5) then begin xcut=fix(event.x*(*q).nxcut/float((*q).d_xsz)+0.5) (*q).xpx=xcut+(*q).xcutmin ycut=fix(event.y*(*q).nycut/float((*q).d_ysz)+0.5) (*q).ypx=ycut+(*q).ycutmin ; check cursor not outside frame ; (1 px inside to set and remember while maintaining valid array samplings) (*q).outframe=0 if ((*q).xpx lt (*q).xcutmin+1) then begin (*q).outframe=1 (*q).xpx=(*q).xcutmin endif if ((*q).xpx gt (*q).xcutmax-2) then begin ; cutmax is 1 beyond last (*q).outframe=1 (*q).xpx=(*q).xcutmax endif if ((*q).ypx lt (*q).ycutmin+1) then begin (*q).outframe=1 (*q).ypx=(*q).ycutmin endif if ((*q).ypx gt (*q).ycutmax-2) then begin (*q).outframe=1 (*q).ypx=(*q).ycutmax endif ; print full-frame coordinates in IDL terminal if ((*q).outframe eq 0) then begin print,' ----- (x,y,t)=('+strtrim((*q).xpx,2)+$ ','+strtrim((*q).ypx,2)+','+strtrim((*q).itthis,2)+')'+$ ', A='+trim((*q).scatimA[xcut,ycut])+$ ', B='+trim((*q).scatimB[xcut,ycut])+$ ', (nx,ny,nt)=('+strtrim(fix((*q).nxfile),2)+$ ','+strtrim(fix((*q).nyfile),2)+ ','+strtrim((*q).ntfile,2)+')' ; ----- write screenshots of all active windows as png files in /tmp ; main image with frame around selected pixel image=(*q).thisimage wset,(*q).mainwindow plots,dx,dy,psym=6,symsize=4,thick=2,color=255,/device mainim=tvread(/greyscale,/quiet) ABixiyit=$ '_'+strmid(string((*q).wavindA+1E2,format='(i3)'),1)+$ '_'+strmid(string((*q).wavindB+1E2,format='(i3)'),1)+$ '_'+strmid(string((*q).xpx+1E5,format='(i6)'),1)+$ '_'+strmid(string((*q).ypx+1E5,format='(i6)'),1)+$ '_'+strmid(string((*q).itthis+1E5,format='(i6)'),1)+'_' write_png,'/tmp/movex'+ABixiyit+'image.png',mainim print,' ----- movex wrote '+'/tmp/movex'+ABixiyit+'image.png' ; profile plot if windowavailable(20) then begin wset,20 profim=tvread(/greyscale,/quiet) write_png,'/tmp/movex'+ABixiyit+'profile.png',profim print,' ----- movex wrote '+'/tmp/movex'+ABixiyit+'profile.png' endif ; timeline plot if windowavailable(21) then begin wset,21 timeim=tvread(/greyscale,/quiet) write_png,'/tmp/movex'+ABixiyit+'timeline.png',timeim print,' ----- movex wrote '+'/tmp/movex'+ABixiyit+'timeline.png' endif ; trace plot if windowavailable(24) then begin wset,24 timeim=tvread(/greyscale,/quiet) write_png,'/tmp/movex'+ABixiyit+'trace.png',timeim print,' ----- movex wrote '+'/tmp/movex'+ABixiyit+'trace.png' endif ; power plot if windowavailable(22) then begin wset,22 powerim=tvread(/greyscale,/quiet) write_png,'/tmp/movex'+ABixiyit+'power.png',powerim print,' ----- movex wrote '+'/tmp/movex'+ABixiyit+'power.png' endif ; scatter plot if windowavailable(23) then begin wset,23 scatterim=tvread(/greyscale,/quiet) write_png,'/tmp/movex'+ABixiyit+'scatter.png',scatterim print,' ----- movex wrote '+'/tmp/movex'+ABixiyit+'scatter.png' endif endif endif else begin ; undo green pixels that appeared out of nowhere if ((*q).streamA and (*q).colorA[1] eq -1) then $ tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig if ((*q).streamB and (*q).colorB[1] eq -1) then $ tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig sx=(sx < (*q).d_xsz - 1) > 0 sy=(sy < (*q).d_ysz - 1) > 0 dx=(dx < (*q).d_xsz - 1) > 0 dy=(dy < (*q).d_ysz - 1) > 0 image=(*q).thisimage xscale=*(*q).xscale yscale=*(*q).yscale xscale=xscale[sxdx] yscale=yscale[sydy] nx=n_elements(xscale)-1 ny=n_elements(yscale)-1 image=image[xscale[0]:xscale[nx],yscale[0]:yscale[ny]] sz=size(image) mind=min(sz[0:2]) xcutmin=(*q).xcutmin ycutmin=(*q).ycutmin xrange=[xscale[0]+xcutmin,xscale[nx]+xcutmin] yrange=[yscale[0]+ycutmin,yscale[ny]+ycutmin] ; call new instance of this whole program (RR: clever!) ;RR (*q) serves as memory between calls, bit more elegant than classic common (*q).instance=(*q).instance+1 movex,(*q).files,nt_mw=(*q).ntfile,mwspectfiles=(*q).mwspectfiles,$ addlabels=(*q).addlabels,$ plotmax=(*q).plotmax,plotscale=(*q).plotscale,$ cadence=(*q).cadence,$ xrange=xrange,yrange=yrange,trange=(*q).trange,$ intscale=(*q).intscale,trimbox=(*q).trimbox,$ magnification=(*q).magnification,smear=(*q).smear,blink=(*q).blink,$ allsdo=(*q).allsdo,sdodirs=(*q).sdodirs,$ allmwf=(*q).allmwf,mwfdirs=(*q).mwfdirs,$ allfits=(*q).allfits,fitsdirs=(*q).fitsdirs,$ allspect=(*q).allspect,spectdirs=(*q).spectdirs,$ frame_speed=(*q).frame_speed,$ ; ----- initial and internal keywords = memory for new zoom instance instance=(*q).instance,duplicate=(*q).duplicate,$ group_leader=event.top,topwindow=(*q).topwindow,$ meanprof=(*q).meanprof,labelwav=(*q).labelwav,$ fixzerowav=(*q).fixzerowav,$ pltxpos=(*q).pltxpos,pltwitdh=(*q).pltwidth,$ plotprofile=(*q).plotprofile,plottimeline=(*q).plottimeline,$ plotxtrace=(*q).plotxtrace,$ plotpower=(*q).plotpower,plotscatter=(*q).plotscatter,$ scatrangeA=(*q).scatrangeA,scatrangeB=(*q).scatrangeB,$ intmin=(*q).intmin,intmax=(*q).intmax,maxprofint=(*q).maxprofint,$ streamA=(*q).streamA,streamB=(*q).streamB,$ streammix=(*q).streammix,seqmean=(*q).seqmean,$ absA=(*q).absA,absB=(*q).absB,$ sqrA=(*q).sqrA,sqrB=(*q).sqrB,$ logA=(*q).logA,logB=(*q).logB,$ revA=(*q).revA,revB=(*q).revB,$ rundifA=(*q).rundifA,rundifB=(*q).rundifB,$ wavindA=(*q).wavindA,wavindB=(*q).wavindB,$ itthis=(*q).itthis,itA=(*q).itA,itB=(*q).itB,$ itfirst=(*q).itfirst,itlast=(*q).itlast,$ timelineA=(*q).timelineA,timelineB=(*q).timelineB,$ imA=(*q).imA,imB=(*q).imB,time_delay=(*q).time_delay,$ R_orig=(*q).R_orig,G_orig=(*q).G_orig,B_orig=(*q).B_orig,$ doppA=(*q).doppA,doppB=(*q).doppB,iwlcfile=(*q).iwlcfile,$ doppcol=(*q).doppcol,$ colorA=(*q).colorA,colorB=(*q).colorB,$ doppmin=(*q).doppmin,doppmax=(*q).doppmax,$ doppmode=(*q).doppmode,iw2=(*q).iw2,$ frame_nr=(*q).frame_nr,scatimA=(*q).scatimA,scatimB=(*q).scatimB,$ imlabel=(*q).imlabel,xyrangecut=(*q).xyrangecut,$ outframe=(*q).outframe,markcenter=(*q).markcenter,$ noblock=(*q).noblock,$ trace=(*q).trace,mintrace=(*q).mintrace,maxtrace=(*q).maxtrace endelse endcase ; Aug 5 2014 Gregal Vissers: live coordinate display 'motion': begin ; get and display pixel coordinates and A, B values in original image (*q).xpx=fix(event.x*(*q).nxcut/float((*q).d_xsz)+0.5) $ +(*q).xcutmin (*q).ypx=fix(event.y*(*q).nycut/float((*q).d_ysz)+0.5) $ +(*q).ycutmin ; check not outside frame ; (1 px inside to set and remember corner for valid array samplings) (*q).outframe=0 if ((*q).xpx lt (*q).xcutmin+1) then begin (*q).outframe=1 (*q).xpx=(*q).xcutmin endif if ((*q).xpx gt (*q).xcutmax-2) then begin ; cutmax is 1 beyond last (*q).outframe=1 (*q).xpx=(*q).xcutmax endif if ((*q).ypx lt (*q).ycutmin+1) then begin (*q).outframe=1 (*q).ypx=(*q).ycutmin endif if ((*q).ypx gt (*q).ycutmax-2) then begin (*q).outframe=1 (*q).ypx=(*q).ycutmax endif if ((*q).outframe eq 0) then begin valueA=(*q).scatimA[(*q).xpx-(*q).xcutmin,(*q).ypx-(*q).ycutmin] valueB=(*q).scatimB[(*q).xpx-(*q).xcutmin,(*q).ypx-(*q).ycutmin] if (valueA lt 1) then ndecA=1 else ndecA=0 if (valueB lt 1) then ndecB=1 else ndecB=0 widget_control,(*q).xycoords_label,$ set_value='('+strtrim((*q).xpx,2)+','+strtrim((*q).ypx,2)+')'+$ ' A'+trimd(valueA,ndecA)+' B'+trimd(valueB,ndecB) endif else widget_control,(*q).xycoords_label,set_value='out frame' ; refresh plots if (*q).plotprofile then movex_plotprofile,event ;? if (*q).plotscatter then movex_plotscatter,event ; not per cursor if (*q).plottimeline then movex_plottimeline,event if (*q).plotxtrace then movex_plotxtrace,event if (*q).plotpower then movex_plotpower,event ; new box: erase the previous one and draw a new one if (*q).drawbox then begin dx=event.x dy=event.y sx=(*q).sx sy=(*q).sy wset,(*q).mainwindow device,copy=[0,0,(*q).d_xsz,(*q).d_ysz,0,0,(*q).pixmapwindow] plots,[sx,sx,dx,dx,sx],[sy,dy,dy,sy,sy],/device,color=255 endif endcase ; ----- end of motion sensing endcase wdelete,(*q).pixmapwindow end ; ------ of ximovie_cursorevent.pro ;RR ========== routines for widget events, order as displayed top-down ;RR ========== menu options (on top) ; option: write current image as fits file ; ---------------------------------------- pro ximovie_writefits,event widget_control,event.top,get_uvalue=q writefits,'/tmp/movex_image.fits',(*q).thisimage end ; option: write current image as ps plot ; -------------------------------------- pro movex_writeps,event widget_control,event.top,get_uvalue=q xsize=10 ysize=10 ps_start,filename='/tmp/movex_image.ps',font=1,tt_font='Times',$ /nomatch,xsize=xsize,ysize=ysize,/metric,charsize=0.5 cgimage,bytscl((*q).thisimage),/keep_aspect,charsize=0.9,$ position=[0.2,0.15,0.95,0.95],$ /axes,axkeywords={font:1,ticklen:-0.02,$ xtitle:'x [px]',ytitle:'y [px]'} ps_end spawn,'gv /tmp/movex_image.ps' end ; menu option: define other color table ; ------------------------------------- pro ximovie_colors,event widget_control,event.top,get_uvalue=q thisevent=tag_names(event,/structure_name) case thisevent of 'WIDGET_BUTTON': begin xcolors,ncolors=(*q).ncolors,bottom=(*q).bottom,$ title='xwhisker colors (' + strtrim((*q).mainwindow,2) + ')',$ group_leader=event.top,notifyid=[event.id,event.top] endcase ;RR xcolors in coyotelib 'XCOLORS_LOAD': begin (*q).R=event.r((*q).bottom:(*q).ncolors-1 + (*q).bottom) (*q).G=event.g((*q).bottom:(*q).ncolors-1 + (*q).bottom) (*q).B=event.b((*q).bottom:(*q).ncolors-1 + (*q).bottom) (*q).R_orig=(*q).R (*q).G_orig=(*q).G (*q).B_orig=(*q).B if !d.n_colors gt 256 then begin pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_tvimage,pseudoevent endif endcase endcase widget_control,event.top,set_uvalue=q end ; of ximovie_colors.pro ; menu option: set A color range for scatterblink ; ----------------------------------------------- pro movex_setArange,event widget_control,event.top,get_uvalue=q setArange_tlb=widget_base(title='Enter A range',$ group_leader=(*q).tlb,/row) iw=(*q).wavindA if ((*q).colorA[0] eq -1) then begin if ((*q).doppA eq 0) then barmin=(*q).intmin[iw] else $ barmin=(*q).doppmin[iw] (*q).Arange_min_id=$ cw_field(setArange_tlb,title='Enter A min',/floating,$ /column,value=barmin) end else begin (*q).Arange_min_id=$ cw_field(setArange_tlb,title='Enter A min',/floating,$ /column,value=(*q).colorA[0]) endelse if ((*q).colorA[1] eq -1) then begin if ((*q).doppA eq 0) then barmax=(*q).intmax[iw] else $ barmax=(*q).doppmax[iw] (*q).Arange_max_id=$ cw_field(setArange_tlb,title='Enter A max',/floating,$ /column,value=barmax) end else begin (*q).Arange_max_id=$ cw_field(setArange_tlb,title='Enter A max',/floating,$ /column,value=(*q).colorA[1]) endelse closefield=widget_base(setArange_tlb,/column) closebutton=widget_button(closefield,value='done',$ event_pro='movex_setArange_destroy') undobutton=widget_button(closefield,value='undo pix color',$ event_pro='movex_setrange_undo') widget_control,setArange_tlb,set_uvalue=q widget_control,setArange_tlb,/realize xmanager,'Enter A range',setArange_tlb,$ /no_block,group_leader=(*q).tlb end ; of movex_setArange.pro ; destroy A-range widget ; ---------------------- pro movex_setArange_destroy,event widget_control,event.top,get_uvalue=q widget_control,(*q).Arange_min_id,get_value=Amin (*q).colorA[0]=Amin widget_control,(*q).Arange_max_id,get_value=Amax (*q).colorA[1]=Amax pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_plotscatter,pseudoevent widget_control,event.top,/destroy end ; of movex_setArange_destroy.pro ; menu option: set B color range for scatterblink ; ----------------------------------------------- pro movex_setBrange,event widget_control,event.top,get_uvalue=q setBrange_tlb=widget_base(title='Enter B range',$ group_leader=(*q).tlb,/row) iw=(*q).wavindB if ((*q).colorB[0] eq -1) then begin if ((*q).doppB eq 0) then barmin=(*q).intmin[iw] else $ barmin=(*q).doppmin[iw] (*q).Brange_min_id=$ cw_field(setBrange_tlb,title='Enter B min',/floating,$ /column,value=barmin) end else begin (*q).Brange_min_id=$ cw_field(setBrange_tlb,title='Enter B min',/floating,$ /column,value=(*q).colorB[0]) endelse if ((*q).colorB[1] eq -1) then begin if ((*q).doppB eq 0) then barmax=(*q).intmax[iw] else $ barmax=(*q).doppmax[iw] (*q).Brange_max_id=$ cw_field(setBrange_tlb,title='Enter B max',/floating,$ /column,value=barmax) end else begin (*q).Brange_max_id=$ cw_field(setBrange_tlb,title='Enter B max',/floating,$ /column,value=(*q).colorB[1]) endelse closefield=widget_base(setBrange_tlb,/column) closebutton=widget_button(closefield,value='done',$ event_pro='movex_setBrange_destroy') undobutton=widget_button(closefield,value='undo pix color',$ event_pro='movex_setrange_undo') widget_control,setBrange_tlb,set_uvalue=q widget_control,setBrange_tlb,/realize xmanager,'Enter B range',setBrange_tlb,$ /no_block,group_leader=(*q).tlb end ; of movex_setBrange.pro ; destroy B-range widget ; ---------------------- pro movex_setBrange_destroy,event widget_control,event.top,get_uvalue=q widget_control,(*q).Brange_min_id,get_value=Bmin (*q).colorB[0]=Bmin widget_control,(*q).Brange_max_id,get_value=Bmax (*q).colorB[1]=Bmax pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_plotscatter,pseudoevent widget_control,event.top,/destroy end ; of movex_setBrange_destroy.pro ; undo A and B pixel-color range settings ; --------------------------------------- pro movex_setrange_undo,event widget_control,event.top,get_uvalue=q (*q).colorA=[-1.,-1.] (*q).colorB=[-1.,-1.] tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig widget_control,event.top,/destroy end ; of movex_setrange_undo ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ begin incomplete running difference business ; menu option: set rundifA interval ; ----------------------------------------------- pro movex_setrundifA,event widget_control,event.top,get_uvalue=q setrundifA_tlb=widget_base(title='Enter B range',$ group_leader=(*q).tlb,/row) iw=(*q).wavindB if ((*q).colorB[0] eq -1) then begin if ((*q).doppB eq 0) then barmin=(*q).intmin[iw] else $ barmin=(*q).doppmin[iw] (*q).rundifA_min_id=$ cw_field(setrundifA_tlb,title='Enter B min',/floating,$ /column,value=barmin) end else begin (*q).rundifA_min_id=$ cw_field(setrundifA_tlb,title='Enter B min',/floating,$ /column,value=(*q).colorB[0]) endelse if ((*q).colorB[1] eq -1) then begin if ((*q).doppB eq 0) then barmax=(*q).intmax[iw] else $ barmax=(*q).doppmax[iw] (*q).rundifA_max_id=$ cw_field(setrundifA_tlb,title='Enter B max',/floating,$ /column,value=barmax) end else begin (*q).rundifA_max_id=$ cw_field(setrundifA_tlb,title='Enter B max',/floating,$ /column,value=(*q).colorB[1]) endelse closefield=widget_base(setrundifA_tlb,/column) closebutton=widget_button(closefield,value='done',$ event_pro='movex_setrundifA_destroy') undobutton=widget_button(closefield,value='undo pix color',$ event_pro='movex_setrange_undo') widget_control,setrundifA_tlb,set_uvalue=q widget_control,setrundifA_tlb,/realize xmanager,'Enter B range',setrundifA_tlb,$ /no_block,group_leader=(*q).tlb end ; of movex_setrundifA.pro ; destroy rundifA widget ; ---------------------- pro movex_setrundifA_destroy,event widget_control,event.top,get_uvalue=q widget_control,(*q).rundifA_min_id,get_value=Bmin (*q).colorB[0]=Bmin widget_control,(*q).rundifA_max_id,get_value=Bmax (*q).colorB[1]=Bmax pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_plotscatter,pseudoevent widget_control,event.top,/destroy end ; of movex_setrundifA_destroy.pro ; menu option: set rundifB interval ; ----------------------------------------------- pro movex_setrundifB,event widget_control,event.top,get_uvalue=q setrundifB_tlb=widget_base(title='Enter B range',$ group_leader=(*q).tlb,/row) iw=(*q).wavindB if ((*q).colorB[0] eq -1) then begin if ((*q).doppB eq 0) then barmin=(*q).intmin[iw] else $ barmin=(*q).doppmin[iw] (*q).rundifB_min_id=$ cw_field(setrundifB_tlb,title='Enter B min',/floating,$ /column,value=barmin) end else begin (*q).rundifB_min_id=$ cw_field(setrundifB_tlb,title='Enter B min',/floating,$ /column,value=(*q).colorB[0]) endelse if ((*q).colorB[1] eq -1) then begin if ((*q).doppB eq 0) then barmax=(*q).intmax[iw] else $ barmax=(*q).doppmax[iw] (*q).rundifB_max_id=$ cw_field(setrundifB_tlb,title='Enter B max',/floating,$ /column,value=barmax) end else begin (*q).rundifB_max_id=$ cw_field(setrundifB_tlb,title='Enter B max',/floating,$ /column,value=(*q).colorB[1]) endelse closefield=widget_base(setrundifB_tlb,/column) closebutton=widget_button(closefield,value='done',$ event_pro='movex_setrundifB_destroy') undobutton=widget_button(closefield,value='undo pix color',$ event_pro='movex_setrange_undo') widget_control,setrundifB_tlb,set_uvalue=q widget_control,setrundifB_tlb,/realize xmanager,'Enter B range',setrundifB_tlb,$ /no_block,group_leader=(*q).tlb end ; of movex_setrundifB.pro ; destroy rundifB widget ; ---------------------- pro movex_setrundifB_destroy,event widget_control,event.top,get_uvalue=q widget_control,(*q).rundifB_min_id,get_value=Bmin (*q).colorB[0]=Bmin widget_control,(*q).rundifB_max_id,get_value=Bmax (*q).colorB[1]=Bmax pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_plotscatter,pseudoevent widget_control,event.top,/destroy end ; of movex_setrundifB_destroy.pro ; undo rundifA and rundifB interval settings ; ----------------------------------------- pro movex_rundif_undo,event widget_control,event.top,get_uvalue=q (*q).rundifA=[-1.,-1.] (*q).rundifB=[-1.,-1.] widget_control,event.top,/destroy end ; of movex_setrundif udo ; @@@@@@@@@@@@@@@@@@@@@@@@@@@ end ; menu option: limit time range ; ----------------------------- pro ximovie_setframes,event widget_control,event.top,get_uvalue=q setframes_tlb=widget_base(title='Limit time range',$ group_leader=(*q).tlb,/row) (*q).start_frame_id=cw_field(setframes_tlb,$ title='Set start',/integer,$ /column,value=0) (*q).stop_frame_id=cw_field(setframes_tlb,$ title='Set stop',/integer,$ /column,value=(*q).ntfile-1) closefield=widget_base(setframes_tlb,/column) closebutton=widget_button(closefield,value='done',$ event_pro='ximovie_setframes_destroy') widget_control,setframes_tlb,set_uvalue=q widget_control,setframes_tlb,/realize xmanager,'Set Frame Range',setframes_tlb,$ /no_block,group_leader=(*q).tlb end ; of ximovie_setframes.pro ; destroy time-range widget ; -------------------------- pro ximovie_setframes_destroy,event widget_control,event.top,get_uvalue=q widget_control,(*q).start_frame_id,get_value=itmin if (itmin lt 0) then begin ok=dialog_message('Can`t start at negative frame value. Using 0',$ /information) itmin=0 endif if itmin gt ((*q).ntfile-1) then begin msg='Start frame must be less then ' +strtrim(string((*q).ntfile-1),2) ok=dialog_message(msg,/information) itmin=(*q).ntfile-2 endif (*q).itfirst=itmin (*q).frame_nr=itmin widget_control,(*q).stop_frame_id,get_value=itmax if (itmax gt (*q).ntfile) then begin msg='Max can not be more than number of frames ( ' +$ strtrim(string((*q).ntfile-1),2)+')' ok=dialog_message(msg,/information) itmax=(*q).ntfile-1 endif if (itmax le itmin) then begin msg='Stop frame must be > start frame. Using ' +strtrim(string(itmin),2) ok=dialog_message(msg,/information) itmax=(*q).ntfile-1 endif (*q).itlast=itmax < (*q).ntfile widget_control,(*q).timeslider,set_slider_min=(*q).itfirst widget_control,(*q).timeslider,set_slider_max=(*q).itlast widget_control,event.top,/destroy end ; of ximovie_setframes_destroy.pro ; option: set smear pro ximovie_setsmear,event widget_control,event.top,get_uvalue=q setsmear_tlb=widget_base(title='Set mear',$ group_leader=(*q).tlb,/row) (*q).smear=cw_field(setsmear_tlb,$ title='smear (px)',/integer,$ /column,value=0) closefield=widget_base(setsmear_tlb,/column) closebutton=widget_button(closefield,value='done',$ event_pro='ximovie_setsmear_done') widget_control,setsmear_tlb,set_uvalue=q widget_control,setsmear_tlb,/realize xmanager,'Set smear',setsmear_tlb,$ /no_block,group_leader=(*q).tlb end ; of ximovie_setsmear.pro ; smear set ; --------- pro ximovie_setsmear_done,event widget_control,event.top,get_uvalue=q widget_control,(*q).smear,get_value=smear if (smear lt 0) then begin ok=dialog_message('Can`t have negative smear. Using 0',$ /information) smear=0 endif (*q).smear=smear widget_control,event.top,/destroy end ; of ximovie_setsmear_done.pro ; @@@@@@@@@@@@@@@@ begin incomplete running difference stuff ; option: set rundifA pro ximovie_setrundifA,event widget_control,event.top,get_uvalue=q setrundifA_tlb=widget_base(title='Set rundifA',$ group_leader=(*q).tlb,/row) (*q).rundifA=cw_field(setrundifA_tlb,$ title='rundifA (nr)',/integer,$ /column,value=0) closefield=widget_base(setrundifA_tlb,/column) closebutton=widget_button(closefield,value='done',$ event_pro='ximovie_setrundifA_done') widget_control,setrundifA_tlb,set_uvalue=q widget_control,setrundifA_tlb,/realize xmanager,'Set rundifA',setrundifA_tlb,$ /no_block,group_leader=(*q).tlb end ; of ximovie_setrundifA.pro ; setrundifA set ; -------------- pro ximovie_setrundifA_done,event widget_control,event.top,get_uvalue=q widget_control,(*q).rundifA,get_value=rundifA ;; if (rundifA lt 0) then begin ;; ok=dialog_message('Can`t have negative rundifA. Using 0',$ ;; /information) ;; rundifA=0 ;; endif (*q).rundifA=rundifA widget_control,event.top,/destroy end ; of ximovie_setrundifA_done.pro ; option: set rundifB pro ximovie_setrundifB,event widget_control,event.top,get_uvalue=q setrundifB_tlb=widget_base(title='Set rundifB',$ group_leader=(*q).tlb,/row) (*q).rundifB=cw_field(setrundifB_tlb,$ title='rundifB (nr)',/integer,$ /column,value=0) closefield=widget_base(setrundifB_tlb,/column) closebutton=widget_button(closefield,value='done',$ event_pro='ximovie_setrundifB_done') widget_control,setrundifB_tlb,set_uvalue=q widget_control,setrundifB_tlb,/realize xmanager,'Set rundifB',setrundifB_tlb,$ /no_block,group_leader=(*q).tlb end ; of ximovie_setrundifB.pro ; setrundifB set ; -------------- pro ximovie_setrundifB_done,event widget_control,event.top,get_uvalue=q widget_control,(*q).rundifB,get_value=rundifB ;; if (rundifB lt 0) then begin ;; ok=dialog_message('Can`t have negative rundifB. Using 0',$ ;; /information) ;; rundifB=0 ;; endif (*q).rundifB=rundifB widget_control,event.top,/destroy end ; of ximovie_setrundifB_done.pro ; @@@@@@@@@@@@@@@@@@@@@@ end imcomplete running difference stuff ; option: plot profile on/off ; --------------------------- pro movex_setprofile,event widget_control,event.top,get_uvalue=q if ((*q).plotprofile eq 1) then begin (*q).plotprofile=0 if (windowavailable(20) eq 1) then wdelete,20 endif else begin (*q).plotprofile=1 if (windowavailable(20) eq 0) then begin window,20,xpos=(*q).pltxpos,ypos=0.,$ xsize=(*q).pltwidth,ysize=(*q).pltwidth/1.5,$ title='profile at cursor' pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_tvimage,pseudoevent endif endelse end ; option: plot timeline on/off ; --------------------------- pro movex_settimeline,event widget_control,event.top,get_uvalue=q if ((*q).plottimeline eq 1) then begin (*q).plottimeline=0 if (windowavailable(21) eq 1) then wdelete,21 endif else begin (*q).plottimeline=1 if (windowavailable(21) eq 0) then begin window,21,xpos=(*q).pltxpos,ypos=(*q).pltwidth/2.,$ xsize=(*q).pltwidth,ysize=(*q).pltwidth/1.5,$ title='timelines A and B at cursor' pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_tvimage,pseudoevent endif endelse end ; option: plot trace on/off ; --------------------------- pro movex_settrace,event widget_control,event.top,get_uvalue=q if ((*q).plotxtrace eq 1) then begin (*q).plotxtrace=0 if (windowavailable(24) eq 1) then wdelete,24 endif else begin (*q).plotxtrace=1 if (windowavailable(24) eq 0) then begin window,24,xpos=(*q).pltxpos,ypos=2*(*q).pltwidth/2.,$ xsize=(*q).pltwidth,ysize=(*q).pltwidth/1.5,$ title='trace along x at cursor' pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_tvimage,pseudoevent endif endelse end ; option: plot power on/off ; --------------------------- pro movex_setpower,event widget_control,event.top,get_uvalue=q if ((*q).plotpower eq 1) then begin (*q).plotpower=0 if (windowavailable(22) eq 1) then wdelete,22 endif else begin (*q).plotpower=1 if (windowavailable(22) eq 0) then begin window,22,xpos=(*q).pltxpos,ypos=2*(*q).pltwidth/2.,$ xsize=(*q).pltwidth,ysize=(*q).pltwidth/1.5,$ title='power spectra A and B at cursor' pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_tvimage,pseudoevent endif endelse end ; option: plot scatter on/off ; --------------------------- pro movex_setscatter,event widget_control,event.top,get_uvalue=q if ((*q).plotscatter eq 1) then begin (*q).plotscatter=0 if (windowavailable(23) eq 1) then wdelete,23 endif else begin (*q).plotscatter=1 if (windowavailable(23) eq 0) then begin window,23,xpos=(*q).pltxpos,ypos=3*(*q).pltwidth/2.,$ xsize=(*q).pltwidth,ysize=(*q).pltwidth,$ title='scatter B versus A' pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_tvimage,pseudoevent endif endelse end ; option: mark center on/off pro movex_markcenter,event widget_control,event.top,get_uvalue=q if ((*q).markcenter eq 1) then (*q).markcenter=0 else begin (*q).markcenter=1 pseudoevent={widget_button,id:0L,$ top:event.top,handler:0l,select:1} movex_tvimage,pseudoevent endelse end ;RR ========== widgets for movie-playing ("animation") ; stream A button event ; --------------------- pro ximovie_streamA,event widget_control,event.top,get_uvalue=q (*q).streamA=1 (*q).streamB=0 (*q).streammix=0 (*q).imA=1 (*q).imB=0 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; stream B button event ; --------------------- pro ximovie_streamB,event widget_control,event.top,get_uvalue=q (*q).streamA=0 (*q).streamB=1 (*q).streammix=0 (*q).imA=0 (*q).imB=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; stream mix button event ; ----------------------- pro ximovie_streammix,event widget_control,event.top,get_uvalue=q (*q).streammix=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; define special movie play buttons per bitmap ; -------------------------------------------- ;RR seems back to basics to create these nice symbols ;RR _blk = black when active function get_bmp_buttons ; define movie play buttons play_rev=[[000B,000B,000B],[000B,032B,000B],[000B,048B,000B],$ [000B,056B,000B],[000B,060B,000B],[000B,046B,000B],$ [000B,231B,015B],[144B,003B,024B],[016B,231B,027B],$ [080B,238B,027B],[208B,060B,026B],[208B,056B,026B],$ [208B,048B,026B],[208B,032B,026B],[208B,000B,026B],$ [208B,000B,026B],[208B,255B,027B],[016B,000B,024B],$ [240B,255B,031B],[224B,255B,015B],[000B,000B,000B],$ [000B,000B,000B],[000B,000B,000B],[000B,000B,000B] ] play_rev_blk=[[255B,255B,255B],[255B,223B,255B],[255B,207B,255B],$ [255B,199B,255B],[255B,195B,255B],[255B,209B,255B],$ [255B,024B,240B],[111B,252B,231B],[239B,024B,228B],$ [175B,017B,228B],[047B,195B,229B],[047B,199B,229B],$ [047B,207B,229B],[047B,223B,229B],[047B,255B,229B],$ [047B,255B,229B],[047B,000B,228B],[239B,255B,231B],$ [015B,000B,224B],[031B,000B,240B],[255B,255B,255B],$ [255B,255B,255B],[255B,255B,255B],[255B,255B,255B] ] pause=[[000B,000B,000B],[000B,000B,000B],[000B,000B,000B],$ [192B,195B,003B],[192B,194B,002B],[192B,194B,002B],$ [192B,194B,002B],[192B,194B,002B],[192B,194B,002B],$ [192B,194B,002B],[192B,194B,002B],[192B,194B,002B],$ [192B,194B,002B],[192B,194B,002B],[192B,194B,002B],$ [192B,194B,002B],[192B,194B,002B],[192B,194B,002B],$ [192B,194B,002B],[192B,195B,003B],[192B,195B,003B],$ [000B,000B,000B],[000B,000B,000B],[000B,000B,000B] ] pause_blk=[[255B,255B,255B],[255B,255B,255B],[255B,255B,255B],$ [063B,060B,252B],[063B,061B,253B],[063B,061B,253B],$ [063B,061B,253B],[063B,061B,253B],[063B,061B,253B],$ [063B,061B,253B],[063B,061B,253B],[063B,061B,253B],$ [063B,061B,253B],[063B,061B,253B],[063B,061B,253B],$ [063B,061B,253B],[063B,061B,253B],[063B,061B,253B],$ [063B,061B,253B],[063B,060B,252B],[063B,060B,252B],$ [255B,255B,255B],[255B,255B,255B],[255B,255B,255B] ] play=[[000B,000B,000B],[000B,004B,000B],[000B,012B,000B],$ [000B,028B,000B],[000B,060B,000B],[000B,116B,000B],$ [240B,231B,000B],[024B,192B,009B],[216B,231B,008B],$ [216B,119B,010B],[088B,060B,011B],[088B,028B,011B],$ [088B,012B,011B],[088B,004B,011B],[088B,000B,011B],$ [088B,000B,011B],[216B,255B,011B],[024B,000B,008B],$ [248B,255B,015B],[240B,255B,007B],[000B,000B,000B],$ [000B,000B,000B],[000B,000B,000B],[000B,000B,000B] ] play_blk=[[255B,255B,255B],[255B,251B,255B],[255B,243B,255B],$ [255B,227B,255B],[255B,195B,255B],[255B,139B,255B],$ [015B,024B,255B],[231B,063B,246B],[039B,024B,247B],$ [039B,136B,245B],[167B,195B,244B],[167B,227B,244B],$ [167B,243B,244B],[167B,251B,244B],[167B,255B,244B],$ [167B,255B,244B],[039B,000B,244B],[231B,255B,247B],$ [007B,000B,240B],[015B,000B,248B],[255B,255B,255B],$ [255B,255B,255B],[255B,255B,255B],[255B,255B,255B] ] cycle=[[000B,000B,000B],[000B,000B,000B],[000B,128B,000B],$ [000B,128B,001B],[000B,128B,003B],[248B,255B,006B],$ [008B,000B,012B],[008B,000B,024B],[248B,255B,012B],$ [248B,255B,006B],[000B,128B,003B],[000B,129B,001B],$ [128B,129B,000B],[192B,001B,000B],[096B,255B,015B],$ [048B,000B,008B],[024B,000B,008B],[048B,255B,015B],$ [096B,255B,015B],[192B,001B,000B],[128B,001B,000B],$ [000B,001B,000B],[000B,000B,000B],[000B,000B,000B] ] cycle_blk=[[255B,255B,255B],[255B,255B,255B],[255B,127B,255B],$ [255B,127B,254B],[255B,127B,252B],[007B,000B,249B],$ [247B,255B,243B],[247B,255B,231B],[007B,000B,243B],$ [007B,000B,249B],[255B,127B,252B],[255B,126B,254B],$ [127B,126B,255B],[063B,254B,255B],[159B,000B,240B],$ [207B,255B,247B],[231B,255B,247B],[207B,000B,240B],$ [159B,000B,240B],[063B,254B,255B],[127B,254B,255B],$ [255B,254B,255B],[255B,255B,255B],[255B,255B,255B] ] bmp_buttons=create_struct('play_rev',play_rev,$ 'play_rev_blk',play_rev_blk,$ 'pause',pause,$ 'pause_blk',pause_blk,$ 'play',play,$ 'play_blk',play_blk,$ 'cycle',cycle,$ 'cycle_blk',cycle_blk) return,bmp_buttons end ; play forward button event ; ------------------------- pro ximovie_play_fwd,event widget_control,event.top,get_uvalue=q (*q).run=1 (*q).playmode='forward' (*q).frame_speed=20 widget_control,(*q).play_fwd_button,set_value=(*q).bmp_buttons.play_blk widget_control,(*q).play_rev_button,set_value=(*q).bmp_buttons.play_rev widget_control,(*q).pause_button,set_value=(*q).bmp_buttons.pause widget_control,(*q).play_fwd_rev_button,set_value=(*q).bmp_buttons.cycle widget_control,(*q).bg_base,timer=0.0 end ; stop movie button event ; ----------------------- pro ximovie_pause,event widget_control,event.top,get_uvalue=q (*q).run=0 (*q).playmode='pause' (*q).frame_speed=7 ; back to blink speed if ((*q).streamA) then iw=(*q).wavindA ; faster stop but no difference? if ((*q).streamB) then iw=(*q).wavindB ;; flush,(*q).lunfile[iwinfile[iw]] ; flush IDL buffer ;; gave error widget_control,(*q).framespeed_slider,set_value=(*q).frame_speed widget_control,(*q).play_fwd_button,set_value=(*q).bmp_buttons.play widget_control,(*q).play_rev_button,set_value=(*q).bmp_buttons.play_rev widget_control,(*q).pause_button,set_value=(*q).bmp_buttons.pause_blk widget_control,(*q).play_fwd_rev_button,set_value=(*q).bmp_buttons.cycle end ; play backward button event ; -------------------------- pro ximovie_play_rev,event widget_control,event.top,get_uvalue=q (*q).run=1 (*q).playmode='reverse' (*q).frame_speed=20 widget_control,(*q).play_fwd_button,set_value=(*q).bmp_buttons.play widget_control,(*q).play_rev_button,set_value=(*q).bmp_buttons.play_rev_blk widget_control,(*q).pause_button,set_value=(*q).bmp_buttons.pause widget_control,(*q).play_fwd_rev_button,set_value=(*q).bmp_buttons.cycle widget_control,(*q).bg_base,timer=0.0 end ; play forward-reverse cycle button event ; --------------------------------------- pro ximovie_play_fwd_rev,event widget_control,event.top,get_uvalue=q (*q).run=1 (*q).playmode='cycle' (*q).frame_speed=20 widget_control,(*q).play_fwd_button,set_value=(*q).bmp_buttons.play widget_control,(*q).play_rev_button,set_value=(*q).bmp_buttons.play_rev widget_control,(*q).pause_button,set_value=(*q).bmp_buttons.pause widget_control,(*q).play_fwd_rev_button,set_value=(*q).bmp_buttons.cycle_blk widget_control,(*q).bg_base,timer=0.0 end ; time slider event ; ----------------- pro ximovie_timeslider,event widget_control,event.top,get_uvalue=q (*q).itthis=event.value (*q).itA=event.value (*q).itB=event.value+(*q).time_delay if ((*q).itB lt (*q).itfirst) then (*q).itB=(*q).itfirst if ((*q).itB gt (*q).itlast) then (*q).itB=(*q).itlast pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q ; if (*q).plotscatter then movex_plotscatter,event ; then player too slow movex_tvimage,pseudoevent end ; animation-speed slider event ; ------------------------ pro ximovie_framespeed,event widget_control,event.top,get_uvalue=q (*q).frame_speed=event.value end ; time-delay slider event ; ----------------------- pro movex_timedelay,event widget_control,event.top,get_uvalue=q (*q).time_delay=event.value ; set image timings itA=(*q).itthis itB=itA+(*q).time_delay if (itB lt (*q).tcutmin) then itB=(*q).tcutmin if (itB gt (*q).tcutmax) then itB=(*q).tcutmax (*q).itA=itA (*q).itB=itB (*q).streamA=1 (*q).streamB=0 ; this is the one that changes pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent wait,0.2 ; give a glimpse of stationary image (*q).streamA=0 (*q).streamB=1 ; this is the one that changes pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event ;? if (*q).plottimeline then movex_plottimeline,event ; cursor out frame ;? if (*q).plotpower then movex_plotpower,event ; cursor out frame end ;RR ======== widgets for wavelength selection ; wav-A slider event ; ------------------ pro movex_wavA,event ximovie_streamA,event widget_control,event.top,get_uvalue=q (*q).wavindA=event.value (*q).imA=1 (*q).imB=0 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event ;? if (*q).plottimeline then movex_plottimeline,event ; cursor out frame ;? if (*q).plotpower then movex_plotpower,event ; cursor out frame end ; wav-B slider event ; ------------------ pro movex_wavB,event ximovie_streamB,event widget_control,event.top,get_uvalue=q (*q).wavindB=event.value (*q).imA=0 (*q).imB=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event ;? if (*q).plottimeline then movex_plottimeline,event ; cursor out frame ;? if (*q).plotpower then movex_plotpower,event ; cursor out frame end ; mode buttons - would ne nice to make these also black when active ; absA = show abs of A (eg magnetogram) ; ------------------------------------- pro movex_absA,event widget_control,event.top,get_uvalue=q if ((*q).absA eq 1) then (*q).absA=0 else (*q).absA=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; absB = show abs of B (eg magnetogram) ; ------------------------------------- pro movex_absB,event widget_control,event.top,get_uvalue=q if ((*q).absB eq 1) then (*q).absB=0 else (*q).absB=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; sqrA = show sqrt of A (eg magnetogram) ; ------------------------------------- pro movex_sqrA,event widget_control,event.top,get_uvalue=q if ((*q).sqrA eq 1) then (*q).sqrA=0 else (*q).sqrA=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; sqrB = show sqrt of B (eg magnetogram) ; ------------------------------------- pro movex_sqrB,event widget_control,event.top,get_uvalue=q if ((*q).sqrB eq 1) then (*q).sqrB=0 else (*q).sqrB=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; logA = show log of A (eg magnetogram) ; ------------------------------------- pro movex_logA,event widget_control,event.top,get_uvalue=q if ((*q).logA eq 1) then (*q).logA=0 else (*q).logA=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; logB = show log of B (eg magnetogram) ; ------------------------------------- pro movex_logB,event widget_control,event.top,get_uvalue=q if ((*q).logB eq 1) then (*q).logB=0 else (*q).logB=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; revA = show A reversed intensity ; -------------------------------- pro movex_revA,event widget_control,event.top,get_uvalue=q if ((*q).revA eq 1) then (*q).revA=0 else (*q).revA=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; revB = show B reversed intensity ; -------------------------------- pro movex_revB,event widget_control,event.top,get_uvalue=q if ((*q).revB eq 1) then (*q).revB=0 else (*q).revB=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; seqmean = show mean of sequence event ; ------------------------------------- pro movex_seqmean,event widget_control,event.top,get_uvalue=q if ((*q).seqmean eq 1) then (*q).seqmean=0 else (*q).seqmean=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; A-Doppler button event ; ---------------------- pro movex_doppA,event widget_control,event.top,get_uvalue=q if (*q).streamB then begin (*q).streamA=1 (*q).streamB=0 endif doppA_old=(*q).doppA if (doppA_old eq 0) then (*q).doppA=1 if (doppA_old eq 1) then (*q).doppA=0 (*q).imA=1 (*q).imB=0 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event ;? if (*q).plottimeline then movex_plottimeline,event ; cursor out frame ;? if (*q).plotpower then movex_plotpower,event ; cursor out frame end ; B-Doppler button event ; ---------------------- pro movex_doppB,event widget_control,event.top,get_uvalue=q if (*q).streamA then begin (*q).streamA=0 (*q).streamB=1 endif doppB_old=(*q).doppB if (doppB_old eq 0) then (*q).doppB=1 if (doppB_old eq 1) then (*q).doppB=0 (*q).imA=0 (*q).imB=1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event ;? if (*q).plottimeline then movex_plottimeline,event ; cursor out frame ;? if (*q).plotpower then movex_plotpower,event ; cursor out frame end ; color-Doppler button event: switch between greyscale and blue-red Doppler ; -------------------------- pro movex_doppcolor,event widget_control,event.top,get_uvalue=q doppcol_old=(*q).doppcol if (doppcol_old eq 0) then (*q).doppcol=1 if (doppcol_old eq 1) then (*q).doppcol=0 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ;RR ======== widgets for single step control ; step one frame backward button event ; ------------------------------------ pro ximovie_decr,event widget_control,event.top,get_uvalue=q (*q).itthis=(*q).itthis-1 ; at start jump back to end if (*q).itthis lt (*q).itfirst then (*q).itthis=(*q).itlast pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event ;? if (*q).plottimeline then movex_plottimeline,event ; cursor out frame ;? if (*q).plotpower then movex_plotpower,event ; cursor out frame end ; step one frame forward button event ; ----------------------------------- pro ximovie_incr,event ; step it to it+1 with + button and refresh display widget_control,event.top,get_uvalue=q (*q).itthis=(*q).itthis + 1 ; at end jump back to begin if (*q).itthis gt (*q).itlast then $ (*q).itthis=(*q).itthis - (*q).itlast - 1 pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event ;? if (*q).plottimeline then movex_plottimeline,event ; cursor out frame ;? if (*q).plotpower then movex_plotpower,event ; cursor out frame end ; start blink button event ; ------------------------ pro ximovie_tvblink_start,event widget_control,event.top,get_uvalue=q if ((*q).blink eq 0) then (*q).blink=1 widget_control,(*q).bg_base2,timer=0.0 end ; stop blink button event ; ----------------------- pro ximovie_tvblink_stop,event widget_control,event.top,get_uvalue=q if ((*q).blink eq 1) then (*q).blink=0 end ; reset time delay button event ; ----------------------------- pro movex_resetdelay,event widget_control,event.top,get_uvalue=q (*q).time_delay=0 ; update delay slider widget_control,(*q).delay_slider,set_value=0 end ;RR ======== widgets for new instance per draw-box with mouse-left ; new instance: slider event to change X zoom position ; ---------------------------------------------------- pro ximovie_xscroll_slider,event widget_control,event.top,get_uvalue=q nxcutold=(*q).xcutmax-(*q).xcutmin (*q).xcutmin=event.value (*q).xcutmax=event.value+nxcutold pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ; new instance: slider event to change Y zoom position ; ---------------------------------------------------- pro ximovie_yscroll_slider,event widget_control,event.top,get_uvalue=q nycutold=(*q).ycutmax-(*q).ycutmin (*q).ycutmin=event.value (*q).ycutmax=event.value+nycutold pseudoevent={widget_button,id:(*q).action,$ top:event.top,handler:0l,select:1} widget_control,event.top,set_uvalue=q movex_tvimage,pseudoevent end ;RR =========== end of main window option routines ;RR =========== routines for image display ; refresh image = main display routine ; ------------- pro movex_tvimage,event widget_control,event.top,get_uvalue=q wset,(*q).mainwindow ; display image or Dopplergram from stream A or from stream B doppmode=0 if ((*q).streamA) then begin iw=(*q).wavindA if ((*q).seqmean) then begin for it=(*q).itfirst,(*q).itlast do begin ifraseq=it*(*q).nwavsfile[(*q).filewav[iw]]+(*q).iwinfile[iw] imseq=(*(*q).ass2pt[(*q).filewav[iw]])[ifraseq] if (it eq (*q).itfirst) then $ sumseq=float(imseq) else sumseq=sumseq+float(imseq) endfor image=sumseq/((*q).itlast-(*q).itfirst+1) endif else begin iframeA=(*q).itA*(*q).nwavsfile[(*q).filewav[iw]]+(*q).iwinfile[iw] if (iframeA lt 0) then iframeA=0 image=(*(*q).ass2pt[(*q).filewav[iw]])[iframeA] endelse imin=(*q).intmin[iw] imax=(*q).intmax[iw] itthis=(*q).itA ; Doppler mode if ((*q).doppA and (*q).nwavsfile[(*q).filewav[iw]] gt 1) then begin doppmode=1 iwlc=(*q).iwlcfile[(*q).filewav[iw]] iwin=(*q).iwinfile[iw] iw2in=iwlc+(iwlc-iwin) thisit=(*q).itA ; check the other wavelength is still within this profile if (iw2in lt 0 or iw2in ge (*q).nwavsfile[(*q).filewav[iw]]) then begin print,' ----- no matching Doppler sample for this wavelength' doppmode=0 endif else begin iw2=iw2in+(*q).iwstartfile[(*q).filewav[iw]] if ((*q).seqmean) then begin for it=(*q).itfirst,(*q).itlast do begin ifra1seq=it*(*q).nwavsfile[(*q).filewav[iw]]+(*q).iwinfile[iw] im1seq=(*(*q).ass2pt[(*q).filewav[iw]])[ifra1seq] ifra2seq=it*(*q).nwavsfile[(*q).filewav[iw2]]+(*q).iwinfile[iw2] im2seq=(*(*q).ass2pt[(*q).filewav[iw2]])[ifra2seq] dopimseq=(float(im2seq)-im1seq)/(im2seq+im1seq) if (it eq (*q).itfirst) then sumseq=float(dopimseq) else $ sumseq=sumseq+float(dopimseq) endfor image=sumseq/((*q).itlast-(*q).itfirst+1) endif else begin iframe2=thisit*(*q).nwavsfile[(*q).filewav[iw2]]+(*q).iwinfile[iw2] image2=(*(*q).ass2pt[(*q).filewav[iw2]])[iframe2] image=(float(image2)-image)/(image2+image) ; Dopplergram endelse imin=(*q).doppmin[iw] imax=(*q).doppmax[iw] endelse endif ; optional image smearing if ((*q).smear gt 1) then image=smooth(image,(*q).smear,/edge_truncate) ; error check (bad cursor action) if ((*q).xcutmin eq -1) then (*q).xcutmin=0 if ((*q).ycutmin eq -1) then (*q).ycutmin=0 if ((*q).xcutmax eq -1) then (*q).xcutmin=(*q).nxfile-1 if ((*q).ycutmax eq -1) then (*q).ycutmax=(*q).nyfile-1 ; set twoside for magnetogram, Dopplergram positive+negative content twosideA=(min(image) lt -avg(image)) ; abs A option if ((*q).absA) then begin image=abs(image) imax=max([abs(imin),abs(imax)]) ; eg Doppler may have larger neg max imin=0 ; eg Doppler ;RR OOPS? Mar 11 2019 imin was er voor op 0 gezet endif ; sqrt A option if ((*q).sqrA) then begin if (twosideA) then begin impos=sqrt(image>0) imneg=-sqrt(abs(image<0)) image=impos+imneg imax=max([sqrt(abs(imax)),sqrt(abs(imin))]) imin=-imax endif else begin image=sqrt(image>0) imin=sqrt(imin>0) imax=sqrt(imax>0) endelse endif ; log A option if ((*q).logA) then begin if (twosideA) then begin impos=0*image impos=alog10(image>1) imneg=0*image imneg=-alog10(abs(image<(-1))) image=impos+imneg imax=alog10(max([imax>1,abs(imin<(-1))])) imin=-imax endif else begin imax=alog10(imax>1.E-3) imin=alog10(imin>1.E-3) image=alog10(image>imin) endelse endif ; reverse option if ((*q).revA) then image=imin+imax-image ; crop and store for plotscatter and cursor values display image=image[(*q).xcutmin:(*q).xcutmax,(*q).ycutmin:(*q).ycutmax] (*q).scatimA=image ; switch stream in mix playing if (*q).streammix then begin (*q).streamA=0 (*q).streamB=1 endif ; now repeat all this for stream B endif else if ((*q).streamB) then begin iw=(*q).wavindB if ((*q).seqmean) then begin for it=(*q).itfirst,(*q).itlast do begin ifraseq=it*(*q).nwavsfile[(*q).filewav[iw]]+(*q).iwinfile[iw] imseq=(*(*q).ass2pt[(*q).filewav[iw]])[ifraseq] if (it eq (*q).itfirst) then sumseq=float(imseq) $ else sumseq=sumseq+float(imseq) endfor image=sumseq/((*q).itlast-(*q).itfirst+1) endif else begin iframeB=(*q).itB*(*q).nwavsfile[(*q).filewav[iw]]+(*q).iwinfile[iw] if (iframeB lt 0) then iframeB=0 image=(*(*q).ass2pt[(*q).filewav[iw]])[iframeB] endelse imin=(*q).intmin[iw] imax=(*q).intmax[iw] itthis=(*q).itB ; Doppler mode if ((*q).doppB and (*q).nwavsfile[(*q).filewav[iw]] gt 1) then begin doppmode=1 iwlc=(*q).iwlcfile[(*q).filewav[iw]] iwin=(*q).iwinfile[iw] iw2in=iwlc+(iwlc-iwin) thisit=(*q).itB ; check the other wavelength is still within this profile if (iw2in lt 0 or iw2in ge (*q).nwavsfile[(*q).filewav[iw]]) then begin print,' ----- no matching Doppler sample for this wavelength' doppmode=0 endif else begin iw2=iw2in+(*q).iwstartfile[(*q).filewav[iw]] if ((*q).seqmean) then begin for it=(*q).itfirst,(*q).itlast do begin ifra1seq=it*(*q).nwavsfile[(*q).filewav[iw]]+(*q).iwinfile[iw] im1seq=(*(*q).ass2pt[(*q).filewav[iw]])[ifra1seq] ifra2seq=it*(*q).nwavsfile[(*q).filewav[iw2]]+(*q).iwinfile[iw2] im2seq=(*(*q).ass2pt[(*q).filewav[iw2]])[ifra2seq] dopimseq=(float(im2seq)-im1seq)/(im2seq+im1seq) if (it eq (*q).itfirst) then sumseq=float(dopimseq) else $ sumseq=sumseq+float(dopimseq) endfor image=sumseq/((*q).itlast-(*q).itfirst+1) endif else begin iframe2=thisit*(*q).nwavsfile[(*q).filewav[iw2]]+(*q).iwinfile[iw2] image2=(*(*q).ass2pt[(*q).filewav[iw2]])[iframe2] image=(float(image2)-image)/(image2+image) endelse imin=(*q).doppmin[iw] imax=(*q).doppmax[iw] endelse endif ; optional image smearing if ((*q).smear gt 1) then image=smooth(image,(*q).smear,/edge_truncate) ; set twoside for magnetogram, Dopplergram positive+negative content twosideB=(min(image) lt -avg(image)) ; abs B option if ((*q).absB) then begin image=abs(image) imin=0 imax=max([abs(imin),abs(imax)]) endif ; sqrt B option if ((*q).sqrB) then begin if (twosideB) then begin impos=sqrt(image>0) imneg=-sqrt(abs(image<0)) image=impos+imneg imax=max([sqrt(abs(imax)),sqrt(abs(imin))]) imin=-imax endif else begin image=sqrt(image>0) imin=sqrt(imin>0) imax=sqrt(imax>0) endelse endif ; log B option if ((*q).logB) then begin if (twosideB) then begin impos=0*image impos=alog10(image>1) imneg=0*image imneg=-alog10(abs(image<(-1))) image=impos+imneg imax=alog10(max([imax>1,abs(imin<(-1))])) imin=-imax endif else begin imax=alog10(imax>1.E-3) imin=alog10(imin>1.E-3) image=alog10(image>imin) endelse endif ; reverse B option if ((*q).revB) then image=imin+imax-image ; crop and store for scatterplot and cursor values display image=image[(*q).xcutmin:(*q).xcutmax,(*q).ycutmin:(*q).ycutmax] (*q).scatimB=image ; switch stream for mix playing if (*q).streammix then begin (*q).streamA=1 (*q).streamB=0 endif endif ; store doppler and iw2 (*q).doppmode=doppmode if (doppmode eq 1) then (*q).iw2=iw2 ; optional Doppler color table if (doppmode eq 1 and (*q).doppcol eq 1) then load_vel,/reverse_switch ; bytscale intensity if ((*q).intscale[0] eq -1) then image=bytscl(image) else begin if (doppmode eq 0 and (*q).fixzerowav[iw] eq 0) then $ image=bytscl(image,min=imin,max=imax) else $ image=byte(255.*(image-imin)/(imax-imin)) endelse ;; ; check cutoffs ;; print,' ----- imin,imax ='+trimd(imin)+trimd(imax) ;; sv,image ;; STOP ; color the pixels when scatterplotting with specified range limits showimage=image colorpixA=0 colorpixB=0 if ((*q).plotscatter) then begin ; only range for A specified: color pixels green if ((*q).colorA[1] ne -1 and (*q).colorB[1] eq -1 and (*q).streamA) then $ begin wherecolor=where((*q).scatimA ge (*q).colorA[0] and $ (*q).scatimA le (*q).colorA[1]) if (wherecolor[0] ne -1) then begin colorpixA=1 cc=cgcolor('green') ; values yellow=115, green=107, blue=93 are OK since in middle range showimage[where(showimage eq cc)]=cc-1 ; muck original cc-valued pixels showimage[wherecolor]=cc endif endif ; only range for B specified: color pixels blue if ((*q).colorA[1] eq -1 and (*q).colorB[1] ne -1 and (*q).streamB) then $ begin wherecolor=where((*q).scatimB ge (*q).colorB[0] and $ (*q).scatimB le (*q).colorB[1]) if (wherecolor[0] ne -1) then begin colorpixB=1 cc=cgcolor('blue') ; values yellow=115, green=107, blue=93 are OK since in middle range showimage[where(showimage eq cc)]=cc-1 ; muck original cc-valued pixels showimage[wherecolor]=cc endif endif ; both A and B ranges specified: color pixels yellow if ((*q).colorA[1] ne -1 and (*q).colorB[1] ne -1) then begin wherecolor=where((*q).scatimA ge (*q).colorA[0] and $ (*q).scatimA le (*q).colorA[1] and $ (*q).scatimB ge (*q).colorB[0] and $ (*q).scatimB le (*q).colorB[1]) if (wherecolor[0] ne -1) then begin colorpixA=1 colorpixB=1 cc=cgcolor('yellow') ; values yellow=115, green=107, blue=93 are OK since in middle range showimage[where(showimage eq cc)]=cc-1 ; muck original cc-valued pixels showimage[wherecolor]=cc endif endif endif ; scale to screen magnification if (*q).magscreen ne 1.0 then $ showimage=congrid(showimage,(*q).d_xsz,(*q).d_ysz) ; add label (after magnification to keep it sharp) if ((*q).addlabels ne 0) then begin wherelabel=where((*q).imlabel[*,*,iw] gt 1) if (wherelabel[0] ne -1) then showimage[wherelabel]=max(showimage) endif ; restore original color table for non-pixel coloring other in scatter blink if ((*q).streamA and colorpixA eq 0 and doppmode eq 0) then $ tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig if ((*q).streamB and colorpixB eq 0 and doppmode eq 0) then $ tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig ; display this image ==== the very heart of this program tv,showimage ; add A or B identifier in row upper-left corner if ((*q).streamA) then xyouts,0.01,0.96,/norm,$ charthick=2,charsize=3,color=255,'A' if ((*q).streamB) then xyouts,0.01,0.92,/norm,$ charthick=2,charsize=3,color=255,'B' ; add mean(t) identifier if ((*q).seqmean) then xyouts,0.01,0.88,/norm,$ charthick=2,charsize=2.5,color=255,'mean(t)' ; add reverse A or B identifier if ((*q).streamA and (*q).revA) then xyouts,0.05,0.96,/norm,$ charthick=2,charsize=2.5,color=255,'rev' if ((*q).streamB and (*q).revB) then xyouts,0.05,0.92,/norm,$ charthick=2,charsize=2.5,color=255,'rev' ; add abs A or B identifier if ((*q).streamA and (*q).absA) then xyouts,0.12,0.96,/norm,$ charthick=2,charsize=2.5,color=255,'abs' if ((*q).streamb and (*q).absB) then xyouts,0.12,0.92,/norm,$ charthick=2,charsize=2.5,color=255,'abs' ; add sqrt A or B identifier if ((*q).streamA and (*q).sqrA) then xyouts,0.19,0.96,/norm,$ charthick=2,charsize=2.5,color=255,'sqr' if ((*q).streamB and (*q).sqrB) then xyouts,0.19,0.92,/norm,$ charthick=2,charsize=2.5,color=255,'sqr' ; add log A or B identifier if ((*q).streamA and (*q).logA) then xyouts,0.26,0.96,/norm,$ charthick=2,charsize=2.5,color=255,'log' if ((*q).streamB and (*q).logB) then xyouts,0.26,0.92,/norm,$ charthick=2,charsize=2.5,color=255,'log' ; optional mark center if ((*q).markcenter) then plots,(*q).d_xsz/2.,(*q).d_ysz/2.,$ psym=6,symsize=3,thick=1,color=255,/device ; restore original color table for other and future displays if ((*q).streamA and colorpixA ne 0) then $ tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig if ((*q).streamB and colorpixB ne 0) then $ tvlct,(*q).R_orig,(*q).G_orig,(*q).B_orig ; store the (non-show) image (*q).thisimage=image ; update time slider widget_control,(*q).timeslider,set_value=(*q).itthis ; update frame speed widget_control,(*q).framespeed_slider,set_value=(*q).frame_speed ; generate timer event widget_control,(*q).bg_base,timer=1./(*q).frame_speed end ; ----- of movex_tvimage.pro ; play movie ; ---------- pro ximovie_tvmovie,event ; looks like ximovie_bck in ximovie widget_control,event.top,get_uvalue=q if (*q).run eq 0 then return ; movie has been paused if ((*q).streamA) then itthis=(*q).itA if ((*q).streamB) then itthis=(*q).itB case (*q).playmode of 'forward': begin ; play forward movie itthis=itthis+1 ; at end jump back to start if itthis gt (*q).itlast then $ itthis=(itthis-(*q).itlast-1)>(*q).itfirst end 'reverse': begin ; play reverse movie itthis=itthis -1 ; at begin jump back to end if itthis lt (*q).itfirst then $ itthis=(itthis+(*q).itlast+1)<(*q).itlast end 'cycle': begin ; cycle direction in movie playing itthis=itthis+(*q).cycle ; reverse direcion at end if itthis gt (*q).itlast then begin (*q).cycle=-1 itthis=(*q).itlast endif ; reverse direction at begin if itthis lt (*q).itfirst then begin (*q).cycle=+1 itthis=(*q).itfirst endif end endcase ; end of movie direction options (*q).itthis=itthis if ((*q).streamA) then (*q).itA=itthis if ((*q).streamB) then (*q).itB=itthis ; refresh image and plots movex_tvimage,event if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event if (*q).plottimeline then movex_plottimeline,event if (*q).plotxtrace then movex_plotxtrace,event if (*q).plotpower then movex_plotpower,event movex_tvimage,event end ; ----- of ximovie_tvmovie.pro ; blink images ; ------------ pro ximovie_tvblink,event widget_control,event.top,get_uvalue=q ; don't blink when movie runs of when blinking is stopped if ((*q).run eq 1 or (*q).blink eq 0) then return ; set image timings itA=(*q).itthis itB=(*q).itthis+(*q).time_delay if (itB lt (*q).tcutmin) then itB=(*q).tcutmin if (itB gt (*q).tcutmax) then itB=(*q).tcutmax (*q).itA=itA (*q).itB=itB ; refresh image and plots alternatingly between A and B if ((*q).imA) then begin (*q).streamA=1 (*q).streamB=0 movex_tvimage,event if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event if (*q).plottimeline then movex_plottimeline,event if (*q).plotxtrace then movex_plotxtrace,event if (*q).plotpower then movex_plotpower,event (*q).imA=0 ; next one show B (*q).imB=1 endif else begin (*q).streamA=0 (*q).streamB=1 (*q).itthis=(*q).itB movex_tvimage,event if (*q).plotprofile then movex_plotprofile,event if (*q).plotscatter then movex_plotscatter,event if (*q).plottimeline then movex_plottimeline,event if (*q).plotxtrace then movex_plotxtrace,event if (*q).plotpower then movex_plotpower,event (*q).itthis=(*q).itA (*q).imA=1 ; next one show A (*q).imB=0 endelse ; keep blinking ;RR Oct 14 2013 lowered the speed to have slower blinking at lowest setting widget_control,(*q).bg_base2,timer=5.0/(*q).frame_speed end ; ----- of ximovie_tvblink.pro ;RR ========== routines for optional plots ; profile plot (meaning spectral profiles) ; ------------ pro movex_plotprofile,event widget_control,event.top,get_uvalue=q if windowavailable(20) then wset,20 else return itthis=(*q).itthis itB=(*q).itB if ((*q).imA eq 1) then thistime=itthis else thistime=itB thisprof=fltarr((*q).nwavs) for iw=0,(*q).nwavs-1 do begin iframeprof=long(thistime)*(*q).nwavsfile[(*q).filewav[iw]]+(*q).iwinfile[iw] imageprof=(*(*q).ass2pt[(*q).filewav[iw]])[iframeprof] thisprof[iw]=100.*imageprof[(*q).xpx,(*q).ypx]/(*q).maxprofint[iw] endfor xaxrange=[-1,(*q).nwavs] ; to make wav cursor lines visible at ends yaxrange=[0,(*q).plotmax] plot,(*q).meanprof,linestyle=3,charsize=1.3,$ xrange=xaxrange,xstyle=1,yrange=yaxrange,ystyle=1,$ xtitle='wavelength index',ytitle='normalized intensity' if ((*q).imA eq 1) then oplot,thisprof if ((*q).imB eq 1) then oplot,thisprof,linestyle=2 ident='('+strtrim((*q).xpx,2)+', '+strtrim((*q).ypx,2)+$ ', '+strtrim(itthis,2)+')' if ((*q).imA and (*q).absA) then ident=ident+' abs' if ((*q).imA and (*q).sqrA) then ident=ident+' sqrt' if ((*q).imA and (*q).logA) then ident=ident+' log' if ((*q).imA and (*q).revA) then ident=ident+' rev' if ((*q).imB and (*q).absB) then ident=ident+' abs' if ((*q).imB and (*q).sqrB) then ident=ident+' sqrt' if ((*q).imB and (*q).logB) then ident=ident+' log' if ((*q).imB and (*q).revB) then ident=ident+' rev' ; add vertical lines as wavelength cursors if ((*q).imA eq 1) then begin plots,[(*q).wavindA,(*q).wavindA],[yaxrange[0],yaxrange[1]] if ((*q).addlabels eq 1) then xyouts,(*q).wavindA,0.9*yaxrange[1],$ charsize=1.5,(*q).labelwav[(*q).wavindA],$ align=((*q).wavindA gt (*q).nwavs/2) if ((*q).doppA eq 1 and (*q).doppmode) then begin ident=ident+' A Doppler' plots,[(*q).iw2,(*q).iw2],[yaxrange[0],yaxrange[1]],linestyle=1 ; label coordinates, time, stream, Doppler mode + sign for current sampling ; Doppler sign tricky: absorption line darkens blue wing when blue ; shifted, emission line the reverse. Whether blueshift means upward ; motion depends on the viewing angle, unknown within this program if ((*q).absA eq 0) then begin if ((*q).wavindA lt (*q).iwlcfile[(*q).filewav[(*q).wavindA]]+$ (*q).iwstartfile[(*q).filewav[(*q).wavindA]] and $ (*q).meanprof[(*q).filewav[(*q).wavindA]] gt $ (*q).meanprof[(*q).iwlcfile[(*q).filewav[(*q).wavindA]]+$ (*q).iwstartfile[(*q).filewav[(*q).wavindA]]]) $ then ident=ident+' bright=blue' else ident=ident+' black=blue' endif else ident=ident+' A' endif endif ; same if stream B if ((*q).imB eq 1) then begin plots,[(*q).wavindB,(*q).wavindB],[yaxrange[0],yaxrange[1]],linestyle=2 if ((*q).addlabels eq 1) then xyouts,(*q).wavindB,0.9*yaxrange[1],$ charsize=1.5,(*q).labelwav[(*q).wavindB],$ align=((*q).wavindB gt (*q).nwavs/2) if ((*q).doppB eq 1 and (*q).doppmode) then begin ident=ident+' B Doppler' plots,[(*q).iw2,(*q).iw2],[yaxrange[0],yaxrange[1]],linestyle=1 if ((*q).absB eq 0) then begin if ((*q).wavindB lt (*q).iwlcfile[(*q).filewav[(*q).wavindB]]+$ (*q).iwstartfile[(*q).filewav[(*q).wavindB]] and $ (*q).meanprof[(*q).filewav[(*q).wavindB]] gt $ (*q).meanprof[(*q).iwlcfile[(*q).filewav[(*q).wavindB]]+$ (*q).iwstartfile[(*q).filewav[(*q).wavindB]]]) $ then ident=ident+' bright=blue' else ident=ident+' black=blue' endif else ident=ident+' B' endif endif xyouts,0.25,0.3,/norm,charsize=1.4,ident wset,(*q).mainwindow end ; ---- of movex_plotprofile ; get timelines for plottimeline and/or plotpower ; ----------------------------------------------- pro movex_gettimeline,event widget_control,event.top,get_uvalue=q itthis=(*q).itthis nt=(*q).ntfile itA=(*q).itthis itB=(*q).itB wavindA=(*q).wavindA wavindB=(*q).wavindB if ((*q).imA eq 1) then thistime=itthis else thistime=itB for it=0,nt-1 do begin iframeA=it*(*q).nwavsfile[(*q).filewav[wavindA]]+(*q).iwinfile[wavindA] imatimA=(*(*q).ass2pt[(*q).filewav[wavindA]])[iframeA] (*q).timelineA[it]=100.*imatimA[(*q).xpx,(*q).ypx]/(*q).maxprofint[wavindA] if ((*q).doppmode eq 1 and (*q).doppA eq 1) then begin iw2=(*q).iw2 iframe2=it*(*q).nwavsfile[(*q).filewav[iw2]]+(*q).iwinfile[iw2] image2=(*(*q).ass2pt[(*q).filewav[iw2]])[iframe2] doppim=(float(image2)-imatimA)/(image2+imatimA) imin=(*q).doppmin[wavindA] imax=(*q).doppmax[wavindA] scaled=(*q).plotmax*(doppim-imin)/(imax-imin) (*q).timelineA[it]=scaled[(*q).xpx,(*q).ypx] endif iframeB=it*(*q).nwavsfile[(*q).filewav[wavindB]]+(*q).iwinfile[wavindB] imatimB=(*(*q).ass2pt[(*q).filewav[wavindB]])[iframeB] (*q).timelineB[it]=100.*imatimB[(*q).xpx,(*q).ypx]/(*q).maxprofint[wavindB] if ((*q).doppmode and (*q).doppB eq 1) then begin iw2=(*q).iw2 iframe2=it*(*q).nwavsfile[(*q).filewav[iw2]]+(*q).iwinfile[iw2] image2=(*(*q).ass2pt[(*q).filewav[iw2]])[iframe2] doppim=(float(image2)-imatimB)/(image2+imatimA) imin=(*q).doppmin[wavindB] imax=(*q).doppmax[wavindB] scaled=100.*(doppim-imin)/(imax-imin) ; zero at 50 (*q).timelineB[it]=scaled[(*q).xpx,(*q).ypx] endif endfor end ; timeline plot ; ------------- pro movex_plottimeline,event widget_control,event.top,get_uvalue=q if windowavailable(21) then wset,21 else return movex_gettimeline,event xaxrange=[-1,(*q).ntfile] ; add values to show cursor lines at ends yaxrange=[0,(*q).plotmax] plot,(*q).timelineA,charsize=1.3,$ xrange=xaxrange,xstyle=1,yrange=yaxrange,ystyle=1,$ xtitle='time step',ytitle='normalized intensity' oplot,(*q).timelineB,linestyle=2 ; add time mark with identifier which curve corresponds to main image ; add coordinates, itthis, stream for the current sampling deltay=0.05*(yaxrange[1]-yaxrange[0]) itA=(*q).itA itthis=(*q).itthis if ((*q).imA eq 1) then begin ypos=(*q).timelineA[itA] plots,[itA,itA],[ypos-deltay,ypos+deltay] xyouts,itA,ypos+deltay,charsize=1.7,'A' if ((*q).doppA eq 1 and (*q).doppmode) then ident=' A Doppler' $ else ident='A' if ((*q).absA) then ident='abs '+ident if ((*q).sqrA) then ident='sqrt '+ident if ((*q).logA) then ident='log '+ident if ((*q).revA) then ident='rev '+ident xyouts,0.25,0.3,/norm,charsize=1.4,$ ident+' ('+strtrim((*q).xpx,2)+', '+strtrim((*q).ypx,2)+$ ', '+strtrim(itthis,2)+')' endif if ((*q).imB eq 1 and not(((*q).nwavs eq 2 and (*q).duplicate eq 1))) $ then begin itB=(*q).itB ypos=(*q).timelineB[(*q).itB] plots,[itB,itB],[ypos-deltay,ypos+deltay] xyouts,itB,ypos+deltay,charsize=1.7,'B' if ((*q).doppB eq 1 and (*q).doppmode) then ident=' B Doppler' $ else ident='B' if ((*q).absB) then ident='abs '+ident if ((*q).sqrB) then ident='sqrt '+ident if ((*q).logB) then ident='log '+ident if ((*q).revB) then ident='rev '+ident xyouts,0.25,0.3,/norm,charsize=1.4,$ ident+' ('+strtrim((*q).xpx,2)+', '+strtrim((*q).ypx,2)+$ ', '+strtrim(itB,2)+')' endif if ((*q).imB eq 1 and ((*q).nwavs eq 2 and (*q).duplicate eq 1)) $ then begin ypos=(*q).timelineA[itB] plots,[itB,itB],[ypos-deltay,ypos+deltay] xyouts,itB,ypos+deltay,charsize=1.7,'B' xyouts,0.25,0.3,/norm,charsize=1.4,$ 'B=A ('+strtrim((*q).xpx,2)+', '+strtrim((*q).ypx,2)+$ ', '+strtrim(itB,2)+')' endif wset,(*q).mainwindow end ; power spectra plot ; ------------------ pro movex_plotpower,event widget_control,event.top,get_uvalue=q if windowavailable(22) then wset,22 else return movex_gettimeline,event apod=0.1 nt=(*q).ntfile apodt=fltarr(nt)+1 ; central part unity apodrim=apod*nt apodt[0]=(sin(!pi/2.*findgen(apodrim)/apodrim))^2 apodt=apodt*shift(rotate(apodt,2),1) ;RR obviously Alfred, not me meanA=avg((*q).timelineA) apodA=((*q).timelineA-meanA)*apodt+meanA meanB=avg((*q).timelineB) apodB=((*q).timelineB-meanB)*apodt+meanB ; power spectra (simply normalize by power at f=0, logarithmic scale) ftseqA=fft(apodA,-1) powerA=float(ftseqA*conj(ftseqA)) powerA=alog10(powerA/powerA[0]) ftseqB=fft(apodB,-1) powerB=float(ftseqB*conj(ftseqB)) powerB=alog10(powerB/powerB[0]) ; frequency axis (mHz when cadence ne 0) if ((*q).cadence eq 0) then plotcadence=1. else plotcadence=(*q).cadence ftxaxis=1000./(plotcadence*2)*findgen(nt/2+1)/(nt/2) ; make plot if ((*q).cadence eq 0) then xtitle='frequency, divide by cadence for mHz' $ else xtitle='frequency [mHz]' yaxrange=[-8,0] ;RR seems sufficient range plot,ftxaxis,powerA,charsize=1.3,$ xstyle=1,yrange=yaxrange,ystyle=1,$ xtitle=xtitle,ytitle='log (power)' oplot,ftxaxis,powerB,linestyle=2 wset,(*q).mainwindow end ; ----- of movex_plotpower ; get trace for trace plot ; ---------------------- pro movex_gettrace,event widget_control,event.top,get_uvalue=q nt=(*q).ntfile wavindA=(*q).wavindA wavindB=(*q).wavindB itA=(*q).itthis itB=(*q).itB if ((*q).imA eq 1) then begin thisit=itA iframeA=thisit*(*q).nwavsfile[(*q).filewav[wavindA]]+(*q).iwinfile[wavindA] imatimA=(*(*q).ass2pt[(*q).filewav[wavindA]])[iframeA] (*q).trace=imatimA[(*q).xcutmin:(*q).xcutmax,(*q).ypx] ; tracex through ypx (*q).mintrace=min(imatimA) (*q).maxtrace=max(imatimA) if ((*q).doppmode eq 1 and (*q).doppA eq 1) then begin iw2=(*q).iw2 iframe2=thisit*(*q).nwavsfile[(*q).filewav[iw2]]+(*q).iwinfile[iw2] image2=(*(*q).ass2pt[(*q).filewav[iw2]])[iframe2] doppim=(float(image2)-imatimA)/(image2+imatimA) imin=(*q).doppmin[wavindA] imax=(*q).doppmax[wavindA] scaled=(*q).plotmax*(doppim-imin)/(imax-imin) (*q).trace=scaled[(*q).xcutmin:(*q).xcutmax,(*q).ypx] ; tracex though ypx (*q).mintrace=min(scaled) (*q).maxtrace=max(scaled) endif endif if ((*q).imB eq 1) then begin thisit=itB iframeB=thisit*(*q).nwavsfile[(*q).filewav[wavindB]]+(*q).iwinfile[wavindB] imatimB=(*(*q).ass2pt[(*q).filewav[wavindB]])[iframeB] (*q).trace=imatimB[(*q).xcutmin:(*q).xcutmax,(*q).ypx] ; tracex though ypx (*q).mintrace=min(imatimB) (*q).maxtrace=max(imatimB) if ((*q).doppmode and (*q).doppB eq 1) then begin iw2=(*q).iw2 iframe2=thisit*(*q).nwavsfile[(*q).filewav[iw2]]+(*q).iwinfile[iw2] image2=(*(*q).ass2pt[(*q).filewav[iw2]])[iframe2] doppim=(float(image2)-imatimB)/(image2+imatimA) imin=(*q).doppmin[wavindB] imax=(*q).doppmax[wavindB] scaled=100.*(doppim-imin)/(imax-imin) ; zero at 50 (*q).trace=scaled[(*q).xcutmin:(*q).xcutmax,(*q).ypx] ; tracex though ypx (*q).mintrace=min(scaled) (*q).maxtrace=max(scaled) endif endif end ; make trace plot ; ------------- pro movex_plotxtrace,event widget_control,event.top,get_uvalue=q if windowavailable(24) then wset,24 else return movex_gettrace,event ; tracex plot xaxrange=[(*q).xcutmin,(*q).xcutmax] yaxrange=[(*q).mintrace,(*q).maxtrace] plot,indgen((*q).nxcut)+(*q).xcutmin,(*q).trace,charsize=1.3,$ xrange=xaxrange,xstyle=1,yrange=yaxrange,ystyle=1,$ xtitle='x pixel',ytitle='normalized intensity' ; mark cursor pixel with + symbol xcursor=(*q).xpx ycursor=(*q).trace[(*q).xpx-(*q).xcutmin] oplot,[xcursor,xcursor],[ycursor,ycursor],psym=1,symsize=5 wset,(*q).mainwindow end ; make scatter plot ; ----------------- pro movex_plotscatter,event widget_control,event.top,get_uvalue=q if (windowavailable(23) eq 1) then wset,23 else return ; redefine scat images when cropped if ((*q).trimbox[0] ne -1 and (*q).xyrangecut eq 0) then begin scatA=(*q).scatimA[(*q).trimbox[0]:(*q).trimbox[2],$ (*q).trimbox[1]:(*q).trimbox[3]] scatB=(*q).scatimB[(*q).trimbox[0]:(*q).trimbox[2],$ (*q).trimbox[1]:(*q).trimbox[3]] endif else begin scatA=(*q).scatimA scatB=(*q).scatimB ; apply croptriangles because flat edges should not count in scatter plot ;RR no; indeed better to use scatcont without edges, but much too slow ;RR you can also zoom in when there are bad edges ;; reformimage,scatA,dummyA,/croptriangles,cropbox=boxA ;; reformimage,scatB,dummyB,/croptriangles,cropbox=boxB ;; cropbox=[max([boxA[0],boxB[0]]),$ ;; max([boxA[1],boxB[1]]),$ ;; min([boxA[2],boxB[2]]),$ ;; min([boxA[3],boxB[3]])] ;; scatA=(*q).scatimA[cropbox[0]:cropbox[2],$ ;; cropbox[1]:cropbox[3]] ;; scatB=(*q).scatimB[cropbox[0]:cropbox[2],$ ;; cropbox[1]:cropbox[3]] endelse ; set scatcont plot ranges if ((*q).scatrangeA[0] eq -1) then begin iw=(*q).wavindA if ((*q).doppA eq 1) then $ plotrangeA=[(*q).doppmin[iw],(*q).doppmax[iw]] else $ plotrangeA=[(*q).intmin[iw],(*q).intmax[iw]] endif else plotrangeA=(*q).scatrangeA if ((*q).scatrangeB[0] eq -1) then begin iw=(*q).wavindB if ((*q).doppB eq 1) then $ plotrangeB=[(*q).doppmin[iw],(*q).doppmax[iw]] else $ plotrangeB=[(*q).intmin[iw],(*q).intmax[iw]] endif else plotrangeB=(*q).scatrangeB ;RR Dec 25 2020 check that the plotranges are not infinite to avoid hanging ;; print,' ===== plotrangeA, plotrangeB = ',plotrangeA,plotrangeB if (total(finite(plotrangeA)) eq n_elements(plotrangeA) and $ total(finite(plotrangeB)) eq n_elements(plotrangeB)) then begin ; run scatcont if ((*q).seqmean) then scatlabel='TEMPORAL MEAN' else scatlabel='' if ((*q).absA) then scatlabel=scatlabel+' abs A' if ((*q).sqrA) then scatlabel=scatlabel+' sqrt A' if ((*q).logA) then scatlabel=scatlabel+' log A' if ((*q).revA) then scatlabel=scatlabel+' rev A' if ((*q).absB) then scatlabel=scatlabel+' abs B' if ((*q).sqrB) then scatlabel=scatlabel+' sqrt B' if ((*q).logB) then scatlabel=scatlabel+' log B' if ((*q).revB) then scatlabel=scatlabel+' rev B' if ((*q).doppA) then scatlabel=scatlabel+' Doppler A' if ((*q).doppB) then scatlabel=scatlabel+' Doppler B' scatcont,scatA,scatB,plotrangeA=plotrangeA,plotrangeB=plotrangeB,$ xtitle='amplitude A',ytitle='amplitude B',ticklen=0.02,charsize=1.5,$ label=scatlabel,fullpearson=1,quadpearson=0,nomoments=1 ;RR Nov 9 2020 quadpearson gave errorrs ;RR Jan 20 2021 moments gave error at small-field zoom-in ; add marker for values currently under cursor if ((*q).outframe eq 0) then $ plots,(*q).scatimA[(*q).xpx-(*q).xcutmin,(*q).ypx-(*q).ycutmin],$ (*q).scatimB[(*q).xpx-(*q).xcutmin,(*q).ypx-(*q).ycutmin],$ psym=2,symsize=1.3,thick=10 ; add pixel-coloring delimiter lines or box if ((*q).colorA[1] ne -1 and (*q).colorB[1] eq -1) then begin cc=cgcolor('green') plots,[(*q).colorA[0],(*q).colorA[0]],[min(scatB),max(scatB)],color=cc plots,[(*q).colorA[1],(*q).colorA[1]],[min(scatB),max(scatB)],color=cc endif if ((*q).colorA[1] eq -1 and (*q).colorB[1] ne -1) then begin cc=cgcolor('blue') plots,[min(scatA),max(scatA)],[(*q).colorB[0],(*q).colorB[0]],color=cc plots,[min(scatA),max(scatA)],[(*q).colorB[1],(*q).colorB[1]],color=cc endif if ((*q).colorA[1] ne -1 and (*q).colorB[1] ne -1) then begin cc=cgcolor('yellow') plots,[(*q).colorA[0],(*q).colorA[0]],[(*q).colorB[0],(*q).colorB[1]],$ color=cc plots,[(*q).colorA[1],(*q).colorA[1]],[(*q).colorB[0],(*q).colorB[1]],$ color=cc plots,[(*q).colorA[0],(*q).colorA[1]],[(*q).colorB[0],(*q).colorB[0]],$ color=cc plots,[(*q).colorA[0],(*q).colorA[1]],[(*q).colorB[1],(*q).colorB[1]],$ color=cc endif endif else print,' ##### scatcont plotrange infinite, not refreshed' ; back to main window wset,(*q).mainwindow end ; ----- of movex_plotscatter ; ----------------------------------- ; stop for parameter inspection in IDL command window pro ximovie_stop,event widget_control,event.top,get_uvalue=q STOP end ; ----------------------------------- ; destroy the current instance widget pro ximovie_destroy,event widget_control,event.top,/destroy end ; free windows, files pointer of the current instance ; --------------------------------------------------- pro ximovie_cleanup,tlb widget_control,tlb,get_uvalue=q ; delete main window wdelete,(*q).mainpixmapwindow ; delete four plot windows for nrwin=20,23 do $ if (not(windowavailable((*q).topwindow)) and windowavailable(nrwin)) then $ wdelete,nrwin ; free luns of this instance, both private (1-99) and IDL (100-128) for ifile=0,(*q).nfiles-1 do $ ;;; close,(*q).lunfile[ifile],/all if ((*q).lunfile[ifile] gt 99) then free_lun,(*q).lunfile[ifile] else $ close,(*q).lunfile[ifile] ; free pointer of this instance ptr_free,q end ; ++++++++++++++++++++++++++ MAIN PRO ++++++++++++++++++++++++++++ pro movex,infiles,nt_mw=nt_mw,mwspectfiles=mwspectfiles,$ ; ----- keyword options for the user intscale=intscale,trimbox=trimbox,magnification=magnification,$ addlabels=addlabels,plotmax=plotmax,plotscale=plotscale,cadence=cadence,$ xrange=xrange,yrange=yrange,trange=trange,smear=smear,blink=blink,$ ; ----- special keyword parameters for SDO and SST data allsdo=allsdo,sdodirs=sdodirs,allmwf=allmwf,mwfdirs=mwfdirs,$ allfits=allfits,fitsdirs=fitsdirs,allspect=allspect,spectdirs=spectdirs,$ ; ----- optional startup parameters one may set plotprofile=plotprofile,plottimeline=plottimeline,plotxtrace=plotxtrace,$ plotpower=plotpower,plotscatter=plotscatter,$ scatrangeA=scatrangeA,scatrangeB=scatrangeB,$ rundifA=rundifA,rundifB=rundifB,$ wavindA=wavindA,wavindB=wavindB,doppA=doppA,doppB=doppB,doppcol=doppcol,$ absA=absA,absB=absB,sqrA=sqrA,sqrB=sqrB,logA=logA,logB=logB,$ revA=revA,revB=revB,$ colorA=colorA,colorB=colorB,markcenter=markcenter,noblock=noblock,$ itthis=itthis,itfirst=itfirst,itlast=itlast,time_delay=time_delay,$ frame_speed=frame_speed,$ ; ----- more startup parameters needed in new instance instance=instance,duplicate=duplicate,$ group_leader=group,topwindow=topwindow,$ meanprof=meanprof,labelwav=labelwav,fixzerowav=fixzerowav,$ pltxpos=pltxpos,pltwitdh=pltwidth,$ intmin=intmin,intmax=intmax,maxprofint=maxprofint,$ streamA=streamA,streamB=streamB,streammix=streammix,seqmean=seqmean,$ imA=imA,imB=imB,itA=itA,itB=itB,$ R_orig=R_orig,G_orig=G_orig,B_orig=B_orig,$ timelineA=timelineA,timelineB=timelineB,$ iwlcfile=iwlcfile,$ doppmax=doppmax,doppmin=doppmin,doppmode=doppmode,iw2=iw2,$ frame_nr=frame_nr,scatimA=scatimA,scatimB=scatimB,$ imlabel=imlabel,$ xyrangecut=xyrangecut,outframe=outframe,$ trace=trace,mintrace=mintrace,maxtrace=maxtrace ; store lun's for subsequent parallel calls in this IDL session common lunsofmovexfiles,ilun_last ; answer query without parameters if (n_params() lt 1 and not(keyword_set(allsdo) $ or keyword_set(allmwf) or keyword_set(allfits))) $ then begin print,' pro movex,infiles,nt_mw=nt_mw,mwspectfiles=mwspectfiles,' print,' ; ----- keyword options' print,' addlabels=addlabels,plotmax=plotmax,plotscale=plotscale,' print,' cadence=cadence,' print,' intscale=intscale,magnification=magnification,' print,' ; ----- special for SDO and SST' print,' allsdo=allsdo,sdodirs=sdodirs,' print,' allmwf=allmwf,mwfdirs=mwfdirs,' print,' allfits=allfits,fitsdirs=fitsdirs,' print,' spect=allspect,spectdirs=spectdirs,' print,' ; ----- startup parameters, many may be set initially' sp,movex return endif ; keyword defaults if (n_elements(nt_mw) eq 0) then ntfile=0 else ntfile=nt_mw ; nonsticky if (n_elements(intscale) eq 0) then intscale=-0.2 ; NB non-zero default if (n_elements(trimbox) eq 0) then trimbox=[-1,-1,-1,-1] if (n_elements(magnification) eq 0) then magnification=0 if (n_elements(plotmax) eq 0) then plotmax=150. if (n_elements(plotscale) eq 0) then plotscale=1. if (n_elements(cadence) eq 0) then cadence=0 if (n_elements(xrange) eq 0) then xrange=[0,-1] if (n_elements(yrange) eq 0) then yrange=[0,-1] if (n_elements(trange) eq 0) then trange=[0,-1] ; ------ special SDO and SST if (n_elements(allsdo) eq 0) then allsdo=0 if (n_elements(allmwf) eq 0) then allmwf=0 if (n_elements(allfits) eq 0) then allfits=0 if (n_elements(allspect) eq 0) then allspect=0 if (n_elements(mwspectfiles) eq 0) then mwspectfiles='' if (n_elements(frame_speed) eq 0) then frame_speed=7 ; I like slow startup ; ----- startup parameters that may be specified by user if (n_elements(plotprofile) eq 0) then plotprofile=-1 if (n_elements(plottimeline) eq 0) then plottimeline=0 if (n_elements(plotxtrace) eq 0) then plotxtrace=0 if (n_elements(plotpower) eq 0) then plotpower=0 if (n_elements(plotscatter) eq 0) then plotscatter=0 if (n_elements(scatrangeA) eq 0) then scatrangeA=[-1,-1] if (n_elements(scatrangeB) eq 0) then scatrangeB=[-1,-1] if (n_elements(rundifA) eq 0) then rundifA=0 if (n_elements(rundifB) eq 0) then rundifB=0 if (n_elements(wavindA) eq 0) then wavindA=0 if (n_elements(wavindB) eq 0) then wavindB=1 if (n_elements(absA) eq 0) then absA=0 if (n_elements(absB) eq 0) then absB=0 if (n_elements(sqrA) eq 0) then sqrA=0 if (n_elements(sqrB) eq 0) then sqrB=0 if (n_elements(logA) eq 0) then logA=0 if (n_elements(logB) eq 0) then logB=0 if (n_elements(revA) eq 0) then revA=0 if (n_elements(revB) eq 0) then revB=0 if (n_elements(itthis) eq 0) then itthis=-1 if (n_elements(itfirst) eq 0) then itfirst=0 if (n_elements(itlast) eq 0) then itlast=-1 if (n_elements(time_delay) eq 0) then time_delay=0 if (n_elements(doppA) eq 0) then doppA=0 if (n_elements(doppB) eq 0) then doppB=0 if (n_elements(doppcol) eq 0) then doppcol=0 if (n_elements(smear) eq 0) then smear=0 if (n_elements(blink) eq 0) then blink=0 if (n_elements(colorA) eq 0) then colorA=[-1.,-1.] if (n_elements(colorB) eq 0) then colorB=[-1.,-1.] if (n_elements(markcenter) eq 0) then markcenter=0 if (n_elements(noblock) eq 0) then noblock=0 ; ----- defaults for a few other startup parameters if (n_elements(instance) eq 0) then instance=0 if (n_elements(topwindow) eq 0) then topwindow=0 ; set ncolors ncolors=!d.table_size ; check/adapt button font size if this is unix (linux; OK for MacOS?) screensize=get_screen_size() if (!version.os_family eq 'unix' and screensize[0] gt 1500) then begin widget_control,default_font=$ '-misc-fixed-medium-r-normal--14-110-100-100-c-70-iso8859-1' leftwidth=249 sliderlength=236 endif else begin ;RR default '-Misc-Fixed-Medium-R-SemiCondensed--13-120-75-75-C-60-ISO8859-1' ;RR was OK for my Tosh3 1366x768 screen but too small for Tosh4 1920x1080 leftwidth=222 sliderlength=201 endelse ; open lun's for all files and get file sampling parameters movex_loadfiles,infiles,$ ; ----- outputs nxfile,nyfile,ntfile,nfiles,files,nwavs,$ lunfile,facfile,nzfiles,bitpixfile,hofffile,swapendianfile,$ mwfile,nwavsfile,$ iwstartfile,iwendfile,iwlcfile,iwinfile,filewav,labelwav,fixzerowav,$ xcutmin,xcutmax,nxcut,ycutmin,ycutmax,nycut,xyrangecut,$ tcutmin,tcutmax,ntcut,duplicate,instance=instance,$ ; ----- user option keyword inputs nt_mw=nt_mw,mwspectfiles=mwspectfiles,$ addlabels=addlabels,plotscatter=plotscatter,$ xrange=xrange,yrange=yrange,trange=trange,$ ; ----- special keyword parameters for SDO and SST data allsdo=allsdo,sdodirs=sdodirs,$ allmwf=allmwf,mwfdirs=mwfdirs,$ allfits=allfits,fitsdirs=fitsdirs,$ allspect=allspect,spectdirs=spectdirs ; check files if (nfiles lt 1) then begin print,' ##### movex abort: no input files' return endif ; if wavindA or wavindB too large set to last if (wavindA gt nwavs-1) then wavindA=nwavs-1 if (wavindB gt nwavs-1) then wavindB=nwavs-1 ; permit singe-image cubes if (ntfile eq 0) then ntfile=1 ; set assoc pointer per file ass2pt=ptrarr(nfiles,/allocate_heap) for ifile=0,nfiles-1 do begin if (bitpixfile[ifile] eq 8) then $ *ass2pt[ifile]=assoc(lunfile[ifile],$ bytarr(nxfile,nyfile,/nozero),$ hofffile[ifile]) if (bitpixfile[ifile] eq 16) then $ *ass2pt[ifile]=assoc(lunfile[ifile],$ intarr(nxfile,nyfile,/nozero),$ hofffile[ifile]) if (abs(bitpixfile[ifile]) eq 32) then $ *ass2pt[ifile]=assoc(lunfile[ifile],$ fltarr(nxfile,nyfile,/nozero),$ hofffile[ifile]) ;; flush,lunfile[ifile] ; no difference in loading speed endfor ; check on movex_loadfiles completion if (n_elements(nxcut) eq 0) then begin print,' ##### movex abort following on movex_loadfiles abort' return endif ; fit default display size to screen size if (magnification eq 0) then begin magscreen=0.87*float(screensize[0])/nxcut magscreen=magscreen < 0.8*float(screensize[1])/nycut endif else begin if (magnification eq 1) then magnification=0.999 ; error otherwise magscreen=magnification endelse ; ---- lots to do at start-off instance if (instance eq 0) then begin ; check time slider range versus trange cutout if (itlast eq -1) then itlast=tcutmax if (itfirst lt tcutmin) then itfirst=tcutmin if (itlast gt tcutmax) then itlast=tcutmax if (itlast-itfirst lt time_delay) then begin print,' ###### movex abort: trange shorter than time_delay' return endif ; initialize other (*q) storage parameters than those in keyword defaults meanprof=0 maxprofint=0 doppmode=0 iw2=0 frame_nr=0 streamA=1 ; start with A streamB=0 streammix=0 imA=1 ; start with A imB=0 if (itthis eq -1) then itthis=fix(itlast/2.) ; start time slider halfway itA=itthis itB=itthis+time_delay iframeB=0 if (plotprofile eq -1) then plotprofile=(max(nwavsfile) gt 1) ; when mw timelineA=fltarr(ntfile) timelineB=fltarr(ntfile) outframe=1 ;; if (nwavs eq 2) then blink=1 else blink=0 ; start blinking when two ; Jul 22 2020: moved to showex.pro seqmean=0 trace=fltarr(nxcut) mintrace=0. maxtrace=0. ; initialize intensity clip arrays intmin=fltarr(nwavs) intmax=fltarr(nwavs) doppmin=fltarr(nwavs) doppmax=fltarr(nwavs) fixzero=intarr(nwavs) ; ---- find intensity and Doppler clip ranges for bytescale display stepintscale=0 ; intscale=2: scan complete sequence (slow) if (intscale[0] eq -2 and n_elements(intscale) eq 1) then stepintscale=1 ; intscale = negative value between 0 and -1: skip fraction of nt in scanning if (intscale[0] lt 0 and intscale[0] gt -1 and n_elements(intscale) eq 1) $ then stepintscale=fix(ntfile[0]*abs(intscale[0])) ; intscale = negative value < -2: step abs(intscale) time steps in scanning if (intscale[0] lt -2 and n_elements(intscale) eq 1) then begin stepintscale=abs(intscale[0]) if (stepintscale gt ntfile-1) then begin print,' ##### movex.pro abort: negative intscale = step exceeds nt' return endif endif ; intscale not -1 (bytscale individually) then find min and max ; first for first image of each sequence if (intscale[0] ne -1 or n_elements(intscale) eq 2) then begin for iw=0,nwavs-1 do begin if (bitpixfile[filewav[iw]] eq 8) then $ ass2d=assoc(lunfile[filewav[iw]],bytarr(nxfile,nyfile,/nozero),$ hofffile[filewav[iw]]) if (bitpixfile[filewav[iw]] eq 16) then $ ass2d=assoc(lunfile[filewav[iw]],intarr(nxfile,nyfile,/nozero),$ hofffile[filewav[iw]]) if (abs(bitpixfile[filewav[iw]]) eq 32) then $ ass2d=assoc(lunfile[filewav[iw]],fltarr(nxfile,nyfile,/nozero),$ hofffile[filewav[iw]]) iframe=long(tcutmin)*nwavsfile[filewav[iw]]+iwinfile[iw] image=ass2d[iframe] if (trimbox[0] ne -1) then $ image=image[trimbox[0]:trimbox[2],trimbox[1]:trimbox[3]] $ else reformimage,image,image,/croptriangles intmin[iw]=min(image) intmax[iw]=max(image) ; find clips for multiwav dopplergrams from first images if (mwfile[filewav[iw]] ne 0 and $ strmatch(files[filewav[iw]],'*stokes*') ne 1) then begin if (iwinfile[iw] ne iwlcfile[filewav[iw]]) then begin iwlc=iwlcfile[filewav[iw]] iwin=iwinfile[iw] iw2in=min([iwlc+(iwlc-iwin),nwavsfile[filewav[iw]]-1]) iw2in=max([iw2in,0]) iw2=iw2in+iwstartfile[filewav[iw]] iframe2=tcutmin*nwavsfile[filewav[iw2]]+iwinfile[iw2] image2=ass2d[iframe2] if (trimbox[0] ne -1) then image2= $ image2[trimbox[0]:trimbox[2],trimbox[1]:trimbox[3]] $ else reformimage,image2,image2,/croptriangles doppim=(float(image2)-image)/(image2+image) ;?? doppim=histo_opt_rr((float(image2)-image)/(image2+image),1E-4) imax=max(doppim) imin=min(doppim) ; maintain zero in Doppler signal if (abs(imin) gt imax) then imax=-imin else imin=-imax doppmin[iw]=imin doppmax[iw]=imax endif endif ; intscale option to use min max of whole or sampled sequence (slow) if (stepintscale gt 0) then begin if (iw eq 0 and ntfile gt 50) then print,' ----- patience: '+$ 'finding minmax sequence(s) may take long' for it=0+stepintscale,ntfile-1,stepintscale do begin iframe=long(it)*nwavsfile[filewav[iw]]+iwinfile[iw] ; must be long image=ass2d[iframe] if (trimbox[0] ne -1) then $ image=image[trimbox[0]:trimbox[2],trimbox[1]:trimbox[3]] else $ reformimage,image,image,/croptriangles imin=min(image) imax=max(image) if (imin lt intmin[iw]) then intmin[iw]=imin if (imax gt intmax[iw]) then intmax[iw]=imax ; maintain zero when fixzerowav set if (fixzerowav[iw] eq 1) then $ if (abs(imin) gt imax) then intmax[iw]=-imin else intmin[iw]=-imax ; find multiwav Dopplergram clips if (mwfile[filewav[iw]] ne 0 and $ strmatch(files[filewav[iw]],'*stokes*') ne 1) then begin if (iwinfile[iw] ne iwlcfile[filewav[iw]]) then begin iframe2=long(it)*nwavsfile[filewav[iw2]]+iwinfile[iw2] image2=ass2d[iframe2] if (trimbox[0] ne -1) then $ image2=image2[trimbox[0]:trimbox[2],trimbox[1]:trimbox[3]] $ else reformimage,image2,image2,/croptriangles doppim=(float(image2)-image)/(image2+image) ;?? doppim=histo_opt_rr((float(image2)-image)/(image2+image),1E-4) imin=min(doppim) imax=max(doppim) if (abs(imin) gt imax) then imax=-imin else imin=-imax if (imin lt doppmin[iw]) then doppmin[iw]=imin if (imax gt doppmax[iw]) then doppmax[iw]=imax endif endif endfor endif ; end loop intscale le -2 endfor ; end of loop over iw endif ; end of intscale ne -1 or array ; intscale single number > 1: set intmax = intmin+itscale if (abs(intscale[0]) gt 1 and n_elements(intscale) eq 1) then $ intmax=intmin+intscale[0] ; optional multipliers to rescale intscale=0 (default) first-frame values if (intscale[0] gt 0 and n_elements(intscale) eq 2) then begin intmin=intscale[0]*intmin intmax=intscale[1]*intmax doppmin=intscale[1]*doppmin ; max scale for both (doppmin<0)) doppmax=intscale[1]*doppmax endif ; determine mean profile and initialize plot windows meanprof=fltarr(nwavs) maxprofint=fltarr(nwavs) ; need the values also when no profile plot ; get mean profile from summing every 10th image naver=10(400)<500)*plotscale ; from idlsimplemanual pltxpos=screensize[0]-pltwidth ; define and open profile plot window ;RR fixed window numbers for these so that they can be clicked away without ; getting revived in a new zoom instance and then usurp the main window if (plotprofile eq 1) then begin window,20,xpos=pltxpos,ypos=0,$ xsize=pltwidth,ysize=pltwidth/1.5,$ title='spectral profile at cursor' xaxrange=[-1,nwavs] ; extend for showing wav cursor line at ends yaxrange=[0,plotmax] plot,meanprof,linestyle=3,charsize=1.3,$ xrange=xaxrange,xstyle=1,yrange=yaxrange,ystyle=1,$ xtitle='wavelength index',ytitle='normalized intensity' ; add pacifier if (addlabels ne 0) then begin xyouts,0.55,0.75,/norm,align=0.5,charsize=1.5,$ 'addlabels=1 delays startup' endif endif ; open timelines plot window if requested if (plottimeline eq 1) then $ window,21,xpos=pltxpos,ypos=pltwidth/2.,$ xsize=pltwidth,ysize=pltwidth/1.5,$ title='timelines A and B at cursor' ; open traceplot window if requested if (plotxtrace eq 1) then $ window,24,xpos=pltxpos,ypos=2*pltwidth/2.,$ xsize=pltwidth,ysize=pltwidth/1.5,$ title='intensity along x through cursor' ; open powerplot window if requested if (plotpower eq 1) then $ window,22,xpos=pltxpos,ypos=2*pltwidth/2.,$ xsize=pltwidth,ysize=pltwidth/1.5,$ title='power spectra A and B at cursor' ; open scatterplot window if requested if (plotscatter eq 1) then $ window,23,xpos=pltxpos,ypos=3*pltwidth/2.,$ xsize=pltwidth,ysize=pltwidth,$ title='scatter B versus A' endif ; ----- end of much stuff to do at first instance only ; ----- now stuff for any instance ; set wavlabel image overlay at current (but magnified) cutout size nxmag=fix(nxcut*magscreen) nymag=fix(nycut*magscreen) imlabel=bytarr(nxmag,nymag,nwavs) if (addlabels ne 0) then begin blank=bytarr(nxmag,nymag) window,xsize=nxmag,ysize=nymag,/pixmap,retain=2 for iw=0,nwavs-1 do begin tv,blank xyouts,nymag/30,nymag/30,labelwav[iw],color=255,$ /device,charsize=sqrt(nymag)/10.,charthick=sqrt(nymag)/10. imlabel[0,0,iw]=tvrd() endfor wdelete endif ; define assoc stream A for startup display if (bitpixfile[filewav[wavindA]] eq 8) then $ assA2d=assoc(lunfile[filewav[wavindA]],bytarr(nxfile,nyfile,/nozero),$ hofffile[filewav[wavindA]]) if (bitpixfile[filewav[wavindA]] eq 16) then $ assA2d=assoc(lunfile[filewav[wavindA]],intarr(nxfile,nyfile,/nozero),$ hofffile[filewav[wavindA]]) if (abs(bitpixfile[filewav[wavindA]]) eq 32) then $ assA2d=assoc(lunfile[filewav[wavindA]],fltarr(nxfile,nyfile,/nozero),$ hofffile[filewav[wavindA]]) ; define initial image A (start-off image when zoomed) iframeA=itA*nwavsfile[filewav[wavindA]]+iwinfile[0] imageA=assA2d[iframeA] imageA=imageA[xcutmin:xcutmax,ycutmin:ycutmax] ; cutout thisimage=imageA scatimA=float(imageA) ; set for (*q), float for Dopplergrams ; define assoc stream B for startup display if (bitpixfile[filewav[wavindB]] eq 8) then $ assB2d=assoc(lunfile[filewav[wavindB]],bytarr(nxfile,nyfile,/nozero),$ hofffile[filewav[wavindB]]) if (bitpixfile[filewav[wavindB]] eq 16) then $ assB2d=assoc(lunfile[filewav[wavindB]],intarr(nxfile,nyfile,/nozero),$ hofffile[filewav[wavindB]]) if (abs(bitpixfile[filewav[wavindB]]) eq 32) then $ assB2d=assoc(lunfile[filewav[wavindB]],fltarr(nxfile,nyfile,/nozero),$ hofffile[filewav[wavindB]]) ; define initial image B (start-off image when zoomed) iframeB=itB*nwavsfile[filewav[wavindB]]+iwinfile[0] imageB=assB2d[iframeB] imageB=imageB[xcutmin:xcutmax,ycutmin:ycutmax] ; cutout scatimB=float(imageB) ; set for (*q), float for Dopplergrams ; set initial movie direction direction=1 ; set sizes including magnification org_sz=1 sz=size(imageA) d_xsz=sz[1]*magscreen ; display window xsize d_ysz=sz[2]*magscreen ; display window ysize ; maintain aspect when resizing (I removed former button) aspect=float(d_ysz/d_xsz) ; load first image onto main window (/pixmap = no display yet) window,/pixmap,/free,xsize=nxcut,ysize=nycut if (intscale[0] eq -1) then tv,bytscl(imageA,top=ncolors) else $ tv,bytscl(imageA,top=ncolors,min=intmin[wavindA],max=intmax[wavindA]) pixmapwindow=!d.window xscale=interpol(indgen(nxcut),d_xsz) yscale=interpol(indgen(nycut),d_ysz) ; ------ fill the widget with buttons and sliders ; add hand-made play/pause buttons bmp_buttons=get_bmp_buttons() ; set screen title if (max(nwavsfile) gt 1) then screentitle='3.5D spectral mode: ' else $ screentitle='3D image mode: ' if (duplicate) then $ screentitle=screentitle+'single file = '+file_basename(files[0]) if (nfiles eq 2 and duplicate eq 0) then $ screentitle=screentitle+'files = '+file_basename(files[0])+$ ', '+file_basename(files[1]) if (nfiles gt 2) then $ screentitle=screentitle+trimd(nfiles)+' files, nwavs/file ='+$ trimd(nwavsfile[*]) ; main widget tlb=widget_base(title=screentitle,mbar=menubar,tlb_size_events=1,$ group_leader=groupleader,/row) lcol=widget_base(tlb,/frame,/column,xsize=leftwidth) ; left column rcol=widget_base(tlb,/column) ; right column ; response to cursor action within the image displaybase=widget_base(rcol,/row) drawid=widget_draw(displaybase,retain=2,xsize=d_xsz,ysize=d_ysz,$ /button_events,event_pro='ximovie_cursorevent') widget_control,drawid,/draw_motion_events ; add menu on top filemenu=widget_button(menubar,value='File',/menu,uvalue='file') stopmenu=widget_button(filemenu,value='Stop for parameter inspection',$ event_pro='ximovie_stop') exitmenu=widget_button(filemenu,value='Quit this instance',$ event_pro='ximovie_destroy') optmenu=widget_button(menubar,value='Options',/menu) dummy=widget_button(optmenu, value='write /tmp/movex_image.fits',$ event_pro='ximovie_writefits') dummy=widget_button(optmenu, value='write /tmp/movex_image.ps',$ event_pro='movex_writeps') dummy=widget_button(optmenu,value='color table',$ event_pro='ximovie_colors') dummy=widget_button(optmenu,value='set A color range',$ event_pro='movex_setArange') dummy=widget_button(optmenu,value='set B color range',$ event_pro='movex_setBrange') ; @@@@@@@@@@@@@@@ begin dummy=widget_button(optmenu,value='set A rundif interval',$ event_pro='movex_setrundifA') dummy=widget_button(optmenu,value='set B rundif interval',$ event_pro='movex_setrundifB') ; @@@@@@@@@@@@@@ endif dummy=widget_button(optmenu,value = 'restrict time range',$ event_pro='ximovie_setframes') dummy=widget_button(optmenu,value = 'set smear',$ event_pro='ximovie_setsmear') dummy=widget_button(optmenu,value='plot profile on/off',$ event_pro='movex_setprofile') dummy=widget_button(optmenu,value='plot scatter on/off',$ event_pro='movex_setscatter') dummy=widget_button(optmenu,value='plot timeline on/off',$ event_pro='movex_settimeline') dummy=widget_button(optmenu,value='plot power on/off',$ event_pro='movex_setpower') dummy=widget_button(optmenu,value='plot xtrace on/off',$ event_pro='movex_settrace') dummy=widget_button(optmenu,value='mark image center on/off',$ event_pro='movex_markcenter') ;; ; quit-this-instance button ;; closefield=widget_base(lcol,/column) ;; quitbutton=widget_button(menubar,value='quit this instance',$ ;; event_pro='ximovie_destroy') ; movie stream selection buttons ;RR "field" means thin-line frame around sliders that belong together anim_field=widget_base(lcol,/column,/frame) twostream_area=widget_base(anim_field,/row) streamA_button=widget_button(twostream_area,value='show A',$ event_pro='ximovie_streamA') streamB_button=widget_button(twostream_area,value='show B',$ event_pro='ximovie_streamB') stream_mix_button=widget_button(twostream_area,value='mix', $ event_pro='ximovie_streammix') quitbutton=widget_button(twostream_area,value='quit this',$ event_pro='ximovie_destroy') ; play movie buttons button_area=widget_base(anim_field,/row) play_fwd_button=widget_button(button_area,value=bmp_buttons.play,$ event_pro='ximovie_play_fwd') pause_button=widget_button(button_area,value=bmp_buttons.pause_blk,/bitmap,$ event_pro='ximovie_pause') play_rev_button=widget_button(button_area,value=bmp_buttons.play_rev,$ event_pro='ximovie_play_rev') play_fwd_rev_button=widget_button(button_area,value=bmp_buttons.cycle,$ event_pro='ximovie_play_fwd_rev') ; time slider framenr_title='time step' timeslider=$ widget_slider(anim_field,xsize=sliderlength,$ minimum=itfirst,maximum=itlast,$ title=framenr_title,$ value=itfirst,event_pro='ximovie_timeslider',/drag) ; animation speed slider framespeed_title='animation speed [frames/sec]' framespeed_slider=$ widget_slider(anim_field,xsize=sliderlength,$ minimum=1,maximum=20,$ ; Nov 15 2020 from 100 for stop title=framespeed_title,$ value=frame_speed,event_pro='ximovie_framespeed',/drag) ; wavelength sliders if nwavs > 2 wav_field=widget_base(lcol,/frame,/column) if (nwavs gt 2) then begin frame_wavA_slider=$ widget_slider(wav_field,xsize=sliderlength,minimum=0,$ maximum=nwavs-1,title='wavelength index stream A',$ value=wavindA,event_pro='movex_wavA',/drag) frame_wavB_slider=$ widget_slider(wav_field,xsize=sliderlength,minimum=0,$ maximum=nwavs-1,title='wavelength index stream B',$ value=wavindB,event_pro='movex_wavB',/drag) ; only 2 streams endif else begin wavindA=0 wavindB=1 ; put 2nd file in stream B when two single-wav files endelse ; mean(t) button mode_field=widget_base(wav_field,/row) seqmean_button=widget_button(mode_field,value='mean(t)', $ event_pro='movex_seqmean') ; row mode A greyscale buttons: revA,absA,sqrA, logA mode_field=widget_base(wav_field,/row) revA_button=widget_button(mode_field,value='rev A', $ event_pro='movex_revA') absA_button=widget_button(mode_field,value='abs A', $ event_pro='movex_absA') sqrA_button=widget_button(mode_field,value='sqr A', $ event_pro='movex_sqrA') logA_button=widget_button(mode_field,value='log A', $ event_pro='movex_logA') ; row mode B greyscale buttons: revB,absB,sqrB, logB mode_field=widget_base(wav_field,/row) revB_button=widget_button(mode_field,value='rev B', $ event_pro='movex_revB') absB_button=widget_button(mode_field,value='abs B', $ event_pro='movex_absB') sqrB_button=widget_button(mode_field,value='sqr B', $ event_pro='movex_sqrB') logB_button=widget_button(mode_field,value='log B', $ event_pro='movex_logB') ; Doppler buttons for spectral cubes if (max(nwavsfile) gt 1) then begin dopp_field=widget_base(wav_field,/row) doppA_button=widget_button(dopp_field,value='A Dopp',$ event_pro='movex_doppA') doppB_button=widget_button(dopp_field,value='B Dopp',$ event_pro='movex_doppB') doppcol_button=widget_button(dopp_field,value='color Dopp',$ event_pro='movex_doppcolor') endif else begin doppA=0 doppB=0 doppcol=0 endelse ; time delay slider single_field=widget_base(lcol,/frame,/column) delay_slider=$ widget_slider(single_field,xsize=sliderlength,$ minimum=-fix((itlast-itfirst)/2),$ maximum=fix((itlast-itfirst)/2),$ title='time delay itB-itA when blinking',$ value=time_delay,$ event_pro='movex_timedelay',/drag) ; buttons for stepping, blink, stop, reset delay button_field=widget_base(single_field,/row) decr_button=widget_button(button_field,value='-',$ event_pro='ximovie_decr') incr_button=widget_button(button_field,value='+',$ event_pro='ximovie_incr') blink_button=widget_button(button_field,value='blink',$ event_pro='ximovie_tvblink_start') blink_pause_button=widget_button(button_field,value='stop',$ event_pro='ximovie_tvblink_stop') reset_delay_button=widget_button(button_field,value='dt=0',$ event_pro='movex_resetdelay') ; zoom-instance slider bars to move cutout around in full image if xyrangecut then begin zoom_field=widget_base(lcol,/frame,/column) xstart_slider= $ widget_slider(zoom_field,xsize=sliderlength,minimum=0,$ maximum=nxfile-nxcut-1,title='shift cutout in x',$ value=xcutmin,event_pro='ximovie_xscroll_slider',/drag) ystart_slider=$ widget_slider(zoom_field,xsize=sliderlength,minimum=0,$ maximum=nyfile-nycut-1,title='shift cutout in y',$ value=ycutmin,event_pro='ximovie_yscroll_slider',/drag) endif ; Aug 5 2015 Gregal Vissers: add cursor (x,y) display xycoords_field=widget_base(lcol,/frame,/row) xycoords_label=$ widget_label(xycoords_field,value='cursor (x,y) = '+$ '('+STRTRIM(xcutmin,2)+','+STRTRIM(ycutmin,2)+')',$ /dynamic_resize) ;; ; quit-this-instance button ;; closefield=widget_base(lcol,/column) ;; closebutton=widget_button(closefield,value='quit this instance',$ ;; event_pro='ximovie_destroy') ; ------ now all is set to start ; start main window widget_control,tlb,/realize,tlb_get_size=tlb_sz ;; ,$ ;; trial larger font doens't work ;; default_font='-misc-fixed-medium-r-normal-ko-18-120-100-100-c-180-iso10646-1' ; set up background bg_base=widget_base(tlb,event_pro='ximovie_tvmovie') bg_base2=widget_base(tlb,event_pro='ximovie_tvblink') ; get window id of display window widget_control,drawid,get_value=mainwindow if (instance eq 0) then topwindow=mainwindow ; used in final cleanup wset,mainwindow ; get window size tlb_xsz=tlb_sz[0] ; xsize of whole widget in pixels tlb_ysz=tlb_sz[1] ; ysize of whole widget in pixels menu_ysz=tlb_ysz-d_ysz menu_xsz=tlb_xsz-d_xsz ; get color table tvlct,R,G,B,/get bottom=0 if (!d.n_colors le 256) then begin R=R[bottom:ncolors-1+bottom] G=G[bottom:ncolors-1+bottom] B=B[bottom:ncolors-1+bottom] endif R_orig=R G_orig=G B_orig=B ;RR what stands tlb for? if n_elements(group_leader) ne 0 then groupleader=group_leader $ else groupleader=tlb ; structure to pass information to subroutines q={files:files,$ nfiles:nfiles,$ nwavs:nwavs,$ filewav:filewav,$ addlabels:addlabels,$ labelwav:labelwav,$ fixzerowav:fixzerowav,$ imlabel:imlabel,$ cadence:cadence,$ bitpixfile:bitpixfile,$ nwavsfile:nwavsfile,$ iwinfile:iwinfile,$ iwstartfile:iwstartfile,$ iwendfile:iwendfile,$ hofffile:hofffile,$ lunfile:lunfile,$ ass2pt:ass2pt,$ thisimage:thisimage,$ nxfile:nxfile,$ nyfile:nyfile,$ ntfile:ntfile,$ trange:trange,$ nxcut:nxcut,$ nycut:nycut,$ ntcut:ntcut,$ xcutmin:xcutmin,$ ycutmin:ycutmin,$ xcutmax:xcutmax,$ ycutmax:ycutmax,$ xscale:ptr_new(),$ yscale:ptr_new(),$ tlb:tlb,$ drawid:drawid,$ bg_base:bg_base,$ bg_base2:bg_base2,$ imA:imA,$ imB:imB,$ streamA:streamA,$ streamB:streamB,$ streammix:streammix,$ seqmean:seqmean,$ absA:absA,$ absB:absB,$ sqrA:sqrA,$ sqrB:sqrB,$ logA:logA,$ logB:logB,$ revA:revA,$ revB:revB,$ d_xsz:d_xsz,$ d_ysz:d_ysz,$ aspect:aspect,$ tlb_xsz:tlb_xsz,$ tlb_ysz:tlb_ysz,$ menu_ysz:menu_ysz,$ menu_xsz:menu_xsz,$ R:R,G:G,B:B,$ R_orig:R_orig,G_orig:G_orig,B_orig:B_orig,$ itthis:itthis,$ itA:itA,$ itB:itB,$ wavindA:wavindA,$ wavindB:wavindB,$ meanprof:meanprof,$ direction:direction,$ time_delay:time_delay,$ frame_speed:frame_speed,$ magscreen:magscreen,$ ncolors:ncolors,$ bottom:bottom,$ playmode:'pause',$ cycle:1,$ tcutmin:tcutmin,$ tcutmax:tcutmax,$ itfirst:itfirst,$ itlast:itlast,$ start_frame_id:0L,$ stop_frame_id:0L,$ frame_nr:frame_nr,$ Arange_min:0.0,$ Arange_max:0.0,$ Arange_min_id:0L,$ Arange_max_id:0L,$ Brange_min:0.0,$ Brange_max:0.0,$ Brange_min_id:0L,$ Brange_max_id:0L,$ run:0,$ instance:instance,$ maxprofint:maxprofint,$ action:drawid,$ mainwindow:mainwindow,$ topwindow:topwindow,$ groupleader:groupleader,$ sx:0,$ sy:0,$ xpx:0,ypx:0,$ ; Gregal position in pixels outframe:outframe,$ drawbox:0B,$ xycoords_label:xycoords_label,$ mainpixmapwindow:pixmapwindow,$ pixmapwindow:pixmapwindow,$ timeslider:timeslider,$ play_fwd_button:play_fwd_button,$ play_rev_button:play_rev_button,$ play_fwd_rev_button:play_fwd_rev_button,$ pause_button:pause_button,$ bmp_buttons:bmp_buttons,$ framespeed_slider:framespeed_slider,$ delay_slider:delay_slider,$ intscale:intscale,$ magnification:magnification,$ allsdo:allsdo,$ sdodirs:sdodirs,$ allmwf:allmwf,$ mwfdirs:mwfdirs,$ allfits:allfits,$ fitsdirs:fitsdirs,$ mwspectfiles:mwspectfiles,$ allspect:allspect,$ spectdirs:spectdirs,$ intmin:intmin,$ intmax:intmax,$ duplicate:duplicate,$ plotmax:plotmax,$ plotscale:plotscale,$ doppA:doppA,$ doppB:doppB,$ doppcol:doppcol,$ iwlcfile:iwlcfile,$ doppmin:doppmin,$ doppmax:doppmax,$ doppmode:doppmode,$ colorA:colorA,$ colorB:colorB,$ iw2:iw2,$ trimbox:trimbox,$ scatimA:scatimA,$ scatimB:scatimB,$ pltxpos:pltxpos,$ pltwidth:pltwidth,$ plotprofile:plotprofile,$ plottimeline:plottimeline,$ plotxtrace:plotxtrace,$ plotpower:plotpower,$ plotscatter:plotscatter,$ scatrangeA:scatrangeA,$ scatrangeB:scatrangeB,$ rundifA:rundifA,$ rundifB:rundifB,$ timelineA:timelineA,$ timelineB:timelineB,$ trace:trace,$ mintrace:mintrace,$ maxtrace:maxtrace,$ xyrangecut:xyrangecut,$ blink:blink,$ smear:smear,$ markcenter:markcenter,$ noblock:noblock} ; pointers q=ptr_new(q,/no_copy) (*q).xscale=ptr_new(xscale) (*q).yscale=ptr_new(yscale) *(*q).xscale=xscale *(*q).yscale=yscale ; set user value of tlb widget to be the q ptr widget_control,tlb,set_uvalue=q widget_control,bg_base,set_uvalue=q ; create pseudo-event to start display pseudoevent={widget_button,id:(*q).action,$ top:tlb,handler:0l,select:1} ; display stream A or start per blink when only two if (blink eq 0) then movex_tvimage,pseudoevent else $ ximovie_tvblink,pseudoevent ; start response sensitivity: here we go! xmanager,'movex',tlb,no_block=noblock,group_leader=group,$ event_handler='ximovie_resize',cleanup='ximovie_cleanup' ;RR Nov 26 2017 no_block: email Gregal ; ; end of program: clean /tmp if (instance eq 0) then spawn,'rm -f /tmp/showex_*' instance=-1 end ; ----- of the whole program movex.pro ;RR ================ main for testing per IDLWAVE H-c ================== ;; ; contrail data: allsdo + IRIS + SST/CRISP ;; cd,'/media/rutten/SSTDATA/alldata/SST/2014-06-21-quiet/' ;; files=['iris2sst/sji1400_algbo.fits','iris2sst/sji2796_algbo.fits',$ ;; 'crispex/crispex.6563.08:02:31.time_corrected.aligned.icube',$ ;; 'crispex/crispex.8542.08:02:31.time_corrected.icube'] ;; mwspectfiles=['crispex/spectfile.6563.idlsave',$ ;; 'crispex/spectfile.8542.idlsave'] ;; allsdo=1 ;; ntfile=377 ;; cadence=31.3066 ;; intscale=-50 ;; trimbox=[50,50,860,860] ; avoid SST derotation triangles ;; wavindA=12 ; outer wing Doppler, black=blue ;; doppA=1 ;; wavindB=7 ; ha_lc ;; plotscatter=1 ;; itthis=88 ; published contrail ;; trange=[88,130] ;; time_delay=18 ; contrail blink ;; colorA=[100,120] ;; colorB=[1000,1600] ;; smear=20 ;; doppcol=1 ;; ; demo data SST + co-aligned SDO ;; cd,'/home/rutten/data/SST/2016-09-05-demo' ;; infiles='crispex/crispex.6563.09:48:31.time_corrected.aligned.icube' ;; nt_mw=35 ;; mwspectfiles=['crispex/spectfile.6563.idlsave',$ ;; 'crispex/spectfile.8542.idlsave'] ;; addlabels=1 ;; plotscatter=1 ;; allsdo=0 ;; allmwf=0 ;; allfits=0 ;; ;; intscale=-5 ;; ;; trange=[20,30] ;; ;; intscale=[1.,0.1] ;; ;; intscale=[1.,0.5] ;; cd,'/media/rutten/SSTDATA/alldata/SST/2014-08-29-gregal' ;; files='crispex/crispex.6563.15:40:09.time_corrected.aligned.icube' ;; nt_mw=735 ;; instcale=-100 ;; plotscatter=0 ;; cd,'/media/rutten/RRDATA/alldata/DST/2017-06-14-schad/ibisB' ;; files=['ibis_wb_6563_20170614_164052.fits',$ ;; 'ibis_mwseq_6563_20170614_164052.fits',$ ;; 'ibis_mwseq_8542_20170614_164052.fits'] ;; mwspectfiles=['ibis_wavs_6563_20170614_164052.txt',$ ;; 'ibis_wavs_8542_20170614_164052.txt'] ;; trimbox=[200,200,800,800] ;; addlabels=1 ;; cd,'/media/rutten/RRDATA/alldata/DST/2017-06-14-schad' ;; files=['ibisB2sdo/ibis_mwseq_6563_20170614_164052_alrev_ip.fits',$ ;; 'ibisB2sdo/ibis_mwseq_8542_20170614_164052_alrev_ip.fits'] ;; mwspectfiles=['ibisB/ibis_wavs_6563_20170614_164052.txt',$ ;; 'ibisB/ibis_wavs_8542_20170614_164052.txt'] ;; trimbox=[200,200,800,800] ;; addlabels=1 ;; cd,'/media/rutten/RRDATA/alldata/DST/2017-06-14-schad' ;; infiles='mxis/mxis_mwseq_10830_20170614_104106.fits' ;; trimbox=[200,200,700,700] ;; cd,'/media/rutten/SSTDATA/alldata/SST/2014-06-21-quiet/iris/center' ;; infiles='iris_l2_20140621_204601_3893012099_SJI_1400_t000.fits' ;; intscale=3000 cd,'/home/rutten/data/SDO/2014-06-14-small' infiles='' ; needed since this is movex, not showex! allsdo=1 sdodirs='target/cubes' ; UV shifts since limbward ;; ;; cd,'/home/rutten/data/SST/2016-09-05-demo' ; Jun 25 2020 doesn't work ;; cd,'/home/rutten/rr/web/sdo-demo/2014-06-24/sst' ;; infiles='' ; needed since this is movex, not showex! ;; allmwf=1 ;; allmwf=1 ;; mwfdirs='.' ;; allspect=1 ;; addlabels=1 ;; allsdo=1 ;; sdodirs='.' ;; fitsdirs='.' ;; plotxtrace=1 wavindA=3 wavindB=6 plotscatter=1 blink=1 ; full call identical to pro movex,infiles,nt_mw=nt_mw,mwspectfiles=mwspectfiles,$ ; ----- keyword options for the user intscale=intscale,trimbox=trimbox,magnification=magnification,$ addlabels=addlabels,plotmax=plotmax,plotscale=plotscale,cadence=cadence,$ xrange=xrange,yrange=yrange,trange=trange,smear=smear,blink=blink,$ ; ----- special keyword parameters for SDO and SST data allsdo=allsdo,sdodirs=sdodirs,allmwf=allmwf,mwfdirs=mwfdirs,$ allfits=allfits,fitsdirs=fitsdirs,allspect=allspect,spectdirs=spectdirs,$ ; ----- optional startup parameters one may set plotprofile=plotprofile,plottimeline=plottimeline,plotxtrace=plotxtrace,$ plotpower=plotpower,plotscatter=plotscatter,$ scatrangeA=scatrangeA,scatrangeB=scatrangeB,$ rundifA=rundifA,rundifB=rundifB,$ wavindA=wavindA,wavindB=wavindB,doppA=doppA,doppB=doppB,doppcol=doppcol,$ absA=absA,absB=absB,sqrA=sqrA,sqrB=sqrB,logA=logA,logB=logB,$ revA=revA,revB=revB,$ colorA=colorA,colorB=colorB,markcenter=markcenter,noblock=noblock,$ itthis=itthis,itfirst=itfirst,itlast=itlast,time_delay=time_delay,$ frame_speed=frame_speed,$ ; ----- more startup parameters needed in new instance instance=instance,duplicate=duplicate,$ group_leader=group,topwindow=topwindow,$ meanprof=meanprof,labelwav=labelwav,fixzerowav=fixzerowav,$ pltxpos=pltxpos,pltwitdh=pltwidth,$ intmin=intmin,intmax=intmax,maxprofint=maxprofint,$ streamA=streamA,streamB=streamB,streammix=streammix,seqmean=seqmean,$ imA=imA,imB=imB,itA=itA,itB=itB,$ R_orig=R_orig,G_orig=G_orig,B_orig=B_orig,$ timelineA=timelineA,timelineB=timelineB,$ iwlcfile=iwlcfile,$ doppmax=doppmax,doppmin=doppmin,doppmode=doppmode,iw2=iw2,$ frame_nr=frame_nr,scatimA=scatimA,scatimB=scatimB,$ imlabel=imlabel,$ xyrangecut=xyrangecut,outframe=outframe,$ trace=trace,mintrace=mintrace,maxtrace=maxtrace end