Commit b2a6f40d authored by Jason Swails's avatar Jason Swails
Browse files

Take the 1-4 non-bonded scaling parameters from the Amber topology files if

present, defaulting to 1.2 (SCEE) and 2.0 (SCNB) if they're not present. If
values for scee and scnb are provided to readAmberSystem they will override any
values in the topology file, but a warning will be printed (since ignoring the
scaling parameters in the topology file really changes the force field).
parent 089767b0
...@@ -41,9 +41,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -41,9 +41,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
import os import os
import os.path import os.path
import copy
import re import re
import math import math
import warnings
try: try:
import numpy import numpy
...@@ -431,12 +431,22 @@ class PrmtopLoader(object): ...@@ -431,12 +431,22 @@ class PrmtopLoader(object):
if int(dihedralPointers[ii+2])>0 and int(dihedralPointers[ii+3])>0: if int(dihedralPointers[ii+2])>0 and int(dihedralPointers[ii+3])>0:
iAtom = int(dihedralPointers[ii])//3 iAtom = int(dihedralPointers[ii])//3
lAtom = int(dihedralPointers[ii+3])//3 lAtom = int(dihedralPointers[ii+3])//3
iidx = int(dihedralPointers[ii+4]) - 1
chargeProd = charges[iAtom]*charges[lAtom] chargeProd = charges[iAtom]*charges[lAtom]
(rVdwI, epsilonI) = nonbondTerms[iAtom] (rVdwI, epsilonI) = nonbondTerms[iAtom]
(rVdwL, epsilonL) = nonbondTerms[lAtom] (rVdwL, epsilonL) = nonbondTerms[lAtom]
rMin = (rVdwI+rVdwL) rMin = (rVdwI+rVdwL)
epsilon = math.sqrt(epsilonI*epsilonL) epsilon = math.sqrt(epsilonI*epsilonL)
returnList.append((iAtom, lAtom, chargeProd, rMin, epsilon)) try:
iScee = float(self._raw_data["SCEE_SCALE_FACTOR"][iidx])
except KeyError:
iScee = 1.2
try:
iScnb = float(self._raw_data["SCNB_SCALE_FACTOR"][iidx])
except KeyError:
iScnb = 2.0
returnList.append((iAtom, lAtom, chargeProd, rMin, epsilon, iScee, iScnb))
return returnList return returnList
def getExcludedAtoms(self): def getExcludedAtoms(self):
...@@ -502,11 +512,15 @@ class PrmtopLoader(object): ...@@ -502,11 +512,15 @@ class PrmtopLoader(object):
units.Quantity(y, units.angstrom), units.Quantity(y, units.angstrom),
units.Quantity(z, units.angstrom)) units.Quantity(z, units.angstrom))
@property
def has_scee_scnb(self):
return ("SCEE_SCALE_FACTOR" in self._raw_data and "SCNB_SCALE_FACTOR" in self._raw_data)
#============================================================================================= #=============================================================================================
# AMBER System builder (based on, but not identical to, systemManager from 'zander') # AMBER System builder (based on, but not identical to, systemManager from 'zander')
#============================================================================================= #=============================================================================================
def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmodel=None, soluteDielectric=1.0, solventDielectric=78.5, nonbondedCutoff=None, nonbondedMethod='NoCutoff', scee=1.2, scnb=2.0, mm=None, verbose=False, EwaldErrorTolerance=None, flexibleConstraints=True, rigidWater=True): def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmodel=None, soluteDielectric=1.0, solventDielectric=78.5, nonbondedCutoff=None, nonbondedMethod='NoCutoff', scee=None, scnb=None, mm=None, verbose=False, EwaldErrorTolerance=None, flexibleConstraints=True, rigidWater=True):
""" """
Create an OpenMM System from an Amber prmtop file. Create an OpenMM System from an Amber prmtop file.
...@@ -520,8 +534,8 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode ...@@ -520,8 +534,8 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
soluteDielectric (float) - The solute dielectric constant to use in the implicit solvent model (default: 1.0) soluteDielectric (float) - The solute dielectric constant to use in the implicit solvent model (default: 1.0)
solventDielectric (float) - The solvent dielectric constant to use in the implicit solvent model (default: 78.5) solventDielectric (float) - The solvent dielectric constant to use in the implicit solvent model (default: 78.5)
nonbondedCutoff (float) - if specified, will set nonbondedCutoff (default: None) nonbondedCutoff (float) - if specified, will set nonbondedCutoff (default: None)
scnb (float) - 1-4 Lennard-Jones scaling factor (default: 1.2) scnb (float) - 1-4 Lennard-Jones scaling factor (default: taken from prmtop or 1.2 if not present there)
scee (float) - 1-4 electrostatics scaling factor (default: 2.0) scee (float) - 1-4 electrostatics scaling factor (default: taken from prmtop or 2.0 if not present there)
mm - if specified, this module will be used in place of pyopenmm (default: None) mm - if specified, this module will be used in place of pyopenmm (default: None)
verbose (boolean) - if True, print out information on progress (default: False) verbose (boolean) - if True, print out information on progress (default: False)
flexibleConstraints (boolean) - if True, flexible bonds will be added in addition ot constrained bonds flexibleConstraints (boolean) - if True, flexible bonds will be added in addition ot constrained bonds
...@@ -571,6 +585,10 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode ...@@ -571,6 +585,10 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
if prmtop.getIfBox()>1: if prmtop.getIfBox()>1:
raise Exception("only standard periodic boxes are currently supported") raise Exception("only standard periodic boxes are currently supported")
if prmtop.has_scee_scnb and (scee is not None or scnb is not None):
warnings.warn("1-4 scaling parameters in topology file are being ignored. "
"This is not recommended unless you know what you are doing.")
# Use pyopenmm implementation of OpenMM by default. # Use pyopenmm implementation of OpenMM by default.
if mm is None: if mm is None:
mm = simtk.openmm mm = simtk.openmm
...@@ -615,7 +633,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode ...@@ -615,7 +633,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
if shake == 'h-angles': if shake == 'h-angles':
numConstrainedBonds = system.getNumConstraints() numConstrainedBonds = system.getNumConstraints()
atomConstraints = [[]]*system.getNumParticles() atomConstraints = [[]]*system.getNumParticles()
for i in range(system.getNumConstraints()): for i in range(numConstrainedBonds):
c = system.getConstraintParameters(i) c = system.getConstraintParameters(i)
distance = c[2].value_in_unit(units.nanometer) distance = c[2].value_in_unit(units.nanometer)
atomConstraints[c[0]].append((c[1], distance)) atomConstraints[c[0]].append((c[1], distance))
...@@ -712,9 +730,12 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode ...@@ -712,9 +730,12 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
# Add 1-4 Interactions # Add 1-4 Interactions
excludedAtomPairs = set() excludedAtomPairs = set()
sigmaScale = 2**(-1./6.) sigmaScale = 2**(-1./6.)
for (iAtom, lAtom, chargeProd, rMin, epsilon) in prmtop.get14Interactions(): _scee, _scnb = scee, scnb
chargeProd /= scee for (iAtom, lAtom, chargeProd, rMin, epsilon, iScee, iScnb) in prmtop.get14Interactions():
epsilon /= scnb if scee is None: _scee = iScee
if scnb is None: _scnb = iScnb
chargeProd /= _scee
epsilon /= _scnb
sigma = rMin * sigmaScale sigma = rMin * sigmaScale
force.addException(iAtom, lAtom, chargeProd, sigma, epsilon) force.addException(iAtom, lAtom, chargeProd, sigma, epsilon)
excludedAtomPairs.add(min((iAtom, lAtom), (lAtom, iAtom))) excludedAtomPairs.add(min((iAtom, lAtom), (lAtom, iAtom)))
......
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