Using the Camera and producing animations

Using the Camera and producing animations

In this tutorial, we will produce a gif and mp4 with a rotating molecule. For that, we will use the Camera from SAMSON.

For this example, you may need to install either moviepy package:

conda install -c conda-forge moviepy

or imageio package:

conda install -c conda-forge imageio

You can find the code in SAMSON Python Scripting samples on github.

Content

Rotation of a molecule

Open a molecule of your choice and run the next script (modify paths if necessary).

import os
import numpy as np
from math import pi, log10
import datetime
import imageio
import moviepy.editor as mpy
 
def create_gif_imageio(filenames, duration):
    '''
    function that creates a gif-file from images thanks to imageio package
    '''
    images = []
    for filename in filenames:
        images.append(imageio.imread(filename))
    output_gif_file = 'imageio-%sam.gif' % datetime.datetime.now().strftime('%Y-%M-%d-%H-%M-%S')  # generate name for the gif-file
    output_mp4_file = 'imageio-%sam.mp4' % datetime.datetime.now().strftime('%Y-%M-%d-%H-%M-%S')  # generate name for the mp4-file
    imageio.mimsave(output_gif_file, images, duration=duration)                                   # save clip to the gif-file
    imageio.mimsave(output_mp4_file, images)                                                      # save clip to the mp4-file
 
def create_gif_moviepy(filenames, fps):
    '''
    function that creates a gif-file from images thanks to moviepy package
    '''
    output_gif_file = 'moviepy-%sam.gif' % datetime.datetime.now().strftime('%Y-%M-%d-%H-%M-%S')  # generate name for the gif-file
    output_mp4_file = 'moviepy-%sam.mp4' % datetime.datetime.now().strftime('%Y-%M-%d-%H-%M-%S')  # generate name for the mp4-file
    clip = mpy.ImageSequenceClip(filenames, fps=fps)                                              # create a clip
    clip.write_gif(output_gif_file)                                                               # save clip to the gif-file
    clip.write_videofile(output_mp4_file)                                                         # save clip to the mp4-file
 
def rotate(camera, velocity, center):
    '''
    rotate the camera with a given velocity and update the viewport
    '''
    camera.rotate(velocity, center)                                         # rotate the camera
    SAMSON.processEvents()                                                  # process events: updates viewport
 
camera = SAMSON.getActiveCamera()                                           # get the active camera
camera.frontView()                                                          # set the view of the camera
SAMSON.processEvents()                                                      # process events: updates viewport
 
indexer = SAMSON.getNodes('n.t a')                                          # get all atoms
 
centerOfMass = np.zeros(3)                                                  # compute center of mass
for a in indexer:
    centerOfMass[0] += a.getX().value
    centerOfMass[1] += a.getY().value
    centerOfMass[2] += a.getZ().value
centerOfMass /= indexer.size
center = Type.length3(Quantity.length(centerOfMass[0]), Quantity.length(centerOfMass[1]), Quantity.length(centerOfMass[2]))  # center of the molecule
 
velocity = pi * 1.0/180.0                                                   # rotation velocity
velocity3 = Type.radianPerSecond3(Quantity.radPerS(0), Quantity.radPerS(velocity), Quantity.radPerS(0)) # rotation is only in y-direction
 
pathToFile = './tmp/'
try:                                                                        # try to create a tmp folder
    os.mkdir(pathToFile)
except:
    pass
 
ext = '.png'                                                                # extension of files
numberOfRorations = 36                                                      # rotate 36 times
 
SAMSON.showProgressBar('Rotating and capturing', 0, numberOfRorations)      # show a progress bar to inform user about the progress
 
for i in range(numberOfRorations):
    rotate(camera, velocity3, center)                                       # rotate the camera around the center of mass with a given velocity
    i_str = str(i).zfill(int(log10(numberOfRorations)) + 1)
    filename = pathToFile + i_str + ext
    SAMSON.captureViewportToFile(filename, 600, 800)                        # save a capture of the viewport in a file with 600x800 resolution
    SAMSON.setProgressBarValue(i)                                           # update the progress bar
    if SAMSON.isProgressBarStopped(): break                                 # break if the rotation is finished
 
os.chdir(pathToFile)                                                        # change directory to the directory with images
img_files = sorted((fn for fn in os.listdir('.') if fn.endswith('.png')))   # get a list of created images
create_gif_imageio(img_files, 0.1)                                          # create a gif and mp4 files using imageio
create_gif_moviepy(img_files, 12)                                           # create a gif and mp4 files using moviepy
os.chdir('../')
 
SAMSON.hideProgressBar()                                                    # close the progress bar

Moving along the path

Let us use functions introduced before for producing an animation of a system changing its states along the path.

SAMSON.importFromFile('/your/folder/path.samx')                             # import path data
 
camera = SAMSON.getActiveCamera()                                           # get the active camera
camera.frontView()                                                          # set the view of the camera
SAMSON.processEvents()                                                      # process events: updates viewport
 
indexer = SAMSON.getNodes('n.t a')                                          # get all atoms
path = SAMSON.getNodes('n.t path')[0]                                       # get the path
 
pathToFile = './tmp/'
try:                                                                        # try to create a tmp folder
    os.mkdir(pathToFile)
except:
    pass
 
ext = '.png'                                                                # extension of files
path.forwardFlag = True                                                     # set a change in positions in a forward direction
path.animationFlag = True                                                   # set an animation
path.animationType = sam.Modeling.StructuralModel.Path.AnimationType.Loop   # set Loop type of an animation
 
SAMSON.showProgressBar('steps', 0, path.numberOfSteps)                      # show a progress bar to inform user about the progress
 
for i in range(path.numberOfSteps):
        path.updateState()                                                  # update the state - change positions to the next step
        SAMSON.processEvents()
        i_str = str(i).zfill(int(log10(path.numberOfSteps)) + 1)
        filename = pathToFile + i_str + ext
        SAMSON.captureViewportToFile(filename, 800, 600)                    # save a capture of the viewport in a file with 800x600 resolution
        SAMSON.setProgressBarValue(i)                                       # update the progress bar
        if SAMSON.isProgressBarStopped(): break                             # break if the rotation is finished
 
os.chdir(pathToFile)                                                        # change directory to the directory with images
img_files = sorted((fn for fn in os.listdir('.') if fn.endswith('.png')))   # get a list of created images
create_gif_imageio(img_files, 0.1)                                          # create a gif and mp4 files using imageio
create_gif_moviepy(img_files, 12)                                           # create a gif and mp4 files using moviepy
os.chdir('../')
 
SAMSON.hideProgressBar()

Comments are closed.