;+ ; NAME: ; MINIVIDEO ; PURPOSE: ; Quick display of an image sequence showing a drifting patch ; over Eureka, using estimated patch drifts to offset successive ; images. The result is a quasi-stationary patch, with the ; Eureka field of view drifting over it. ; CATEGORY: ; ; CALLING SEQUENCE: ; MINIVIDEO, NAME ; INPUTS: ; NAME: The name (file only, not whole path) of the .mt[gp] ; file that contains the image sequence. ; OPTIONAL INPUTS: ; None. ; KEYWORD PARAMETERS: ; None. ; OUTPUTS: ; None. ; OPTIONAL OUTPUTS: ; None. ; COMMON BLOCKS: ; None. ; SIDE EFFECTS: ; The specified file is read, and images are displayed to an ; X window. ; RESTRICTIONS: ; The specified file, and a corresponding {.geo|.pgm} file, ; must exist. ; PROCEDURE: ; ... ; EXAMPLE: ; ; SEE ALSO: ; Lots of .pro files; look 'em up. ; MODIFICATION HISTORY: ; Written by: D P Steele, June/July 1994. ;- PRO minivideo,name IF N_PARAMS() EQ 0 THEN BEGIN doc_library,'minivideo' RETURN ENDIF ; Set the edge length of a single image from the {.geo|.pgm} file. edge=383 ; Determine the type of mapped image file we're working with. lastchr=STRMID(name,STRLEN(name)-1,1) HELP,lastchr ; Load the .mt[gp] file into a STRING array. path='/jasper/cnsr3_data1/pgm/'+name mtg=qgetfile(path) ; Determine how many images go into the montage. n=N_ELEMENTS(mtg) READS,mtg(n-1),lastn npix2=FIX(lastn+1) PRINT,npix2,' images analysed',FORMAT='(I0,A)' ; Get the {.geo|.pgm} image resolution info0=n-npix2 READS,mtg(info0-3),pixres,FORMAT='(40X,F6.4)' ; Set up the arrays to hold the essential .mt[gp] file contents. times=FLTARR(npix2) cshift=INTARR(npix2) rshift=cshift vdusk=times vasun=times p1='' ; Extract the file contents from the STRING array. FOR i=0,npix2-1 DO BEGIN j=i+info0 READS,mtg(j),p0,p1,p2,p3,p4,p5,p6,p7,p8 $ ,FORMAT='(I3,2X,A12,2X,F8.2,2X,I3,2X,F8.4,2(2X,I3),2(2X,F8.5))' times(i)=p2 cshift(i)=-p5 ; opposite sign to what is in .mt[gp] file rshift(i)=-p6 ; ditto vasun(i)=p7 vdusk(i)=p8 ENDFOR ; Identify and fill gaps in the velocity and shift arrays flag=BYTARR(npix2) gap=WHERE((vasun EQ 0.) and (vdusk EQ 0.),ngap) IF ngap GT 0 THEN BEGIN flag(gap)=1 ; flag gaps for later use good=REPLICATE(1B,N_ELEMENTS(flag))-flag FOR i=0,ngap-1 DO BEGIN k=gap(i) tmp=extrac(vasun,k-3,7) ; first do antisunward vels vasun(k)=TOTAL(tmp)/TOTAL(tmp GT 0) ; mean of non-0 vels IF k NE npix2-1 $ ; dt=interval between images THEN dt=times(k+1)-times(k) $ ELSE dt=times(k-1)-times(k-2) rshift(k)=ROUND(dt*vasun(k)/pixres) ; estimate rshift tmp=extrac(vdusk,k-3,7) ; repeat for duskward vels vdusk(k)=TOTAL(tmp)/TOTAL(tmp GT 0) cshift(k)=ROUND(dt*vdusk(k)/pixres) ENDFOR ENDIF ; Show the image numbers and times to aid the user's selection of ; a display sequence FOR ii=0L,npix2/10 DO $ PRINT,ii*10,strsec(times(ii*10)),FORMAT='(I3,": ",A)' ; Find out which images the user wants to show as a video. READ,'Enter the numbers of the first and last images to be ' $ +'shown as a video: ',first,last imgs=INDGEN(last-first+1)+FIX(first) nimgs=N_ELEMENTS(imgs) PRINT,imgs ; Calculate total shifts over sequence trsh=FIX(TOTAL(rshift(first:last-1))) tcsh=FIX(TOTAL(cshift(first:last-1))) ; Determine the type of mapped image file to read CASE lastchr OF 'g': mapsuffix='geo' 'p': mapsuffix='pgm' ELSE: BEGIN MESSAGE,'Unknown type of mapped image: '+lastchr $ ,/INFORMATIONAL RETURN END ENDCASE ; Open {.geo|.pgm} file that contains the transformed images ifile=path STRPUT,ifile,mapsuffix,STRLEN(ifile)-3 OPENR,data,ifile,/GET_LUN image=ASSOC(data,BYTARR(edge,edge)) ; Find first filled row in first image and last filled row in last image wnz=WHERE(image(first)) frf=MIN(wnz/edge) wnz=WHERE(image(last)) lrf=MAX(wnz/edge) PRINT,'frf = ',frf,', lrf = ',lrf,FORMAT='(2(A,I0))' ; Decide how big montage has to be, given net shifts found PRINT,trsh,tcsh,FORMAT= $ '("Total of ",I4," rows and ",I3," columns of shift")' height=MAX([tcsh+2+edge,trsh+edge+20-frf-(edge-1-lrf)]) montage=BYTARR(tcsh+1+edge,height,N_ELEMENTS(imgs)) ; Set up to begin filling montage array. c0=MAX([0,-tcsh]) ; position for L edge of first image r0=0 loadct,3,/silent ; Add each image to the montage csz=2 ; big characters for time labels cth=csz ; big, THICK characters! FOR i=0,nimgs-1 DO BEGIN PRINT,'c0 = ',c0,', r0 = ',r0,FORMAT='(2(A,I0))' srow=(frf-10)>0 erow=MIN([edge-1,height-1-r0+srow]) montage(c0,r0,i)=(image(imgs(i)))(*,srow:erow) ; Turn time string into an image to paste into the montage ut=strsec(times(imgs(i))+.5) xs=csz*STRLEN(ut)*!D.X_CH_SIZE ys=csz*!D.Y_CH_SIZE WINDOW,/FREE,XSIZE=xs,YSIZE=ys,/PIXMAP pwin=!D.WINDOW XYOUTS,0,0,ut,/DEVICE,CHARSIZE=csz,CHARTHICK=cth utim=TVRD() WDELETE,pwin montage(0,height-(size(utim))(2),i)=BYTSCL(utim,TOP=MAX(image(i))) ; Update L edge and bottom unfilled row pointers c0=c0+cshift(imgs(i)) r0=r0+rshift(imgs(i)) ENDFOR ; No further need for {.geo|.pgm} file FREE_LUN,data ; Now have a look at the MONTAGE array. msize=SIZE(montage) WINDOW,0,XSIZE=msize(1),YSIZE=msize(2) movie,montage,2,order=0B IF lastchr EQ 'p' THEN BEGIN ; Add PACE geomagnetic coordinate grid to montage. First, ; create the window. wedge=msize(1) WINDOW,/FREE,XSIZE=wedge,YSIZE=wedge,/PIXMAP csz=1 cth=csz !P.THICK=csz ; Establish the coordinate system. PLOT,INDGEN(wedge),INDGEN(wedge),/DEVICE,/NODATA $ ,POSITION=[0,0,wedge-1,wedge-1],XMARGIN=[0,0],YMARGIN=[0,0] $ ,XRANGE=[0,wedge],YRANGE=[0,wedge],XSTYLE=5,YSTYLE=5 ; Draw a circle at 85 deg PACE geomagnetic latitude. arcs,5./pixres,0,360,wedge/2,wedge/2,/device ; Draw meridians every 3 hrs of MLT. FOR i=-5,2 DO radii,0,edge/2,i*45,wedge/2,wedge/2,/device ; Label MLT meridians. mlt_label_offset=[4.,6.,7.,6.,6.,3.,3.,3.] rr=8./pixres FOR i=0,7 DO BEGIN ang=-90.+i*45. dr=0.4*(-SIN(ang*!DTOR)-1.)/pixres xoff=(rr+dr)*COS((ang-mlt_label_offset(i))*!DTOR) yoff=(rr+dr)*SIN((ang-mlt_label_offset(i))*!DTOR) XYOUTS,wedge/2+xoff,wedge/2+yoff,STRTRIM(i*3,2) $ ,ALIGNMENT=0.5,/DEVICE,CHARSIZE=csz,CHARTHICK=cth IF i EQ 0 $ THEN XYOUTS,wedge/2-xoff,wedge/2+yoff,'MLT' $ ,ALIGNMENT=0.1,CHARSIZE=csz,CHARTHICK=cth ENDFOR ; Label PGMLat parallels. FOR i=1,1 DO BEGIN yoff=(5.*i+0.2)/pixres xoff=-1.5/pixres XYOUTS,wedge/2+xoff,wedge/2+yoff,STRTRIM(90-i*5,2) $ ,ALIGNMENT=0,/DEVICE,CHARSIZE=csz,CHARTHICK=cth IF i EQ 1 THEN XYOUTS,wedge/2+0.3/pixres,wedge/2+yoff,'PGMLat' $ ,ALIGNMENT=0,/DEVICE,CHARSIZE=csz,CHARTHICK=cth ENDFOR ; Write the date, place, emission height, and full scale brightness ; on the plot somewhere. date=STRTRIM(mtg(3),2) XYOUTS,0,0,date,ALIGNMENT=0,/DEVICE,CHARSIZE=csz,CHARTHICK=cth place='Eureka 88.7!7K!X' XYOUTS,0,csz*(1.1*!D.Y_CH_SIZE),place $ ,ALIGNMENT=0,/DEVICE,CHARSIZE=csz,CHARTHICK=cth height=FIX(getwrd(mtg(6),3)) XYOUTS,wedge-1,csz*(1.1*!D.Y_CH_SIZE) $ ,STRING(height,FORMAT='(I3," km")') $ ,ALIGNMENT=1,/DEVICE,CHARSIZE=csz,CHARTHICK=cth fsp=-1 FOR i=9,11 DO IF STRPOS(mtg(i),'Full scale') GT -1 THEN fsp=i IF fsp GT 0 THEN BEGIN fullscale=ROUND(FLOAT(getwrd(mtg(fsp),4))) XYOUTS,wedge-1,0,STRING(fullscale,FORMAT='("<",I3," R")') $ ,ALIGNMENT=1,/DEVICE,CHARSIZE=csz,CHARTHICK=cth ENDIF ; Read back the coordinate grid as an image. grid=TVRD() WDELETE,!D.WINDOW ; Now insert it into the first frame of the montage. wg=WHERE(grid,nwg) montage(wg)=grid(wg) ; Now show the montage again. movie,montage,2,order=0B ENDIF RETURN END