;+ ; NAME: ; vu_movie ; PURPOSE: ; Create animations from final (averaged) tomography files ; CATEGORY: ; smei/sat/idl/util/vupack ; CALLING SEQUENCE: PRO vu_movie, ut, map_type , $ ut_extra = ut_extra , $ path = path , $ filter = filter , $ movie_destination=movie_destination,$ image_destination=image_destination,$ hdr = hdr , $ ff = ff , $ movie_file = movie_file , $ delay = delay , $ png = png , $ gif = gif , $ mpeg = mpeg , $ fillsky = fillsky , $ skip = skip , $ type = type , $ roi_offset = roi_offset , $ ut_off = ut_off , $ silent = silent , $ nv_filter = nv_filter , $ nv_hdr = nv_hdr , $ nv_ff = nv_ff , $ _extra = _extra ; INPUTS: ; ut array[2]; type: float or time structure ; range of times for which movie is required. ; Times can be specified as Carrington variables or in UT ; map_type scalar; type: character ; Any one of 'synoptic', 'earth_skysnap', 'earth_skysweep', ; 'earth_insitu' ; OPTIONAL INPUT PARAMETERS: ; hdr = hdr array[k]; type: structure ; headers of tomography files used to make individual images ; ff = ff array[n,l,m,2,k]; type: float ; 3d heliospheric arrays used ; ; These arrays are either density/velocity or magnetic field data. ; If these do not exist on entry then files are selected and read, and ; output in these keywords (see OUTPUT PARAMETERS). Altnernatively, these ; arrays are passed from a previous call, bypassing the read section here. ; This saves a lot of time. ; ; nv_hdr = nv_hdr ; array[k]; type: structure ; headers of tomography files (density/velocity) ; nv_ff = nv_ff ; array[n,l,m,2,k]; type: float ; 3d heliospheric arrays (density/velocity) ; ; These arrays should only be specified if hdr,ff contain magnetic data. ; They should contain the density/velocity data matching the magnetic data, ; and will be used only to make a density/velocity remoteview movie, with the ; current sheet embedded in it. ; ; If nv_hdr is not defined on entry, and nv_filter is set then an attempt ; is made to locate the density/velocity data matching the hdr,ff data. ; ; path=path scalar; type: string; default: $dat/nagoya/slow/final ; directory in which to search for files ; filter=filter ; scalar; type: string; default: nv3d*.* ; file filter (including wildcard) used to search for files ; nv_filter=nv_filter ; scalar; type: string; default: nv3d*.* ; file filter (including wildcard) used to search for density/velocityfiles ; ; movie_destination=movie_destination ; scalar; type: string; default: $TUB ; destination directory for animations ; If the directory doesn't exist then the animation is written to $TUB ; image_destination=image_destination ; scalar; type: string; default: none ; destination directory for individual frames ; By default the individual frames are deleted. If image_destination is set to an ; existing directory then the individual frames are saved in this directory. ; /mpeg by default an animated png is created; if /mpeg or /gif is set then an ; /gif mpeg movie (NOT YET IMPLEMENTED) or animated gif (REQUIRES CAPABILITY TO ; WRITE GIFS) is made. ; _extra=_extra ; OUTPUTS: ; (animation, and optionally the individual frames) ; OPTIONAL OUTPUT PARAMETERS: ; hdr = hdr array[k]; type: structure ; headers of tomography files used to make individual images ; ff = ff array[n,l,m,2,k]; type: float ; 3d heliospheric arrays used ; ; nv_hdr = nv_hdr ; array[k]; type: structure ; headers of tomography files (density/velocity) ; nv_ff = nv_ff ; array[n,l,m,2,k]; type: float ; 3d heliospheric arrays (density/velocity) ; ; Will only be filled if nv_hdr does not exist on entry, and nv_filter is set. ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; Carrington, CheckDir, vu_type_insitu, vu_type_skymap, vu_select, vu_synopticmap ; vu_earthskymap, Instrument, vu_localskymap, vu_insitu, vu_solardisk ; mk_flick, TimeOp, TimeSet, IsTime, IsType, TimeGet ; TimeUnit, SetFileSpec, GetFileSpec, do_file, vu_remoteview ; vu_get, InitVar ; PROCEDURE: ; > The returned 'hdr' and 'ff' arrays can be passed to a subsequent call to ; make another movie from the same data. This bypasses the time-consuming ; reading of the same set of files. ; > All nv3d files in the source directory 'path' fitting the 'filter' wildcard ; within the time range 'ut' are processed. Image are created at the time ; of each file. ; MODIFICATION HISTORY: ; MAR-2001, Paul Hick (UCSD/CASS) ; JUL-2003, Paul Hick (UCSD/CASS) ; Adapted to make movies of remoteviews with hcs embedded ; JUL-2004, Paul Hick (UCSD/CASS) ; Improved handling of individual frames for movies. ; SEP-2007, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ; Added Stereo A and Stereo B ;- InitVar, silent , 0 InitVar, fillsky , /key InitVar, map_type, 'synoptic' InitVar, path , filepath(root=getenv('NAGOYA'), subdir='slow','final') InitVar, ut_off , 0.0 InitVar, mpeg , /key InitVar, png , /key InitVar, gif , /key png = png OR (1-gif and 1-mpeg) fillsky = fillsky AND map_type EQ 'earth_skysweep' uday = TimeUnit(/day) case IsType(movie_destination, /defined) of 0: movie_destination = getenv('TUB') 1: begin ; Make sure the destination dir for the movies exists. If not use $TUB. IF NOT CheckDir(movie_destination) THEN BEGIN message, /info, 'movie directory '+movie_destination+' does not exist; using '+getenv('TUB')+' instead' movie_destination = getenv('TUB') ENDIF END ENDCASE ; If an explicit destination for the individual frames is specified ; check whether it exists. If not then ignore it. keep_frms = IsType(image_destination, /defined) IF keep_frms THEN keep_frms = CheckDir(image_destination) IF NOT keep_frms THEN image_destination = getenv('TUB') CASE map_type OF 'synoptic' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'earth_skysnap' : type = vu_type_skymap(map_type, _extra=_extra, type=type) 'earth_skysweep' : type = vu_type_skymap(map_type, _extra=_extra, type=type) 'earth_insitu' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'earth_remoteview' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'earth_solardisk' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'planarcut' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'mercury_insitu' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'venus_insitu' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'mars_insitu' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'ulysses_insitu' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'stereoa_insitu' : type = vu_type_insitu(map_type, _extra=_extra, type=type) 'stereob_insitu' : type = vu_type_insitu(map_type, _extra=_extra, type=type) ENDCASE IF (where(type.data))[0] EQ -1 THEN BEGIN message, /info, 'no movie type selected' RETURN ENDIF ; A single time is take to be the end of the movie. ; Go back one week. mov_range = Carrington(ut,/get_time) IF n_elements(mov_range) EQ 1 THEN $ mov_range = TimeOp(/add, mov_range, TimeSet(/diff, day=[-7,0])) ; For skysweeps add another day to the start of the movie. This day is used to ; make sure the first image in the movie has the whole sky filled. IF fillsky THEN $ mov_range[0] = TimeOp(/add, mov_range[0], TimeSet(/diff, day=-1)) ; If hdr and ff are still available from a previous run, and passed here as input arguments ; then the read section is skipped (saves a lot of time). cnt = n_elements(hdr) IF cnt EQ 0 THEN BEGIN CASE 1 OF IsTime(ut_extra ): range = TimeOp(/add,mov_range,ut_extra) IsType(ut_extra, /defined): range = TimeOp(/add,mov_range,TimeSet(/diff,day=ut_extra)) ELSE : range = mov_range ENDCASE ; Get a list of all files. Don't read the headers yet. Just extract ; the Carrington variables from the file names times = vu_select(files, /nohdr, path=path, filter=filter, count=cnt) ; Determine which files are inside 'mov_range'. IF cnt GT 0 THEN BEGIN dt = TimeOp(/subtract,mov_range[1],mov_range[0],uday) tt = TimeOp(/subtract,times ,mov_range[0],uday) tmp = where(0 le tt and tt le dt, cnt) ;tmp = where(0 le TimeOp(/subtract,times,mov_range[0],uday) and TimeOp(/subtract,times,mov_range[1],uday) le 0, cnt) ENDIF IF cnt EQ 0 THEN BEGIN message, /info, 'no files in ['+strjoin(TimeGet(mov_range,/ymd),',')+']' RETURN ENDIF ; Check for files inside 'range' (may extend beyond 'mov_range'). Read these files. dt = TimeOp(/subtract,range[1],range[0],uday) tt = TimeOp(/subtract,times ,range[0],uday) tmp = where(0 LE tt AND tt LE dt, cnt) ;tmp = where(0 le TimeOp(/subtract,times,range[0],uday) and TimeOp(/subtract,times,range[1],uday) le 0, cnt) files = files[tmp] IF IsType(skip, /defined) THEN BEGIN tmp = where( (indgen(cnt) mod skip) EQ 0, cnt) IF cnt NE 0 then files = files[tmp] ENDIF hdr = vu_select(files, /check, /read, /get_roi, silent=silent+1, ff=ff, roi_offset=roi_offset) ENDIF ; Collect density data matching the magnetic data stored in hdr and ff ; (used for remoteview only) IF IsType(nv_hdr, /undefined) AND IsType(nv_filter,/defined) THEN BEGIN SetFileSpec, hdr.file bb_prefix_len = strlen(hdr[0].prefix) nv_prefix_len = strpos(nv_filter,'*.*') IF nv_prefix_len EQ -1 THEN nv_prefix_len = strlen(nv_filter) nv_files = strmid(nv_filter,0,nv_prefix_len)+strmid(GetFileSpec(from='name'),bb_prefix_len) nv_files = filepath(root=(GetFileSpec(upto='directory'))[0], nv_files) nv_hdr = vu_select(nv_files, /check, /read, /get_roi, silent=silent+1, ff=nv_ff, roi_offset=roi_offset) IF n_elements(nv_hdr) NE cnt THEN BEGIN destroyvar, nv_hdr, nv_ff message, /info, 'error reading data: '+nv_filter RETURN ENDIF ENDIF time = vu_get(hdr, /uttime) tmp = where(TimeOp(/subtract,time,mov_range[0],uday) GE 0 AND $ TimeOp(/subtract,time,mov_range[1],uday) LE 0, cnt) IF cnt EQ 0 THEN BEGIN message, /info, 'no times left to make movies' RETURN ENDIF time = time[tmp] CASE fillsky OF 0: npad = 0 1: tmp = where(TimeOp(/subtract,time,time[0],uday) LT 1, npad) ENDCASE IF map_type EQ 'earth_skysweep' THEN BEGIN band = TimeOp(/subtract,time[1],time[0],TimeUnit(/hour)) band = round(band) ; Time between first two files used band = [band, band] ; 'band' is only used by vu_localskymap if keyword /track ENDIF ; .. IS PASSED HERE BY CALLER. IF png THEN BEGIN boost, frm_type, '.png' boost, mov_type, '.mng' ENDIF IF gif THEN BEGIN boost, frm_type, '.gif' boost, mov_type, '.gif' ENDIF IF mpeg THEN BEGIN boost, frm_type, '.gif' boost, mov_type, '.mpeg' ENDIF nmov = n_elements(mov_type) ; Postfix the individual frames with the time. If only one time is input ; use the file name vu_get(hdr,/file) instead. ; Note that is replaced by the actual module name in vu_get_page frm_file = TimeGet(time, /string, /_ydoy) IF n_elements(uniq(frm_file)) EQ 1 THEN $ frm_file = GetFileSpec(vu_get(hdr, /file), from='name', upto='type') frm_file = filepath(root=image_destination, '_'+frm_file) FOR i=0,cnt-1 DO BEGIN ; LOOP OVER ALL FILES CASE type.display OF 'synoptic': $ vu_synopticmap, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif OR mpeg, png=png, $ module=module, same_T0=i NE 0 'earth_skysnap': $ vu_earthskymap, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif OR mpeg, png=png, $ module=module 'earth_skysweep': $ vu_localskymap, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif OR mpeg, png=png, $ module=module, RA_full=RA_full, F_full=F_full, band=band 'earth_insitu': $ vu_insitu, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif OR mpeg, png=png, $ module=module, $ source=([Instrument(/aceb),Instrument(/acesw)])[strmid(type.label,0,2) EQ '_v' OR strmid(type.label,0,2) eq '_n'], $ /timeseries, same_T0=i NE 0, thick=type.thick, charsize=type.charsize 'earth_solardisk': $ vu_solardisk, hdr, ff, ut0=TimeOp(/add,time[i],TimeSet(/diff,day=ut_off)), type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif OR mpeg, png=png, $ module=module 'planarcut': $ vu_planarcut, hdr, ff, ut0=TimeOp(/add,time[i],TimeSet(/diff,day=ut_off)), type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif OR mpeg, png=png, $ module=module 'earth_remoteview': BEGIN CASE IsType(nv_hdr,/defined) OF 0: vu_remoteview, hdr, ff, ut0=time[i], type_ff=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif OR mpeg, png=png,$ module=module, view_time=time[i], charsize=type.charsize 1: vu_remoteview, nv_hdr, nv_ff, ut0=time[i], type_ff=type, silent=silent+1,$ destination=frm_file[i], _extra=_extra, gif=gif OR mpeg, png=png, $ module=module, view_time=time[i], charsize=type.charsize, /meshhcs, hdr_bb=hdr, bb=ff ENDCASE END 'mercury_insitu': $ vu_insitu, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif or mpeg, png=png, $ module=module, /timeseries, same_T0=i NE 0, thick=type.thick, $ charsize=type.charsize, body=jpl_body(/mercury,/string) 'venus_insitu': $ vu_insitu, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif or mpeg, png=png, $ module=module, /timeseries, same_T0=i NE 0, thick=type.thick, $ charsize=type.charsize, body=jpl_body(/venus,/string) 'mars_insitu': $ vu_insitu, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif or mpeg, png=png, $ module=module, /timeseries, same_T0=i Ne 0, thick=type.thick, $ charsize=type.charsize, body=jpl_body(/mars,/string) 'ulysses_insitu': $ vu_insitu, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif or mpeg, png=png, $ module=module, /timeseries, same_T0=i Ne 0, thick=type.thick, $ charsize=type.charsize, body=big_body('Ulysses') 'stereoa_insitu': $ vu_insitu, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif or mpeg, png=png, $ module=module, /timeseries, same_T0=i Ne 0, thick=type.thick, $ charsize=type.charsize, body=big_body('Stereo A') 'stereob_insitu': $ vu_insitu, hdr, ff, ut0=time[i], type=type, silent=silent+1, $ destination=frm_file[i], _extra=_extra, gif=gif or mpeg, png=png, $ module=module, /timeseries, same_T0=i Ne 0, thick=type.thick, $ charsize=type.charsize, body=big_body('Stereo B') ENDCASE ENDFOR frm_wild = filepath(root=image_destination, module+'_*') movie_file = filepath(root=movie_destination, module+'_movie'+mov_type) ; Movie names IF silent LE 1 THEN message, /info, 'created'+strcompress(cnt)+' '+module+' images' ; Create the movie. Currently movies can only be created on the Linux boxes. ; On NT mk_flick does not do anything. FOR imov=0,nmov-1 DO BEGIN ; If fillsky is set then remove the first npad images. This is used for ; skysweeps only after 24 hours the sky has been filled completely. ; (it's up to the caller to add a day to the duration of the movie). IF fillsky AND npad GT 0 THEN $ tmp = do_file(/delete, frm_file[0:npad-1]+frm_type[imov]) tmp = frm_wild+frm_type[imov] CASE (file_search(tmp))[0] EQ '' OF 0: BEGIN mk_flick, movie_file[imov], tmp, /loop, delay=delay, $ png=mov_type[imov] EQ '.mng', gif=mov_type[imov] EQ '.gif', mpeg=mov_type[imov] EQ '.mpeg' IF NOT keep_frms THEN tmp = do_file(/delete, tmp, /silent) END 1: movie_file[imov] = '' ; Clear name for return argument ENDCASE ENDFOR RETURN & END