VisIt can be used in several ways to make movies of simulation data.
- 1 Making movies with the GUI
- 2 Making movies using the movie script
- 3 Making movies in batch
- 4 Making movies with scripting
- 5 Using an external movie encoder
- 6 Advanced Movie Making Workflow Tips and Wishlist
Making movies with the GUI
VisIt's GUI provides a Save Movie wizard that lets you save your current visualizations into a movie. The wizard lets you choose from both simple and template-based movies and then takes care of all of the details of movie generation.
- A simple movie is a movie that animates the visualizations in the active vis window and saves the results to a movie.
- A template movie is a movie that uses the visualizations from multiple vis windows and arranges them in a user-defined viewport tiling. Each vis window becomes a sequence of images that is mapped into a viewport. Various transitions can also be used between sequences, allowing the movie to fade,dissolve,fly-in,etc. from one sequence to another. Additional sequences such as rotations can be added as well so the user can fly around the visualization. The movie can be arbitrarily complex and can be saved out as a movie template so it can be generated later with different data.
The wizard lets you build up a "shopping list" of movie formats and resolutions so they can all be generated at once, a useful feature since processing the data from large simulations takes much longer than rendering at different resolutions so it makes sense to create all movies at once. Movies may be saved as series of images in various formats or other playable formats such as MPEG or streaming movie.
Making movies using the movie script
VisIt's movie-making is built upon the visit -movie script. The visit -movie script takes care of setting up plots, iterating over frames, and encoding frames into playable movies. The script automatically takes care of the intricacies of saving out multiple sizes and formats of movies or image frames and can also save out stereo and normal movies.
As visit -movie does so much, it should really be used first before deciding on custom Python scripting.
The 3 main use cases for saving movies with visit -movie are:
- Animating the plots in a session file (pass the -sessionfile argument)
- Running a user-defined Python script (pass the -scriptfile argument)
- Creating a template-movie (pass the -templatefile argument)
Command line arguments
Usage: visit -movie [-format fmt] [-geometry size] -sessionfile name | -scriptfile name [-output moviename] [-framestep step] [PARALLEL OPTIONS] OPTIONS The following options are recognized by visit -movie -format fmt The format option allows you to set the output format for your movie. The supported values for fmt are: mpeg : MPEG 1 movie. qt : Quicktime movie. sm : Streaming movie format (popular for powerwall demos). ppm : Save raw movie frames as individual PPM files. tiff : Save raw movie frames as individual TIFF files. jpeg : Save raw movie frames as individual JPEG files. bmp : Save raw movie frames as individual BMP (Windows Bitmap) files. rgb : Save raw movie frames as individual RGB (SGI format) files. png : Save raw movie frames as individual PNG files. You can specify multiple formats by concatenating more than one allowed format using commas. Example: -format mpeg,qt,jpeg. *** Important Note *** The qt and sm formats are not supported on the Windows platform. -geometry size The geometry option allows you to set the movie resolution. The size argument is of the form WxH where W is the width of the image and H is the height of the image. For example, if you want an image that is 1024 pixels wide and 768 pixels tall, you would provide: -geometry 1024x768. You can specify multiple geometries by concatenating more than one WxH using commas. Example: -geometry 320x320,1024x768. If you omit the -geometry argument then the window sizes stored in your session file will be used. If you are not using a session file then the default size will be 512x512. -sessionfile name The sessionfile option lets you pick the name of the VisIt session to use as input for your movie. The VisIt session is a file that describes the movie that you want to make and it is created when you save your session from within VisIt's GUI after you set up your plots how you want them. -source filename The source option appends a filename to a list of filenames to be used as the new sources when restoring the session file selected via the -sessionfile command line argument. If you want to override multiple sources in the session file then you must pass multiple instances of the -source command line argument. Example: visit -movie -geometry 1000x1000 -format mpeg \ -sessionfile A.session \ -source new.silo -source other.silo If you are replacing a time series of files, remember that VisIt often renames them slightly. A time series composed of files with names A0000.silo, A0001.silo, A0002.silo, ... will have the name: "A*.silo database" When you pass the -source argument to visit -movie, be sure to pass -source "A*.silo database". -adjustview This command line argument is useful when -sessionfile and -source arguments are given since it will cause the view to be adjusted for the bounds of the new dataset. When replacing a dataset using -source, the new dataset may have different extents, making the view stored in the session file less then optimal. The -adjustview option resets the view so the new dataset will fill the screen while still preserving the view normal & up vectors, 2 important components of the view. -scriptfile name The scriptfile option lets you pick the name of a VisIt Python script to use as input for your movie. -templatefile name The templatefile option lets you pick the name of a VisIt movie template file to use as input for your movie. A movie template file is an XML file that describes how to put together a movie. -framestep step The number of frames to advance when going to the next frame. -start frame The frame that we want to start at. -end frame The frame that we want to end at. -frame value When dumping image instead of starting with 0 use the value instead. -output moviename The output option lets you set the name of your movie. -fps number Sets the frames per second the movie should play at. -stereo fmt Makes a stereo movie. Note that stereo movies with left and right channels are only created for Streaming movie format, though left and right channel images are saved if you save a movie in an image format. The redblue and redgreen formats are available in any image format. The supported values for fmt are: off : No stereo leftright : Left/Right channel stereo. Use this format with streaming movie to create movies viewable with stereo projection and glasses. redblue : Red/Blue stereo. redgreen : Red/Green stereo. You can specify multiple stereo formats by concatenating more than one allowed format using commas. Example: -stereo off,leftright,redgreen -ignoresessionengines Prevents compute engine information in the session file from being used to restart the compute engine(s) during movie generation. -email addresses If specified, this script will provide e-mail progress reports for movie generation. Multiple e-mail addresses can be provided if they are separated by commas. -noffmpeg Don't use ffmpeg for the mpeg encoder even if it is available. -enginerestartinterval number Restarts the compute engine after the specified number of images are generated. Parallel arguments: -np <# procs> The number of processors to use. -nn <# nodes> The number of nodes to allocate. -l <method> Launch in parallel using the given method. Method is one of the following: mpirun, poe, psub, srun. -la <args> Additional arguments for the parallel launcher. -p <part> Partition to run in. -b <bank> Bank from which to draw resources. -t <time> Maximum job run time. -expedite Makes batch system give priority scheduling.
Save out a single 800x800 pixel MPEG movie called mymovie.mpeg and use the plots.session file to set up the plots:
visit -movie -format mpeg -geometry 800x800 -sessionfile plots.session -output mymovie
Multiple resolutions and formats
Save out 800x800 MPEG and a series of 2000x2000 JPEG files:
visit -movie -format mpeg,jpeg -geometry 800x800,2000x2000 -sessionfile plots.session -output mymovie
Invoking a custom Python script
Execute the custom python script, replacing its SaveWindow() calls with calls to save multiple formats, as desired by the visit -movie script:
visit -movie -format mpeg,jpeg -geometry 800x800,2000x2000 -scriptfile setup.py -output mymovie
Save out a single 800x800 pixel MPEG movie called mymovie.mpeg and use the template.session file to set up the plots but use a different set of files for the input data. Note that the files must be compatible with the plots and variables used in the session file. This case is useful when you want to use a session file as a template to make movies of several related simulation runs.
visit -movie -format mpeg -geometry 800x800 -sessionfile template.session -source "/path/to/new/data*.silo database" -output mymovie
Making movies in batch
The visit -movie command can be used in a batch environment to make movies. The trick is to make sure that you tell the script to ignore any engine information that might be present in your session file and that it launch using the parallel sublauncher directly from within the running batch job.
If you are using a session file to generate your movie and you created the session file using client/server but now you want to simply generate the movie in batch on the remote server then you may transfer the session file to the remote server and use the -source arguments. The -source command line arguments (to appear in VisIt 2.4.2) let you provide a different filename for the data used in the session file. For example, had you generated the session file using client/server, the name of the file in the session file would be of the form remotehost:/path/to/data. You could use the -source argument when invoking the visit -movie script on the remote computer to pass localhost:/path/to/data instead for the data file. An alternative is to edit the session file directly.
LC batch systems
This is an example msub script that will launch a visit -movie job on one node of LC's hera cluster to generate a movie using a session file that was generated previously. The important pieces of the 'visit -movie' command that dictate how the compute engine will be launched are located on the last line. The extra flags tell the script to ignore compute engine information that may be present in the session file and to use srun to launch a new engine on 16 processors in the current node. Note the usage of the standard VisIt parallel command line arguments -np, -nn, -l.
#!/bin/csh #MSUB -l walltime=01:00:00 #MSUB -A bdivp #MSUB -l nodes=1 #MSUB -l partition=rzzeus #MSUB -N name of movie #MSUB -q pbatch cd /g/g19/username/test /usr/gapps/visit/bin/visit -movie -v 2.7.1 -format png -geometry 560x527 \ -output /g/g19/username/test/frame -fps 10 \ -start 0 -framestep 10 -end 300 \ -sessionfile /g/g19/username/test/movie.session \ -ignoresessionengines -np 16 -nn 1 -l srun
Making movies with scripting
Make movies with scripting...
When you make movies using VisIt, you should run -nowin so the viewer will not create a window. You should also specify the movie geometry using the -geometry flag or by setting size of the output images in the SaveWindowAttributes.
This section shows how to do the basic operations needed to make a movie using VisIt's Python interface.
Adding a plot
Plots are added by calling the AddPlot function, which takes two arguments: a plot plugin name and a variable name. The plot plugin name must exist in the tuple returned by the PlotPlugins() function in order to be valid. The variable name must exist in the active database.
AddPlot("Pseudocolor", "pressure") DrawPlots()
Setting plot attributes
All plot plugins provide a function to return a state object that can be used to set the plot attributes for its plot. The name of the function is typically the name of the plot plugin + Attributes().
pc = PseudocolorAttributes() pc.legendFlag = 0 SetPlotOptions(pc)
Animating through time and saving images
for ts in range(TimeSliderGetNStates()): SetTimeSliderState(ts) DrawPlots() # Draw the plots in case there is ever an error SaveWindow()
Using an external movie encoder
VisIt's visit -movie script can encode different types of movies, depending on the platform on which it is run and the encoders that are available. By default, MPEG movies are supported on all platforms using the mpeg2encode software that is bundled with VisIt.
|Movie file format||Encoder used||Platforms supported||Viewers|
||Windows media, Quicktime, mplayer, etc.|
|Quicktime||dmconvert||SGI/IRIX systems that have dmconvert installed.||Quicktime player, SGI Media player|
|Streaming movie (for powerwalls)||img2sm||Any UNIX system that has LLNL's img2sm software installed.||Blockbuster|
Sometimes, you may want to generate image frames using VisIt and then use your own movie encoder to produce superior quality movies or movies in a format that VisIt does not automatically support.
Sometimes when you generate a movie, there will be some frames in the movie that you will want to skip. For example, you might have had some bad data for certain time steps that cause unwanted features in the visualization. The easiest way to skip frames is to output the frames for your movie to an image format, renumber the frames, and then encode them using an external movie encoder such as ffmpeg.
import os, sys # Change these values for your inputs nFrames = 100 # The number of frames in your input movie inputBase = "movie" # The base name of your movie files skipFrames = [1,3,10] # The list of frames to skip # This loop renumbers the files by creating symbolic links to the old files. # The files in the skipFrames list are omitted from the new sequence. index = 0 for i in range(nFrames): if i not in skipFrames: cmd = "ln -s %s%04d.jpg frame%04d.jpg" % (inputBase, i, index) os.system(cmd) index = index + 1 sys.exit(0)
- Copy the above Python code to a file called rename.py
- Edit the file, changing the nFrames, inputBase, and skipFrames as needed
- Run the script: python rename.py
- Use an external movie encoder to encode the frame0000.jpg,frame0001.jpg,... files into a movie.
MPEG is a popular, well supported format with many possible tools that can be used for encoding. Most tools are commercial packages such as Adobe Premier but there are some free command line tools that can be used as well. Many image viewers are capable of showing various versions of MPEG but it seems that MPEG 1 and MPEG 4 enjoy the best support. MPEG 4 should be used when possible since it produces high quality movies with good compression and few artifacts.
ffmpeg is a very fast movie encoder that can be used to encode many different movie formats, including MPEG 4. VisIt does not bundle ffmpeg due to potential licensing issues but ffmpeg is a very good movie encoder that can be used to encode frames generated using VisIt. Using ffmpeg can be somewhat daunting since it is a command line tool with a lot of options. Here is a sample command line that can be used to generate good MPEG 4 movies from VisIt frames:
ffmpeg -f image2 -i frame%04d.jpeg -mbd rd -flags +4mv+trell+aic -flags qprd -bf 2 -cmp 2 -g 25 -pass 1 -y -b bitrate movie.mpeg
Cyrus: I have had some good luck making mpeg 4 movies with ffmpeg v.5 using the following options:
ffmpeg -f image2 -i frame%04d.png -vcodec mpeg4 -mbd rd -flags +4mv+aic -trellis 2 -cmp 2 -g 300 -pass 1/2 -r fps -b 18000000 movie.mp4
The above command line needs some adjustments to work with your movie frames:
|frame%04d.jpeg||This argument is the pattern of the frames that were output by VisIt: frame0000.jpeg, frame0001.jpeg, ... . JPEG images are used in this example but ffmpeg supports other formats as well. Substitute the base name of your frames for the word frame used in the provided pattern, if necessary.|
|bitrate||The bitrate is a number that you must calculate. The bitrate is used to guide the compression algorithms and is influenced by the number of frames per second and the size of the movie frames. Larger movie frames need a larger bitrate than smaller movie frames to avoid introducing compression artifacts. Smaller bitrates produce smaller MPEG files but they may contain artifacts if you go too low.
VisIt uses this formula as an upper limit for the bit rate and you can reduce the number as you see fit:
|movie.mpeg||This is the name of your movie. Call it whatever you want.|
You can obtain ffmpeg via svn checkout from their repository.
svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
You can also obtain ffmpeg via git checkout from the following newer repository.
git pull git://git.videolan.org/ffmpeg.git
VisIt bundles mpeg2encode as its default MPEG movie encoder. The mpeg2encode movie encoder supports a couple of input file formats but PPM format is the only format that is supported by both mpeg2encode and VisIt. The mpeg2encode program takes its arguments from an input file, which can be somewhat complex to set up. The following Python code can be used to set up an input file that will generate an MPEG1 movie for input frames that are smaller than 1000x1000 pixels. If your images are larger than that, you should try using ffmpeg instead.
def WriteParamFile(paramFile, framePattern, xres, yres, nframes): bitrate = xres * yres * 30 * 3 if bitrate > 104000000: bitrate = 104000000 f = open(paramFile, "w") f.write('Generated by VisIt (http://www.llnl.gov/visit), MPEG-1 Movie, 30 frames/sec\n') f.write('%s /* name of source files */\n' % framePattern) f.write('- /* name of reconstructed images ("-": do not store) */\n') f.write('- /* name of intra quant matrix file ("-": default matrix) */\n') f.write('- /* name of non intra quant matrix file ("-": default matrix) */\n') f.write('- /* name of statistics file ("-": stdout ) */\n') f.write('2 /* input picture file format: 0=*.Y,*.U,*.V, 1=*.yuv, 2=*.ppm */\n') f.write('%d /* number of frames */\n' % nframes) f.write('0 /* number of first frame */\n') f.write('00:00:00:00 /* timecode of first frame */\n') f.write('15 /* N (# of frames in GOP) */\n') # 15 f.write('3 /* M (I/P frame distance) */\n') f.write('1 /* ISO/IEC 11172-2 stream */\n') f.write('0 /* 0:frame pictures, 1:field pictures */\n') f.write('%d /* horizontal_size */\n' % xres) f.write('%d /* vertical_size */\n' % yres) f.write('8 /* aspect_ratio_information 8=CCIR601 625 line, 9=CCIR601 525 line */\n') f.write('5 /* frame_rate_code 1=23.976, 2=24, 3=25, 4=29.97, 5=30 frames/sec. */\n') f.write('%d.0 /* bit_rate (bits/s) */\n' % bitrate) f.write('112 /* vbv_buffer_size (in multiples of 16 kbit) */\n') f.write('0 /* low_delay */\n') f.write('0 /* constrained_parameters_flag */\n') f.write('4 /* Profile ID: Simple = 5, Main = 4, SNR = 3, Spatial = 2, High = 1 */\n') f.write('4 /* Level ID: Low = 10, Main = 8, High 1440 = 6, High = 4 */\n') f.write('1 /* progressive_sequence */\n') f.write('1 /* chroma_format: 1=4:2:0, 2=4:2:2, 3=4:4:4 */\n') f.write('0 /* video_format: 0=comp., 1=PAL, 2=NTSC, 3=SECAM, 4=MAC, 5=unspec. */\n') f.write('5 /* color_primaries */\n') f.write('5 /* transfer_characteristics */\n') f.write('5 /* matrix_coefficients */\n') f.write('%d /* display_horizontal_size */\n' % xres) f.write('%d /* display_vertical_size */\n' % yres) f.write('0 /* intra_dc_precision (0: 8 bit, 1: 9 bit, 2: 10 bit, 3: 11 bit */\n') f.write('0 /* top_field_first */\n') f.write('1 1 1 /* frame_pred_frame_dct (I P B) */\n') f.write('0 0 0 /* concealment_motion_vectors (I P B) */\n') f.write('0 0 0 /* q_scale_type (I P B) */\n') f.write('0 0 0 /* intra_vlc_format (I P B)*/\n') f.write('0 0 0 /* alternate_scan (I P B) */\n') f.write('0 /* repeat_first_field */\n') f.write('1 /* progressive_frame */\n') f.write('0 /* P distance between complete intra slice refresh */\n') f.write('0 /* rate control: r (reaction parameter) */\n') f.write('0 /* rate control: avg_act (initial average activity) */\n') f.write('0 /* rate control: Xi (initial I frame global complexity measure) */\n') f.write('0 /* rate control: Xp (initial P frame global complexity measure) */\n') f.write('0 /* rate control: Xb (initial B frame global complexity measure) */\n') f.write('0 /* rate control: d0i (initial I frame virtual buffer fullness) */\n') f.write('0 /* rate control: d0p (initial P frame virtual buffer fullness) */\n') f.write('0 /* rate control: d0b (initial B frame virtual buffer fullness) */\n') f.write('2 2 11 11 /* P: forw_hor_f_code forw_vert_f_code search_width/height */\n') f.write('1 1 3 3 /* B1: forw_hor_f_code forw_vert_f_code search_width/height */\n') f.write('1 1 7 7 /* B1: back_hor_f_code back_vert_f_code search_width/height */\n') f.write('1 1 7 7 /* B2: forw_hor_f_code forw_vert_f_code search_width/height */\n') f.write('1 1 3 3 /* B2: back_hor_f_code back_vert_f_code search_width/height */\n') f.close(); # Write the parameter file for 100 400x400 PPM image files(frame0000.ppm, frame0001.ppm, ...) WriteParamFile("movie.params", "frame%04d", 400, 400, 100)
After writing the parameter file, call mpeg2encode:
mpeg2encode movie.params movie.mpeg
Fill this out...
Fill this out...
mencoder can be used to write out AVI files. This example uses JPEG images output from VisIt and encodes them into an AVI movie.
mencoder "mf://frame*.jpeg" -mf fps=6:w=400:h=400:type=jpeg -o movie.avi -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=3000:vhq
|frame*.jpeg||This argument is a wildcard that matches the frames that were output by VisIt: frame0000.jpeg, frame0001.jpeg, ... . Substitute the base name of your frames for the word frame used in the provided pattern, if necessary.|
|400||This is the width of your image frames.|
|400||This is the height of your image frames.|
|movie.avi||This is the name of your movie. Call it whatever you want.|
Sometimes AVI files encoded using the above method are not compatible with Microsoft players. You can make the AVI compatible by converting using the following method. Quality may suffer somewhat but the movie should play in PowerPoint.
mencoder movie.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vhq -o movie_MS.avi
Streaming movies are generated to play on powerwalls (large tiled displays) using LLNL's Blockbuster software. Accordingly, image sizes for streaming movies are usually in the range of 2000x2000 pixels up to 4000x4000 pixels, or whatever resolution the display can support. Streaming movies are encoded using the img2sm command:
img2sm -rle -form tiff frame%04d.tif movie.sm
|frame%04d.tif||This argument is the pattern of the frames that were output by VisIt: frame0000.tif, frame0001.tif, ... . The img2sm command supports several commonly used image formats such as TIFF, PNG, JPEG. Substitute the base name of your frames for the word frame used in the provided pattern, if necessary.|
|movie.sm||This is the name of your movie. Call it whatever you want.|
The visit_utils framework is a Python module distributed with VisIt that contains many useful features, including routines that can be used to encode image files into playable movie files. In fact, VisIt's visit -movie script uses visit_utils under the covers to encode movies into movie formats.
Example python to encode to all supported formats:
import visit_utils for ext in ["sm","wmv","mpg","mov","avi","swf"]: visit_utils.encoding.encode("frame%04d.png","output.%s" % ext)
Example including duplicate frames:
import visit_utils for ext in ["sm","wmv","mpg","mov","avi","swf"]: visit_utils.encoding.encode("frame%04d.png","output.%s" % ext, fdup=2)
wmv,mpg,mov,avi,swf all use ffmpeg with decent params sm uses img2sm
Advanced Movie Making Workflow Tips and Wishlist
The use-case here is quick turn-around time for complex movies involving multiple insets and/or segments, scene transitions and annotations. We need the ability to quickly adjust things and re-produce the movie. So, the heavy lifting of VisIt renders is typically done only once at high resolution. But, even that process is optimized to the extent possible enabling the use of a wealth of compute resources to parallelize rendering over time. Those images than serve as building blocks from which final, composited and annotated image sequences are constructed typically using non-VisIt tools for everything else includind annotations, curve plots, etc.
Basic Workflow Steps
- Scene Description Setup
- View parameters and Image size
- Plots and Operators
- Material colors
- Color tables
- Test a single frame for correctness
- Simulation Database State Selection
- Enumerate all the file(s) in a .visit file
- Use time-step delta and find all nearest neighbors in the ensemble generated by the simulation
- Resource allocation for VisIt Renders (longest step in the process)
- Launching the driver to orchestrate multiple VisIt instances and renders of various images in the output sequence
- Generate the VisIt images
- Try to parallelize as much as possible (over time for example)
- 2D Scene Assembly
- Define final canvas
- Define insets into the canvas
- Define various annotations
- Generate the movie segment
- The process is fast and so can be re-done many times to make minor adjustments
- Edit movie segments into a larger final movie
- Not always necessary
- Add sound
- Scene transitions
- Intro and Credits
Tips (much of what Cyrus' existing Insanity Does)
- Render your plots in VisIt at high resolution, maybe 2K x 2K or more
- Turn off all (2D) annotations in VisIt
- Its easier to handle all annotations as a post-processing step instead of having to re-render plots with VisIt simply to adjust/change annotations
- 3D annotations, if any are essential, still need to be rendered by VisIt
- Ensure color tables (mins and maxs too) are consistent across all plots you plan to use
- To ensure a consistent time-base across a bunch of simulation outputs (silo files or whatever) is consistent, pick a desired time spacing and then construct a .visit file containing only the time instances from a simulation that are nearest neighbors to each time delta
- A short-hand notation for describing a scene in VisIt (which plots, operators, which view, etc.
- Multiple instances of (parallel) VisIt running and rendering some of the frames of a long sequence
- Maximal fault tolerance in the use of VisIt for rendering
- Detect render failures and automatically re-run those frames
- Track engine failures (perhaps due to OOM) and then insert calls to close and re-open the engine
- Re-use a given processor allocation to launch new engines
- Obtain a large processor allocation and then launch multiple engines within it each handling different times in the output
- A WYSIWYG movie frame assembly tool that allows users to assemble different 2D entities into a larger 2D canvas representing some frames in a sequence
- Including 2D annotations
- A scriptible interface is good as well. But, I think there are several aspects of the workflow that could benefit from a WYSIWYG tool that maybe outputs a script
- Cyrus's Note: WYSIWYG is just to hard in practice to maintain, I think our effort would be better spent creating usable tutorial scripts.
- A movie editing tool that allows different image sequences to be knitted together to form a larger movie and encode it into different sizes and formats
- Stuff that works with basically same interface on Windows, OSX and Linux
- Pre-defined, maybe even animated logos