Commit 16b5edb6 authored by peastman's avatar peastman
Browse files

Handle extra particles correctly when guessing why no template matched a residue.

parent 9e09ca68
...@@ -465,9 +465,7 @@ def _countResidueAtoms(elements): ...@@ -465,9 +465,7 @@ def _countResidueAtoms(elements):
"""Count the number of atoms of each element in a residue.""" """Count the number of atoms of each element in a residue."""
counts = {} counts = {}
for element in elements: for element in elements:
if element is None: if element in counts:
pass # This residue contains "atoms" (probably virtual sites) that should match any element
elif element in counts:
counts[element] += 1 counts[element] += 1
else: else:
counts[element] = 1 counts[element] = 1
...@@ -479,7 +477,8 @@ def _createResidueSignature(elements): ...@@ -479,7 +477,8 @@ def _createResidueSignature(elements):
counts = _countResidueAtoms(elements) counts = _countResidueAtoms(elements)
sig = [] sig = []
for c in counts: for c in counts:
sig.append((c, counts[c])) if c is not None:
sig.append((c, counts[c]))
sig.sort(key=lambda x: -x[0].mass) sig.sort(key=lambda x: -x[0].mass)
# Convert it to a string. # Convert it to a string.
...@@ -549,7 +548,7 @@ def _findMatchErrors(forcefield, res): ...@@ -549,7 +548,7 @@ def _findMatchErrors(forcefield, res):
"""Try to guess why a residue failed to match any template and return an error message.""" """Try to guess why a residue failed to match any template and return an error message."""
residueCounts = _countResidueAtoms([atom.element for atom in res.atoms()]) residueCounts = _countResidueAtoms([atom.element for atom in res.atoms()])
numResidueAtoms = sum(residueCounts.itervalues()) numResidueAtoms = sum(residueCounts.itervalues())
numResidueHeavyAtoms = sum(residueCounts[element] for element in residueCounts if element.symbol != 'H') numResidueHeavyAtoms = sum(residueCounts[element] for element in residueCounts if element not in (None, elem.hydrogen))
# Loop over templates and see how closely each one might match. # Loop over templates and see how closely each one might match.
...@@ -568,7 +567,7 @@ def _findMatchErrors(forcefield, res): ...@@ -568,7 +567,7 @@ def _findMatchErrors(forcefield, res):
# If there are too many missing atoms, discard this template. # If there are too many missing atoms, discard this template.
numTemplateAtoms = sum(templateCounts.itervalues()) numTemplateAtoms = sum(templateCounts.itervalues())
numTemplateHeavyAtoms = sum(templateCounts[element] for element in templateCounts if element.symbol != 'H') numTemplateHeavyAtoms = sum(templateCounts[element] for element in templateCounts if element not in (None, elem.hydrogen))
if numTemplateAtoms > numBestMatchAtoms: if numTemplateAtoms > numBestMatchAtoms:
continue continue
if numTemplateHeavyAtoms > numBestMatchHeavyAtoms: if numTemplateHeavyAtoms > numBestMatchHeavyAtoms:
...@@ -586,6 +585,7 @@ def _findMatchErrors(forcefield, res): ...@@ -586,6 +585,7 @@ def _findMatchErrors(forcefield, res):
bestMatchName = templateName bestMatchName = templateName
numBestMatchAtoms = numTemplateAtoms numBestMatchAtoms = numTemplateAtoms
numBestMatchHeavyAtoms = numTemplateHeavyAtoms numBestMatchHeavyAtoms = numTemplateHeavyAtoms
numBestMatchExtraParticles = len([atom for atom in template.atoms if atom.element is None])
# Return an appropriate error message. # Return an appropriate error message.
...@@ -596,7 +596,11 @@ def _findMatchErrors(forcefield, res): ...@@ -596,7 +596,11 @@ def _findMatchErrors(forcefield, res):
return 'The set of atoms matches %s, but the bonds are different.' % bestMatchName return 'The set of atoms matches %s, but the bonds are different.' % bestMatchName
if bestMatchName is not None: if bestMatchName is not None:
if numBestMatchHeavyAtoms == numResidueHeavyAtoms: if numBestMatchHeavyAtoms == numResidueHeavyAtoms:
return 'The set of atoms is similar to %s, but it is missing %d hydrogen atoms.' % (bestMatchName, numBestMatchAtoms-numResidueAtoms) numResidueExtraParticles = len([atom for atom in res.atoms() if atom.element is None])
if numResidueExtraParticles == 0 and numBestMatchExtraParticles == 0:
return 'The set of atoms is similar to %s, but it is missing %d hydrogen atoms.' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
if numBestMatchExtraParticles-numResidueExtraParticles == numBestMatchAtoms-numResidueAtoms:
return 'The set of atoms is similar to %s, but it is missing %d extra particles. You can add them with Modeller.addExtraParticles().' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
return 'The set of atoms is similar to %s, but it is missing %d atoms.' % (bestMatchName, numBestMatchAtoms-numResidueAtoms) return 'The set of atoms is similar to %s, but it is missing %d atoms.' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
return 'This might mean your input topology is missing some atoms or bonds, or possibly that you are using the wrong force field.' return 'This might mean your input topology is missing some atoms or bonds, or possibly that you are using the wrong force field.'
......
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