Introduction Compiling miniproc Step by step instructions Adding additional objects Hints and Gotchas SAF specific Hints and Gotchas Example povinterp instructions file Example GridEngine/povray/miniproc/povinterp.mpc/mpeg_encode shell script Author and date information
This distribution contains tools and instructions for making movies of molecules. You should already have these files:
example.pdb PDB file for example movie example.pov POVray .pov file for example movie example.inc POVray .pov file for example movie example.txt povinterp instructions for example movie instructions.html This file miniproc.c Source code for miniproc program miniproc_doc.html Documentation for miniproc povinterp.mpc Script for generating frame specific .pov/.inc files timrom_specs.mpc text/font attribute information, called by povinterp.mpc testfile.mpc Test script for miniproc
In addition to these files, you will need
miniproc miniproc program. Download or compile from source code provided SPDBV 3.7 Swiss PDB viewer ONLY versions 3.7 and 3.6B3 will work! mpeg_encode MPEG1 encoder from Berkeley
Movies of molecular objects are produced by first using SPDBV 3.7 to define a set of objects and views. The final movie will show different sets of these objects as it moves smoothly between the views. Additionally, captions (fixed text) and labels (which are attached to objects) will be added. The trick is to get from the SPDBV information to the final movie. To do this the miniproc script povinterp.mpc is used. Under the direction of a file which describes the movie it processes the files output by SPDBV to generate rendering instructions for each frame. These are then run through the POVray ray tracer to produce images of each frame. The frames are then fed through MPEG_ENCODE to produce the final movie.
In general terms these are the steps which must be followed. First, use SPDBV to construct a PDB file so that it contains K layers named "layer1" through "layerK", where "layer1" is the layer that's at the top of the pull down menu in the control panel. For "layer1" define sequentially N views named "view1" through "viewN". It is essential that all views be set on the first layer (the one that is created when the first model is loaded). Each layer is then modified to contain one object (a section of protein, a ribbon, whatever) formatted as it will appear in the final movie. Once this is complete the PDB project file is saved (see example.pdb) as is a POV view (see example.pov and example.inc).Next the miniproc script povinterp.mpc processes all of these files according to instructions you supply to it in a command file (see example.txt). This generates the desired number of ".pov" files, each containing instructions for the rendering of a single frame of the movie, plus several ".inc" files which hold the objects which the .pov files display, and a ".act" script, which contains instructions for rendering the .pov files. This script smoothly interpolates between views (which are read from the example.pdb file) to achieve this result. Specifically, it uses a constant set of object coordinates and rotates the camera and lights around these objects. While doing so, and independently of the view, it can turn on or off objects (layers) and apply labels and captions to the image.
After the ".act" script has been executed - which may take a very long time - a large set of frame images will have been produced. These are then converted into an MPEG-1 movie with the mpeg_encode program.
There may already be a copy of miniproc on your system, in which case you need only run the test described below to verify that it will be able to run the povinterp.mpc script. Otherwise, you will need to build an executable version of this program. Miniproc should build on any system that has an ANSI C compiler and a command line. The following list shows build commands for several platforms:
% miniproc testfile.mpc FAILONLY=1 and then view the results, for instance on Unix with % cat test.txt or on VMS or Windows (DOS shell) with % type test.txt
Ideally the result will be a very large number of successful tests and zero failed tests.
Here are the steps which were used to create the example files. If you recreate these steps be careful not to write over the example files provided in the distribution! The choice of objects to display was essentially arbitrary.
Frame View Objects/labels displayed Caption(s) 1 view1 layer5/"sheet1",layer6/"sheet2","His32" "Two sheets to the wind" 2 | ditto ditto 3 | ditto ditto 4 view2 ditto ditto 5 | layer1/"A chain","Tyr87" "Active site" 6 | ditto ditto 7 | layer1/"A chain" "Active site without key residue" 5 view3Each layer (see below) will be a separate object. Labels are applied to coordinates in PDB space, so to place 'HIS32 NE2' find that atom in the example.pdb and note its coordinates. It is generally a good idea to have the first and last frames in the story be at of the same view. That way the movie may be looped continuously without having a discontinuity in view at that point. Similarly, the speed of transition from one view to another is determined by the number of intervening frames. If there are less than 10 frames between two views that are widely spaced the movie will jerk as it moves between them. Note that the view, object, label, and caption may all be set independently on a frame.
//---- Ribbon ----
smooth_triangle {<14.291,11.967,-11.578><-0.631,-0.679,0.374>,<14.482,11.811,-11.538><-0.631,-0.679,0.374>,<14.400,11.560,-12.132><-0.631,-0.679,0.374>texture{pigment{ colour red 0.80 green 0.80 blue 0.80} finish{ RIBBON_FINISH }}}
smooth_triangle {<14.291,11.967,-11.578><-0.631,-0.679,0.374>,<14.400,11.560,-12.132><-0.631,-0.679,0.374>,<14.356,11.425,-12.452><-0.631,-0.679,0.374>texture{pigment{ colour red 0.80 green 0.80 blue 0.80} finish{ RIBBON_FINISH }}}
etc.
You need to edit these sections to look like one of these forms, the second one is marginally
faster, but requires much more editing.
Slower, more memory intensive form - but easier to edit:
//---- Ribbon ----
#declare R1_shape=union{
smooth_triangle {<14.291,11.967,-11.578><-0.631,-0.679,0.374>,<14.482,11.811,-11.538><-0.631,-0.679,0.374>,<14.400,11.560,-12.132><-0.631,-0.679,0.374>texture{pigment{ colour red 0.80 green 0.80 blue 0.80} finish{ RIBBON_FINISH }}}
smooth_triangle {<14.291,11.967,-11.578><-0.631,-0.679,0.374>,<14.400,11.560,-12.132><-0.631,-0.679,0.374>,<14.356,11.425,-12.452><-0.631,-0.679,0.374>texture{pigment{ colour red 0.80 green 0.80 blue 0.80} finish{ RIBBON_FINISH }}}
etc.
}
Marginally faster, less memory intensive form - more complex to edit:
//---- Ribbon ----
#declare TXTR1=texture{pigment{ colour red 0.80 green 0.80 blue 0.80} finish{ RIBBON_FINISH }}
#declare TXTR2=texture{pigment{ colour red 0.00 green 1.00 blue 0.00} finish{ RIBBON_FINISH }}
#declare TXTR3=texture{pigment{ colour red 1.00 green 0.00 blue 0.00} finish{ RIBBON_FINISH }}
#declare R1_shape=mesh{
smooth_triangle {<14.291,11.967,-11.578><-0.631,-0.679,0.374>,<14.482,11.811,-11.538><-0.631,-0.679,0.374>,<14.400,11.560,-12.132><-0.631,-0.679,0.374>texture{ TXTR1 }}
smooth_triangle {<14.291,11.967,-11.578><-0.631,-0.679,0.374>,<14.400,11.560,-12.132><-0.631,-0.679,0.374>,<14.356,11.425,-12.452><-0.631,-0.679,0.374>texture{ TXTR1 }}
etc.
}
For the faster form, specifically what is done is to:
// ----- layer5 -----
// ----- layer6 -----
to
// ----- layer5 -----
object{ R1_shape } // Ribbon 1
// ----- layer6 -----
object{ R2_shape } // Ribbon 2
#version 3 // this scene uses POV-Ray 3.x syntax to #version 3.1 // this scene uses POV-Ray 3.x syntaxIf you are using Povray 3.5 (or above, most likely), expect a lot of warnings about #declare statements lacking semicolons as well as some warnings about text statements. These can be ignored.
% miniproc povinterp.mpc 'root=&example' 'outroot=&new'and on a windows system the command would be:
% miniproc povinterp.mpc "root=&example" "outroot=&new"Watch out for warnings about frames with no objects. While you might actually intend to make some completely dark frames in your movie it is more typically a result of having put the wrong commands into example.txt. When it runs these files will be created ("new" is not mandatory, you may use another string there, like "my_movie" or "second_try". No spaces or other punctuation should be included in the file name though!) :
new_common.pov most of the definitions from example.inc new_layer1.inc this layer, in its own file new_layer2.inc etc. new_layerK.inc where K is the largest layer number you used new_frame_1.pov instuctions for rendering this frame etc. new_frame_M.pov M is the highest frame number new.act A script to render the imagesThe distribution example.txt will generate a new.act file which is just the render instructions for POVray on a Unix system. By modifying example.txt a different new.act may be generated which is more appropriate for your site.
% source new.actThis may take a while! Do not be alarmed if there are some warnings. Do be alarmed if some of the output files are empty or nonexistant.
#!/bin/sh
#
# first parameter is number of frames in
# second is number of output frames per input frame
# It creates links called link#.ppm -> frame#.ppm. Then the
# resulting links can be used to generate an mpeg that runs slower
# than the default 30 frames per second.
#
framein=$1
replicate=$2
icount=1
lcount=1
while [ $icount -le $framein ]
do
reps=$replicate
while [ $reps -ge 1 ]
do
ln -s frame$icount.ppm link$lcount.ppm
reps=`expr $reps - 1`
lcount=`expr $lcount + 1`
done
icount=`expr $icount + 1`
done
Then do:
% ./fake_more_frames.sh 120 4Set up the MPEG render parameters (these may not be optimal!)
% cat >make_mpeg_link_params <<EOD BASE_FILE_FORMAT PPM INPUT_DIR . INPUT link*.ppm [1-480] END_INPUT INPUT_CONVERT * GOP_SIZE 12 REFERENCE_FRAME ORIGINAL SLICES_PER_FRAME 1 PATTERN IBBPBBPBBPBBPB PIXEL FULL RANGE 10 PQSCALE 2 IQSCALE 1 BQSCALE 2 PSEARCH_ALG LOGARITHMIC BSEARCH_ALG SIMPLE OUTPUT movie.mpg EODand finally render the movie with
% mpeg_encode make_mpeg_link_params
Fx = write output file in format x
FC - Compressed Targa with 24 or 32 bpp
FNn - PNG (n bits/color, n = 5 to 16, default is 8)
FP - PPM
FS - System specific
FT - Uncompressed Targa with 24 or 32 bpp
If POVray objects are added as layers to the initial example.pov file before processing they may be treated by the povinterp.mpc script just like any other object. For visible in every single frame generated. This limits your control over the moview, so it is usually best to not have anything visible in layer1.
showview 'view10' 'view11' 1 10 showview 'view11' 'view12' 10 20 showview 'view12' 'view13' 20 30 showview 'view13' 'view10' 30 40where view10 -> view13 are 90 degree rotations around that axis. To generate these views do:
width = 800 ! of output image ! height = 600 ! of output image !
#__alt_prefix=""
!
frames = 120 ! total number of frames to render !
layers = 6 ! total number of layers, in movie !
width = 800 ! of output image !
height = 600 ! of output image !
! width = 640 ! of output image !
! height = 480 ! of output image !
! numwidth = "%4.4d" ! large enough for most things, if not, change it !
captions = 10 ! >= number of showcaptions below !
labels = 10 ! >= number of showlabels below !
globals = 10 ! >= number of addglobal statements !
makedata ! creates arrays for processing based on the above !
!
! examples showing how to define a couple of macros which make global
! variables for use within POVRAY. The variables so defined may be
! used within the POVRAY sections of the input file. Modify the one
! input POVRAY file as desired BEFORE running povinterp.mpc and all frames
! will be able to vary based on these values.
!
macro linear(0)
macro_prototype _CREATE_INT_:frameindex _CREATE_INT_:ofil
macro_body
[ -
'#declare my_linearvar = ' -
:frameindex 1 .-. -
frames 1 .-. -
./. ! ratio, runs 0.0 -> 1.0 !-
'%5.4f' .d->s. ! now as a string !-
' ;' ! declare must end with ;!-
'' .append_. -
]
f$write RESULT :ofil
endmacro linear
addglobal @linear
macro two_cycle_sine_wave(0)
macro_prototype _CREATE_INT_:frameindex _CREATE_INT_:ofil
macro_body
[ '#declare my_cyclevar = ' -
:frameindex 1 .-. -
frames 1 .-. -
./. ! ratio, runs 0.0 -> 1.0 !-
3.14159 2 .*. ! scale for two cycles !-
.*. .sin. ! sin(2pi*x),x=0->1.0 !-
'%5.4f' .d->s. ! now as a string !-
' ;' ! declare must end with ;!-
'' .append_. ]
f$write RESULT :ofil
endmacro two_cycle_sine_wave
addglobal @two_cycle_sine_wave
!
!
! POVINTERP makes an output command file if there is a macro defined
! called emitcommand. If it doesn't exist, no command file is created.
! In this example a set of commands are made for running each povray
! job sequentially.
!
macro emit_command(0)
macro_prototype _CREATE_INT_:frameindex _CREATE_INT_:ofil
macro_body
[ -
'povray' -
' "+I' -
outroot -
'_frame_' -
:frameindex numwidth .i->s. -
'.pov"' -
' "+L/usr/common/povray31/include"' -
' "+W' -
width '%d' .i->s. -
'"' -
' "+H' -
height '%d' .i->s. -
'"' -
' "+FP"' -
' "+Oframe' -
:frameindex numwidth .i->s. -
'.ppm"' -
'' .append_. ]
f$write RESULT :ofil
endmacro emit_command
!
! The next line is MANDATORY if any addglobal statements are used
! or an emit_command has been defined.
!
! Miniproc variables are automatically deleted when they go out
! of scope, which the macros above will when this file exits.
! In order to preserve them for future use they must be moved up
! into the scope of the main POVINTERP.MPC script, which is what
! the next command does.
!
[ -
@emit_command -
@linear -
@two_cycle_sine_wave -
'MINIPROC' .changescope_. -
]
!
! define colors that labels and captions can use
!
_CREATE_STRING_mywhite = 'colour red 1.00 green 1.00 blue 1.00'
_CREATE_STRING_myred = 'colour red 1.00 green 0.00 blue 0.00'
_CREATE_STRING_mygreen = 'colour red 0.00 green 1.00 blue 0.00'
_CREATE_STRING_myblue = 'colour red 0.00 green 0.00 blue 1.00'
!
! as many of these as are appropriate, these set the values in the arrays
! for processing
!
! showlayer arguments
! arg what units
! 1 layer the layer to show
! 2 start frame number
! 3 end frame number
showlayer 2 1 20 ! make layer 2 visible in frames indicated !
showlayer 2 90 120 ! make layer 2 visible in frames indicated !
showlayer 3 1 20 ! make layer 3 visible in frames indicated !
showlayer 4 20 90 ! make layer 4 visible in frames indicated !
showlayer 5 30 90 ! make layer 4 visible in frames indicated !
showlayer 6 30 120 ! make layer 4 visible in frames indicated !
!
!
! as many of these as are appropriate, at the end frames the view
! is exactly the one derived from SPDBV. In between the camera travels
! on a straight line in even increments. In the first frame of a range
! the initial view is shown with no interpolation, in the final frame of
! a range the final view is shown with no interpolation. Therefore it is
! possible, and usually desirable, to overlap the showview commands on the
! ends so that there is no discontinuous "bump" in the film. This overlap
! must only be ONE FRAME. Having the same view throughout a range is allowed
! but no motion will occur within this frame. However, captions and labels may be
! turned on and off within subranges.
!
! showview arguments
! arg what units
! 1 view the initial view to show in this range of frames
! 2 view the final view to show in this range of frames
! 3 start frame number
! 4 end frame number
!
showview 'view1' 'view2' 1 20
showview 'view2' 'view3' 20 40
showview 'view3' 'view4' 40 80
showview 'view4' 'view5' 80 100
showview 'view5' 'view6' 100 frames
!
! frame captions:
! arg what units
! 1 start frame number
! 2 end frame number
! 3 upangle degrees
! 4 rightangle degrees
! 5 charsize pixels
! 6 caption 'text string'
! 7 color string var holding color descriptor
!
! For upangle, rightangle use:
! 8.0 0.0 10. for a top caption
! -8.0 0.0 10. for a bottom caption
!
! Normally showcaption ranges will not overlap. It's possible to have multiple
! captions on screen at once if they are on different parts of the screen.
!
showcaption 1 20 7. 0. 10. 'center on His32' MYWHITE
showcaption 21 40 7. 0. 10. 'Zoom In' MYWHITE
showcaption 41 80 7. 0. 10. 'Rotate around X' MYWHITE
showcaption 81 100 7. 0. 10. 'Rotate around Y' MYWHITE
showcaption 101 frames 7. 0. 10. 'Rotate around Z and Zoom Out' MYWHITE
!
! atomic position labels
! arg what units
! 1 start frame number
! 2 end frame number
! 3 x PDB coords in Angstroms
! 4 y PDB coords in Angstroms
! 5 z PDB coords in Angstroms
! 6 offset Angstroms, towards viewer (always put label in FRONT of atoms!)
! 7 charsize pixels
! 8 caption 'text string'
! 9 color string var holding color descriptor
!
showlabel 1 frames 29.201 10.679 38.636 2.0 7.6 'TYR86 OH' MYWHITE
showlabel 1 30 44.822 33.475 50.350 2.0 5.4 'HIS32 NE2' MYGREEN
showlabel 91 frames 44.822 33.475 50.350 2.0 5.4 'HIS32 NE2' MYGREEN
showlabel 1 40 44.185 37.799 50.117 2.0 5.4 'TYR76 OH' MYBLUE
showlabel 61 90 22.511 36.174 42.308 2.0 5.4 'TYR96 OH' MYRED
showlabel 31 90 47.536 46.273 59.008 2.0 5.4 'Sheet 1' MYGREEN
showlabel 31 frames 39.952 53.185 58.166 2.0 5.4 'Sheet 2' MYRED
!******************************************************************
f$exit 1
#!/bin/bash
# make_movies.bash
#
#
# this routine automates the creation of a movie using GridEngine, miniproc, povinterp.mpc
# povray, mpeg_encoder, a beowulf cluster and a tremendous amount of pixie dust.
#
# Submit it this way:
# qsub -l povray -S /bin/sh /usr/common/bin/make_movie.sh root frames
#
# where
#
# 1. "root" is the prefix for the input files test.pov,test.inc,test.pdb, use
# "test". Do not include any path info. These files must reside
# in the user's home directory.
# 2. the number of iterations of each frame to use in the movie. The
# default is 4. This slows down the movie to about the right speed.
#
# Note the file formatting %4.4d below - that is the default but may
# have been overwritten by a numwidth value when povinterp was run.
# See also the width and height for the rendered frames.
#
# Besides the root.* files, povinterp.mpc and timrom_specs.mpc must
# also be in the home directory.
#
#
THEMINI=/usr/common/bin/miniproc
THEPOV=/usr/common/bin/povray
THEMPEG=/usr/common/bin/mpeg_encode
MSCRIPT=makemovie.sh
if [ $1 ]
then
THEROOT=$1
else
echo "Fatal syntax error for make_movie.sh"
echo "==========================================="
head -19 $0 | tail -18
echo "==========================================="
exit
fi
if [ $2 ]
then
PADX=$2
else
PADX=4
fi
echo "theroot is $THEROOT and padx is $PADX"
#
# create the working directory, if it doesn't already exist.
#
MYDIR=/usr/common/tmp/$USER
if [ ! -e $MYDIR ]
then
mkdir $MYDIR
fi
#
# use miniproc and povinterp.mpc to generate the .pov and .inc files
# for all the frames. These remain in the user's home directory.
#
$THEMINI povinterp.mpc "root=&$THEROOT" "outroot=&tempf"
if [ ! $? ]
then
echo "Miniproc logged a fatal error, processing aborted"
fi
#
# count the output frames produced
#
set `ls -1 tempf_frame_*.pov | wc `
FRAMES=$1
#
# Create a shell script to do all the render jobs:
#
cat >renderone.sh <<EOD
#!/bin/sh
JOBNO=\$SGE_TASK_ID
NUMVALUE=`printf "%4.4d" $JOBNO`
$THEPOV\
"+Itempf_frame_\$NUMVALUE.pov" \
"+L/usr/common/povray31/include" \
"+W800" \
"+H600" \
"+FP" \
"+O$MYDIR/frame\$NUMVALUE.ppm"
exit
EOD
#
# create a shell script to produce the movie from the rendered frames -
# this will depend upon the link numbers
#
cat >$MSCRIPT <<EOD
#!/bin/sh
cd $MYDIR
#
EOD
if [ $PADX -ge 2 ]
then
replicate=$PADX
frameout=`expr $FRAMES \* $replicate`
cat >>$MSCRIPT <<EOD
icount=1
lcount=1
while [ \$icount -le $FRAMES ]
do
reps=$replicate
while [ \$reps -ge 1 ]
do
ln -s frame\$icount.ppm link\$lcount.ppm
reps=\`expr \$reps - 1\`
lcount=\`expr \$lcount + 1\`
done
icount=\`expr \$icount + 1\`
done
EOD
fi
#
# create an mpeg_encode parameter file
#
cat >$MYDIR/mpeg_params <<EOD
BASE_FILE_FORMAT PPM
INPUT_DIR .
INPUT
link*.ppm [1-$frameout]
END_INPUT
INPUT_CONVERT *
GOP_SIZE 12
REFERENCE_FRAME ORIGINAL
SLICES_PER_FRAME 1
PATTERN IBBPBBPBBPBBPB
PIXEL FULL
RANGE 10
PQSCALE 2
IQSCALE 1
BQSCALE 2
PSEARCH_ALG LOGARITHMIC
BSEARCH_ALG SIMPLE
OUTPUT movie.mpg
EOD
#
# finish up the rendering script
#
cat >>$MSCRIPT <<EOD
$THEMPEG mpeg_params
#
# clean up
#
rm -f frame*.ppm
rm -f link*.ppm
rm -f mpeg_params
mv -f movie.mpg $HOME
cd
rm -f tempf*
#
echo "movie completed, look in your directory for movie.mpg"
touch $HOME/MOVIE.DONE
exit
EOD
#
# send off all the render jobs and the final cleanup (movie) job.
# This horrible syntax is required
# because qsub does not return the job number as the status value.
# run the final mpeg_encode job on barrel because that is the
# NFS file server for all other nodes and it's needlessly slow to move all this
# data out and back in over the net. Another user's render job could be
# running on the other nodes in the meantime.
#
#
qsub -hold_jid \
`qsub -l povray -t 1-$FRAMES -S /bin/sh renderone.sh |\
awk -F '[ \.]' '{print $3}'` \
-l povray -q barrel.q -S /bin/sh $MSCRIPT
#
echo "render and movie jobs have been queued."
echo "Watch for a MOVIE.DONE file in your directory"
Updated: 28-NOV-2001
miniproc, povinterp.mpc, and these instructions were written by David Mathog, Biology division, Caltech, mathog@caltech.edu