1 | #!@PERL@ -w
|
---|
2 | #
|
---|
3 | # In the course of numerous fragment calculations with breaks and interrupts in between, there might
|
---|
4 | # arise some hickhack and mess with the sequence of the calculations. BOSSMatcher compares the nuclear
|
---|
5 | # coordinates given in the config files of each fragment with those written out in the forces file of
|
---|
6 | # ESPACK and prints which fragments do not match with their config file coordinates.
|
---|
7 |
|
---|
8 | use strict;
|
---|
9 |
|
---|
10 | use Getopt::Long;
|
---|
11 | use File::Copy;
|
---|
12 |
|
---|
13 | my ($Help, $Prefix, $Inputdir);
|
---|
14 |
|
---|
15 | GetOptions("help" => \$Help,
|
---|
16 | "prefix=s", => \$Prefix,
|
---|
17 | "inputdir=s" => \$Inputdir);
|
---|
18 |
|
---|
19 | if ($Help) { usage(); }
|
---|
20 |
|
---|
21 | sub usage {
|
---|
22 | print STDERR <<"EOF";
|
---|
23 | Usage: $0 [OPTIONS]
|
---|
24 | compares the nuclear
|
---|
25 | coordinates given in the config files of each fragment with those written out in the forces file of
|
---|
26 | ESPACK and prints which fragments do not match with their config file coordinates.
|
---|
27 | --prefix <prefix> prefix in front of .forces.all and .energy.all
|
---|
28 | --inputdir <inputdir> read data from this directory
|
---|
29 | --help this help
|
---|
30 | EOF
|
---|
31 | exit 1;
|
---|
32 | }
|
---|
33 |
|
---|
34 | if ((!defined $Inputdir) || (!defined $Prefix)) {
|
---|
35 | print "Inputdir and/or Prefix not specified! See --help.\n";
|
---|
36 | exit 1;
|
---|
37 | }
|
---|
38 |
|
---|
39 | # 1. find the digits of the fragment number
|
---|
40 | print "Finding the correct number of digits.\n";
|
---|
41 | my $digits="";
|
---|
42 | my $digit=0;
|
---|
43 | my $file;
|
---|
44 | do {
|
---|
45 | $digits=$digits."0"; # add a zero
|
---|
46 | $digit++;
|
---|
47 | $file=$Inputdir."/BondFragment".$digits.".conf";
|
---|
48 | print "Looking for $file ... \n";
|
---|
49 | } while ((! -e $file) && ($digit < 10));
|
---|
50 |
|
---|
51 | if (!($digit < 10)) {
|
---|
52 | print "In the directory specified no initial fragment config file was found, typo?\n";
|
---|
53 | exit 1;
|
---|
54 | }
|
---|
55 |
|
---|
56 | # 2. loop over all fragments and parse config and forces file, comparing the coordinates
|
---|
57 |
|
---|
58 | my $number=0;
|
---|
59 | my $failures=0;
|
---|
60 | my $failflag=0;
|
---|
61 | my @lines;
|
---|
62 | my $i;
|
---|
63 | my @configcoordinates;
|
---|
64 | my @forcecoordinates;
|
---|
65 | my @line;
|
---|
66 | my $IsAngstroem=0;
|
---|
67 | do {
|
---|
68 | @configcoordinates = ();
|
---|
69 | @forcecoordinates = ();
|
---|
70 | $failflag=0;
|
---|
71 | $file = sprintf("%s%0${digit}d%s", $Inputdir."/BondFragment",$number,".conf");
|
---|
72 | if (-e $file) {
|
---|
73 | print "Scanning $file ... ";
|
---|
74 | # 2a. parse the config file
|
---|
75 | open(CONFIG, $file);
|
---|
76 | @lines = <CONFIG>;
|
---|
77 | for ($i=0; $i < scalar(@lines); $i++) {
|
---|
78 | if (${lines[$i]} =~ /Ion_Type._/) {
|
---|
79 | @line = split(/[ \t]+/,${lines[$i]});
|
---|
80 | my @coord = (${line[1]}, ${line[2]}, ${line[3]});
|
---|
81 | push(@configcoordinates, \@coord);
|
---|
82 | }
|
---|
83 | if (${lines[$i]} =~ /IsAngstroem/) {
|
---|
84 | @line = split(/[ \t]+/,${lines[$i]});
|
---|
85 | if (${line[1]} == 0) {
|
---|
86 | $IsAngstroem = 1;
|
---|
87 | } else {
|
---|
88 | $IsAngstroem = 1.8897261;
|
---|
89 | }
|
---|
90 | #print "Found IsAngstroem ".${line[1]}.", setting to $IsAngstroem.\n";
|
---|
91 | }
|
---|
92 | }
|
---|
93 | close(CONFIG);
|
---|
94 | # 2b. parse the pcp.forces.file
|
---|
95 | $file = sprintf("%s%0${digit}d%s", $Inputdir."/BondFragment",$number,"/${Prefix}.forces.all");
|
---|
96 | if (-e $file) {
|
---|
97 | open(FORCES, $file);
|
---|
98 | @lines = <FORCES>; # read file into buffer
|
---|
99 | for ($i=1; $i < (scalar(@lines)-1); $i++) { # skip first and last line
|
---|
100 | @line = split(/[ \t]+/,${lines[$i]});
|
---|
101 | my @coord = (${line[2]}, ${line[3]}, ${line[4]});
|
---|
102 | push(@forcecoordinates, \@coord);
|
---|
103 | }
|
---|
104 | close(FORCES);
|
---|
105 | } else {
|
---|
106 | $failflag = 1;
|
---|
107 | }
|
---|
108 | # 2c. compare both coordinates and sum up the deviation
|
---|
109 | if (scalar(@configcoordinates) != scalar(@forcecoordinates) ) {
|
---|
110 | $failflag = 1;
|
---|
111 | print "mismatch in number of ions ".scalar(@configcoordinates)." vs. ".scalar(@forcecoordinates)." ... ";
|
---|
112 | } else {
|
---|
113 | #print "match in number of ions ".scalar(@configcoordinates)." vs. ".scalar(@forcecoordinates)." ... ";
|
---|
114 | }
|
---|
115 | my $forces;
|
---|
116 | my $configs;
|
---|
117 | my $error = 0;
|
---|
118 | do {
|
---|
119 | $forces = pop(@forcecoordinates);
|
---|
120 | $configs = pop(@configcoordinates);
|
---|
121 | my $currenterror = 0;
|
---|
122 | for ($i=0;$i<3;$i++) {
|
---|
123 | @$configs[$i] *= $IsAngstroem;
|
---|
124 | $currenterror += (@$configs[$i]-@$forces[$i])*(@$configs[$i]-@$forces[$i]);
|
---|
125 | }
|
---|
126 | $error += sqrt($currenterror);
|
---|
127 | #print "$currenterror ";
|
---|
128 | } while (scalar(@configcoordinates) > 0);
|
---|
129 | print "deviation: ";
|
---|
130 | if ($error > 1e-4) {
|
---|
131 | $failflag=1;
|
---|
132 | print "$error ";
|
---|
133 | } else {
|
---|
134 | printf "<1e-4 ";
|
---|
135 | }
|
---|
136 |
|
---|
137 | # 2d. print final status
|
---|
138 | if ($failflag) {
|
---|
139 | $failures++;
|
---|
140 | print "failed.\n";
|
---|
141 | } else {
|
---|
142 | print "done.\n";
|
---|
143 | }
|
---|
144 | $number++;
|
---|
145 | } else {
|
---|
146 | print "Last config file nr. $number reached, done.\n";
|
---|
147 | }
|
---|
148 | } while (-e $file);
|
---|
149 |
|
---|
150 | # 3. finish
|
---|
151 | print "Done checking, I noticed $failures failure(s).\n";
|
---|
152 | exit 0
|
---|