#!/usr/local/bin/perl # Script to extract nomrmal modes from the DMOL output file. # Now how the data are printed? They are printed as required by xmol # to display frequences. Each normal mode is printed as a separate file # with an extension nu1 ... nu(3N-6). The root of file name is taken from # as everything from the beginning of output file name from GAUSSIAN up to # first period. The OUT file name from DMOL is given on the command line. # # search for line 'df ATOMIC COORDINATES' and save its position # in the file with tell. # In the same time look for line 'Eigenvalues, occupations, and MO coefficients' # and if found, reset file pointer to last ATOMIC COORDINATES with seek. # Read in coordinates after skipping 2 lines. Read coordinates until line # contains 'self consistent binding energy' # Now search for line: 'Frequencies (CM-1) and normal modes' # Then collect modes which are given as: # Frequencies (CM-1) and normal modes # 0.0 0.0 0.0 0.0 0.0 0.0 193.9 268.7 363.2 709.9 # # -0.112 0.147 0.015 0.409 -0.435 -0.483 0.068 -0.047 -0.171 0.066 die "You did not give DMOL output file name as argument\n" if $#ARGV < 0; die "You need only one parameter --- DMOL output file name\n" if $#ARGV > 0; $DMOLOUT = $ARGV[0]; $DMOLOUT =~ /([\w\/+#-]+)/; $OUT_root = $1; @at_symbols = ('H ', 'He', 'Li', 'Be', 'B ', 'C ', 'N ', 'O ', 'F ', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P ', 'S ', 'Cl', 'Ar', 'K ', 'Ca', 'Ti', 'V ', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr', 'X '); open(DMOLOUT,"<$DMOLOUT") || die "Could not open $DMOLOUT\n"; #now search for coordinates line while () { if(/ATOMIC COORDINATES DERIVATIVES/) { $coor_pointer = tell(DMOLOUT); } last if /Eigenvalues, occupations, and MO coefficients:/; } #reset file pointer to last COORDINATES seek(DMOLOUT,$coor_pointer,0); #skip 2 lines; $line = ; $line = ; #now collect cartesian coordinates in an array $n_at = 0; while ($line = ) { last if ($line =~ /self consistent binding energy/); $n_at++; $line =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/; $at_symb[$n_at] = $2; $x_coor[$n_at] = $3 * 0.529177249; # to Angstroms $y_coor[$n_at] = $4 * 0.529177249; $z_coor[$n_at] = $5 * 0.529177249; } #search for line: "Frequencies (CM-1) and normal modes" while ($line = ) { last if ($line =~ /Frequencies \(CM-1\)/); } $n_cols = 3*$n_at-6; #will be decremented by number of processed modes $first_pass = 1; $n_col_num = 0; while($n_cols > 0) { if($n_cols >= 10) { $n_curr_cols = 10; } else { $n_curr_cols = $n_cols; } if($first_pass == 1) { #skip first 6 modes $n_curr_cols = $n_curr_cols - 6; } #open files for modes in the xmol format if($n_curr_cols >= 1) { $k = $n_col_num + 1; # Which frequency we are" $temp = sprintf("%d",$k); $NU1F = $OUT_root . '.nu' . $temp; open(NU1F,">$NU1F") || die "Could not open $NU1F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 2) { $k = $n_col_num + 2; # Which frequency we are" $temp = sprintf("%d",$k); $NU2F = $OUT_root . '.nu' . $temp; open(NU2F,">$NU2F") || die "Could not open $NU2F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 3) { $k = $n_col_num + 3; # Which frequency we are" $temp = sprintf("%d",$k); $NU3F = $OUT_root . '.nu' . $temp; open(NU3F,">$NU3F") || die "Could not open $NU3F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 4) { $k = $n_col_num + 4; # Which frequency we are" $temp = sprintf("%d",$k); $NU4F = $OUT_root . '.nu' . $temp; open(NU4F,">$NU4F") || die "Could not open $NU4F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 5) { $k = $n_col_num + 5; # Which frequency we are" $temp = sprintf("%d",$k); $NU5F = $OUT_root . '.nu' . $temp; open(NU5F,">$NU5F") || die "Could not open $NU5F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 6) { $k = $n_col_num + 6; # Which frequency we are" $temp = sprintf("%d",$k); $NU6F = $OUT_root . '.nu' . $temp; open(NU6F,">$NU6F") || die "Could not open $NU6F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 7) { $k = $n_col_num + 7; # Which frequency we are" $temp = sprintf("%d",$k); $NU7F = $OUT_root . '.nu' . $temp; open(NU7F,">$NU7F") || die "Could not open $NU7F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 8) { $k = $n_col_num + 8; # Which frequency we are" $temp = sprintf("%d",$k); $NU8F = $OUT_root . '.nu' . $temp; open(NU8F,">$NU8F") || die "Could not open $NU8F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 9) { $k = $n_col_num + 9; # Which frequency we are" $temp = sprintf("%d",$k); $NU9F = $OUT_root . '.nu' . $temp; open(NU9F,">$NU9F") || die "Could not open $NU9F\n"; } #open files for modes in the xmol format if($n_curr_cols >= 10) { $k = $n_col_num + 10; # Which frequency we are" $temp = sprintf("%d",$k); $NU10F = $OUT_root . '.nu' . $temp; open(NU10F,">$NU10F") || die "Could not open $NU10F\n"; } $i = 0; #get frequences $line = ; chop($line); @vib_freq = split(/[ \t]+/, $line); if($first_pass == 1) { #skip first 6 modes for ($j = 1; $j <= 6; $j++) { shift(@vib_freq); } } if($n_curr_cols >= 1) { printf NU1F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[1]; } if($n_curr_cols >= 2) { printf NU2F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[2]; } if($n_curr_cols >= 3) { printf NU3F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[3]; } if($n_curr_cols >= 4) { printf NU4F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[4]; } if($n_curr_cols >= 5) { printf NU5F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[5]; } if($n_curr_cols >= 6) { printf NU6F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[6]; } if($n_curr_cols >= 7) { printf NU7F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[7]; } if($n_curr_cols >= 8) { printf NU8F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[8]; } if($n_curr_cols >= 9) { printf NU9F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[9]; } if($n_curr_cols >= 10) { printf NU10F "%d\nNUDMOL=%f\n",$n_at, $vib_freq[10]; } $line = ; #skip one line; for ($n = 1; $n <= $n_at; $n++) { if($n_curr_cols >= 1) { printf(NU1F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 2) { printf(NU2F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 3) { printf(NU3F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 4) { printf(NU4F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 5) { printf(NU5F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 6) { printf(NU6F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 7) { printf(NU7F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 8) { printf(NU8F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 9) { printf(NU9F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } if($n_curr_cols >= 10) { printf(NU10F " %2s %11.5f %11.5f %11.5f", $at_symb[$n], $x_coor[$n], $y_coor[$n], $z_coor[$n]); } for ($i = 1; $i <= 3; $i++) { $line = ; chop($line); @modes = split(/[ \t]+/, $line); if($first_pass == 1) { #skip first 6 modes for ($j = 1; $j <= 6; $j++) { shift(@modes); } } if($n_curr_cols >= 1) { printf NU1F " %10.4f", $modes[1]; } if($n_curr_cols >= 2) { printf NU2F " %10.4f", $modes[2]; } if($n_curr_cols >= 3) { printf NU3F " %10.4f", $modes[3]; } if($n_curr_cols >= 4) { printf NU4F " %10.4f", $modes[4]; } if($n_curr_cols >= 5) { printf NU5F " %10.4f", $modes[5]; } if($n_curr_cols >= 6) { printf NU6F " %10.4f", $modes[6]; } if($n_curr_cols >= 7) { printf NU7F " %10.4f", $modes[7]; } if($n_curr_cols >= 8) { printf NU8F " %10.4f", $modes[8]; } if($n_curr_cols >= 9) { printf NU9F " %10.4f", $modes[9]; } if($n_curr_cols >= 10) { printf NU10F " %10.4f", $modes[10]; } } # for $i if($n_curr_cols >= 1) { printf NU1F "\n"; } if($n_curr_cols >= 2) { printf NU2F "\n"; } if($n_curr_cols >= 3) { printf NU3F "\n"; } if($n_curr_cols >= 4) { printf NU4F "\n"; } if($n_curr_cols >= 5) { printf NU5F "\n"; } if($n_curr_cols >= 6) { printf NU6F "\n"; } if($n_curr_cols >= 7) { printf NU7F "\n"; } if($n_curr_cols >= 8) { printf NU8F "\n"; } if($n_curr_cols >= 9) { printf NU9F "\n"; } if($n_curr_cols >= 10) { printf NU10F "\n"; } } # for $n if($n_curr_cols >= 1) { close(NU1F); } if($n_curr_cols >= 2) { close(NU2F); } if($n_curr_cols >= 3) { close(NU3F); } if($n_curr_cols >= 4) { close(NU4F); } if($n_curr_cols >= 5) { close(NU5F); } if($n_curr_cols >= 6) { close(NU6F); } if($n_curr_cols >= 7) { close(NU7F); } if($n_curr_cols >= 8) { close(NU8F); } if($n_curr_cols >= 9) { close(NU9F); } if($n_curr_cols >= 10) { close(NU10F); } $n_col_num += $n_curr_cols; $n_cols -= $n_curr_cols; #skip 2 lines to take next batch $line = ; $line = ; $first_pass = 0; } # while close(DMOLOUT);