Making an Animation with MESA

In my last post, I showed an animation I made with MESA. Here’s a guide explaning how I made it.

The MESA SDK now comes with a movie-making script. You probably want to use that.

Step 0: Install the following software

Step 1: Run your MESA model

Set up your MESA inlist to study the scenario of interest. If you want to make a movie, you’re going to want to have frequent output. Set the parameters in the controls namelist in your inlist correspondingly. I dumped a profile and a log entry at every step :

profile_interval = 1
log_cnt = 1
max_num_profile_models = 30000

Be careful though, disk space could be an issue. I wrote out about 25000 profiles, which ate up about 100 GB.

Step 2: Generate your plots

You don’t have to use Tioga of course; a lot of this guide applies to any set of PNG files. But Tioga makes pretty plots, the scripts to read MESA data already exist, and Bill has a lot of great figures pre-defined. If you’re unfamiliar with Ruby and/or Tioga, this could be the most challenging part.

I made use of the existing movie_batch.rb scripts that live in :


Bill recently characterized these scripts as “out-of-date leftovers”, but they still mostly work even if they aren’t officially supported. (I made one minor change, which is to zero-pad the output files to 5 digits instead of 4.)

In movie_batch.rb, select which figure to generate and the range of model numbers to generate it for. I just made a pdf for every MESA step; I’ll choose the subset to include in my movie later. Once you’ve made these choices or perhaps defined your own new figure, execute:

ruby < movie_batch.rb

and you’ll end up with a set of pdfs in the movie_out directory, named plot_ddddd.pdf, where plot is a placeholder for the name of whatever figure you chose and ddddd is the zero-padded MESA step number.

Step 3: Convert plots to PNG files

Use ImageMagick to convert the .pdf files to .png. For a single file, this is as easy as :

convert -density dpi filename.pdf filename.png

The value you choose for dpi will set the resolution of the movie. The size (in pixels) of the resulting png file is the pdf size (in inches) times dpi .

If you want to convert many files, you could just write a loop in your shell of choice. But here’s where something like GNU parallel can make your day a whole lot better. (On the other hand, it means there’s less time to duck out and get a cup of coffee.)

Your pdf files have names plot_ddddd.png. Prepare a list of the a list of the numbers that you want to convert by whatever means you prefer. Then just pipe it into parallel :

printf "%05d\n" {0..N} | parallel -j n --eta convert plot_{}.pdf plot_{}.png

and it takes care of the rest. n specifies how many simultaneous jobs you want to run. (I set n to be the number of cores on my machine). The --eta flag gives a nice display of how far long it is, how much time is left, etc.

Around this time, you can also use ImageMagick to do any number of other things. For example, I wasn’t initially sure what information I wanted in my movie. I generated several different plots at each step (an HR diagram, an abundance plot, etc), but each plot was contained in its own pdf file. Then, after converting each of those pdfs to pngs, I stitched together the ones that I wanted using the montage command.

For every MESA step, you should now have one file that displays the information you want to animate.

Step 4: Choose which steps to include

You probably don’t want a frame for every step MESA took. Your movie would speed through the main sequence but creep up the RGB. This choice depends on what you want to illustrate and a little bit on aesthetics, so it’s inevitable that you have to do it at least semi-manually. For me, that meant choosing a simple set of rules to generate a list of the steps that I wanted to include. For example,

Regardless of how you do it, the end goal is to have a set of sequentially numbered PNG files.

For those of you who speak Python, I did something like :

import shutil
plots = [] # list of step numbers that I wanted to include
for fnum, plot in enumerate(plots):
    frame_file = "plot_{0:05.0f}.png".format(plot)
    final_file = "frame_{0:05.0f}.png".format(fnum)
    shutil.copy(frame_file, final_file)

Step 5: Join the frames into a movie

png2yuv decompresses a sequence of PNG files into a YUV4MPEG2 stream. Do :

png2yuv -f 30 -I p -j frame_%05d.png > movie.y4m

We choose the frame rate with -f. The -j specifies the naming pattern of the png files to read. png2yuv will stop once it fails to match the pattern, which is why we want our files to be numbered sequentially. If you want to begin with a frame that is not number 0, investigate the -b option. The -I p selects progressive scan, that is no interlacing.

Now we have an (uncompressed) video. Be careful, the y4m file could be many GB.

Step 6: Encode the movie

There are many ways to encode video, but I’ve found x264 to be simple to use and give great results. It just gobbles up y4m files, which is of course why we bothered to generate one in the first place. Do :

x264 movie.y4m -o movie.mp4

How easy is that! I’m sure you could go down the rabbit hole and start playing with the infinite options, but I’ve been happy with the defaults. Hopefully, now you have a good looking stellar evolution movie to show in talks, lectures, etc.