# reads molecule and normal mode vectors from dmol3 outmol file. # It generates povray (http://povray.org) input files, that can be turned # into pretty pictures. The main benefit is that the arrows describing the # displacements of each of the atoms now have a proper "size or volume", so # that the "Persistance of Vision" principle makes their direction clearly # visible. # # REQUIRED: AWK (www.gnu.org) and Povray (povray.org) # # To link the masses of the atoms to the symbols, an external list # "atomicmasses.dat" is used. # # USE: awk -f thisfile.awk yourdmol3outputfile.outmol # # LvE 2005 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["molecule_rgb"]="0.9 0.9 0.9" scene["arrow_rgb"]="0.4 0.4 0.4" scene["camera"]="7, 7, 5" scene["light"]="20, 20, 20" scene["magnify_mode"]=5 sizes["bond"]=0.2 sizes["ball"]=0.2 sizes["arrow"]=0.1 sizes["head"]=0.15 # this assumes the atomic masses file is in the current dir while (getline <"atomicmass.dat") { if ($1 !~ /\#/) { mass[$3]=$4 } } structure_done=0 } #need to translate chemical symbols S,C,H,Li to mass # read equilibrium structure /^\$coordinates/ && (structure_done==0) { i=0 getline while (NF==4) { i++; type[i]=$1 X[i]=$2/2 Y[i]=$3/2 Z[i]=$4/2 getline } for (atom in type) { mass[atom]=mass[type[atom]] #centerofmass["x"] += X[atom]*mass[atom] #centerofmass["y"] += Y[atom]*mass[atom] #centerofmass["z"] += Z[atom]*mass[atom] centerofmass["x"] += X[atom] centerofmass["y"] += Y[atom] centerofmass["z"] += Z[atom] } } # check equi geom with reported number of atoms /^N_atoms / { noatoms=$3 if (noatoms!=i) { print "n.o. atoms according to equilibrium structure (",i,")"; print "n.o. atoms according to gamess (",noatoms,"). BAILING OUT!"; exit } else {structure_done=1} } # read in the block of displacements of corresponding to the 3N-6 modes of # vibration, but dmol3 might remove the 6 modes by itself /vibrational frequencies, intensities/ { getline getline modenr["lowest"]=$1 while (NF==4) { getline freq[$1]=$3 } # goto block and loop until a "*******" is seen while (1) { #skip to line with column description while ($0 !~ ":") { getline ; if ($0 ~ "Dipole derivatives") {exit} } # remember modenr of this block gsub(":"," ") counter=0 for (i=1;i<=NF;i=i+2) { counter++ modenr[counter]=$i } getline # read in block of dx,dy,dz with each mode getblock(noatoms,modenr) } } ################################################################ 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 atomnr=0 while (c<=coords) { getline if (c%3==1) { atomnr++ atomtype=$1 for (i=1;i<=NF-2;i++) { delta[modenr[i],atomnr,$2]=$(i+2) } } 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=modenr["lowest"];mode<=noatoms*3;mode++) { modename=sprintf("mode_%03i",mode) freqname=sprintf("freq_%04i",freq[mode]) FNAME=modename"_"freqname".pov" #FNAME="mode_"mode"_freq_"freq[mode]".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.3;\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< %s >}\n",scene["molecule_rgb"]) >>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< %s >}\n",scene["arrow_rgb"]) >>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["ball"]) >>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 }