2"""OpenMD affine scaling transform
4Takes an OpenMD file and scales both the periodic box and the
5coordinates of all StuntDoubles in the system by the same amount.
7You can either specify a new volume scaling for isotropic scaling, or
8specify one (or more) of the coordinates for non-isotropic scaling.
13 -h, --help show this help
14 -m, --meta-data=... use specified meta-data (.omd, .eor) file
15 -o, --output-file=... use specified output file
16 -x, --newX=... scale the system to a new x dimension
17 -y, --newY=... scale the system to a new y dimension
18 -z, --newZ=... scale the system to a new z dimension
19 -v, --newV=... scale the system to a new volume
22 affineScale -m lipidSystem.omd -o scaledSystem.omd -v 77000.0
26__author__ = "Dan Gezelter (gezelter@nd.edu)"
27__copyright__ = "Copyright (c) 2004-present The University of Notre Dame. All Rights Reserved."
52def readFile(mdFileName):
53 mdFile = open(mdFileName, 'r')
54 # Find OpenMD version info first
55 line = mdFile.readline()
57 if '<OOPSE version=' in line or '<OpenMD version=' in line:
60 line = mdFile.readline()
62 # Rewind file and find start of MetaData block
65 line = mdFile.readline()
66 print("Reading MetaData")
68 if '<MetaData>' in line:
71 line = mdFile.readline()
72 if '</MetaData>' in line:
76 line = mdFile.readline()
78 line = mdFile.readline()
79 print("Reading Snapshot")
81 if '<Snapshot>' in line:
82 line = mdFile.readline()
84 print("Reading FrameData")
85 if '<FrameData>' in line:
87 frameData.append(line)
89 line = line.replace("{","").replace("}","").replace("Hmat:","")
100 Hmat.append([Hxx, Hxy, Hxz])
101 Hmat.append([Hyx, Hyy, Hyz])
102 Hmat.append([Hzx, Hzy, Hzz])
103 BoxInv.append(1.0/Hxx)
104 BoxInv.append(1.0/Hyy)
105 BoxInv.append(1.0/Hzz)
106 line = mdFile.readline()
107 if '</FrameData>' in line:
108 frameData.append(line)
112 line = mdFile.readline()
114 if '<StuntDoubles>' in line:
115 line = mdFile.readline()
119 indices.append(myIndex)
129 p.append([0.0, 0.0, 0.0])
134 v.append([vx, vy, vz])
137 v.append([0.0, 0.0, 0.0])
143 q.append([qw, qx, qy, qz])
146 q.append([0.0, 0.0, 0.0, 0.0])
151 j.append([jx, jy, jz])
154 j.append([0.0, 0.0, 0.0])
155 wrap.append([0, 0, 0])
157 line = mdFile.readline()
158 if '</StuntDoubles>' in line:
161 line = mdFile.readline()
163 if '<SiteData>' in line:
164 print("Reading SiteData")
167 line = mdFile.readline()
168 siteData.append(line)
169 if '</SiteData>' in line:
174 line = mdFile.readline()
178def writeFile(outputFileName, repeatX, repeatY, repeatZ):
179 outputFile = open(outputFileName, 'w')
181 outputFile.write("<OpenMD version=2>\n");
183 print("Writing MetaData")
184 for metaline in metaData:
185 if 'nMol' in metaline:
186 metasplit = metaline.split()
187 nMol = float(metasplit[2].strip(';'))
188 newNmol = nMol * repeatX * repeatY * repeatZ
189 outputFile.write(' nMol = %10d;\n' % (newNmol))
191 outputFile.write(metaline)
193 print("Writing Snapshot")
194 outputFile.write(" <Snapshot>\n")
196 print("Writing FrameData")
197 for frameline in frameData:
198 if 'Hmat:' in frameline:
200 myH.append([repeatX * Hmat[0][0], repeatX * Hmat[0][1], repeatX * Hmat[0][2]])
201 myH.append([repeatY * Hmat[1][0], repeatY * Hmat[1][1], repeatY * Hmat[1][2]])
202 myH.append([repeatZ * Hmat[2][0], repeatZ * Hmat[2][1], repeatZ * Hmat[2][2]])
203 outputFile.write(" Hmat: {{ %.10g, %.10g, %.10g }, { %.10g, %.10g, %.10g }, { %.10g, %.10g, %.10g }}\n" % (myH[0][0], myH[0][1], myH[0][2], myH[1][0], myH[1][1], myH[1][2], myH[2][0], myH[2][1], myH[2][2]))
205 outputFile.write(frameline)
207 print("Writing StuntDoubles")
208 outputFile.write(" <StuntDoubles>\n")
210 #print(repeatX, repeatY, repeatZ)
212 deco = sorted([ (index, i) for i, index in enumerate(indices) ])
214 for index in range(len(deco)):
215 (index, i) = deco[index]
216 for ii in range(repeatX):
217 for jj in range(repeatY):
218 for kk in range(repeatZ):
220 myP.append(p[i][0] + ii*Hmat[0][0] + jj*Hmat[1][0] + kk*Hmat[2][0])
221 myP.append(p[i][1] + ii*Hmat[0][1] + jj*Hmat[1][1] + kk*Hmat[2][1])
222 myP.append(p[i][2] + ii*Hmat[0][2] + jj*Hmat[1][2] + kk*Hmat[2][2])
225 outputFile.write("%10d %7s %18.10g %18.10g %18.10g\n" % (whichSD, pvqj[i], myP[0], myP[1], myP[2]))
226 elif (pvqj[i] == 'pv'):
227 outputFile.write("%10d %7s %18.10g %18.10g %18.10g %13e %13e %13e\n" % (whichSD, pvqj[i], myP[0], myP[1], myP[2], v[i][0], v[i][1], v[i][2]))
228 elif (pvqj[i] == 'pq'):
229 outputFile.write("%10d %7s %18.10g %18.10g %18.10g %13e %13e %13e %13e\n" % (whichSD, pvqj[i], myP[0], myP[1], myP[2], q[i][0], q[i][1], q[i][2], q[i][3]))
230 elif (pvqj[i] == 'pvqj'):
231 outputFile.write("%10d %7s %18.10g %18.10g %18.10g %13e %13e %13e %13e %13e %13e %13e %13e %13e %13e\n" % (whichSD, pvqj[i], myP[0], myP[1], myP[2], v[i][0], v[i][1], v[i][2], q[i][0], q[i][1], q[i][2], q[i][3], j[i][0], j[i][1], j[i][2]))
232 whichSD = whichSD + 1
233 outputFile.write(" </StuntDoubles>\n")
235 print("Writing SiteData")
236 outputFile.write(" <SiteData>\n")
237 for line in siteData:
238 outputFile.write(line)
240 print("Writing finished")
241 outputFile.write(" </Snapshot>\n")
242 outputFile.write("</OpenMD>\n")
247 return math.floor(x + 0.5)
249 return math.ceil(x - 0.5)
251def wrapVector(myVect):
252 scaled = [0.0, 0.0, 0.0]
253 wrappingNumber = [0, 0, 0]
255 scaled[i] = myVect[i] * BoxInv[i]
256 wrappingNumber[i] = roundMe(scaled[i])
257 scaled[i] = scaled[i] - wrappingNumber[i]
258 myVect[i] = scaled[i] * Hmat[i][i]
259 return myVect, wrappingNumber
263 for i in range(len(L1)):
264 myDot = myDot + L1[i]*L2[i]
269 myLength = math.sqrt(dot(L1, L1))
270 for i in range(len(L1)):
271 L2.append(L1[i] / myLength)
275 # don't call this with anything other than length 3 lists please
278 L3[0] = L1[1]*L2[2] - L1[2]*L2[1]
279 L3[1] = L1[2]*L2[0] - L1[0]*L2[2]
280 L3[2] = L1[0]*L2[1] - L1[1]*L2[0]
284 for i in range(len(indices)):
289 p[i], wrap[i] = wrapVector(dpos)
291def scaleBox(scaleX, scaleY, scaleZ):
293 Hmat[0][i] = scaleX * Hmat[0][i]
295 Hmat[1][i] = scaleY * Hmat[1][i]
297 Hmat[2][i] = scaleZ * Hmat[2][i]
299 BoxInv[i] = 1.0/Hmat[i][i]
301def scaleCoordinates(scaleX, scaleY, scaleZ):
302 for i in range(len(indices)):
303 p[i][0] = p[i][0]*scaleX + wrap[i][0] * Hmat[0][0]
304 p[i][1] = p[i][1]*scaleY + wrap[i][1] * Hmat[1][1]
305 p[i][2] = p[i][2]*scaleZ + wrap[i][2] * Hmat[2][2]
309 _haveOutputFileName = 0
311 opts, args = getopt.getopt(argv, "hm:o:x:y:z:v:", ["help", "meta-data=", "output-file=", "newX=", "newY=", "newZ=", "newV="])
312 except getopt.GetoptError:
319 for opt, arg in opts:
320 if opt in ("-h", "--help"):
323 elif opt in ("-m", "--meta-data"):
326 elif opt in ("-o", "--output-file"):
328 _haveOutputFileName = 1
329 if opt in ("-x", "--newX"):
332 elif opt in ("-y", "--newY"):
335 elif opt in ("-z", "--newZ"):
338 elif opt in ("-v", "--newV"):
342 if (_haveMDFileName != 1):
344 print("No meta-data file was specified")
346 if (_haveOutputFileName != 1):
348 print("No output file was specified")
351 if not (doV or doX or doY or doZ):
353 print("no scaling options given. Nothing to do!")
356 if doV and (doX or doY or doZ):
358 print("-v is mutually exclusive with any of the -x, -y, and -z options")
368 scaleX = newX / Hmat[0][0]
370 scaleY = newY / Hmat[1][1]
372 scaleZ = newZ / Hmat[2][2]
375 oldV = Hmat[0][0] * Hmat[1][1] * Hmat[2][2]
376 scaleX = pow(newV/oldV, 1.0/3.0)
381 scaleBox(scaleX, scaleY, scaleZ)
382 scaleCoordinates(scaleX, scaleY, scaleZ)
383 writeFile(outputFileName, 1, 1, 1)
385if __name__ == "__main__":
386 if len(sys.argv) == 1: