OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
solvator
1#!@PERL_EXECUTABLE@
2
3# program that reads in a water box and solute xyz (or pdb), merges the two systems, and
4# deletes overlapping molecules
5
6# author = "Chris Fennell
7# copyright = "Copyright (c) 2004-present The University of Notre Dame. All Rights Reserved."
8# license = "OpenMD"
9
10
11use Getopt::Std;
12
13$d2tolerance = 7.5625; #distance to start cutting
14$fileName = 'solvatedSystem.omd';
15$startSnap = 0;
16$startFrame = 0;
17$startStunts = 0;
18$startMeta = 0;
19$soluteName = 'SOLUTE';
20$nSolvent = 0;
21
22# get our options
23getopts('fhd:i:n:o:p:x:');
24
25# if we don't have a filename, drop to -h
26$opt_h = 'true' if $#ARGV != -1;
27
28# our option output
29if ($opt_h){
30 print "solvator: carves a solute void in an OpenMD water box\n\n";
31 print "usage: solvator [-fh] [-d distance tolerance] [-i file name (solvent)]";
32 print " [-n solute name] [-px file name (solute)] [-o file name (output)]\n\n";
33 print " -f : include a flexible solute model description in the output file rather\n";
34 print " than the rigid body solute model description\n";
35 print " -h : show this message\n\n";
36 print " -d real : overlap removal distance\n";
37 print " (default: 2.75 ang)\n";
38 print " -i char : solvent input file (OpenMD .omd file)\n";
39 print " -n char : name for the solute\n";
40 print " (default: SOLUTE)\n";
41 print " -o char : carved solvent output file (OpenMD .omd format)\n";
42 print " (default: 'solvatedSystem.omd')\n";
43 print " -p char : solute input file (pdb)\n";
44 print " -x char : solute input file (xyz)\n\n";
45 print "Example:\n";
46 die " solvator -i myWater.omd -p mySolute.pdb -o mySystem.omd\n";
47}
48
49# set some variables to be used in the code
50if (defined($opt_i)){
51 $solventName = $opt_i;
52} else {
53 die "Error: No solvent box specified\n Please select a solvent box using the -i flag\n";
54}
55
56$soluteFileName = $opt_p if defined($opt_p);
57$soluteFileName = $opt_x if defined($opt_x);
58$fileName = $opt_o if defined($opt_o);
59$soluteName = $opt_n if defined($opt_n);
60
61if (defined($opt_p) || defined($opt_x)){
62} else {
63 die "Error: No solute file specifed\n Please select a solute file with the -p or -x flags (pdb or xyz respectively)\n";
64}
65
66if (defined($opt_d)){
67 if ($opt_d =~ /^[0-9]/) {
68 $dval = $opt_d;
69 $d2tolerance = $dval*$dval;
70 } else {
71 die "Error: The '-d' value ($opt_d) is not a valid number\n Please choose a positive real # value\n";
72 }
73}
74
75# open the file writer
76open(OUTFILE, ">./$fileName") || die "Error: can't open file $fileName\n";
77
78# open and read the pdb or xyz file and get solute coordinates
79open(SOLUTEFILE, "$soluteFileName") || die "Error: Can't open file $soluteFileName\n";
80
81if (defined($opt_x)){
82 $headerLines = 2;
83 while (<SOLUTEFILE>){
84 if ($headerLines > 0){
85 $headerLines--;
86 } else {
87 chomp;
88 @line = split;
89 push(@solute_names, $line[0]);
90 push(@solute_x, $line[1]);
91 push(@solute_y, $line[2]);
92 push(@solute_z, $line[3]);
93 }
94 }
95}
96if (defined($opt_p)){
97 while (<SOLUTEFILE>){
98 chomp;
99 @line = split;
100 if ($line[0] eq 'ATOM'){
101 push(@solute_names, $line[2]);
102 push(@solute_x, $line[5]);
103 push(@solute_y, $line[6]);
104 push(@solute_z, $line[7]);
105 }
106 }
107}
108
109# remap solute to the center of the box
110$xSol = 0;
111$ySol = 0;
112$zSol = 0;
113for ($i=0; $i<=$#solute_x; $i++){
114 $xSol += $solute_x[$i];
115 $ySol += $solute_y[$i];
116 $zSol += $solute_z[$i];
117}
118$xSol /= $#solute_x + 1;
119$ySol /= $#solute_y + 1;
120$zSol /= $#solute_z + 1;
121for ($i=0; $i<=$#solute_x; $i++){
122 $solute_x[$i] -= $xSol;
123 $solute_y[$i] -= $ySol;
124 $solute_z[$i] -= $zSol;
125}
126
127if ($opt_f){
128 $soluteCount = $#solute_x + 1;
129} else {
130 $soluteCount = 1;
131}
132
133$solventCount = $soluteCount;
134# okay, let's open the solvent box and write a carved file
135open(SOLVENT, "$solventName") || die "Error: Can't open file $solventName\n";
136
137
138while (<SOLVENT>){
139 $startSnap = 0 if /\/Snapshot/;
140 $startFrame = 0 if /\/FrameData/;
141 $startStunts = 0 if /\/StuntDoubles/;
142 $startMeta = 0 if /\/MetaData/;
143
144 # save the MetaData lines
145 push(@metaLines, $_) if $startMeta == 1;
146
147 if ($startSnap == 1){
148 # save the frame data
149 push(@frameData, $_) if $startFrame == 1;
150 if (/Hmat/){
151 @line = split;
152 $hxx = $line[2];
153 chop($hxx);
154 $hyy = $line[8];
155 chop($hyy);
156 $hzz = $line[14];
157 }
158 if ($startStunts == 1){
159 @line = split;
160
161 # wrap positions back into the box
162 $x_val = $line[2] - ($hxx*round($line[2]/$hxx));
163 $y_val = $line[3] - ($hyy*round($line[3]/$hyy));
164 $z_val = $line[4] - ($hzz*round($line[4]/$hzz));
165
166 $saveFlag = 1;
167 for($i=0; $i<=$#solute_x; $i++){
168 $diff_x = $x_val - $solute_x[$i];
169 $diff_y = $y_val - $solute_y[$i];
170 $diff_z = $z_val - $solute_z[$i];
171 $dist2 = $diff_x*$diff_x + $diff_y*$diff_y + $diff_z*$diff_z;
172 if ($dist2 < $d2tolerance) {
173 $saveFlag = 0;
174 last;
175 }
176 }
177 if ($saveFlag == 1){
178 $saveLine = "$solventCount\t$line[1]\t$line[2]";
179 for ($i = 3; $i <= $#line; $i++){
180 $saveLine = join(' ', $saveLine, $line[$i]);
181 }
182 push(@goodSolventMolecules, $saveLine);
183 $solventCount++;
184 }
185 }
186 }
187 $startSnap = 1 if /Snapshot/;
188 $startFrame = 1 if /FrameData/;
189 $startStunts = 1 if /StuntDoubles/;
190 $startMeta = 1 if /MetaData/;
191 # check again since "/value" contains "value"
192 $startSnap = 0 if /\/Snapshot/;
193 $startFrame = 0 if /\/FrameData/;
194 $startStunts = 0 if /\/StuntDoubles/;
195 $startMeta = 0 if /\/MetaData/;
196}
197
198$nSolvent = $#goodSolventMolecules + 1;
199
200# write out the final file
201writeOutFile();
202print "The solvated system \"$fileName\" was generated.\n";
203
204
205sub writeOutFile {
206 # write out the header
207 print OUTFILE "<OpenMD version=1>\n";
208 printMetaData();
209 printFrameData();
210 print OUTFILE " <StuntDoubles>\n";
211 # now print out the atoms
212 if (defined($opt_f)){
213 for ($i=0; $i<=$#solute_x; $i++){
214 print OUTFILE "$i\tp\t$solute_x[$i] $solute_y[$i] $solute_z[$i]\n";
215 }
216 } else {
217 print OUTFILE "0\tpq\t0.0 0.0 0.0 1.0 0.0 0.0 0.0\n";
218 }
219 for ($i=0; $i<=$#goodSolventMolecules; $i++) {
220 print OUTFILE "$goodSolventMolecules[$i]\n";
221 }
222 print OUTFILE " </StuntDoubles>\n </Snapshot>\n</OpenMD>\n";
223}
224
225sub printMetaData() {
226 print OUTFILE " <MetaData>\n";
227
228 writeSoluteDescription();
229
230 for ($i = 0; $i<=$#metaLines; $i++) {
231 # reset the number of solvent molecules
232 if ($metaLines[$i] =~ /nMol/) {
233 $metaLines[$i] = " nMol = $nSolvent;\n";
234 }
235
236 print OUTFILE "$metaLines[$i]";
237 }
238
239 print OUTFILE " </MetaData>\n";
240}
241
242sub writeSoluteDescription {
243 # include a solute model description in the meta data region
244
245 print OUTFILE "\nmolecule{\n name = \"$soluteName\";\n\n";
246
247 if (defined($opt_f)) {
248 # for flexible solutes
249 for ($i=0; $i<=$#solute_x; $i++){
250 print OUTFILE " atom[$i]{\n type = \"$solute_names[$i]\";\n }\n";
251 }
252 print OUTFILE "}\n";
253 } else {
254 # the default is a rigid body solute
255 for ($i=0; $i<=$#solute_x; $i++){
256 print OUTFILE " atom[$i]{\n type = \"$solute_names[$i]\";\n position($solute_x[$i], $solute_y[$i], $solute_z[$i]);\n }\n";
257 }
258 print OUTFILE "\n rigidBody[0]{\n members(";
259 for ($i=0; $i<$#solute_x; $i++){
260 print OUTFILE "$i, ";
261 }
262 print OUTFILE "$#solute_x);\n }\n}\n";
263 }
264
265 # now back to the metaData output
266 print OUTFILE "\ncomponent{
267 type = \"$soluteName\";
268 nMol = 1;
269}\n";
270
271 print "The solute model definition was included in '$fileName'.\n";
272}
273
274sub printFrameData {
275 print OUTFILE " <Snapshot>\n <FrameData>\n";
276
277 for($i = 0; $i<=$#frameData; $i++) {
278 print OUTFILE "$frameData[$i]";
279 }
280
281 print OUTFILE " </FrameData>\n";
282}
283
284sub round {
285 return int( $_[0] + 0.5 * ($_[0] <=> 0) );
286}