Commit 4bb7ddb9 authored by John Chodera's avatar John Chodera
Browse files

Merge in recent changes

parent 1260cb24
...@@ -632,6 +632,29 @@ class ForceField(object): ...@@ -632,6 +632,29 @@ class ForceField(object):
atom = self.getAtomIndexByName(atom_name) atom = self.getAtomIndexByName(atom_name)
self.addExternalBond(atom) self.addExternalBond(atom)
def areParametersIdentical(self, template2, matchingAtoms, matchingAtoms2):
"""Get whether this template and another one both assign identical atom types and parameters to all atoms.
Parameters
----------
template2: _TemplateData
the template to compare this one to
matchingAtoms: list
the indices of atoms in this template that atoms of the residue are matched to
matchingAtoms2: list
the indices of atoms in template2 that atoms of the residue are matched to
"""
atoms1 = [self.atoms[m] for m in matchingAtoms]
atoms2 = [template2.atoms[m] for m in matchingAtoms2]
if any(a1.type != a2.type or a1.parameters != a2.parameters for a1,a2 in zip(atoms1, atoms2)):
return False
# Properly comparing virtual sites really needs a much more complicated analysis. This simple check
# could easily fail for templates containing vsites, even if they're actually identical. Since we
# currently have no force fields that include both patches and vsites, I'm not going to worry about it now.
if self.virtualSites != template2.virtualSites:
return False
return True
class _TemplateAtomData(object): class _TemplateAtomData(object):
"""Inner class used to encapsulate data about an atom in a residue template definition.""" """Inner class used to encapsulate data about an atom in a residue template definition."""
def __init__(self, name, type, element, parameters={}): def __init__(self, name, type, element, parameters={}):
...@@ -866,7 +889,7 @@ class ForceField(object): ...@@ -866,7 +889,7 @@ class ForceField(object):
Returns Returns
------- -------
template : _ForceFieldTemplate template : _TemplateData
The matching forcefield residue template, or None if no matches are found. The matching forcefield residue template, or None if no matches are found.
matches : list matches : list
a list specifying which atom of the template each atom of the residue a list specifying which atom of the template each atom of the residue
...@@ -888,7 +911,13 @@ class ForceField(object): ...@@ -888,7 +911,13 @@ class ForceField(object):
template = allMatches[0][0] template = allMatches[0][0]
matches = allMatches[0][1] matches = allMatches[0][1]
elif len(allMatches) > 1: elif len(allMatches) > 1:
raise Exception('Multiple matching templates found for residue %d (%s): %s.' % (res.index+1, res.name, ', '.join(match[0].name for match in allMatches))) # We found multiple matches. This is OK if and only if they assign identical types and parameters to all atoms.
t1, m1 = allMatches[0]
for t2, m2 in allMatches[1:]:
if not t1.areParametersIdentical(t2, m1, m2):
raise Exception('Multiple non-identical matching templates found for residue %d (%s): %s.' % (res.index+1, res.name, ', '.join(match[0].name for match in allMatches)))
template = allMatches[0][0]
matches = allMatches[0][1]
return [template, matches] return [template, matches]
def _buildBondedToAtomList(self, topology): def _buildBondedToAtomList(self, topology):
...@@ -4447,7 +4476,7 @@ class AmoebaVdwGenerator(object): ...@@ -4447,7 +4476,7 @@ class AmoebaVdwGenerator(object):
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args): def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
sigmaMap = {'ARITHMETIC':1, 'GEOMETRIC':1, 'CUBIC-MEAN':1} sigmaMap = {'ARITHMETIC':1, 'GEOMETRIC':1, 'CUBIC-MEAN':1}
epsilonMap = {'ARITHMETIC':1, 'GEOMETRIC':1, 'HARMONIC':1, 'HHG':1} epsilonMap = {'ARITHMETIC':1, 'GEOMETRIC':1, 'HARMONIC':1, 'W-H':1, 'HHG':1}
force = mm.AmoebaVdwForce() force = mm.AmoebaVdwForce()
sys.addForce(force) sys.addForce(force)
......
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