4
# This is amber2lammps, a program written by Keir E. Novik to convert
5
# Amber files to Lammps files.
7
# Copyright 1999, 2000 Keir E. Novik; all rights reserved.
9
# Modified by Vikas Varshney, U Akron, 5 July 2005, as described in README
10
# Bug Fixed :Third argument in Dihedral Coeffs section is an integer - Ketan S Khare September 26, 2011
11
# Modified by Vikas Varshney, Oct 8, 2013 to include additional flags (Atomic_Number, Coulombic and van der Waals 1-4 factors which are included in newer vesions of .top and .crd files in amber12.
13
#============================================================
16
'Pop item I from list'
21
#============================================================
25
#--------------------------------------------------------
28
'Write out contents of self (intended for debugging)'
29
Name_list = self.__dict__.keys()
31
for Name in Name_list:
32
print Name + ':', self.__dict__[Name]
34
#--------------------------------------------------------
36
def Write_data(self, Basename, Item_list):
37
'Write the Lammps data to file (used by Write_Lammps)'
40
Filename = 'data.' + Basename
42
Dir_list = os.listdir('.')
44
while Filename in Dir_list:
45
Filename = 'data' + `i` + '.' + Basename
49
print 'Writing', Filename + '...',
53
F = open(Filename, 'w')
54
except IOError, Detail:
55
print '(error:', Detail[1] + '!)'
59
F.writelines(Item_list)
60
except IOError, Detail:
61
print '(error:', Detail[1] + '!)'
68
#--------------------------------------------------------
70
def Write_Lammps(self, Basename):
71
'Write the Lammps data file, ignoring blank sections'
75
L.append('LAMMPS data file for ' + self.name + '\n\n')
77
L.append(`self.atoms` + ' atoms\n')
78
L.append(`self.bonds` + ' bonds\n')
79
L.append(`self.angles` + ' angles\n')
80
L.append(`self.dihedrals` + ' dihedrals\n')
81
L.append(`self.impropers` + ' impropers\n\n')
83
L.append(`self.atom_types` + ' atom types\n')
85
L.append(`self.bond_types` + ' bond types\n')
87
L.append(`self.angle_types` + ' angle types\n')
88
if self.dihedrals > 0:
89
L.append(`self.dihedral_types` + ' dihedral types\n')
92
L.append(`self.xlo` + ' ' + `self.xhi` + ' xlo xhi\n')
93
L.append(`self.ylo` + ' ' + `self.yhi` + ' ylo yhi\n')
94
L.append(`self.zlo` + ' ' + `self.zhi` + ' zlo zhi\n\n')
96
if self.atom_types != 0:
97
L.append('Masses\n\n')
98
for i in range(self.atom_types):
99
L.append(`i+1` + ' ' + `self.Masses[i]` + '\n')
102
L.append('Pair Coeffs\n\n')
103
for i in range(self.atom_types):
105
for j in range(len(self.Nonbond_Coeffs[0])):
106
L.append(' ' + `self.Nonbond_Coeffs[i][j]`)
110
if self.bonds != 0 and self.bond_types != 0:
111
L.append('Bond Coeffs\n\n')
112
for i in range(self.bond_types):
114
for j in range(len(self.Bond_Coeffs[0])):
115
L.append(' ' + `self.Bond_Coeffs[i][j]`)
119
if self.angles != 0 and self.angle_types != 0:
120
L.append('Angle Coeffs\n\n')
121
for i in range(self.angle_types):
123
for j in range(len(self.Angle_Coeffs[0])):
124
L.append(' ' + `self.Angle_Coeffs[i][j]`)
128
if self.dihedrals != 0 and self.dihedral_types != 0:
129
L.append('Dihedral Coeffs\n\n')
130
for i in range(self.dihedral_types):
132
for j in range(len(self.Dihedral_Coeffs[0])):
133
L.append(' ' + `self.Dihedral_Coeffs[i][j]`)
138
L.append('Atoms\n\n')
139
for i in range(self.atoms):
141
for j in range(len(self.Atoms[0])):
142
L.append(' ' + `self.Atoms[i][j]`)
146
if self.bonds != 0 and self.bond_types != 0:
147
L.append('Bonds\n\n')
148
for i in range(self.bonds):
150
for j in range(len(self.Bonds[0])):
151
L.append(' ' + `self.Bonds[i][j]`)
155
if self.angles != 0 and self.angle_types != 0:
156
L.append('Angles\n\n')
157
for i in range(self.angles):
159
for j in range(len(self.Angles[0])):
160
L.append(' ' + `self.Angles[i][j]`)
164
if self.dihedrals != 0 and self.dihedral_types != 0:
165
L.append('Dihedrals\n\n')
166
for i in range(self.dihedrals):
168
for j in range(len(self.Dihedrals[0])):
169
L.append(' ' + `self.Dihedrals[i][j]`)
173
self.Write_data(Basename, L)
175
#============================================================
179
'Initialise the Amber class'
183
#--------------------------------------------------------
186
'Write out contents of self (intended for debugging)'
187
Name_list = self.__dict__.keys()
189
for Name in Name_list:
190
print Name + ':', self.__dict__[Name]
192
#--------------------------------------------------------
194
def Coerce_to_Lammps(self):
195
'Return the Amber data converted to Lammps format'
199
if self.CRD_is_read and self.TOP_is_read:
201
print 'Converting...',
205
l.bonds = self.NBONH + self.MBONA
206
l.angles = self.NTHETH + self.MTHETA
207
l.dihedrals = self.NPHIH + self.MPHIA
209
l.atom_types = self.NTYPES
210
l.bond_types = self.NUMBND
211
l.angle_types = self.NUMANG
212
l.dihedral_types = self.NPTRA
215
if self.__dict__.has_key('BOX'):
222
if (l.xlo > min(self.X)) or (l.xhi < max(self.X)) or \
223
(l.ylo > min(self.Y)) or (l.yhi < max(self.Y)) or \
224
(l.zlo > min(self.Z)) or (l.zhi < max(self.Z)):
225
# Vikas Modification: Disabling Shifting. This means I am intend to send exact coordinates of each atom and let LAMMPS
226
# take care of imaging into periodic image cells. If one wants to shift all atoms in the periodic box,
227
# please uncomment the below 2 lines.
228
print '(warning: Currently not shifting the atoms to the periodic box)'
231
print '(warning: Guessing at periodic box!)',
239
# This doesn't check duplicate values
241
for i in range(l.atom_types):
243
for i in range(self.NATOM):
244
l.Masses[self.IAC[i] - 1] = self.AMASS[i]
246
l.Nonbond_Coeffs = []
247
for i in range(self.NTYPES):
248
l.Nonbond_Coeffs.append([0,0])
249
for i in range(self.NTYPES):
250
j = self.ICO[i * (self.NTYPES + 1)] - 1
251
if self.CN1[j] == 0.0:
252
l.Nonbond_Coeffs[i][0] = 0.0
254
l.Nonbond_Coeffs[i][0] = \
255
0.25 * (self.CN2[j])**2 / self.CN1[j]
256
if self.CN2[j] == 0.0:
257
l.Nonbond_Coeffs[i][1] = 0.0
259
l.Nonbond_Coeffs[i][1] = \
260
(self.CN1[j] / self.CN2[j])**(1.0/6.0)
263
for i in range(self.NUMBND):
264
l.Bond_Coeffs.append([0,0])
265
for i in range(self.NUMBND):
266
l.Bond_Coeffs[i][0] = self.RK[i]
267
l.Bond_Coeffs[i][1] = self.REQ[i]
270
for i in range(self.NUMANG):
271
l.Angle_Coeffs.append([0,0])
272
for i in range(self.NUMANG):
273
l.Angle_Coeffs[i][0] = self.TK[i]
274
l.Angle_Coeffs[i][1] = (180/math.pi) * self.TEQ[i]
276
l.Dihedral_Coeffs = []
277
for i in range(self.NPTRA):
278
l.Dihedral_Coeffs.append([0,0,0])
279
for i in range(self.NPTRA):
280
l.Dihedral_Coeffs[i][0] = self.PK[i]
281
if self.PHASE[i] == 0:
282
l.Dihedral_Coeffs[i][1] = 1
284
l.Dihedral_Coeffs[i][1] = -1
285
l.Dihedral_Coeffs[i][2] = int(self.PN[i])
288
for i in range(self.NATOM):
305
l.Atoms.append([0, self.IAC[i], self.CHRG[i]/18.2223, \
309
for i in range(l.bonds):
310
l.Bonds.append([0,0,0])
311
for i in range(self.NBONH):
312
l.Bonds[i][0] = self.ICBH[i]
313
l.Bonds[i][1] = abs(self.IBH[i])/3 + 1
314
l.Bonds[i][2] = abs(self.JBH[i])/3 + 1
315
for i in range(self.NBONA):
316
l.Bonds[self.NBONH + i][0] = self.ICB[i]
317
l.Bonds[self.NBONH + i][1] = abs(self.IB[i])/3 + 1
318
l.Bonds[self.NBONH + i][2] = abs(self.JB[i])/3 + 1
321
for i in range(l.angles):
322
l.Angles.append([0,0,0,0])
323
for i in range(self.NTHETH):
324
l.Angles[i][0] = self.ICTH[i]
325
l.Angles[i][1] = abs(self.ITH[i])/3 + 1
326
l.Angles[i][2] = abs(self.JTH[i])/3 + 1
327
l.Angles[i][3] = abs(self.KTH[i])/3 + 1
328
for i in range(self.NTHETA):
329
l.Angles[self.NTHETH + i][0] = self.ICT[i]
330
l.Angles[self.NTHETH + i][1] = abs(self.IT[i])/3 + 1
331
l.Angles[self.NTHETH + i][2] = abs(self.JT[i])/3 + 1
332
l.Angles[self.NTHETH + i][3] = abs(self.KT[i])/3 + 1
335
for i in range(l.dihedrals):
336
l.Dihedrals.append([0,0,0,0,0])
337
for i in range(self.NPHIH):
338
l.Dihedrals[i][0] = self.ICPH[i]
339
l.Dihedrals[i][1] = abs(self.IPH[i])/3 + 1
340
l.Dihedrals[i][2] = abs(self.JPH[i])/3 + 1
341
l.Dihedrals[i][3] = abs(self.KPH[i])/3 + 1
342
l.Dihedrals[i][4] = abs(self.LPH[i])/3 + 1
343
for i in range(self.NPHIA):
344
l.Dihedrals[self.NPHIH + i][0] = self.ICP[i]
345
l.Dihedrals[self.NPHIH + i][1] = abs(self.IP[i])/3 + 1
346
l.Dihedrals[self.NPHIH + i][2] = abs(self.JP[i])/3 + 1
347
l.Dihedrals[self.NPHIH + i][3] = abs(self.KP[i])/3 + 1
348
l.Dihedrals[self.NPHIH + i][4] = abs(self.LP[i])/3 + 1
353
print '(Error: Not all the Amber data has been read!)'
355
#--------------------------------------------------------
357
def Read_data(self, Filename):
358
'Read the filename, returning a list of strings'
362
print 'Reading', Filename + '...',
367
except IOError, Detail:
368
print '(error:', Detail[1] + '!)'
372
Lines = F.readlines()
373
except IOError, Detail:
374
print '(error:', Detail[1] + '!)'
380
# If the first line is empty, use the Basename
381
if Filename[-4:] == '.crd':
382
if string.split(Lines[0]) == []: # This line corresponds to TITLE name in CRD file
383
Basename = Filename[:string.find(Filename, '.')]
384
Item_list = [Basename]
385
print 'Warning: Title not present... Assigning Basename as Title'
389
if string.split(Lines[3]) == []: # This line corresponds to TITLE name in TOPOLOGY file
390
Basename = Filename[:string.find(Filename, '.')]
391
Item_list = [Basename]
392
print 'Warning: Title not present... Assigning Basename as Title'
397
if Line[0]!='%': #Vikas' Modification: This condition ignores all the lines starting with % in the topology file.
398
Item_list.extend(string.split(Line))
402
#--------------------------------------------------------
404
def Read_CRD(self, Basename):
405
'Read the Amber coordinate/restart (.crd) file'
407
# The optional velocities and periodic box size are not yet parsed.
409
Item_list = self.Read_data(Basename + '.crd')
411
if Item_list == None:
413
elif len(Item_list) < 2:
414
print '(error: File too short!)'
418
if self.__dict__.has_key('ITITL'):
419
if Pop(Item_list,0) != self.ITITL:
420
print '(warning: ITITL differs!)',
422
self.ITITL = Pop(Item_list,0)
423
print self.ITITL #Vikas Modification : Priting the Title
425
if self.__dict__.has_key('NATOM'):
426
if eval(Pop(Item_list,0)) != self.NATOM:
427
print '(error: NATOM differs!)'
430
self.NATOM = eval(Pop(Item_list,0))
431
print self.NATOM # Vikas' Modification: Printing number of atoms just to make sure that the program is reading the correct value.
433
#if len(Item_list) == 1 + 3 * self.NATOM:
434
# Vikas' Modification: I changed the condition.
435
if (len(Item_list)%3) != 0:
436
self.TIME = eval(Pop(Item_list,0))
439
print self.TIME # Vikas' Modification : Printing simulation time, just to make sure that the program is readint the correct value.
440
if len(Item_list) < 3 * self.NATOM:
441
print '(error: File too short!)'
447
for i in range(self.NATOM):
448
self.X.append(eval(Pop(Item_list,0)))
449
self.Y.append(eval(Pop(Item_list,0)))
450
self.Z.append(eval(Pop(Item_list,0)))
452
if (self.NATOM == 1) and len(Item_list):
453
print '(warning: Ambiguity!)',
455
if len(Item_list) >= 3 * self.NATOM:
459
for i in range(self.NATOM):
460
self.VX.append(eval(Pop(Item_list,0)))
461
self.VY.append(eval(Pop(Item_list,0)))
462
self.VZ.append(eval(Pop(Item_list,0)))
464
if len(Item_list) >= 3:
467
self.BOX.append(eval(Pop(Item_list,0)))
470
print '(warning: File too large!)',
475
#--------------------------------------------------------
477
def Read_TOP(self, Basename):
478
'Read the Amber parameter/topology (.top) file'
479
Item_list = self.Read_data(Basename + '.top')
481
if Item_list == None:
483
elif len(Item_list) < 31:
484
print '(error: File too short!)'
488
if self.__dict__.has_key('ITITL'):
489
if Pop(Item_list,0) != self.ITITL:
490
print '(warning: ITITL differs!)'
492
self.ITITL = Pop(Item_list,0)
493
print self.ITITL # Printing Self Title
495
if self.__dict__.has_key('NATOM'):
496
if eval(Pop(Item_list,0)) != self.NATOM:
497
print '(error: NATOM differs!)'
500
self.NATOM = eval(Pop(Item_list,0))
501
print self.NATOM # Printing total number of atoms just to make sure that thing are going right
502
self.NTYPES = eval(Pop(Item_list,0))
503
self.NBONH = eval(Pop(Item_list,0))
504
self.MBONA = eval(Pop(Item_list,0))
505
self.NTHETH = eval(Pop(Item_list,0))
506
self.MTHETA = eval(Pop(Item_list,0))
507
self.NPHIH = eval(Pop(Item_list,0))
508
self.MPHIA = eval(Pop(Item_list,0))
509
self.NHPARM = eval(Pop(Item_list,0))
510
self.NPARM = eval(Pop(Item_list,0))
511
self.NEXT = eval(Pop(Item_list,0))
512
self.NRES = eval(Pop(Item_list,0))
513
self.NBONA = eval(Pop(Item_list,0))
514
self.NTHETA = eval(Pop(Item_list,0))
515
self.NPHIA = eval(Pop(Item_list,0))
516
self.NUMBND = eval(Pop(Item_list,0))
517
self.NUMANG = eval(Pop(Item_list,0))
518
self.NPTRA = eval(Pop(Item_list,0))
519
self.NATYP = eval(Pop(Item_list,0))
520
self.NPHB = eval(Pop(Item_list,0))
521
self.IFPERT = eval(Pop(Item_list,0))
522
self.NBPER = eval(Pop(Item_list,0))
523
self.NGPER = eval(Pop(Item_list,0))
524
self.NDPER = eval(Pop(Item_list,0))
525
self.MBPER = eval(Pop(Item_list,0))
526
self.MGPER = eval(Pop(Item_list,0))
527
self.MDPER = eval(Pop(Item_list,0))
528
self.IFBOX = eval(Pop(Item_list,0))
529
self.NMXRS = eval(Pop(Item_list,0))
530
self.IFCAP = eval(Pop(Item_list,0))
532
#....................................................
534
if len(Item_list) < 5 * self.NATOM + self.NTYPES**2 + \
535
2*(self.NRES + self.NUMBND + self.NUMANG) + \
536
3*self.NPTRA + self.NATYP:
537
print '(error: File too short!)'
543
# A little kludge is needed here, since the IGRAPH strings are
544
# not separated by spaces if 4 characters in length.
545
for i in range(self.NATOM):
546
if len(Item_list[0]) > 4:
547
Item_list.insert(1, Item_list[0][4:])
548
Item_list.insert(1, Item_list[0][0:4])
550
self.IGRAPH.append(Pop(Item_list,0))
552
# Vikas' Modification : In the following section, I am printing out each quantity which is currently being read from the topology file.
553
print 'Reading Charges...'
555
for i in range(self.NATOM):
556
self.CHRG.append(eval(Pop(Item_list,0)))
558
print 'Reading Atomic Number...'
560
for i in range(self.NATOM):
561
self.ANUMBER.append(eval(Pop(Item_list,0)))
563
print 'Reading Atomic Masses...'
565
for i in range(self.NATOM):
566
self.AMASS.append(eval(Pop(Item_list,0)))
568
print 'Reading Atom Types...'
570
for i in range(self.NATOM):
571
self.IAC.append(eval(Pop(Item_list,0)))
573
print 'Reading Excluded Atoms...'
575
for i in range(self.NATOM):
576
self.NUMEX.append(eval(Pop(Item_list,0)))
578
print 'Reading Non-bonded Parameter Index...'
580
for i in range(self.NTYPES**2):
581
self.ICO.append(eval(Pop(Item_list,0)))
583
print 'Reading Residue Labels...'
585
for i in range(self.NRES):
586
self.LABRES.append(Pop(Item_list,0))
588
print 'Reading Residues Starting Pointers...'
590
for i in range(self.NRES):
591
self.IPRES.append(eval(Pop(Item_list,0)))
593
print 'Reading Bond Force Constants...'
595
for i in range(self.NUMBND):
596
self.RK.append(eval(Pop(Item_list,0)))
598
print 'Reading Equilibrium Bond Values...'
600
for i in range(self.NUMBND):
601
self.REQ.append(eval(Pop(Item_list,0)))
603
print 'Reading Angle Force Constants...'
605
for i in range(self.NUMANG):
606
self.TK.append(eval(Pop(Item_list,0)))
608
print 'Reading Equilibrium Angle Values...'
610
for i in range(self.NUMANG):
611
self.TEQ.append(eval(Pop(Item_list,0)))
613
print 'Reading Dihedral Force Constants...'
615
for i in range(self.NPTRA):
616
self.PK.append(eval(Pop(Item_list,0)))
618
print 'Reading Dihedral Periodicity...'
620
for i in range(self.NPTRA):
621
self.PN.append(eval(Pop(Item_list,0)))
623
print 'Reading Dihedral Phase...'
625
for i in range(self.NPTRA):
626
self.PHASE.append(eval(Pop(Item_list,0)))
628
print 'Reading 1-4 Electrostatic Scaling Factor...'
630
for i in range(self.NPTRA):
631
self.SCEEFAC.append(eval(Pop(Item_list,0)))
633
print 'Reading 1-4 Van der Waals Scaling Factor...'
635
for i in range(self.NPTRA):
636
self.SCNBFAC.append(eval(Pop(Item_list,0)))
638
print 'Reading Solty...' #I think this is currently not used in AMBER. Check it out, though
640
for i in range(self.NATYP):
641
self.SOLTY.append(eval(Pop(Item_list,0)))
643
#....................................................
645
if len(Item_list) < 2 * self.NTYPES * (self.NTYPES + 1) / 2:
646
print '(error: File too short!)'
649
print 'Reading LJ A Coefficient...'
651
for i in range(self.NTYPES * (self.NTYPES + 1) / 2):
652
self.CN1.append(eval(Pop(Item_list,0)))
654
print 'Reading LJ B Coefficient...'
656
for i in range(self.NTYPES * (self.NTYPES + 1) / 2):
657
self.CN2.append(eval(Pop(Item_list,0)))
659
#....................................................
661
if len(Item_list) < 3 * (self.NBONH + self.NBONA) + \
662
4 * (self.NTHETH + self.NTHETA) + 5 * (self.NPHIH + self.NPHIA):
663
print '(error: File too short!)'
666
print 'Reading Bonds which include hydrogen...'
670
for i in range(self.NBONH):
671
self.IBH.append(eval(Pop(Item_list,0)))
672
self.JBH.append(eval(Pop(Item_list,0)))
673
self.ICBH.append(eval(Pop(Item_list,0)))
675
print 'Reading Bonds which dont include hydrogen...'
679
for i in range(self.NBONA):
680
self.IB.append(eval(Pop(Item_list,0)))
681
self.JB.append(eval(Pop(Item_list,0)))
682
self.ICB.append(eval(Pop(Item_list,0)))
684
print 'Reading Angles which include hydrogen...'
689
for i in range(self.NTHETH):
690
self.ITH.append(eval(Pop(Item_list,0)))
691
self.JTH.append(eval(Pop(Item_list,0)))
692
self.KTH.append(eval(Pop(Item_list,0)))
693
self.ICTH.append(eval(Pop(Item_list,0)))
695
print 'Reading Angles which dont include hydrogen...'
700
for i in range(self.NTHETA):
701
self.IT.append(eval(Pop(Item_list,0)))
702
self.JT.append(eval(Pop(Item_list,0)))
703
self.KT.append(eval(Pop(Item_list,0)))
704
self.ICT.append(eval(Pop(Item_list,0)))
706
print 'Reading Dihedrals which include hydrogen...'
712
for i in range(self.NPHIH):
713
self.IPH.append(eval(Pop(Item_list,0)))
714
self.JPH.append(eval(Pop(Item_list,0)))
715
self.KPH.append(eval(Pop(Item_list,0)))
716
self.LPH.append(eval(Pop(Item_list,0)))
717
self.ICPH.append(eval(Pop(Item_list,0)))
719
print 'Reading Dihedrals which dont include hydrogen...'
725
for i in range(self.NPHIA):
726
self.IP.append(eval(Pop(Item_list,0)))
727
self.JP.append(eval(Pop(Item_list,0)))
728
self.KP.append(eval(Pop(Item_list,0)))
729
self.LP.append(eval(Pop(Item_list,0)))
730
self.ICP.append(eval(Pop(Item_list,0)))
732
#....................................................
734
if len(Item_list) < self.NEXT + 3 * self.NPHB + 4 * self.NATOM:
735
print '(error: File too short!)'
738
print 'Reading Excluded Atom List...'
740
for i in range(self.NEXT):
741
self.NATEX.append(eval(Pop(Item_list,0)))
743
print 'Reading H-Bond A Coefficient, corresponding to r**12 term for all possible types...'
745
for i in range(self.NPHB):
746
self.ASOL.append(eval(Pop(Item_list,0)))
748
print 'Reading H-Bond B Coefficient, corresponding to r**10 term for all possible types...'
750
for i in range(self.NPHB):
751
self.BSOL.append(eval(Pop(Item_list,0)))
753
print 'Reading H-Bond Cut...' # I think it is not being used nowadays
755
for i in range(self.NPHB):
756
self.HBCUT.append(eval(Pop(Item_list,0)))
758
print 'Reading Amber Atom Types for each atom...'
760
for i in range(self.NATOM):
761
self.ISYMBL.append(Pop(Item_list,0))
763
print 'Reading Tree Chain Classification...'
765
for i in range(self.NATOM):
766
self.ITREE.append(Pop(Item_list,0))
768
print 'Reading Join Array: Tree joining information' # Currently unused in Sander, an AMBER module
770
for i in range(self.NATOM):
771
self.JOIN.append(eval(Pop(Item_list,0)))
773
print 'Reading IRotate...' # Currently unused in Sander and Gibbs
775
for i in range(self.NATOM):
776
self.IROTAT.append(eval(Pop(Item_list,0)))
778
#....................................................
781
if len(Item_list) < 3:
782
print '(error: File too short!)'
785
print 'Reading final residue which is part of solute...'
786
self.IPTRES = eval(Pop(Item_list,0))
787
print 'Reading total number of molecules...'
788
self.NSPM = eval(Pop(Item_list,0))
789
print 'Reading first solvent moleule index...'
790
self.NSPSOL = eval(Pop(Item_list,0))
792
if len(Item_list) < self.NSPM + 4:
793
print '(error: File too short!)'
796
print 'Reading atom per molecule...'
798
for i in range(self.NSPM):
799
self.NSP.append(eval(Pop(Item_list,0)))
801
self.BETA = eval(Pop(Item_list,0))
803
print 'Reading Box Dimensions...'
804
if self.__dict__.has_key('BOX'):
807
BOX.append(eval(Pop(Item_list,0)))
809
if BOX[i] != self.BOX[i]:
810
print '(warning: BOX differs!)',
816
self.BOX.append(eval(Pop(Item_list,0)))
818
#....................................................
821
if len(Item_list) < 5:
822
print '(error: File too short!)'
824
print 'Reading ICAP variables::: For details, refer to online AMBER format manual'
825
self.NATCAP = eval(Pop(Item_list,0))
826
self.CUTCAP = eval(Pop(Item_list,0))
827
self.XCAP = eval(Pop(Item_list,0))
828
self.YCAP = eval(Pop(Item_list,0))
829
self.ZCAP = eval(Pop(Item_list,0))
831
#....................................................
834
if len(Item_list) < 4 * self.NBPER + 5 * self.NGPER + \
835
6 * self.NDPER + self.NRES + 6 * self.NATOM:
836
print '(error: File too short!)'
839
print 'Reading perturb variables, 1. Bond, 2. Angles, 3. Dihedrals, etc etc.::: For details, refer to online AMBER format manual'
842
for i in range(self.NBPER):
843
self.IBPER.append(eval(Pop(Item_list,0)))
844
self.JBPER.append(eval(Pop(Item_list,0)))
847
for i in range(2 * self.NBPER):
848
self.ICBPER.append(eval(Pop(Item_list,0)))
853
for i in range(self.NGPER):
854
self.ITPER.append(eval(Pop(Item_list,0)))
855
self.JTPER.append(eval(Pop(Item_list,0)))
856
self.KTPER.append(eval(Pop(Item_list,0)))
859
for i in range(2 * self.NGPER):
860
self.ICTPER.append(eval(Pop(Item_list,0)))
866
for i in range(self.NDPER):
867
self.IPPER.append(eval(Pop(Item_list,0)))
868
self.JPPER.append(eval(Pop(Item_list,0)))
869
self.KPPER.append(eval(Pop(Item_list,0)))
870
self.LPPER.append(eval(Pop(Item_list,0)))
873
for i in range(2 * self.NDPER):
874
self.ICPPER.append(eval(Pop(Item_list,0)))
877
for i in range(self.NRES):
878
LABRES.append(Pop(Item_list,0))
879
for i in range(self.NRES):
880
if LABRES[i] != self.LABRES[i]:
881
print '(warning: BOX differs!)',
885
for i in range(self.NATOM):
886
self.IGRPER.append(eval(Pop(Item_list,0)))
889
for i in range(self.NATOM):
890
self.ISMPER.append(eval(Pop(Item_list,0)))
893
for i in range(self.NATOM):
894
self.ALMPER.append(eval(Pop(Item_list,0)))
897
for i in range(self.NATOM):
898
self.IAPER.append(eval(Pop(Item_list,0)))
901
for i in range(self.NATOM):
902
self.IACPER.append(eval(Pop(Item_list,0)))
905
for i in range(self.NATOM):
906
self.CGPER.append(eval(Pop(Item_list,0)))
908
#....................................................
912
if len(Item_list) < self.NATOM:
913
print '(error: File too short!)'
915
print 'Reading Polarizability Data. For details, refer to online AMBER format manual'
917
for i in range(self.NATOM):
918
self.ATPOL.append(eval(Pop(Item_list,0)))
921
if len(Item_list) < self.NATOM:
922
print '(error: File too short!)'
925
for i in range(self.NATOM):
926
self.ATPOL1.append(eval(Pop(Item_list,0)))
928
#....................................................
931
print '(warning: File too large!)',
936
#============================================================
938
def Find_Amber_files():
939
'Look for sets of Amber files to process'
940
'''If not passed anything on the command line, look for pairs of
941
Amber files (.crd and .top) in the current directory. For
942
each set if there is no corresponding Lammps file (data.), or it is
943
older than any of the Amber files, add its basename to a list of
944
strings. This list is returned by the function'''
946
# Date and existence checks not yet implemented
952
# Extract basenames from command line
953
for Name in sys.argv[1:]:
954
if Name[-4:] == '.crd':
955
Basename_list.append(Name[:-4])
957
if Name[-4:] == '.top':
958
Basename_list.append(Name[:-4])
960
Basename_list.append(Name)
962
# Remove duplicate basenames
963
for Basename in Basename_list[:]:
964
while Basename_list.count(Basename) > 1:
965
Basename_list.remove(Basename)
967
if Basename_list == []:
968
print 'Looking for Amber files...',
969
Dir_list = os.listdir('.')
971
for File in Dir_list:
972
if File[-4:] == '.top':
974
if (Basename + '.crd') in Dir_list:
975
Basename_list.append(Basename)
976
if Basename_list != []:
978
for i in range(len(Basename_list)-1):
979
print Basename_list[i] + ',',
980
print Basename_list[-1] + '\n'
982
if Basename_list == []:
987
#============================================================
989
def Convert_Amber_files():
990
'Handle the whole conversion process'
992
print 'Welcome to amber2lammps, a program to convert Amber files to Lammps format!'
994
Basename_list = Find_Amber_files()
995
for Basename in Basename_list:
1001
l = a.Coerce_to_Lammps()
1002
l.Write_Lammps(Basename)
1007
#============================================================
1009
Convert_Amber_files()
1
#! /usr/bin/evn python2
3
# This is amber2lammps, a program written by Keir E. Novik to convert
4
# Amber files to Lammps files.
6
# Copyright 1999, 2000 Keir E. Novik; all rights reserved.
8
# Modified by Vikas Varshney, U Akron, 5 July 2005, as described in README
9
# Bug Fixed :Third argument in Dihedral Coeffs section is an integer - Ketan S Khare September 26, 2011
10
# Modified by Vikas Varshney, Oct 8, 2013 to include additional flags (Atomic_Number, Coulombic and van der Waals 1-4 factors which are included in newer vesions of .top and .crd files in amber12.
12
#============================================================
15
'Pop item I from list'
20
#============================================================
24
#--------------------------------------------------------
27
'Write out contents of self (intended for debugging)'
28
Name_list = self.__dict__.keys()
30
for Name in Name_list:
31
print Name + ':', self.__dict__[Name]
33
#--------------------------------------------------------
35
def Write_data(self, Basename, Item_list):
36
'Write the Lammps data to file (used by Write_Lammps)'
39
Filename = 'data.' + Basename
41
Dir_list = os.listdir('.')
43
while Filename in Dir_list:
44
Filename = 'data' + `i` + '.' + Basename
48
print 'Writing', Filename + '...',
52
F = open(Filename, 'w')
53
except IOError, Detail:
54
print '(error:', Detail[1] + '!)'
58
F.writelines(Item_list)
59
except IOError, Detail:
60
print '(error:', Detail[1] + '!)'
67
#--------------------------------------------------------
69
def Write_Lammps(self, Basename):
70
'Write the Lammps data file, ignoring blank sections'
74
L.append('LAMMPS data file for ' + self.name + '\n\n')
76
L.append(`self.atoms` + ' atoms\n')
77
L.append(`self.bonds` + ' bonds\n')
78
L.append(`self.angles` + ' angles\n')
79
L.append(`self.dihedrals` + ' dihedrals\n')
80
L.append(`self.impropers` + ' impropers\n\n')
82
L.append(`self.atom_types` + ' atom types\n')
84
L.append(`self.bond_types` + ' bond types\n')
86
L.append(`self.angle_types` + ' angle types\n')
87
if self.dihedrals > 0:
88
L.append(`self.dihedral_types` + ' dihedral types\n')
91
L.append(`self.xlo` + ' ' + `self.xhi` + ' xlo xhi\n')
92
L.append(`self.ylo` + ' ' + `self.yhi` + ' ylo yhi\n')
93
L.append(`self.zlo` + ' ' + `self.zhi` + ' zlo zhi\n\n')
95
if self.atom_types != 0:
96
L.append('Masses\n\n')
97
for i in range(self.atom_types):
98
L.append(`i+1` + ' ' + `self.Masses[i]` + '\n')
101
L.append('Pair Coeffs\n\n')
102
for i in range(self.atom_types):
104
for j in range(len(self.Nonbond_Coeffs[0])):
105
L.append(' ' + `self.Nonbond_Coeffs[i][j]`)
109
if self.bonds != 0 and self.bond_types != 0:
110
L.append('Bond Coeffs\n\n')
111
for i in range(self.bond_types):
113
for j in range(len(self.Bond_Coeffs[0])):
114
L.append(' ' + `self.Bond_Coeffs[i][j]`)
118
if self.angles != 0 and self.angle_types != 0:
119
L.append('Angle Coeffs\n\n')
120
for i in range(self.angle_types):
122
for j in range(len(self.Angle_Coeffs[0])):
123
L.append(' ' + `self.Angle_Coeffs[i][j]`)
127
if self.dihedrals != 0 and self.dihedral_types != 0:
128
L.append('Dihedral Coeffs\n\n')
129
for i in range(self.dihedral_types):
131
for j in range(len(self.Dihedral_Coeffs[0])):
132
L.append(' ' + `self.Dihedral_Coeffs[i][j]`)
137
L.append('Atoms\n\n')
138
for i in range(self.atoms):
140
for j in range(len(self.Atoms[0])):
141
L.append(' ' + `self.Atoms[i][j]`)
145
if self.bonds != 0 and self.bond_types != 0:
146
L.append('Bonds\n\n')
147
for i in range(self.bonds):
149
for j in range(len(self.Bonds[0])):
150
L.append(' ' + `self.Bonds[i][j]`)
154
if self.angles != 0 and self.angle_types != 0:
155
L.append('Angles\n\n')
156
for i in range(self.angles):
158
for j in range(len(self.Angles[0])):
159
L.append(' ' + `self.Angles[i][j]`)
163
if self.dihedrals != 0 and self.dihedral_types != 0:
164
L.append('Dihedrals\n\n')
165
for i in range(self.dihedrals):
167
for j in range(len(self.Dihedrals[0])):
168
L.append(' ' + `self.Dihedrals[i][j]`)
172
self.Write_data(Basename, L)
174
#============================================================
178
'Initialise the Amber class'
182
#--------------------------------------------------------
185
'Write out contents of self (intended for debugging)'
186
Name_list = self.__dict__.keys()
188
for Name in Name_list:
189
print Name + ':', self.__dict__[Name]
191
#--------------------------------------------------------
193
def Coerce_to_Lammps(self):
194
'Return the Amber data converted to Lammps format'
198
if self.CRD_is_read and self.TOP_is_read:
200
print 'Converting...',
204
l.bonds = self.NBONH + self.MBONA
205
l.angles = self.NTHETH + self.MTHETA
206
l.dihedrals = self.NPHIH + self.MPHIA
208
l.atom_types = self.NTYPES
209
l.bond_types = self.NUMBND
210
l.angle_types = self.NUMANG
211
l.dihedral_types = self.NPTRA
214
if self.__dict__.has_key('BOX'):
221
if (l.xlo > min(self.X)) or (l.xhi < max(self.X)) or \
222
(l.ylo > min(self.Y)) or (l.yhi < max(self.Y)) or \
223
(l.zlo > min(self.Z)) or (l.zhi < max(self.Z)):
224
# Vikas Modification: Disabling Shifting. This means I am intend to send exact coordinates of each atom and let LAMMPS
225
# take care of imaging into periodic image cells. If one wants to shift all atoms in the periodic box,
226
# please uncomment the below 2 lines.
227
print '(warning: Currently not shifting the atoms to the periodic box)'
230
print '(warning: Guessing at periodic box!)',
238
# This doesn't check duplicate values
240
for i in range(l.atom_types):
242
for i in range(self.NATOM):
243
l.Masses[self.IAC[i] - 1] = self.AMASS[i]
245
l.Nonbond_Coeffs = []
246
for i in range(self.NTYPES):
247
l.Nonbond_Coeffs.append([0,0])
248
for i in range(self.NTYPES):
249
j = self.ICO[i * (self.NTYPES + 1)] - 1
250
if self.CN1[j] == 0.0:
251
l.Nonbond_Coeffs[i][0] = 0.0
253
l.Nonbond_Coeffs[i][0] = \
254
0.25 * (self.CN2[j])**2 / self.CN1[j]
255
if self.CN2[j] == 0.0:
256
l.Nonbond_Coeffs[i][1] = 0.0
258
l.Nonbond_Coeffs[i][1] = \
259
(self.CN1[j] / self.CN2[j])**(1.0/6.0)
262
for i in range(self.NUMBND):
263
l.Bond_Coeffs.append([0,0])
264
for i in range(self.NUMBND):
265
l.Bond_Coeffs[i][0] = self.RK[i]
266
l.Bond_Coeffs[i][1] = self.REQ[i]
269
for i in range(self.NUMANG):
270
l.Angle_Coeffs.append([0,0])
271
for i in range(self.NUMANG):
272
l.Angle_Coeffs[i][0] = self.TK[i]
273
l.Angle_Coeffs[i][1] = (180/math.pi) * self.TEQ[i]
275
l.Dihedral_Coeffs = []
276
for i in range(self.NPTRA):
277
l.Dihedral_Coeffs.append([0,0,0])
278
for i in range(self.NPTRA):
279
l.Dihedral_Coeffs[i][0] = self.PK[i]
280
if self.PHASE[i] == 0:
281
l.Dihedral_Coeffs[i][1] = 1
283
l.Dihedral_Coeffs[i][1] = -1
284
l.Dihedral_Coeffs[i][2] = int(self.PN[i])
287
for i in range(self.NATOM):
304
l.Atoms.append([0, self.IAC[i], self.CHRG[i]/18.2223, \
308
for i in range(l.bonds):
309
l.Bonds.append([0,0,0])
310
for i in range(self.NBONH):
311
l.Bonds[i][0] = self.ICBH[i]
312
l.Bonds[i][1] = abs(self.IBH[i])/3 + 1
313
l.Bonds[i][2] = abs(self.JBH[i])/3 + 1
314
for i in range(self.NBONA):
315
l.Bonds[self.NBONH + i][0] = self.ICB[i]
316
l.Bonds[self.NBONH + i][1] = abs(self.IB[i])/3 + 1
317
l.Bonds[self.NBONH + i][2] = abs(self.JB[i])/3 + 1
320
for i in range(l.angles):
321
l.Angles.append([0,0,0,0])
322
for i in range(self.NTHETH):
323
l.Angles[i][0] = self.ICTH[i]
324
l.Angles[i][1] = abs(self.ITH[i])/3 + 1
325
l.Angles[i][2] = abs(self.JTH[i])/3 + 1
326
l.Angles[i][3] = abs(self.KTH[i])/3 + 1
327
for i in range(self.NTHETA):
328
l.Angles[self.NTHETH + i][0] = self.ICT[i]
329
l.Angles[self.NTHETH + i][1] = abs(self.IT[i])/3 + 1
330
l.Angles[self.NTHETH + i][2] = abs(self.JT[i])/3 + 1
331
l.Angles[self.NTHETH + i][3] = abs(self.KT[i])/3 + 1
334
for i in range(l.dihedrals):
335
l.Dihedrals.append([0,0,0,0,0])
336
for i in range(self.NPHIH):
337
l.Dihedrals[i][0] = self.ICPH[i]
338
l.Dihedrals[i][1] = abs(self.IPH[i])/3 + 1
339
l.Dihedrals[i][2] = abs(self.JPH[i])/3 + 1
340
l.Dihedrals[i][3] = abs(self.KPH[i])/3 + 1
341
l.Dihedrals[i][4] = abs(self.LPH[i])/3 + 1
342
for i in range(self.NPHIA):
343
l.Dihedrals[self.NPHIH + i][0] = self.ICP[i]
344
l.Dihedrals[self.NPHIH + i][1] = abs(self.IP[i])/3 + 1
345
l.Dihedrals[self.NPHIH + i][2] = abs(self.JP[i])/3 + 1
346
l.Dihedrals[self.NPHIH + i][3] = abs(self.KP[i])/3 + 1
347
l.Dihedrals[self.NPHIH + i][4] = abs(self.LP[i])/3 + 1
352
print '(Error: Not all the Amber data has been read!)'
354
#--------------------------------------------------------
356
def Read_data(self, Filename):
357
'Read the filename, returning a list of strings'
361
print 'Reading', Filename + '...',
366
except IOError, Detail:
367
print '(error:', Detail[1] + '!)'
371
Lines = F.readlines()
372
except IOError, Detail:
373
print '(error:', Detail[1] + '!)'
379
# If the first line is empty, use the Basename
380
if Filename[-4:] == '.crd':
381
if string.split(Lines[0]) == []: # This line corresponds to TITLE name in CRD file
382
Basename = Filename[:string.find(Filename, '.')]
383
Item_list = [Basename]
384
print 'Warning: Title not present... Assigning Basename as Title'
388
if string.split(Lines[3]) == []: # This line corresponds to TITLE name in TOPOLOGY file
389
Basename = Filename[:string.find(Filename, '.')]
390
Item_list = [Basename]
391
print 'Warning: Title not present... Assigning Basename as Title'
396
if Line[0]!='%': #Vikas' Modification: This condition ignores all the lines starting with % in the topology file.
397
Item_list.extend(string.split(Line))
401
#--------------------------------------------------------
403
def Read_CRD(self, Basename):
404
'Read the Amber coordinate/restart (.crd) file'
406
# The optional velocities and periodic box size are not yet parsed.
408
Item_list = self.Read_data(Basename + '.crd')
410
if Item_list == None:
412
elif len(Item_list) < 2:
413
print '(error: File too short!)'
417
if self.__dict__.has_key('ITITL'):
418
if Pop(Item_list,0) != self.ITITL:
419
print '(warning: ITITL differs!)',
421
self.ITITL = Pop(Item_list,0)
422
print self.ITITL #Vikas Modification : Priting the Title
424
if self.__dict__.has_key('NATOM'):
425
if eval(Pop(Item_list,0)) != self.NATOM:
426
print '(error: NATOM differs!)'
429
self.NATOM = eval(Pop(Item_list,0))
430
print self.NATOM # Vikas' Modification: Printing number of atoms just to make sure that the program is reading the correct value.
432
#if len(Item_list) == 1 + 3 * self.NATOM:
433
# Vikas' Modification: I changed the condition.
434
if (len(Item_list)%3) != 0:
435
self.TIME = eval(Pop(Item_list,0))
438
print self.TIME # Vikas' Modification : Printing simulation time, just to make sure that the program is readint the correct value.
439
if len(Item_list) < 3 * self.NATOM:
440
print '(error: File too short!)'
446
for i in range(self.NATOM):
447
self.X.append(eval(Pop(Item_list,0)))
448
self.Y.append(eval(Pop(Item_list,0)))
449
self.Z.append(eval(Pop(Item_list,0)))
451
if (self.NATOM == 1) and len(Item_list):
452
print '(warning: Ambiguity!)',
454
if len(Item_list) >= 3 * self.NATOM:
458
for i in range(self.NATOM):
459
self.VX.append(eval(Pop(Item_list,0)))
460
self.VY.append(eval(Pop(Item_list,0)))
461
self.VZ.append(eval(Pop(Item_list,0)))
463
if len(Item_list) >= 3:
466
self.BOX.append(eval(Pop(Item_list,0)))
469
print '(warning: File too large!)',
474
#--------------------------------------------------------
476
def Read_TOP(self, Basename):
477
'Read the Amber parameter/topology (.top) file'
478
Item_list = self.Read_data(Basename + '.top')
480
if Item_list == None:
482
elif len(Item_list) < 31:
483
print '(error: File too short!)'
487
if self.__dict__.has_key('ITITL'):
488
if Pop(Item_list,0) != self.ITITL:
489
print '(warning: ITITL differs!)'
491
self.ITITL = Pop(Item_list,0)
492
print self.ITITL # Printing Self Title
494
if self.__dict__.has_key('NATOM'):
495
if eval(Pop(Item_list,0)) != self.NATOM:
496
print '(error: NATOM differs!)'
499
self.NATOM = eval(Pop(Item_list,0))
500
print self.NATOM # Printing total number of atoms just to make sure that thing are going right
501
self.NTYPES = eval(Pop(Item_list,0))
502
self.NBONH = eval(Pop(Item_list,0))
503
self.MBONA = eval(Pop(Item_list,0))
504
self.NTHETH = eval(Pop(Item_list,0))
505
self.MTHETA = eval(Pop(Item_list,0))
506
self.NPHIH = eval(Pop(Item_list,0))
507
self.MPHIA = eval(Pop(Item_list,0))
508
self.NHPARM = eval(Pop(Item_list,0))
509
self.NPARM = eval(Pop(Item_list,0))
510
self.NEXT = eval(Pop(Item_list,0))
511
self.NRES = eval(Pop(Item_list,0))
512
self.NBONA = eval(Pop(Item_list,0))
513
self.NTHETA = eval(Pop(Item_list,0))
514
self.NPHIA = eval(Pop(Item_list,0))
515
self.NUMBND = eval(Pop(Item_list,0))
516
self.NUMANG = eval(Pop(Item_list,0))
517
self.NPTRA = eval(Pop(Item_list,0))
518
self.NATYP = eval(Pop(Item_list,0))
519
self.NPHB = eval(Pop(Item_list,0))
520
self.IFPERT = eval(Pop(Item_list,0))
521
self.NBPER = eval(Pop(Item_list,0))
522
self.NGPER = eval(Pop(Item_list,0))
523
self.NDPER = eval(Pop(Item_list,0))
524
self.MBPER = eval(Pop(Item_list,0))
525
self.MGPER = eval(Pop(Item_list,0))
526
self.MDPER = eval(Pop(Item_list,0))
527
self.IFBOX = eval(Pop(Item_list,0))
528
self.NMXRS = eval(Pop(Item_list,0))
529
self.IFCAP = eval(Pop(Item_list,0))
531
#....................................................
533
if len(Item_list) < 5 * self.NATOM + self.NTYPES**2 + \
534
2*(self.NRES + self.NUMBND + self.NUMANG) + \
535
3*self.NPTRA + self.NATYP:
536
print '(error: File too short!)'
542
# A little kludge is needed here, since the IGRAPH strings are
543
# not separated by spaces if 4 characters in length.
544
for i in range(self.NATOM):
545
if len(Item_list[0]) > 4:
546
Item_list.insert(1, Item_list[0][4:])
547
Item_list.insert(1, Item_list[0][0:4])
549
self.IGRAPH.append(Pop(Item_list,0))
551
# Vikas' Modification : In the following section, I am printing out each quantity which is currently being read from the topology file.
552
print 'Reading Charges...'
554
for i in range(self.NATOM):
555
self.CHRG.append(eval(Pop(Item_list,0)))
557
print 'Reading Atomic Number...'
559
for i in range(self.NATOM):
560
self.ANUMBER.append(eval(Pop(Item_list,0)))
562
print 'Reading Atomic Masses...'
564
for i in range(self.NATOM):
565
self.AMASS.append(eval(Pop(Item_list,0)))
567
print 'Reading Atom Types...'
569
for i in range(self.NATOM):
570
self.IAC.append(eval(Pop(Item_list,0)))
572
print 'Reading Excluded Atoms...'
574
for i in range(self.NATOM):
575
self.NUMEX.append(eval(Pop(Item_list,0)))
577
print 'Reading Non-bonded Parameter Index...'
579
for i in range(self.NTYPES**2):
580
self.ICO.append(eval(Pop(Item_list,0)))
582
print 'Reading Residue Labels...'
584
for i in range(self.NRES):
585
self.LABRES.append(Pop(Item_list,0))
587
print 'Reading Residues Starting Pointers...'
589
for i in range(self.NRES):
590
self.IPRES.append(eval(Pop(Item_list,0)))
592
print 'Reading Bond Force Constants...'
594
for i in range(self.NUMBND):
595
self.RK.append(eval(Pop(Item_list,0)))
597
print 'Reading Equilibrium Bond Values...'
599
for i in range(self.NUMBND):
600
self.REQ.append(eval(Pop(Item_list,0)))
602
print 'Reading Angle Force Constants...'
604
for i in range(self.NUMANG):
605
self.TK.append(eval(Pop(Item_list,0)))
607
print 'Reading Equilibrium Angle Values...'
609
for i in range(self.NUMANG):
610
self.TEQ.append(eval(Pop(Item_list,0)))
612
print 'Reading Dihedral Force Constants...'
614
for i in range(self.NPTRA):
615
self.PK.append(eval(Pop(Item_list,0)))
617
print 'Reading Dihedral Periodicity...'
619
for i in range(self.NPTRA):
620
self.PN.append(eval(Pop(Item_list,0)))
622
print 'Reading Dihedral Phase...'
624
for i in range(self.NPTRA):
625
self.PHASE.append(eval(Pop(Item_list,0)))
627
print 'Reading 1-4 Electrostatic Scaling Factor...'
629
for i in range(self.NPTRA):
630
self.SCEEFAC.append(eval(Pop(Item_list,0)))
632
print 'Reading 1-4 Van der Waals Scaling Factor...'
634
for i in range(self.NPTRA):
635
self.SCNBFAC.append(eval(Pop(Item_list,0)))
637
print 'Reading Solty...' #I think this is currently not used in AMBER. Check it out, though
639
for i in range(self.NATYP):
640
self.SOLTY.append(eval(Pop(Item_list,0)))
642
#....................................................
644
if len(Item_list) < 2 * self.NTYPES * (self.NTYPES + 1) / 2:
645
print '(error: File too short!)'
648
print 'Reading LJ A Coefficient...'
650
for i in range(self.NTYPES * (self.NTYPES + 1) / 2):
651
self.CN1.append(eval(Pop(Item_list,0)))
653
print 'Reading LJ B Coefficient...'
655
for i in range(self.NTYPES * (self.NTYPES + 1) / 2):
656
self.CN2.append(eval(Pop(Item_list,0)))
658
#....................................................
660
if len(Item_list) < 3 * (self.NBONH + self.NBONA) + \
661
4 * (self.NTHETH + self.NTHETA) + 5 * (self.NPHIH + self.NPHIA):
662
print '(error: File too short!)'
665
print 'Reading Bonds which include hydrogen...'
669
for i in range(self.NBONH):
670
self.IBH.append(eval(Pop(Item_list,0)))
671
self.JBH.append(eval(Pop(Item_list,0)))
672
self.ICBH.append(eval(Pop(Item_list,0)))
674
print 'Reading Bonds which dont include hydrogen...'
678
for i in range(self.NBONA):
679
self.IB.append(eval(Pop(Item_list,0)))
680
self.JB.append(eval(Pop(Item_list,0)))
681
self.ICB.append(eval(Pop(Item_list,0)))
683
print 'Reading Angles which include hydrogen...'
688
for i in range(self.NTHETH):
689
self.ITH.append(eval(Pop(Item_list,0)))
690
self.JTH.append(eval(Pop(Item_list,0)))
691
self.KTH.append(eval(Pop(Item_list,0)))
692
self.ICTH.append(eval(Pop(Item_list,0)))
694
print 'Reading Angles which dont include hydrogen...'
699
for i in range(self.NTHETA):
700
self.IT.append(eval(Pop(Item_list,0)))
701
self.JT.append(eval(Pop(Item_list,0)))
702
self.KT.append(eval(Pop(Item_list,0)))
703
self.ICT.append(eval(Pop(Item_list,0)))
705
print 'Reading Dihedrals which include hydrogen...'
711
for i in range(self.NPHIH):
712
self.IPH.append(eval(Pop(Item_list,0)))
713
self.JPH.append(eval(Pop(Item_list,0)))
714
self.KPH.append(eval(Pop(Item_list,0)))
715
self.LPH.append(eval(Pop(Item_list,0)))
716
self.ICPH.append(eval(Pop(Item_list,0)))
718
print 'Reading Dihedrals which dont include hydrogen...'
724
for i in range(self.NPHIA):
725
self.IP.append(eval(Pop(Item_list,0)))
726
self.JP.append(eval(Pop(Item_list,0)))
727
self.KP.append(eval(Pop(Item_list,0)))
728
self.LP.append(eval(Pop(Item_list,0)))
729
self.ICP.append(eval(Pop(Item_list,0)))
731
#....................................................
733
if len(Item_list) < self.NEXT + 3 * self.NPHB + 4 * self.NATOM:
734
print '(error: File too short!)'
737
print 'Reading Excluded Atom List...'
739
for i in range(self.NEXT):
740
self.NATEX.append(eval(Pop(Item_list,0)))
742
print 'Reading H-Bond A Coefficient, corresponding to r**12 term for all possible types...'
744
for i in range(self.NPHB):
745
self.ASOL.append(eval(Pop(Item_list,0)))
747
print 'Reading H-Bond B Coefficient, corresponding to r**10 term for all possible types...'
749
for i in range(self.NPHB):
750
self.BSOL.append(eval(Pop(Item_list,0)))
752
print 'Reading H-Bond Cut...' # I think it is not being used nowadays
754
for i in range(self.NPHB):
755
self.HBCUT.append(eval(Pop(Item_list,0)))
757
print 'Reading Amber Atom Types for each atom...'
759
for i in range(self.NATOM):
760
self.ISYMBL.append(Pop(Item_list,0))
762
print 'Reading Tree Chain Classification...'
764
for i in range(self.NATOM):
765
self.ITREE.append(Pop(Item_list,0))
767
print 'Reading Join Array: Tree joining information' # Currently unused in Sander, an AMBER module
769
for i in range(self.NATOM):
770
self.JOIN.append(eval(Pop(Item_list,0)))
772
print 'Reading IRotate...' # Currently unused in Sander and Gibbs
774
for i in range(self.NATOM):
775
self.IROTAT.append(eval(Pop(Item_list,0)))
777
#....................................................
780
if len(Item_list) < 3:
781
print '(error: File too short!)'
784
print 'Reading final residue which is part of solute...'
785
self.IPTRES = eval(Pop(Item_list,0))
786
print 'Reading total number of molecules...'
787
self.NSPM = eval(Pop(Item_list,0))
788
print 'Reading first solvent moleule index...'
789
self.NSPSOL = eval(Pop(Item_list,0))
791
if len(Item_list) < self.NSPM + 4:
792
print '(error: File too short!)'
795
print 'Reading atom per molecule...'
797
for i in range(self.NSPM):
798
self.NSP.append(eval(Pop(Item_list,0)))
800
self.BETA = eval(Pop(Item_list,0))
802
print 'Reading Box Dimensions...'
803
if self.__dict__.has_key('BOX'):
806
BOX.append(eval(Pop(Item_list,0)))
808
if BOX[i] != self.BOX[i]:
809
print '(warning: BOX differs!)',
815
self.BOX.append(eval(Pop(Item_list,0)))
817
#....................................................
820
if len(Item_list) < 5:
821
print '(error: File too short!)'
823
print 'Reading ICAP variables::: For details, refer to online AMBER format manual'
824
self.NATCAP = eval(Pop(Item_list,0))
825
self.CUTCAP = eval(Pop(Item_list,0))
826
self.XCAP = eval(Pop(Item_list,0))
827
self.YCAP = eval(Pop(Item_list,0))
828
self.ZCAP = eval(Pop(Item_list,0))
830
#....................................................
833
if len(Item_list) < 4 * self.NBPER + 5 * self.NGPER + \
834
6 * self.NDPER + self.NRES + 6 * self.NATOM:
835
print '(error: File too short!)'
838
print 'Reading perturb variables, 1. Bond, 2. Angles, 3. Dihedrals, etc etc.::: For details, refer to online AMBER format manual'
841
for i in range(self.NBPER):
842
self.IBPER.append(eval(Pop(Item_list,0)))
843
self.JBPER.append(eval(Pop(Item_list,0)))
846
for i in range(2 * self.NBPER):
847
self.ICBPER.append(eval(Pop(Item_list,0)))
852
for i in range(self.NGPER):
853
self.ITPER.append(eval(Pop(Item_list,0)))
854
self.JTPER.append(eval(Pop(Item_list,0)))
855
self.KTPER.append(eval(Pop(Item_list,0)))
858
for i in range(2 * self.NGPER):
859
self.ICTPER.append(eval(Pop(Item_list,0)))
865
for i in range(self.NDPER):
866
self.IPPER.append(eval(Pop(Item_list,0)))
867
self.JPPER.append(eval(Pop(Item_list,0)))
868
self.KPPER.append(eval(Pop(Item_list,0)))
869
self.LPPER.append(eval(Pop(Item_list,0)))
872
for i in range(2 * self.NDPER):
873
self.ICPPER.append(eval(Pop(Item_list,0)))
876
for i in range(self.NRES):
877
LABRES.append(Pop(Item_list,0))
878
for i in range(self.NRES):
879
if LABRES[i] != self.LABRES[i]:
880
print '(warning: BOX differs!)',
884
for i in range(self.NATOM):
885
self.IGRPER.append(eval(Pop(Item_list,0)))
888
for i in range(self.NATOM):
889
self.ISMPER.append(eval(Pop(Item_list,0)))
892
for i in range(self.NATOM):
893
self.ALMPER.append(eval(Pop(Item_list,0)))
896
for i in range(self.NATOM):
897
self.IAPER.append(eval(Pop(Item_list,0)))
900
for i in range(self.NATOM):
901
self.IACPER.append(eval(Pop(Item_list,0)))
904
for i in range(self.NATOM):
905
self.CGPER.append(eval(Pop(Item_list,0)))
907
#....................................................
911
if len(Item_list) < self.NATOM:
912
print '(error: File too short!)'
914
print 'Reading Polarizability Data. For details, refer to online AMBER format manual'
916
for i in range(self.NATOM):
917
self.ATPOL.append(eval(Pop(Item_list,0)))
920
if len(Item_list) < self.NATOM:
921
print '(error: File too short!)'
924
for i in range(self.NATOM):
925
self.ATPOL1.append(eval(Pop(Item_list,0)))
927
#....................................................
930
print '(warning: File too large!)',
935
#============================================================
937
def Find_Amber_files():
938
'Look for sets of Amber files to process'
939
'''If not passed anything on the command line, look for pairs of
940
Amber files (.crd and .top) in the current directory. For
941
each set if there is no corresponding Lammps file (data.), or it is
942
older than any of the Amber files, add its basename to a list of
943
strings. This list is returned by the function'''
945
# Date and existence checks not yet implemented
951
# Extract basenames from command line
952
for Name in sys.argv[1:]:
953
if Name[-4:] == '.crd':
954
Basename_list.append(Name[:-4])
956
if Name[-4:] == '.top':
957
Basename_list.append(Name[:-4])
959
Basename_list.append(Name)
961
# Remove duplicate basenames
962
for Basename in Basename_list[:]:
963
while Basename_list.count(Basename) > 1:
964
Basename_list.remove(Basename)
966
if Basename_list == []:
967
print 'Looking for Amber files...',
968
Dir_list = os.listdir('.')
970
for File in Dir_list:
971
if File[-4:] == '.top':
973
if (Basename + '.crd') in Dir_list:
974
Basename_list.append(Basename)
975
if Basename_list != []:
977
for i in range(len(Basename_list)-1):
978
print Basename_list[i] + ',',
979
print Basename_list[-1] + '\n'
981
if Basename_list == []:
986
#============================================================
988
def Convert_Amber_files():
989
'Handle the whole conversion process'
991
print 'Welcome to amber2lammps, a program to convert Amber files to Lammps format!'
993
Basename_list = Find_Amber_files()
994
for Basename in Basename_list:
1000
l = a.Coerce_to_Lammps()
1001
l.Write_Lammps(Basename)
1006
#============================================================
1008
Convert_Amber_files()