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

# User Rev Content
1 gezelter 1646 #!@PYTHON_EXECUTABLE@
2 cpuglis 1189 """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 gezelter 1442 __version__ = "$Revision$"
22     __date__ = "$Date$"
23 cpuglis 1189 __copyright__ = "Copyright (c) 2006 by the University of Notre Dame"
24 gezelter 1390 __license__ = "OpenMD"
25 cpuglis 1189
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 gezelter 1370 surfaceSet = set([-1])
56 cpuglis 1189
57    
58    
59     def usage():
60     print __doc__
61    
62    
63     def readFile(mdFileName):
64     mdFile = open(mdFileName, 'r')
65 gezelter 1390 # Find OpenMD version info first
66 cpuglis 1189 line = mdFile.readline()
67     while 1:
68 gezelter 1390 if '<OOPSE version=' in line or '<OpenMD version=' in line:
69     OpenMDversion = line
70 cpuglis 1189 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 gezelter 1390 outputFile.write("<OpenMD version=1>\n");
164 cpuglis 1189
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 gezelter 1390 outputFile.write("</OpenMD>\n")
183 cpuglis 1189 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 gezelter 1370 if (len(neighbors[i]) < 4):
249 cpuglis 1189 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 gezelter 1370 # pick unreasonable start values (that don't match surface atom
290     # unreasonable values)
291 cpuglis 1189 acceptor = -10
292    
293     for i in range(50000):
294     #while (acceptor != origPoint):
295 gezelter 1370 myNeighbors = set(neighbors[donor])
296 cpuglis 1189
297     # can't pick a proton choice from one of my current protons:
298 gezelter 1370 badChoices = set(DonatingTo[donor]).union(set(OldDonor[acceptor]))
299 cpuglis 1189 # can't send a proton back to guy who sent one to me (no give-backs):
300 gezelter 1370 #badChoices.add(set(OldDonor[acceptor]))
301 cpuglis 1189 # 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 gezelter 1370
310     if (len(myNeighbors.difference(badChoices)) != 0):
311     acceptor = random.choice(list(myNeighbors.difference(badChoices)))
312     else:
313     acceptor = -1
314    
315 cpuglis 1189 DonatingTo[donor].append(acceptor)
316 gezelter 1370
317 cpuglis 1189 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 gezelter 1370 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 cpuglis 1189 else:
385 gezelter 1370 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 cpuglis 1189
403    
404 gezelter 1370 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 cpuglis 1189
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 gezelter 1390 # RotMat to Quat code is out of OpenMD's SquareMatrix3.hpp code:
434 cpuglis 1189
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 gezelter 1370 if (Dipole > 40 or Dipole < -40):
478 cpuglis 1189 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