;+--------------------------------------------------------------------------- ; NAME: ; cine2mpeg ; ; PURPOSE: ; Create an mpeg movie from a .cin files from Phantom 7 Cameras. ; The data can be color or monochrome ; ; CATEGORY: ; animation ; ; CALLING SEQUENCE: ; cine2mpeg, CineFile1, outFile=outfile, t1=t1, t2=t2, ndups=ndups ; or ; cine2mpeg, shot=shot, t1=t1, t2=t2, /verbose ; ; INPUTS: ; CineFile1 - a cine filename ; OPTIONAL KEYWORD PARAMETERS: ; outFile - name of output MPEG file (will default to a nice name), or ; prefix - what would precede _shot_t1_t2 (in msec) in the output filename ; t1 - start time of animation in seconds ; t2 - end time of animation in seconds ; VIEW - if set, just displays images, and does not make an mpeg ; ndups - if given means repeat every image 'ndups' times ; despeckle - if set call despeckle routine (slow, but less "intrusive" ; than median) ; nSmooth - number input to median smoothing routine ; topPixels - ; botPixels - ; charsize - character size for plots. Default=2 ; ctb - color table for non-color image ; label1 - label on plot ; verbose - if set will print out info as it works ; OUTPUTS: ; an MPEG file named by outFile keyword ; ; PROCEDURE: ; EXAMPLE: ; ; cine2mpeg, '/p/nstxusr3/miro/MIRO_130389.cin', $ ; t1=0.02, t2=0.0300, /verbose , /debug ; ; cine2mpeg, shot=130277, t1=0.100, t2=0.200, /verbose, /view , /debug ; ; cine2mpeg, '/p/nstxusr2/phantom4/GDNex10usFps27000DC110maP1.98torr-1.cin', $ ; outfile='Ne110us.mpg', t1=.0007, t2=0.0017, ndups=4, mag=3 ; ; mv files to /w/nstx.pppl.gov/htdocs/nstx/Software/Diagnostics/Miro/GlobalMPEGs ; for web viewing at ; http://nstx.pppl.gov/nstx/Software/Diagnostics/Miro/GlobalMPEGs ; ; MODIFICATION HISTORY: ; 12-Nov-2008 mods because cineload now assuming frame 0 is beginning of data ; 18-Sep-2008 mods to magnify keyword ; 05-Aug-2008 Written by Bill Davis ;------------------------------------------------------------------------------ PRO cine2mpeg, file1_in, shot=shot, $ outDir=outDir, outFile=outfile, prefix=prefix, $ ; specify only one of these magnify=magnify, ctb=ctb, dialog=dialog, $$ ndups=ndups, skip=skip, border=border, $ topPixels=topPixels, botPixels=botPixels, $ debug=debug, nsmooth=nsmooth, $ thick=thick, badValue=badValue, framenum=framenum, $ inc=inc, t1_in=t1_in, t2_in=t2_in, type=type, $ label1=label1, charsize=charsize, $ gamma1=gamma1, logo=logo, $ VIEW=view, xsize=xsize, ysize=ysize, verbose=verbose ; determine if monitor is 24-bit color (pixmap always?) set_plot,'x' Device, Get_Visual_Depth=thisDepth IF thisDepth GT 8 THEN BEGIN Device, Decomposed=0 truecolor = 1 ENDIF ELSE truecolor = 0 if not trueColor then begin if dialog then a=dialog_message('This may only runs on 24-bit monitors') ;;; return endif if n_elements(t1_in) eq 0 then t1_in = 0. ; sec ;;;if n_elements(t2_in) eq 0 then t2_in = t1_in + 0.1 if n_elements( ndups ) eq 0 then ndups=0 ; for output frames if n_elements( debug ) eq 0 then debug=0 if n_elements( verbose ) eq 0 then verbose=0 if n_elements( dialog ) eq 0 then dialog = 1 if n_elements( nonGlobal ) eq 0 then nonGlobal=0 if n_elements( nsmooth ) eq 0 then nsmooth=0 if n_elements( magnify ) eq 0 then magnify=1 if n_elements( skip) gt 0 then inc=skip+1 ; alternate input for inc if n_elements( inc) eq 0 then inc=1 ; 2 will skip every other frame if n_elements( border ) eq 0 then border=10 if n_elements( topPixels ) eq 0 then topPixels= 20 if n_elements( botPixels ) eq 0 then botPixels= 30 if n_elements( prefix ) eq 0 then prefix = 'GlobalColor_' else begin if lastChar( prefix ) ne '_' then prefix= prefix + '_' endelse if n_elements( type ) eq 0 then type = 'mpg' if n_elements( charsize ) eq 0 then charsize = 1.5 if n_elements( outDir ) eq 0 then outDir = '' if debug then view = 1 if n_elements( view ) eq 0 then view = 0 if n_elements( logo ) eq 0 then logo = 0 if n_elements( file1_in ) eq 0 then begin if n_elements( shot ) ne 0 then begin file1_in= file_search( '/p/nstxusr3/miro/*'+strtrim(shot,2)+'.cin*') endif if nwords( file1_in ) eq 0 then begin file1_in= file_search( '/p/nstxusr2/phantom4/*'+strtrim(shot,2)+'.cin*') endif if nwords( file1_in ) eq 0 then begin file1_in= file_search( '/p/nstxusr2/nstxphantom7/*'+strtrim(shot,2)+'.cin*') endif if nwords( file1_in ) eq 0 then begin file1_in = DIALOG_PICKFILE( title='Choose a .cin file', filter='*.cin*', $ path='/p/nstxusr3/miro/') if file1_in eq '' then return endif endif file1 = file1_in[0] if strpos(file1,'.gz') eq strlen(file1)-3 then begin print, ' >>> (Unzipping file '+file1+'-- have patience!)' spawn, 'gunzip '+file1, result, Exit_Status=errors if errors then print,"*** probably don't have privileges to unzip file" file1 = strpos( file1, 0, strlen(file1)-3 ) endif if isnumber( file1 ) then begin print, 'One of the file specifications is a number!' print, ' ' print, 'Usage: IDL> cine2mpeg, shot=130372, /verb, t1=.25,.t2=4 print, ' or: IDL> cine2mpeg, file1, /verb, t1=.25,.t2=4 return endif delim = get_delim() if n_elements( label1 ) eq 0 then begin fdecomp, file1, disk, dir1, name, ext wordarray, dir1, words, delim=delim label1 = words[ n_elements(words)-1] endif ; open .cin files and determine times CINE_TIME, file1, cine1Times, status=status if not status then begin print, ' *** could not read times from file '+file1 return endif print, ' >>> for cine Times in file1:' minmax, cine1Times dts1 = cine1Times[1:*] - cine1Times[0:*] if n_elements( max1 ) eq 0 then begin if strpos( STRUPCASE(file1), 'MIRO') ge 0 $ then max1 = 2L^10 - 1 $ else max1 = 2L^14 - 1 ;;; max1 = 2L^bitcount1 - 1 endif ; limit movie to common times within both files minTime = MIN( cine1times, MAX=maxTime ) t1 = t1_in > minTime if n_elements(t2_in) eq 0 then t2_in = t1 ; just do one time, if t2 not entered t2 = t2_in < maxtime ; cineload uses a COMMON block, so can't be used for 2 files simultaneously ; cineLoadSimple does not use COMMON blocks, but is slower cine1Img= CINELOAD( file1, NEARESTI(cine1Times,t1), $ pps, exposure, bitcount=bitcount1, $ verbose=verbose, status=status ) if verbose then print, 'Bitcount for file1=', bitcount1 info = SIZE( cine1Img ) IF info[0] eq 2 THEN BEGIN TrueColor1 = 0 cine1Width = info[1] cine1Ht = info[2] ENDIF ELSE IF info[0] eq 3 AND info[1] eq 3 THEN BEGIN TrueColor1 = 1 cine1Width = info[2] cine1Ht = info[3] ENDIF ELSE BEGIN Message, 'Frame from file1 is not 2D' STOP ENDELSE if magnify gt 1 then begin cine1Width = cine1Width*magnify cine1Ht = cine1Ht*magnify endif ; Load current color table into byte arrays TVLCT, red, green, blue, /GET if n_elements( xsize ) gt 0 then begin mpegWidth = xsize endif else begin mpegWidth = cine1Width + 2*border endelse if n_elements( ysize ) gt 0 then begin mpegHt = ysize endif else begin mpegHt = cine1Ht + 2*border + topPixels + botPixels endelse if oddnumber( mpegWidth ) then mpegWidth = mpegWidth +1 if oddnumber( mpegHt ) then mpegHt = mpegHt +1 if verbose then print, 'MPEG width and heighth=', mpegWidth, mpegHt ; output filename if n_elements( outFile ) eq 0 then begin if n_elements( shot ) eq 0 then begin shotStr1 = extractshotnumber( file1 ) if shotStr1 ne -1 then shot = shotStr1 else shot = -1 endif if long( shot ) lt 0 then shot = 999999 t1str = STRING(ROUND(ABS(t1)*1000), FORMAT='(I4.4)') t2str = STRING(ROUND(ABS(t2)*1000), FORMAT='(I4.4)') outFile = prefix + strcompress(shot,/remove_all) + '_' + $ t1str + '_' + t2str + 'ms' + '.'+type endif if nwords( outDir ) gt 0 then begin delim = get_delim() if lastChar( outDir ) ne delim then outDir = outDir+delim ; make sure directory not already in filename if strpos( outFile, outDir ) lt 9 then outFile = outDir + outFile endif if verbose then print, 'outFile=', outFile found = file_test( outFile ) if found then begin result = 'Y' if dialog then result = dialog_input( $ prompt=outFile+' exists! Do you want to delete it first?') if STRUPCASE( result ) NE 'Y' then return file_delete, outFile endif FDECOMP, outFile, disk, dir, name, ext if nwords( ext ) eq 0 then outFile = outFile+'.'+type if n_elements( ctb ) eq 0 then ctb = 0 ; Lane says grayscale shows the most cStr = mk_color( table=ctb, /load, max=256, N_NONFIXED=ncolors ) if view then window, xsize=mpegWidth, ysize=mpegHt, xpos=50, ypos=50 SET_PLOT, 'Z' Device, set_resolution=[mpegWidth,mpegHt] ch_siz=2 if n_elements( thick ) eq 0 then thick=2 ;;;if NOT debug then stat = ANIM_OPEN( outFile, mpegWidth, mpegHt, type=type ) if NOT view then mpegID = MPEG_OPEN( [mpegWidth, mpegHt] ) y0 = botPixels x1 = border iCineFastT1 = nearesti( cine1times, t1 ) nFastFrames = nearesti( cine1times, t2 ) - iCineFastT1 + 1 if not view then begin TVLCT, RED, GREEN, BLUE, /GET fullImage24 = BYTARR(3,mpegWidth, mpegHt ) xf1 = x1 xf2 = x1 + cine1Width-1 yf1 = y0 yf2 = y0 + cine1Ht-1 endif ifr=0 lastSlowFrame = -1 FOR iCine = 0, nFastFrames*inc-inc, inc DO BEGIN if iCine gt (nFastFrames-1) then break iFast = iCine+iCineFastT1 cine1Img = CINELOAD( file1, iFast, pps, exposure, $ verbose=0, status=status ) if not status then begin print, ' *** bad status on file1' stop endif cine1Min = MIN( cine1Img, MAX=cine1Max ) if magnify gt 1 then cine1Img = REBIN(cine1Img, cine1Width, cine1Ht) if verbose then print, 'iFast, cine1Min, cine1Max=', iFast, cine1Min, cine1Max if N_ELEMENTS( gamma1 ) gt 0 then cine1Img = GAMMA_RAISE(cine1Img, gamma1) if nsmooth gt 1 then cine1Img = amedian( cine1Img, nsmooth ) cine1Img = bytscl( cine1Img, top=ncolors, max=max1 ) if view then begin ; if viewing in 'X', need to set back to Z buffer to form plot SET_PLOT, 'Z' Device, set_resolution=[mpegWidth,mpegHt] endif erase, color=cStr.black tv, cine1Img, x1, y0, true=trueColor1 xyouts, x1, border, label1, /device, charsize=charsize, align=0, color=cStr.white C1Time = cine1Times[iFast] timeStr = string(C1Time*1000, format='(f9.3)') ; output milliseconds xyouts, x1+5+strlen(label1)*charsize*!d.x_ch_size, border, timeStr + ' ms', $ charsize=charsize, color=cStr.green, /device ; top if logo then NSTXLOGO, blue=cStr.blue, red=cStr.red, charthick=1.5 ; thicker for mpeg ; when image saturated, hard to see green text: if n_elements( shot ) gt 0 then begin FANCY_TITLE,'Shot '+strtrim(shot,2), charthick=1.3, charsize=2, $ charColor=cStr.white, line=0.5 endif else begin fdecomp, file1, disk, dir, name, ext FANCY_TITLE,name+'.'+ext, charthick=1.2, charsize=2, $ charColor=cStr.white, line=0.5 endelse if view then begin img = TVRD( true=trueColor1 ) set_plot,'x' tv, img, true=trueColor1 if debug then stop endif else begin if trueColor1 then begin img = TVRD( ) fullImage24(0,*,*) = RED(img(*,*)) fullImage24(1,*,*) = GREEN(img(*,*)) fullImage24(2,*,*) = BLUE(img(*,*)) ; now insert full-color image into color array fullImage24(0,xf1:xf2,yf1:yf2) = cine1Img(0,*,*) fullImage24(1,xf1:xf2,yf1:yf2) = cine1Img(1,*,*) fullImage24(2,xf1:xf2,yf1:yf2) = cine1Img(2,*,*) endif else begin img = TVRD( ) fullImage24(0,*,*) = RED(img(*,*)) fullImage24(1,*,*) = GREEN(img(*,*)) fullImage24(2,*,*) = BLUE(img(*,*)) endelse ;;; ANIM_WRITE, img, FRAME=ifr, ndups=ndups, /verbose for j=0,ndups do begin ; duplicate frames to slow down mpeg MPEG_PUT, mpegID, image=fullImage24, FRAME=ifr, order=1 ifr = ifr + 1 endfor endelse ENDFOR print, ' ' print, ' >> Done processing files '+file1 print, ' ' ; Close the animation file: ;;;if NOT debug then ANIM_CLOSE if NOT view then begin print, ' (saving animation file '+outFile+'; this may take a long time!)' MPEG_SAVE, mpegID, filename=outFile MPEG_CLOSE, mpegID print, 'Done writing animation file '+outfile endif ;;;if not debug then device, z_buffer=1 set_plot, 'X' beep if debug then stop RETURN badWrite: alert, 'Unable to write MPEG/AVI file!' stop END