Commit b0cf367c authored by Stephen Constable's avatar Stephen Constable
Browse files

Code cleanup

I have made things more technically correct: GROMACS processes pairs
and exclusions separately.  Also added proper support for fudgeLJ term.
Also added improved gro file parsing (technically it’s a fixed-field
format but this works too).
parent cd391b1b
...@@ -72,6 +72,9 @@ def _is_gro_coord(line): ...@@ -72,6 +72,9 @@ def _is_gro_coord(line):
sline = line.split() sline = line.split()
if len(sline) == 6 or len(sline) == 9: if len(sline) == 6 or len(sline) == 9:
return all([_isint(sline[2]), _isfloat(sline[3]), _isfloat(sline[4]), _isfloat(sline[5])]) return all([_isint(sline[2]), _isfloat(sline[3]), _isfloat(sline[4]), _isfloat(sline[5])])
#handles case when first entry is split
elif len(sline) == 7:
return all([_isint(sline[3]), _isfloat(sline[4]), _isfloat(sline[5]), _isfloat(sline[6])])
elif len(sline) == 5 or len(sline) == 8: elif len(sline) == 5 or len(sline) == 8:
return all([_isint(line[15:20]), _isfloat(sline[2]), _isfloat(sline[3]), _isfloat(sline[4])]) return all([_isint(line[15:20]), _isfloat(sline[2]), _isfloat(sline[3]), _isfloat(sline[4])])
else: else:
......
...@@ -258,8 +258,14 @@ class GromacsTopFile(object): ...@@ -258,8 +258,14 @@ class GromacsTopFile(object):
def _processDefaults(self, line): def _processDefaults(self, line):
"""Process the [ defaults ] line.""" """Process the [ defaults ] line."""
fields = line.split() fields = line.split()
if len(fields) < 4: if len(fields) < 5:
raise ValueError('Too few fields in [ defaults ] line: '+line) # fudgeLJ and fudgeQQ not specified, assumed 1.0 by default
if len(fields) == 3:
fields.append(1.0)
fields.append(1.0)
else:
print len(fields)
raise ValueError('Too few fields in [ defaults ] line: '+len(fields))
if fields[0] != '1': if fields[0] != '1':
raise ValueError('Unsupported nonbonded type: '+fields[0]) raise ValueError('Unsupported nonbonded type: '+fields[0])
if not (fields[1] == '2' or fields[1] == '1'): if not (fields[1] == '2' or fields[1] == '1'):
...@@ -592,7 +598,7 @@ class GromacsTopFile(object): ...@@ -592,7 +598,7 @@ class GromacsTopFile(object):
elif nonbondedMethod in (ff.CutoffPeriodic, ff.Ewald, ff.PME, ff.LJPME): elif nonbondedMethod in (ff.CutoffPeriodic, ff.Ewald, ff.PME, ff.LJPME):
raise ValueError('Illegal nonbonded method for a non-periodic system') raise ValueError('Illegal nonbonded method for a non-periodic system')
if self._defaults[1] == '1': if self._defaults[1] == '1':
#factor of 138.935456 for coulomb taken from tests/TestCustomNonbondedForce.h:574 # factor of 138.935456 for coulomb taken from tests/TestCustomNonbondedForce.h:574
nb = mm.CustomNonbondedForce('138.935456*q1*q2/r-sqrt(C1*C2)/r^6+sqrt(A1*A2)/r^12') nb = mm.CustomNonbondedForce('138.935456*q1*q2/r-sqrt(C1*C2)/r^6+sqrt(A1*A2)/r^12')
nb.addPerParticleParameter('q') nb.addPerParticleParameter('q')
nb.addPerParticleParameter('C') nb.addPerParticleParameter('C')
...@@ -618,10 +624,9 @@ class GromacsTopFile(object): ...@@ -618,10 +624,9 @@ class GromacsTopFile(object):
bondIndices = [] bondIndices = []
topologyAtoms = list(self.topology.atoms()) topologyAtoms = list(self.topology.atoms())
exceptions = [] exceptions = []
if self._defaults[1] == '1': pairs = []
fudgeQQ = 0.0 fudgeQQ = float(self._defaults[4])
elif self._defaults[1] == '2': fudgeLJ = float(self._defaults[3])
fudgeQQ = float(self._defaults[4])
# Build a lookup table to let us process dihedrals more quickly. # Build a lookup table to let us process dihedrals more quickly.
...@@ -786,16 +791,15 @@ class GromacsTopFile(object): ...@@ -786,16 +791,15 @@ class GromacsTopFile(object):
elif dihedralType == '2': elif dihedralType == '2':
# Harmonic torsion # Harmonic torsion
k = float(params[6]) k = float(params[6])
phi0 = float(params[5])
if k != 0: if k != 0:
if harmonicTorsion is None: if harmonicTorsion is None:
#harmonicTorsion = mm.CustomTorsionForce('k*(theta-theta0)^2')
harmonicTorsion = mm.CustomTorsionForce('0.5*k*(thetap-theta0)^2; thetap = step(-(theta-theta0+pi))*2*pi+theta+step(theta-theta0-pi)*(-2*pi); pi = 3.14159') harmonicTorsion = mm.CustomTorsionForce('0.5*k*(thetap-theta0)^2; thetap = step(-(theta-theta0+pi))*2*pi+theta+step(theta-theta0-pi)*(-2*pi); pi = 3.14159')
harmonicTorsion.addPerTorsionParameter('theta0') harmonicTorsion.addPerTorsionParameter('theta0')
harmonicTorsion.addPerTorsionParameter('k') harmonicTorsion.addPerTorsionParameter('k')
sys.addForce(harmonicTorsion) sys.addForce(harmonicTorsion)
phi0 = float(params[5]) # map phi0 into correct space
if phi0 > 180: phi0 = phi0 - 360 if phi0 > 180 else phi0
phi0 = phi0 - 360
harmonicTorsion.addTorsion(baseAtomIndex+atoms[0], baseAtomIndex+atoms[1], baseAtomIndex+atoms[2], baseAtomIndex+atoms[3], (phi0*degToRad, k)) harmonicTorsion.addTorsion(baseAtomIndex+atoms[0], baseAtomIndex+atoms[1], baseAtomIndex+atoms[2], baseAtomIndex+atoms[3], (phi0*degToRad, k))
else: else:
# RB Torsion # RB Torsion
...@@ -877,37 +881,44 @@ class GromacsTopFile(object): ...@@ -877,37 +881,44 @@ class GromacsTopFile(object):
continue # We'll use the automatically generated parameters continue # We'll use the automatically generated parameters
atom1params = nb.getParticleParameters(baseAtomIndex+atoms[0]) atom1params = nb.getParticleParameters(baseAtomIndex+atoms[0])
atom2params = nb.getParticleParameters(baseAtomIndex+atoms[1]) atom2params = nb.getParticleParameters(baseAtomIndex+atoms[1])
exceptions.append((baseAtomIndex+atoms[0], baseAtomIndex+atoms[1], atom1params[0]*atom2params[0]*fudgeQQ, params[0], params[1])) # enable tracking pairs and exceptions separately
if self._defaults[1] == '2': if self._defaults[1] == '1':
for fields in moleculeType.exclusions: pairs.append((baseAtomIndex+atoms[0], baseAtomIndex+atoms[1], atom1params[0]*atom2params[0]*fudgeQQ, params[0], params[1]))
atoms = [int(x)-1 for x in fields] elif self._defaults[1] == '2':
for atom in atoms[1:]: exceptions.append((baseAtomIndex+atoms[0], baseAtomIndex+atoms[1], atom1params[0]*atom2params[0]*fudgeQQ, params[0], params[1]))
if atom > atoms[0]: for fields in moleculeType.exclusions:
atoms = [int(x)-1 for x in fields]
for atom in atoms[1:]:
if atom > atoms[0]:
if self._defaults[1] == '1':
exceptions.append((baseAtomIndex+atoms[0], baseAtomIndex+atom))
elif self._defaults[1] == '2':
exceptions.append((baseAtomIndex+atoms[0], baseAtomIndex+atom, 0, 0, 0)) exceptions.append((baseAtomIndex+atoms[0], baseAtomIndex+atom, 0, 0, 0))
# Create nonbonded exceptions. # Create nonbonded exceptions.
if self._defaults[1] == '1': if self._defaults[1] == '1':
#no 1-4 scaling for electrostatics or VdW, only VdW exceptions # implement named exceptions (generally used for 1-4 interactions)
bond_exceptions = mm.CustomBondForce('-C/r^6+A/r^12') pair_bond = mm.CustomBondForce('138.935456*q/r-C/r^6+A/r^12')
bond_exceptions.addPerBondParameter('C') pair_bond.addPerBondParameter('q')
bond_exceptions.addPerBondParameter('A') pair_bond.addPerBondParameter('C')
sys.addForce(bond_exceptions) pair_bond.addPerBondParameter('A')
sys.addForce(pair_bond)
#generate 1-2 and 1-3 exclusions
# generate 1-2, 1-3, and 1-4 exclusions
nb.createExclusionsFromBonds(bondIndices, 3) nb.createExclusionsFromBonds(bondIndices, 3)
for pair in pairs:
pair_bond.addBond(pair[0], pair[1], [pair[2],float(pair[3])*fudgeLJ, float(pair[4])*fudgeLJ])
# create requested exclusions
for exception in exceptions: for exception in exceptions:
##debugging info, not needed
#print 'excl a1 =', str(exception[0]+1), ' excl a2 =', str(exception[1]+1), ' C =', exception[3], ' A =', exception[4]
nb.addExclusion(exception[0], exception[1]) nb.addExclusion(exception[0], exception[1])
bond_exceptions.addBond(exception[0], exception[1], [float(exception[3]), float(exception[4])])
elif self._defaults[1] == '2': elif self._defaults[1] == '2':
nb.createExceptionsFromBonds(bondIndices, fudgeQQ, float(self._defaults[3])) nb.createExceptionsFromBonds(bondIndices, fudgeQQ, fudgeLJ)
for exception in exceptions: for exception in exceptions:
nb.addException(exception[0], exception[1], exception[2], float(exception[3]), float(exception[4]), True) nb.addException(exception[0], exception[1], exception[2], float(exception[3])*fudgeLJ, float(exception[4]), True)
# Finish configuring the NonbondedForce. # Finish configuring the NonbondedForce.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment