Make all the frames and combine into a video

To make the video we need to run the plot script thousands of times, making an image file for each point in time, and then to merge the thousands of resulting images into a single video.

To make a smooth video we generate one frame every hour.

This script calls the plot script for each hour over a period:

#!/usr/bin/env python

# Make all the individual frames for a movie

import os
import subprocess
import datetime

# Where to put the output files
opdir = "%s/slurm_output" % os.getenv("SCRATCH")
if not os.path.isdir(opdir):
    os.makedirs(opdir)


# Function to check if the job is already done for this timepoint
def is_done(year, month, day, hour):
    op_file_name = ("%s/AnimH/visualizations/SyCLoPS/" + "%04d%02d%02d%02d%02d.png") % (
        os.getenv("SCRATCH"),
        year,
        month,
        day,
        int(hour),
        int(hour % 1 * 60),
    )
    if os.path.isfile(op_file_name):
        return True
    return False


f = open("run.txt", "w+")

start_day = datetime.datetime(2020, 2, 1, 0)
end_day = datetime.datetime(2021, 1, 31, 23)

current_day = start_day
while current_day <= end_day:
    if is_done(
        current_day.year,
        current_day.month,
        current_day.day,
        current_day.hour + current_day.minute / 60,
    ):
        current_day = current_day + datetime.timedelta(hours=1)
        continue
    cmd = (
        "./make_frame.py --year=%d --month=%d "
        + "--day=%d --hour=%f "
        + "--pole_latitude=90 --pole_longitude=180 "
        + "--npg_longitude=0 "
        + "--zoom=1 "
        + "\n"
    ) % (
        current_day.year,
        current_day.month,
        current_day.day,
        current_day.hour + current_day.minute / 60,
    )
    f.write(cmd)
    current_day = current_day + datetime.timedelta(hours=1)
f.close()

We then run those jobs in parallel, either with GNU parallel or by submitting them to a batch system (I used the MO SPICE cluster).

When all the frame images are rendered we make a video using ffmpeg. We will render at 1080p resolution - 5Mb/s bandwidth. (Overkill for a simple video, but now everyone has lots of internet bandwidth, so it’s not worth optimizing).

#!/bin/bash

cd $SCRATCH/AnimH/visualizations/
ffmpeg -r 48 -pattern_type glob -i SyCLoPS/\*.png \
       -c:v libx264 -threads 16 -preset veryslow -tune film \
       -profile:v high -level 4.2 -pix_fmt yuv420p \
       -b:v 5M -maxrate 5M -bufsize 20M \
       -c:a copy SyCLoPS.mp4