# reads molecule and normal mode vectors from pcgamess log file # (of a vibs calc). It generates Povray (http://povray.org/) input files that # can then be converted to pictures that are visually attractive and # unambigiously interpretable. Arrows on each atom show the sense and direction # of displacement of the atoms in a vibrational mode. # # LvE 2005 # this script is provided "as is", without any garantees. # # REQUIRED: AWK (www.gnu.org) to interprete this script # and Povray (povray.org) to generate the graphics # # use: awk -f thisfile.awk yourpcgamessoutputfile.log # # it generate 3N files named according to the normal modes of vibration # (where N is the number of atoms in your molecule) BEGIN{ # these variables can be changed to alter the "look" of the normal mode # pictures. Many more options can be added and some options are in your # povray.ini file. scene["background"]="White" scene["camera"]="20, 10, 10" scene["light"]="20, 20, 20" scene["magnify_mode"]=10 sizes["bond"]=0.3 sizes["atom"]=0.3 sizes["arrow"]=0.1 sizes["head"]=0.15 } # read equilibrium structure /COORDINATES \(BOHR\)/ { i=0; getline getline while (NF>4) { i++; type[i]=$1 charge[i]=$2 X[i]=$3/2 Y[i]=$4/2 Z[i]=$5/2 getline } for (atom in charge) { mass[atom]=charge[atom]*2 centerofmass["x"] += X[atom]*mass[atom] centerofmass["y"] += Y[atom]*mass[atom] centerofmass["z"] += Z[atom]*mass[atom] } } # check equi geom with respect to reported number of atoms / TOTAL NUMBER OF ATOMS / { noatoms=$NF if (noatoms!=i) { print "n.o. atoms according to equilibrium structure (",i,")"; print "n.o. atoms according to gamess (",noatoms,"). BAILING OUT!"; exit; } } # read in the block of displacements of corresponding to the 3N-6 modes of # vibration ( not always are the 6 modes projected out and so you might end up # with 3N modes instead of 3N-6). /HARMONIC APPROXIMATION/ { while (1) { getline # remember modenr if ($0 !~ /[[:alpha:]]/) { for (i=1;i<=NF;i++) { modenr[i]=$i } } # remember frequeny of these modes and read in block of dx,dy,dz with # each mode if ($1 == "FREQUENCY:" ) { coord="X"; for (i=2;i<=NF;i++) { freq[modenr[i-1]]=$i ; }; getblock(noatoms,modenr) } # stop if at end of block if ($0 ~ /THERMOCHEMISTRY AT/) {break} } } END { #printmodes(noatoms,type,modenr,freq,delta) povray_printmodes(noatoms,type,modenr,freq,delta,sizes,scene) } ## below only function definitions function getblock(noatoms,modenr, coords,i) { coords=noatoms*3; c=1 getline getline getline while (c<=coords) { getline if (c%3==1) { atomnr=$1 atomtype=$2 # (redundant) for (i=1;i<=NF-3;i++) { delta[modenr[i],atomnr,$3]=$(i+3) } } if ( (c%3==2) || (c%3==0) ) { for (i=1;i<=NF-1;i++) { delta[modenr[i],atomnr,$1]=$(i+1) } } c++; } } function povray_printmodes(noatoms,type,modenr,freq,delta,sizes,scene) { for (mode=1;mode<=noatoms*3;mode++) { modename=sprintf("mode_%03i",mode) freqname=sprintf("freq_%04i",freq[mode]) FNAME=modename"_"freqname".pov" povray_printheader(centerofmass,scene,FNAME) povray_printmolecule(noatoms,type,charge,X,Y,Z,sizes,FNAME) povray_printarrows(noatoms,mode,X,Y,Z,delta,sizes,scene,FNAME) povray_printfooter(FNAME) } } function povray_printheader(centerofmass,scene,FNAME) { printf("#include \"colors.inc\"\n") >FNAME printf("#include \"transforms.inc\"\n") >>FNAME printf("background { color %s }\n\n",scene["background"]) >>FNAME printf("camera {\n") >>FNAME printf(" location < %s >\n",scene["camera"]) >>FNAME printf(" look_at < %f, %f, %f >\n",\ centerofmass["x"],centerofmass["y"],centerofmass["z"]) >>FNAME printf(" angle 45 \n}\n\n") >>FNAME printf("light_source { < %s >\n",scene["light"]) >>FNAME printf(" color rgb<1, 1, 1> }\n\n") >>FNAME printf("#declare BSAMBI = 0.2;\n") >>FNAME printf("#declare BSDIFF = 0.8;\n") >>FNAME printf("#declare BSSPEC = 0.8;\n\n") >>FNAME print "" >>FNAME printf("#declare colorA =\n") >>FNAME printf(" texture {\n") >>FNAME printf(" pigment { rgb< 0.5000 0.5000 0.5000 >}\n") >>FNAME printf(" finish {ambient BSAMBI diffuse BSDIFF specular BSSPEC}\n") >>FNAME printf(" }\n\n") >>FNAME printf("#declare colorB =\n") >>FNAME printf(" texture {\n") >>FNAME printf(" pigment { rgb< 0.2000 0.2000 0.2000 >}\n") >>FNAME printf(" finish {ambient BSAMBI diffuse BSDIFF specular BSSPEC}\n") >>FNAME printf(" }\n\n") >>FNAME } function povray_printmolecule(noatoms,type,charge,X,Y,Z,sizes,FNAME) { printf("# declare molecule = union {\n") >>FNAME for (atom=1;atom<=noatoms;atom++){ printf(" sphere {\n") >>FNAME printf(" < %f, %f, %f >, %f \n",X[atom],Y[atom],Z[atom],sizes["atom"]) >>FNAME printf(" texture { colorA }\n") >>FNAME printf(" }\n") >>FNAME for (neighbour=1;neighbour<=noatoms;neighbour++) { distance=( \ (X[atom]-X[neighbour])**2 + \ (Y[atom]-Y[neighbour])**2 + \ (Z[atom]-Z[neighbour])**2 \ )**0.5 if ( (neighbour != atom) && (distance < 2) ) { printf(" cylinder {\n") >>FNAME printf(" < %f, %f, %f >, < %f, %f, %f >, %f \n",\ X[atom],Y[atom],Z[atom],\ X[neighbour],Y[neighbour],Z[neighbour],sizes["bond"]) >>FNAME printf(" texture { colorA }\n") >>FNAME printf(" }\n") >>FNAME } } } printf("}\n\n\n") >>FNAME } function povray_printarrows(noatoms,mode,X,Y,Z,delta,sizes,scene,FNAME) { printf("# declare arrows = union {\n") >>FNAME for (atom=1;atom<=noatoms;atom++){ endX[atom]=X[atom]+delta[mode,atom,"X"]*scene["magnify_mode"] endY[atom]=Y[atom]+delta[mode,atom,"Y"]*scene["magnify_mode"] endZ[atom]=Z[atom]+delta[mode,atom,"Z"]*scene["magnify_mode"] headX[atom]=X[atom]+delta[mode,atom,"X"]*scene["magnify_mode"]*1.2 headY[atom]=Y[atom]+delta[mode,atom,"Y"]*scene["magnify_mode"]*1.2 headZ[atom]=Z[atom]+delta[mode,atom,"Z"]*scene["magnify_mode"]*1.2 # print cylinder printf(" cylinder {\n") >>FNAME printf(" < %f, %f, %f >, < %f, %f, %f >, %f \n",\ X[atom],Y[atom],Z[atom],\ endX[atom],endY[atom],endZ[atom],sizes["arrow"]) >>FNAME printf(" texture { colorB }\n") >>FNAME printf(" }\n") >>FNAME # print arrow head printf(" cone {\n") >>FNAME printf(" < %f, %f, %f >, %f\n", \ endX[atom],endY[atom],endZ[atom], sizes["head"]) >>FNAME printf(" < %f, %f, %f >, 0.0\n", \ headX[atom],headY[atom],headZ[atom]) >>FNAME printf(" texture { colorB }\n") >>FNAME printf(" }\n") >>FNAME } printf("}\n") >>FNAME } function povray_printfooter(FNAME) { printf("object{molecule}\n") >>FNAME printf("object{arrows}\n") >>FNAME }