Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
a773f1c7
Commit
a773f1c7
authored
Jan 19, 2016
by
John Chodera (MSKCC)
Browse files
Add methods to get unmatched residues without forcefield templates.
parent
39120086
Changes
3
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1666 additions
and
28 deletions
+1666
-28
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+83
-0
wrappers/python/tests/TestForceField.py
wrappers/python/tests/TestForceField.py
+76
-28
wrappers/python/tests/systems/nacl-water.pdb
wrappers/python/tests/systems/nacl-water.pdb
+1507
-0
No files found.
wrappers/python/simtk/openmm/app/forcefield.py
View file @
a773f1c7
...
...
@@ -569,6 +569,89 @@ class ForceField(object):
break
return
[
template
,
matches
]
def
getUnmatchedResidues
(
self
,
topology
):
"""Return a list of Residue objects from specified topology for which no forcefield templates are available.
Parameters
----------
topology : Topology
The Topology for which to create a System
Returns
-------
unmatched_residues : list of Residue
List of residue templates from `topology` for which no forcefield residue templates are available.
Note that multiple instances of the same residue appearing at different points in the topology may be returned.
This method may be of use in generating missing residue templates or diagnosing parameterization failures.
"""
# Find the template matching each residue, compiling a list of residues for which no templates are available.
unmatched_residues
=
list
()
# list of unmatched residues
for
chain
in
topology
.
chains
():
for
res
in
chain
.
residues
():
# Attempt to match one of the existing templates.
[
template
,
matches
]
=
self
.
_getResidueTemplateMatches
(
res
,
bondedToAtom
)
if
matches
is
None
:
# No existing templates match.
unmatched_residues
.
append
(
res
)
return
unmatched_residues
def
getUniqueUnmatchedResidues
(
self
,
topology
):
"""Returns a unique list of Residue objects from specified topology for which no forcefield templates are available.
Parameters
----------
topology : Topology
The Topology for which to create a System
Returns
-------
unmatched_residues : list of Residue
List of residue templates from `topology` for which no forcefield residue templates are available.
Note that only a single instances each missing residue type will be returned.
This method may be of use in generating missing residue templates.
"""
# Get a non-unique list of unmatched residues.
unmatched_residues
=
self
.
getUnmatchedResidues
(
topology
)
# Record which atoms are bonded to each other atom
bondedToAtom
=
[]
for
atom
in
topology
.
atoms
():
bondedToAtom
.
append
(
set
())
for
bond
in
topology
.
bonds
():
bondedToAtom
[
bond
.
atom1
.
index
].
add
(
bond
.
atom2
.
index
)
bondedToAtom
[
bond
.
atom2
.
index
].
add
(
bond
.
atom1
.
index
)
# Generate a unique list of unmatched residues by comparing fingerprints.
unique_unmatched_residues
=
list
()
signatures
=
set
()
for
residue
in
unmatched_residues
:
signature
=
_createResidueSignature
([
atom
.
element
for
atom
in
residue
.
atoms
()
])
is_unique
=
True
if
signature
in
signatures
:
# Signature is the same as an existing residue; check connectivity.
template
=
ForceField
.
_TemplateData
(
residue
.
name
)
for
atom
in
residue
.
atoms
():
template
.
atoms
.
append
(
ForceField
.
_TemplateAtomData
(
atom
.
name
,
None
,
atom
.
element
))
for
(
atom1
,
atom2
)
in
residue
.
internal_bonds
():
template
.
addBondByName
(
atom1
.
name
,
atom2
.
name
)
residue_atoms
=
[
atom
for
atom
in
residue
.
atoms
()
]
for
(
atom1
,
atom2
)
in
residue
.
external_bonds
():
if
atom1
in
residue_atoms
:
template
.
addExternalBondByName
(
atom1
.
name
)
elif
atom2
in
residue_atoms
:
template
.
addExternalBondByName
(
atom2
.
name
)
for
check_residue
in
unique_unmatched_residues
:
matches
=
_matchResidue
(
check_residue
,
template
,
bondedToAtom
)
if
matches
is
not
None
:
is_unique
=
False
if
is_unique
:
# Residue is unique.
unique_unmatched_residues
.
append
(
residue
)
signatures
.
add
(
signature
)
return
unique_unmatched_residues
def
createSystem
(
self
,
topology
,
nonbondedMethod
=
NoCutoff
,
nonbondedCutoff
=
1.0
*
unit
.
nanometer
,
constraints
=
None
,
rigidWater
=
True
,
removeCMMotion
=
True
,
hydrogenMass
=
None
,
**
args
):
"""Construct an OpenMM System representing a Topology with this force field.
...
...
wrappers/python/tests/TestForceField.py
View file @
a773f1c7
...
...
@@ -347,6 +347,55 @@ class TestForceField(unittest.TestCase):
system
=
forcefield
.
createSystem
(
pdb
.
topology
,
nonbondedMethod
=
test
[
'nonbondedMethod'
])
# TODO: Test energies are finite?
def
test_getUnmatchedResidues
(
self
):
"""Test retrieval of list of residues for which no templates are available."""
#
# Test where we generate parameters for only a ligand.
#
# Load the PDB file.
pdb
=
PDBFile
(
os
.
path
.
join
(
'systems'
,
'T4-lysozyme-L99A-p-xylene-implicit.pdb'
))
# Create a ForceField object.
forcefield
=
ForceField
(
'amber99sb.xml'
,
'tip3p.xml'
)
# Get list of unmatched residues.
unmatched_residues
=
forcefield
.
getUnmatchedResidues
(
pdb
.
topology
)
# Check results.
self
.
assertEqual
(
len
(
unmatched_residues
),
1
)
self
.
assertEqual
(
unmatched_residues
[
0
].
name
,
'TMP'
)
self
.
assertEqual
(
unmatched_residues
[
0
].
id
,
163
)
# Load the PDB file.
pdb
=
PDBFile
(
os
.
path
.
join
(
'systems'
,
'ala_ala_ala.pdb'
))
# Create a ForceField object.
forcefield
=
ForceField
(
'tip3p.xml'
)
# Get list of unmatched residues.
unmatched_residues
=
forcefield
.
getUnmatchedResidues
(
pdb
.
topology
)
# Check results.
self
.
assertEqual
(
len
(
unmatched_residues
),
3
)
self
.
assertEqual
(
unmatched_residues
[
0
].
name
,
'ALA'
)
self
.
assertEqual
(
unmatched_residues
[
0
].
chain
,
'X'
)
self
.
assertEqual
(
unmatched_residues
[
0
].
id
,
1
)
def
test_getUniqueUnmatchedResidues
(
self
):
"""Test retrieval of list of residues for which no templates are available."""
#
# Test where we generate parameters for only a ligand.
#
# Load the PDB file.
pdb
=
PDBFile
(
os
.
path
.
join
(
'systems'
,
'nacl-water.pdb'
))
# Create a ForceField object.
forcefield
=
ForceField
(
'tip3p.xml'
)
# Get list of unmatched residues.
unmatched_residues
=
forcefield
.
getUnmatchedResidues
(
pdb
.
topology
)
unique_unmatched_residues
=
forcefield
.
getUniqueUnmatchedResidues
(
pdb
.
topology
)
# Check results.
self
.
assertEqual
(
len
(
unmatched_residues
),
14
)
self
.
assertEqual
(
len
(
unique_unmatched_residues
),
2
)
unique_names
=
set
([
residue
.
name
for
residue
in
unique_unmatched_residues
])
self
.
assertTrue
(
'NA'
in
unique_names
)
self
.
assertTrue
(
'CL'
in
unique_names
)
class
AmoebaTestForceField
(
unittest
.
TestCase
):
"""Test the ForceField.createSystem() method with the AMOEBA forcefield."""
...
...
@@ -436,4 +485,3 @@ class AmoebaTestForceField(unittest.TestCase):
if
__name__
==
'__main__'
:
unittest
.
main
()
wrappers/python/tests/systems/nacl-water.pdb
0 → 100644
View file @
a773f1c7
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment