ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/applications/utilities/waterRotator
Revision: 1646
Committed: Mon Sep 26 13:30:00 2011 UTC (13 years, 7 months ago) by gezelter
File size: 17372 byte(s)
Log Message:
update for cmake build and install

File Contents

# Content
1 #!@PYTHON_EXECUTABLE@
2 """Water Quaternion Sampler
3
4 Samples water orientations from a list of known good
5 orientations
6
7 Usage: waterRotator
8
9 Options:
10 -h, --help show this help
11 -m, --meta-data=... use specified meta-data (.md) file
12 -o, --output-file=... use specified output (.md) file
13
14
15 Example:
16 waterRotator -m basal.md -o basal.new.md
17
18 """
19
20 __author__ = "Dan Gezelter (gezelter@nd.edu)"
21 __version__ = "$Revision$"
22 __date__ = "$Date$"
23 __copyright__ = "Copyright (c) 2006 by the University of Notre Dame"
24 __license__ = "OpenMD"
25
26 import sys
27 import getopt
28 import string
29 import math
30 import random
31
32 _haveMDFileName = 0
33 _haveOutputFileName = 0
34
35 metaData = []
36 frameData = []
37 positions = []
38 velocities = []
39 quaternions = []
40 angVels = []
41 indices = []
42 neighbors = []
43 DonatingTo = []
44 AcceptingFrom = []
45 OldDonor = []
46 Hmat = []
47 BoxInv = []
48 #Hmat = zeros([3,3],Float)
49 #BoxInv = zeros([3],Float)
50 H1vects = []
51 H2vects = []
52 DipoleVects = []
53 allAcceptors = []
54 availableneighbs = []
55 surfaceSet = set([-1])
56
57
58
59 def usage():
60 print __doc__
61
62
63 def readFile(mdFileName):
64 mdFile = open(mdFileName, 'r')
65 # Find OpenMD version info first
66 line = mdFile.readline()
67 while 1:
68 if '<OOPSE version=' in line or '<OpenMD version=' in line:
69 OpenMDversion = line
70 break
71 line = mdFile.readline()
72
73 # Rewind file and find start of MetaData block
74
75 mdFile.seek(0)
76 line = mdFile.readline()
77 print "reading MetaData"
78 while 1:
79 if '<MetaData>' in line:
80 while 2:
81 metaData.append(line)
82 line = mdFile.readline()
83 if '</MetaData>' in line:
84 metaData.append(line)
85 break
86 break
87 line = mdFile.readline()
88
89 mdFile.seek(0)
90 print "reading Snapshot"
91 line = mdFile.readline()
92 while 1:
93 if '<Snapshot>' in line:
94 line = mdFile.readline()
95 while 1:
96 print "reading FrameData"
97 if '<FrameData>' in line:
98 while 2:
99 frameData.append(line)
100 if 'Hmat:' in line:
101 L = line.split()
102 Hxx = float(L[2].strip(','))
103 Hxy = float(L[3].strip(','))
104 Hxz = float(L[4].strip(','))
105 Hyx = float(L[7].strip(','))
106 Hyy = float(L[8].strip(','))
107 Hyz = float(L[9].strip(','))
108 Hzx = float(L[12].strip(','))
109 Hzy = float(L[13].strip(','))
110 Hzz = float(L[14].strip(','))
111 Hmat.append([Hxx, Hxy, Hxz])
112 Hmat.append([Hyx, Hyy, Hyz])
113 Hmat.append([Hzx, Hzy, Hzz])
114 print Hmat
115 BoxInv.append(1.0/Hxx)
116 BoxInv.append(1.0/Hyy)
117 BoxInv.append(1.0/Hzz)
118 print BoxInv
119 line = mdFile.readline()
120 if '</FrameData>' in line:
121 frameData.append(line)
122 break
123 break
124
125 line = mdFile.readline()
126 while 1:
127 if '<StuntDoubles>' in line:
128 line = mdFile.readline()
129 while 2:
130 L = line.split()
131 myIndex = int(L[0])
132 indices.append(myIndex)
133 pvqj = L[1]
134 x = float(L[2])
135 y = float(L[3])
136 z = float(L[4])
137 positions.append([x, y, z])
138 vx = float(L[5])
139 vy = float(L[6])
140 vz = float(L[7])
141 velocities.append([vx, vy, vz])
142 qw = float(L[8])
143 qx = float(L[9])
144 qy = float(L[10])
145 qz = float(L[11])
146 quaternions.append([qw, qx, qy, qz])
147 jx = float(L[12])
148 jy = float(L[13])
149 jz = float(L[14])
150 angVels.append([jx, jy, jz])
151 line = mdFile.readline()
152 if '</StuntDoubles>' in line:
153 break
154 break
155 line = mdFile.readline()
156 if not line: break
157
158 mdFile.close()
159
160 def writeFile(outputFileName):
161 outputFile = open(outputFileName, 'w')
162
163 outputFile.write("<OpenMD version=1>\n");
164
165 for metaline in metaData:
166 outputFile.write(metaline)
167
168 outputFile.write(" <Snapshot>\n")
169
170 for frameline in frameData:
171 outputFile.write(frameline)
172
173 outputFile.write(" <StuntDoubles>\n")
174
175 sdFormat = 'pvqj'
176 for i in range(len(indices)):
177
178 outputFile.write("%10d %7s %18.10g %18.10g %18.10g %13e %13e %13e %13e %13e %13e %13e %13e %13e %13e\n" % (indices[i], sdFormat, positions[i][0], positions[i][1], positions[i][2], velocities[i][0], velocities[i][1], velocities[i][2], quaternions[i][0], quaternions[i][1], quaternions[i][2], quaternions[i][3], angVels[i][0], angVels[i][1], angVels[i][2]))
179
180 outputFile.write(" </StuntDoubles>\n")
181 outputFile.write(" </Snapshot>\n")
182 outputFile.write("</OpenMD>\n")
183 outputFile.close()
184
185 def roundMe(x):
186 if (x >= 0.0):
187 return math.floor(x + 0.5)
188 else:
189 return math.ceil(x - 0.5)
190
191 def wrapVector(myVect):
192 scaled = [0.0, 0.0, 0.0]
193 for i in range(3):
194 scaled[i] = myVect[i] * BoxInv[i]
195 scaled[i] = scaled[i] - roundMe(scaled[i])
196 myVect[i] = scaled[i] * Hmat[i][i]
197 return myVect
198
199 def dot(L1, L2):
200 myDot = 0.0
201 for i in range(len(L1)):
202 myDot = myDot + L1[i]*L2[i]
203 return myDot
204
205 def normalize(L1):
206 L2 = []
207 myLength = math.sqrt(dot(L1, L1))
208 for i in range(len(L1)):
209 L2.append(L1[i] / myLength)
210 return L2
211
212 def cross(L1, L2):
213 # don't call this with anything other than length 3 lists please
214 # or you'll be sorry
215 L3 = [0.0, 0.0, 0.0]
216 L3[0] = L1[1]*L2[2] - L1[2]*L2[1]
217 L3[1] = L1[2]*L2[0] - L1[0]*L2[2]
218 L3[2] = L1[0]*L2[1] - L1[1]*L2[0]
219 return L3
220
221 def f(x):
222 return x
223
224 def findNeighbors():
225
226 for i in range(len(indices)):
227 neighbors.append(list())
228
229
230 for i in range(len(indices)-1):
231 iPos = positions[i]
232 for j in range(i+1, len(indices)):
233 jPos = positions[j]
234
235 dpos = [jPos[0] - iPos[0], jPos[1]-iPos[1], jPos[2]-iPos[2]]
236 dpos = wrapVector(dpos)
237 dist2 = dot(dpos,dpos)
238
239 if (dist2 < 9.0):
240 neighbors[i].append(j)
241 neighbors[j].append(i)
242
243 if (len(neighbors[i]) == 4):
244 break
245
246 surfaceCount = 0
247 for i in range(len(indices)):
248 if (len(neighbors[i]) < 4):
249 neighbors[i].append(-1)
250 surfaceCount = surfaceCount + 1
251
252 print "surfaceCount = %d" % surfaceCount
253
254 def randomizeProtons():
255
256 # do 10 proton bucket brigades:
257 for i in range(10):
258 origPoint = random.randint(0,len(indices))
259 protonBucketBrigade(origPoint)
260
261 # check to make sure everyone has a happy proton set:
262
263 for j in range(len(indices)):
264 if (len(DonatingTo[j]) != 2):
265 # print "first round to fix molecule %d" % j
266 protonBucketBrigade(j)
267
268 # check to make sure everyone has a happy proton set:
269
270 for j in range(len(indices)):
271 if (len(DonatingTo[j]) != 2):
272 print "second round to fix molecule %d" % j
273 protonBucketBrigade(j)
274
275 for j in range(len(indices)):
276 if (len(DonatingTo[j]) != 2):
277 print "unfilled proton donor list for molecule %d" % j
278
279
280
281 def protonBucketBrigade(origPoint):
282
283 for i in range(len(indices)):
284 DonatingTo.append(list())
285 AcceptingFrom.append(list())
286 OldDonor.append(list())
287
288 donor = origPoint
289 # pick unreasonable start values (that don't match surface atom
290 # unreasonable values)
291 acceptor = -10
292
293 for i in range(50000):
294 #while (acceptor != origPoint):
295 myNeighbors = set(neighbors[donor])
296
297 # can't pick a proton choice from one of my current protons:
298 badChoices = set(DonatingTo[donor]).union(set(OldDonor[acceptor]))
299 # can't send a proton back to guy who sent one to me (no give-backs):
300 #badChoices.add(set(OldDonor[acceptor]))
301 # can't send a proton to anyone who is already taking 2:
302 for j in myNeighbors.difference(surfaceSet):
303 if (len(AcceptingFrom[j]) == 2):
304 badChoices.add(j)
305
306 nDonors = len(DonatingTo[donor])
307
308 if (nDonors <= 1):
309
310 if (len(myNeighbors.difference(badChoices)) != 0):
311 acceptor = random.choice(list(myNeighbors.difference(badChoices)))
312 else:
313 acceptor = -1
314
315 DonatingTo[donor].append(acceptor)
316
317 if (acceptor != -1):
318 AcceptingFrom[acceptor].append(donor)
319 OldDonor[acceptor].append(donor)
320 elif (nDonors == 2):
321 acceptor = random.choice(DonatingTo[donor])
322 else:
323 print "Whoah! How'd we get here?"
324
325 donor = acceptor
326 if (acceptor == -1):
327 # surface atoms all have a -1 neighbor, but that's OK. A proton
328 # is allowed to point out of the surface, but it does break the
329 # proton chain letter
330 # print "surface atom found, starting over from origPoint"
331 donor = origPoint
332 # break
333
334 def computeQuats():
335
336 for i in range(len(indices)):
337 DonatingTo.append(list())
338 AcceptingFrom.append(list())
339 OldDonor.append(list())
340 # print "Computing Quaternions"
341 ux = [0.0, 0.0, 0.0]
342 uy = [0.0, 0.0, 0.0]
343 uz = [0.0, 0.0, 0.0]
344 RotMat = [ux, uy, uz]
345 totalDipole = [0.0, 0.0, 0.0]
346 for i in range(len(indices)):
347 # print "doing quats for molecule %d" % i
348 # print "Dlen = %d " % len(DonatingTo[i])
349 # print DonatingTo[i]
350
351
352 myPos = positions[i]
353
354 acceptor1 = DonatingTo[i][0]
355 acceptor2 = DonatingTo[i][1]
356 if (acceptor1 == -1 and acceptor2 == -1):
357 donor1 = AcceptingFrom[i][0]
358 donor2 = AcceptingFrom[i][1]
359 npos = positions[donor1]
360 apos1 = [npos[0] - myPos[0], npos[1] - myPos[1], npos[2] - myPos[2]]
361 apos1 = wrapVector(apos1)
362 npos = positions[donor2]
363 apos2 = [npos[0] - myPos[0], npos[1] - myPos[1], npos[2] - myPos[2]]
364 apos2 = wrapVector(apos2)
365 tempX = [0.0, 0.0, 0.0]
366 tempY = [0.0, 0.0, 0.0]
367 tempZ = [0.0, 0.0, 0.0]
368 tempZ[0] = 0.5*(apos1[0] + apos2[0])
369 tempZ[1] = 0.5*(apos1[1] + apos2[1])
370 tempZ[2] = 0.5*(apos1[2] + apos2[2])
371 tempX[0] = (apos2[0] - apos1[0])
372 tempX[1] = (apos2[1] - apos1[1])
373 tempX[2] = (apos2[2] - apos1[2])
374 tempZ = normalize(tempZ)
375 tempX = normalize(tempX)
376 tempY = cross(tempX, tempZ)
377 dpos1[0] = tempZ[0] - 0.5*tempY[0]
378 dpos1[1] = tempZ[1] - 0.5*tempY[1]
379 dpos1[2] = tempZ[2] - 0.5*tempY[2]
380 dpos2[0] = tempZ[0] + 0.5*tempY[0]
381 dpos2[1] = tempZ[1] + 0.5*tempY[1]
382 dpos2[2] = tempZ[2] + 0.5*tempY[2]
383
384 else:
385 if (acceptor1 == -1):
386 tempVec = [0.0, 0.0, 0.0]
387 for j in range(3):
388 thisNeighbor = neighbors[i][j]
389 npos = positions[thisNeighbor]
390 npos1 = [npos[0] - myPos[0], npos[1] - myPos[1], npos[2] - myPos[2]]
391 npos1 = wrapVector(npos1)
392 tempVec[0] = tempVec[0] + npos1[0]
393 tempVec[1] = tempVec[1] + npos1[1]
394 tempVec[2] = tempVec[2] + npos1[2]
395 dpos1 = [-tempVec[0]/3.0, -tempVec[1]/3.0, -tempVec[2]/3.0]
396 dpos1 = normalize(dpos1)
397 else:
398 a1pos = positions[acceptor1]
399 dpos1 = [a1pos[0] - myPos[0], a1pos[1] - myPos[1], a1pos[2] - myPos[2]]
400 dpos1 = wrapVector(dpos1)
401 dpos1 = normalize(dpos1)
402
403
404 if (acceptor2 == -1):
405 tempVec = [0.0, 0.0, 0.0]
406 for j in range(3):
407 thisNeighbor = neighbors[i][j]
408 npos = positions[thisNeighbor]
409 npos1 = [npos[0] - myPos[0], npos[1] - myPos[1], npos[2] - myPos[2]]
410 npos1 = wrapVector(npos1)
411 tempVec[0] = tempVec[0] + npos1[0]
412 tempVec[1] = tempVec[1] + npos1[1]
413 tempVec[2] = tempVec[2] + npos1[2]
414 dpos2 = [-tempVec[0]/3.0, -tempVec[1]/3.0, -tempVec[2]/3.0]
415 dpos2 = normalize(dpos2)
416 else:
417 a2pos = positions[acceptor2]
418 dpos2 = [a2pos[0] - myPos[0], a2pos[1] - myPos[1], a2pos[2] - myPos[2]]
419 dpos2 = wrapVector(dpos2)
420 dpos2 = normalize(dpos2)
421
422 for j in range(3):
423 uz[j] = (dpos1[j] + dpos2[j])/2.0
424 uz = normalize(uz)
425 for j in range(3):
426 uy[j] = dpos2[j] - dpos1[j]
427 uy = normalize(uy)
428 ux = cross(uy, uz)
429 ux = normalize(ux)
430
431 q = [0.0, 0.0, 0.0, 0.0]
432
433 # RotMat to Quat code is out of OpenMD's SquareMatrix3.hpp code:
434
435 RotMat[0] = ux
436 RotMat[1] = uy
437 RotMat[2] = uz
438
439 t = RotMat[0][0] + RotMat[1][1] + RotMat[2][2] + 1.0
440
441 if( t > 1e-6 ):
442 s = 0.5 / math.sqrt( t )
443 q[0] = 0.25 / s
444 q[1] = (RotMat[1][2] - RotMat[2][1]) * s
445 q[2] = (RotMat[2][0] - RotMat[0][2]) * s
446 q[3] = (RotMat[0][1] - RotMat[1][0]) * s
447 else:
448 ad1 = RotMat[0][0]
449 ad2 = RotMat[1][1]
450 ad3 = RotMat[2][2]
451
452 if( ad1 >= ad2 and ad1 >= ad3 ):
453 s = 0.5 / math.sqrt( 1.0 + RotMat[0][0] - RotMat[1][1] - RotMat[2][2] )
454 q[0] = (RotMat[1][2] - RotMat[2][1]) * s
455 q[1] = 0.25 / s
456 q[2] = (RotMat[0][1] + RotMat[1][0]) * s
457 q[3] = (RotMat[0][2] + RotMat[2][0]) * s
458 elif ( ad2 >= ad1 and ad2 >= ad3 ):
459 s = 0.5 / math.sqrt( 1.0 + RotMat[1][1] - RotMat[0][0] - RotMat[2][2] )
460 q[0] = (RotMat[2][0] - RotMat[0][2] ) * s
461 q[1] = (RotMat[0][1] + RotMat[1][0]) * s
462 q[2] = 0.25 / s
463 q[3] = (RotMat[1][2] + RotMat[2][1]) * s
464 else:
465 s = 0.5 / math.sqrt( 1.0 + RotMat[2][2] - RotMat[0][0] - RotMat[1][1] )
466 q[0] = (RotMat[0][1] - RotMat[1][0]) * s
467 q[1] = (RotMat[0][2] + RotMat[2][0]) * s
468 q[2] = (RotMat[1][2] + RotMat[2][1]) * s
469 q[3] = 0.25 / s
470
471 quaternions[i] = q
472 totalDipole = [totalDipole[0] + uz[0], totalDipole[1] + uz[1], totalDipole[2] + uz[2]]
473 totalDipole = [-totalDipole[0], -totalDipole[1], -totalDipole[2]]
474 print totalDipole
475 Dipole = math.sqrt(dot(totalDipole, totalDipole))
476 print 'Total Dipole Moment = %d' % Dipole
477 if (Dipole > 40 or Dipole < -40):
478 print "Bad Dipole, starting over"
479 for i in range(len(indices)):
480 del OldDonor[:]
481 del AcceptingFrom[:]
482 del DonatingTo[:]
483 # del badChoices[:]
484 randomizeProtons()
485 computeQuats()
486 else:
487 print "All Done!"
488
489
490
491 def main(argv):
492 try:
493 opts, args = getopt.getopt(argv, "hm:o:", ["help", "meta-data=", "output-file="])
494 except getopt.GetoptError:
495 usage()
496 sys.exit(2)
497 for opt, arg in opts:
498 if opt in ("-h", "--help"):
499 usage()
500 sys.exit()
501 elif opt in ("-m", "--meta-data"):
502 mdFileName = arg
503 global _haveMDFileName
504 _haveMDFileName = 1
505 elif opt in ("-o", "--output-file"):
506 outputFileName = arg
507 global _haveOutputFileName
508 _haveOutputFileName = 1
509 if (_haveMDFileName != 1):
510 usage()
511 print "No meta-data file was specified"
512 sys.exit()
513 if (_haveOutputFileName != 1):
514 usage()
515 print "No output file was specified"
516 sys.exit()
517 readFile(mdFileName)
518 # analyzeQuats()
519 findNeighbors()
520 randomizeProtons()
521 computeQuats()
522 writeFile(outputFileName)
523
524 if __name__ == "__main__":
525 if len(sys.argv) == 1:
526 usage()
527 sys.exit()
528 main(sys.argv[1:])

Properties

Name Value
svn:executable *
svn:keywords Author Id Revision Date