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
d4d25d46
Commit
d4d25d46
authored
Jun 20, 2016
by
peastman
Committed by
GitHub
Jun 20, 2016
Browse files
Merge pull request #1453 from peastman/patches
Support patches in force fields
parents
ba686094
238a1068
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1729 additions
and
54 deletions
+1729
-54
docs-source/usersguide/application.rst
docs-source/usersguide/application.rst
+101
-0
docs-source/usersguide/conf.py
docs-source/usersguide/conf.py
+1
-1
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+414
-50
wrappers/python/tests/TestForceField.py
wrappers/python/tests/TestForceField.py
+3
-3
wrappers/python/tests/TestPatches.py
wrappers/python/tests/TestPatches.py
+317
-0
wrappers/python/tests/systems/bpti.pdb
wrappers/python/tests/systems/bpti.pdb
+893
-0
No files found.
docs-source/usersguide/application.rst
View file @
d4d25d46
...
@@ -2063,6 +2063,107 @@ are :code:`wo1`\ , :code:`wo2`\ , :code:`wo3`\ , :code:`wx1`\ , :code:`wx2`\ ,
...
@@ -2063,6 +2063,107 @@ are :code:`wo1`\ , :code:`wo2`\ , :code:`wo3`\ , :code:`wx1`\ , :code:`wx2`\ ,
:code:`wx3`\ , :code:`wy1`\ , :code:`wy2`\ , :code:`wy3`\ , :code:`p1`\ ,
:code:`wx3`\ , :code:`wy1`\ , :code:`wy2`\ , :code:`wy3`\ , :code:`p1`\ ,
:code:`p2`\ , and :code:`p3`\ .
:code:`p2`\ , and :code:`p3`\ .
<Patches>
=========
A "patch" is a set of rules for modifying a residue template (or possibly multiple
templates at once). For example a terminal amino acid is slightly different from
one in the middle of a chain. A force field could of course define multiple
templates for each amino acid (standard, N-terminal, C-terminal, and monomer),
but since the modifications are the same for nearly all amino acids, it is simpler
to include only the "standard" templates, along with a set of patches for
modifying terminal residues.
Here is an example of a patch definition:
.. code-block:: xml
<Patch name="NTER">
<RemoveAtom name="H"/>
<RemoveBond atomName1="N" atomName2="H"/>
<AddAtom name="H1" type="H"/>
<AddAtom name="H2" type="H"/>
<AddAtom name="H3" type="H"/>
<AddBond atomName1="N" atomName2="H1"/>
<AddBond atomName1="N" atomName2="H2"/>
<AddBond atomName1="N" atomName2="H3"/>
<RemoveExternalBond atomName="N"/>
<ChangeAtom name="N" type="N3"/>
</Patch>
There is one :code:`<Patch>` tag for each patch definition. That in turn may
contain any of the following tags:
* An :code:`<AddAtom>` tag indicates that an atom should be added to the
template. It specifies the name of the atom and its atom type.
* A :code:`<ChangeAtom>` tag indicates that the type of an atom already present
in the template should be altered. It specifies the name of the atom and its
new atom type.
* A :code:`<RemoveAtom>` tag indicates that an atom should be removed from the
template. It specifies the name of the atom to remove.
* An :code:`<AddBond>` tag indicates that a bond should be added to the
template. It specifies the names of the two bonded atoms.
* A :code:`<RemoveBond>` tag indicates that a bond already present in the
template should be removed. It specifies the names of the two bonded atoms.
* An :code:`<AddExternalBond>` tag indicates that a new external bond should be
added to the template. It specifies the name of the bonded atom.
* A :code:`<RemoveExternalBond>` tag indicates that an external bond aleady
present in the template should be removed. It specifies the name of the
bonded atom.
In addition to defining the patches, you also must identify which residue
templates each patch can be applied to. This can be done in two ways. The more
common one is to have each template identify the patches that can be applied to
it. This is done with an :code:`<AllowPatch>` tag:
.. code-block:: xml
<Residue name="ALA">
<AllowPatch name="CTER"/>
<AllowPatch name="NTER"/>
...
</Residue>
Alternatively, the patch can indicate which residues it may be applied to. This
is done with an :code:`<ApplyToResidue>` tag:
.. code-block:: xml
<Patch name="NTER">
<ApplyToResidue name="ALA"/>
<ApplyToResidue name="ARG"/>
...
</Patch>
A patch can alter multiple templates at once. This is useful for creating bonds
between molecules, and allows the atom types in one residue to depend on the
identity of the other residue it is bonded to. To create a multi-residue patch,
added a :code:`residues` attribute to the :code:`<Patch>` tag specifying how many
residues that patch covers. Then whenever you refer to an atom, prefix its name
with the index of the residue it belongs to:
.. code-block:: xml
<Patch name="Disulfide" residues="2">
<RemoveAtom name="1:HG"/>
<RemoveAtom name="2:HG"/>
<AddBond atomName1="1:SG" atomName2="2:SG"/>
<ApplyToResidue name="1:CYS"/>
<ApplyToResidue name="2:CYS"/>
</Patch>
In this example, the patch modifies two residues of the same type, but that need
not always be true. Each :code:`<ApplyToResidue>` tag therefore indicates which
one of the residue templates it modifies may be of the specified type. Similarly,
if a residue template includes an :code:`<AcceptPatch>` tag for a multi-residue
patch, it must specify the name of the patch, followed by the index of the residue
within that patch:
.. code-block:: xml
<AllowPatch name="Disulfide:1"/>
Missing residue templates
Missing residue templates
=========================
=========================
...
...
docs-source/usersguide/conf.py
View file @
d4d25d46
...
@@ -26,7 +26,7 @@ sys.path.append(os.path.abspath('../sphinx'))
...
@@ -26,7 +26,7 @@ sys.path.append(os.path.abspath('../sphinx'))
# Add any Sphinx extension module names here, as strings. They can be extensions
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions
=
[
'sphinx.ext.pngmath'
,
'sphinx.ext.mathjax'
,
'sphinxcontrib.bibtex'
,
'autonumber'
,
'samepage'
,
'caption'
,
'numsec'
]
extensions
=
[
'sphinx.ext.mathjax'
,
'sphinxcontrib.bibtex'
,
'autonumber'
,
'samepage'
,
'caption'
,
'numsec'
]
# Add any paths that contain templates here, relative to this directory.
# Add any paths that contain templates here, relative to this directory.
templates_path
=
[
'_templates'
]
templates_path
=
[
'_templates'
]
...
...
wrappers/python/simtk/openmm/app/forcefield.py
View file @
d4d25d46
This diff is collapsed.
Click to expand it.
wrappers/python/tests/TestForceField.py
View file @
d4d25d46
...
@@ -569,8 +569,8 @@ class TestForceField(unittest.TestCase):
...
@@ -569,8 +569,8 @@ class TestForceField(unittest.TestCase):
# confirm charge
# confirm charge
self
.
assertEqual
(
sys
.
getForce
(
0
).
getParticleParameters
(
0
)[
0
].
_value
,
3.0
)
self
.
assertEqual
(
sys
.
getForce
(
0
).
getParticleParameters
(
0
)[
0
].
_value
,
3.0
)
def
test_ResidueOver
loa
ding
(
self
):
def
test_ResidueOver
ri
ding
(
self
):
"""Test residue over
loa
ding via over
load
tag in the XML"""
"""Test residue over
ri
ding via over
ride
tag in the XML"""
ffxml1
=
"""<ForceField>
ffxml1
=
"""<ForceField>
<AtomTypes>
<AtomTypes>
...
@@ -607,7 +607,7 @@ class TestForceField(unittest.TestCase):
...
@@ -607,7 +607,7 @@ class TestForceField(unittest.TestCase):
<Type name="Fe2+_tip3p_standard" class="Fe2+_tip3p_standard" element="Fe" mass="55.85"/>
<Type name="Fe2+_tip3p_standard" class="Fe2+_tip3p_standard" element="Fe" mass="55.85"/>
</AtomTypes>
</AtomTypes>
<Residues>
<Residues>
<Residue name="FE2" over
load
="1">
<Residue name="FE2" over
ride
="1">
<Atom name="FE2" type="Fe2+_tip3p_standard" charge="2.0"/>
<Atom name="FE2" type="Fe2+_tip3p_standard" charge="2.0"/>
</Residue>
</Residue>
</Residues>
</Residues>
...
...
wrappers/python/tests/TestPatches.py
0 → 100644
View file @
d4d25d46
import
unittest
from
simtk.openmm.app
import
*
from
simtk.openmm
import
*
from
simtk.unit
import
*
import
simtk.openmm.app.forcefield
as
forcefield
import
math
try
:
from
cStringIO
import
StringIO
except
ImportError
:
from
io
import
StringIO
import
os
class
TestPatches
(
unittest
.
TestCase
):
"""Test ForceFields that use patches."""
def
testParsePatch
(
self
):
"""Test parsing a <Patch> tag."""
xml
=
"""
<ForceField>
<AtomTypes>
<Type name="A type" class="A class" element="O" mass="15.99943"/>
<Type name="B type" class="B class" element="H" mass="1.007947"/>
</AtomTypes>
<Patches>
<Patch name="Test">
<AddAtom name="A" type="A type"/>
<ChangeAtom name="B" type="B type"/>
<RemoveAtom name="C"/>
<AddBond atomName1="A" atomName2="B"/>
<RemoveBond atomName1="B" atomName2="C"/>
<AddExternalBond atomName="A"/>
<RemoveExternalBond atomName="C"/>
<ApplyToResidue name="RES"/>
</Patch>
</Patches>
</ForceField>"""
ff
=
ForceField
(
StringIO
(
xml
))
self
.
assertEqual
(
1
,
len
(
ff
.
_patches
))
patch
=
ff
.
_patches
[
'Test'
]
self
.
assertEqual
(
1
,
len
(
patch
.
addedAtoms
))
self
.
assertEqual
(
1
,
len
(
patch
.
addedAtoms
[
0
]))
self
.
assertEqual
(
1
,
len
(
patch
.
changedAtoms
))
self
.
assertEqual
(
1
,
len
(
patch
.
changedAtoms
[
0
]))
self
.
assertEqual
(
1
,
len
(
patch
.
deletedAtoms
))
self
.
assertEqual
(
1
,
len
(
patch
.
addedBonds
))
self
.
assertEqual
(
1
,
len
(
patch
.
deletedBonds
))
self
.
assertEqual
(
1
,
len
(
patch
.
addedExternalBonds
))
self
.
assertEqual
(
1
,
len
(
patch
.
deletedExternalBonds
))
self
.
assertEqual
(
1
,
len
(
ff
.
_templatePatches
))
self
.
assertEqual
(
1
,
len
(
ff
.
_templatePatches
[
'RES'
]))
self
.
assertEqual
(
'A'
,
patch
.
addedAtoms
[
0
][
0
].
name
)
self
.
assertEqual
(
'A type'
,
patch
.
addedAtoms
[
0
][
0
].
type
)
self
.
assertEqual
(
'B'
,
patch
.
changedAtoms
[
0
][
0
].
name
)
self
.
assertEqual
(
'B type'
,
patch
.
changedAtoms
[
0
][
0
].
type
)
self
.
assertEqual
(
'C'
,
patch
.
deletedAtoms
[
0
].
name
)
self
.
assertEqual
(
0
,
patch
.
deletedAtoms
[
0
].
residue
)
self
.
assertEqual
(
'A'
,
patch
.
addedBonds
[
0
][
0
].
name
)
self
.
assertEqual
(
0
,
patch
.
addedBonds
[
0
][
0
].
residue
)
self
.
assertEqual
(
'B'
,
patch
.
addedBonds
[
0
][
1
].
name
)
self
.
assertEqual
(
0
,
patch
.
addedBonds
[
0
][
1
].
residue
)
self
.
assertEqual
(
'B'
,
patch
.
deletedBonds
[
0
][
0
].
name
)
self
.
assertEqual
(
0
,
patch
.
deletedBonds
[
0
][
0
].
residue
)
self
.
assertEqual
(
'C'
,
patch
.
deletedBonds
[
0
][
1
].
name
)
self
.
assertEqual
(
0
,
patch
.
deletedBonds
[
0
][
1
].
residue
)
self
.
assertEqual
(
'A'
,
patch
.
addedExternalBonds
[
0
].
name
)
self
.
assertEqual
(
0
,
patch
.
addedExternalBonds
[
0
].
residue
)
self
.
assertEqual
(
'C'
,
patch
.
deletedExternalBonds
[
0
].
name
)
self
.
assertEqual
(
0
,
patch
.
deletedExternalBonds
[
0
].
residue
)
self
.
assertEqual
(
'Test'
,
ff
.
_templatePatches
[
'RES'
][
0
][
0
])
self
.
assertEqual
(
0
,
ff
.
_templatePatches
[
'RES'
][
0
][
1
])
def
testParseMultiresiduePatch
(
self
):
"""Test parsing a <Patch> tag that affects two residues."""
xml
=
"""
<ForceField>
<AtomTypes>
<Type name="A type" class="A class" element="O" mass="15.99943"/>
<Type name="B type" class="B class" element="H" mass="1.007947"/>
</AtomTypes>
<Patches>
<Patch name="Test" residues="2">
<AddAtom name="1:A" type="A type"/>
<ChangeAtom name="2:B" type="B type"/>
<AddBond atomName1="1:A" atomName2="2:B"/>
<ApplyToResidue name="1:RESA"/>
<ApplyToResidue name="2:RESB"/>
</Patch>
</Patches>
</ForceField>"""
ff
=
ForceField
(
StringIO
(
xml
))
self
.
assertEqual
(
1
,
len
(
ff
.
_patches
))
patch
=
ff
.
_patches
[
'Test'
]
self
.
assertEqual
(
2
,
len
(
patch
.
addedAtoms
))
self
.
assertEqual
(
1
,
len
(
patch
.
addedAtoms
[
0
]))
self
.
assertEqual
(
0
,
len
(
patch
.
addedAtoms
[
1
]))
self
.
assertEqual
(
2
,
len
(
patch
.
changedAtoms
))
self
.
assertEqual
(
0
,
len
(
patch
.
changedAtoms
[
0
]))
self
.
assertEqual
(
1
,
len
(
patch
.
changedAtoms
[
1
]))
self
.
assertEqual
(
1
,
len
(
patch
.
addedBonds
))
self
.
assertEqual
(
2
,
len
(
ff
.
_templatePatches
))
self
.
assertEqual
(
1
,
len
(
ff
.
_templatePatches
[
'RESA'
]))
self
.
assertEqual
(
1
,
len
(
ff
.
_templatePatches
[
'RESB'
]))
self
.
assertEqual
(
'A'
,
patch
.
addedAtoms
[
0
][
0
].
name
)
self
.
assertEqual
(
'A type'
,
patch
.
addedAtoms
[
0
][
0
].
type
)
self
.
assertEqual
(
'B'
,
patch
.
changedAtoms
[
1
][
0
].
name
)
self
.
assertEqual
(
'B type'
,
patch
.
changedAtoms
[
1
][
0
].
type
)
self
.
assertEqual
(
'A'
,
patch
.
addedBonds
[
0
][
0
].
name
)
self
.
assertEqual
(
0
,
patch
.
addedBonds
[
0
][
0
].
residue
)
self
.
assertEqual
(
'B'
,
patch
.
addedBonds
[
0
][
1
].
name
)
self
.
assertEqual
(
1
,
patch
.
addedBonds
[
0
][
1
].
residue
)
self
.
assertEqual
(
'Test'
,
ff
.
_templatePatches
[
'RESA'
][
0
][
0
])
self
.
assertEqual
(
0
,
ff
.
_templatePatches
[
'RESA'
][
0
][
1
])
self
.
assertEqual
(
'Test'
,
ff
.
_templatePatches
[
'RESB'
][
0
][
0
])
self
.
assertEqual
(
1
,
ff
.
_templatePatches
[
'RESB'
][
0
][
1
])
def
testApplyPatch
(
self
):
"""Test applying a patch to a template."""
xml
=
"""
<ForceField>
<AtomTypes>
<Type name="A type" class="A class" element="O" mass="15.99943"/>
<Type name="B type" class="B class" element="H" mass="1.007947"/>
<Type name="C type" class="C class" element="H" mass="1.007947"/>
<Type name="D type" class="D class" element="C" mass="12.010000"/>
</AtomTypes>
<Residues>
<Residue name="RES">
<Atom name="A" type="A type"/>
<Atom name="B" type="B type"/>
<Atom name="C" type="C type"/>
<Bond atomName1="A" atomName2="B"/>
<Bond atomName1="B" atomName2="C"/>
<ExternalBond atomName="C"/>
<VirtualSite type="average2" siteName="C" atomName1="B" atomName2="C" weight1="0.6" weight2="0.4"/>
</Residue>
</Residues>
<Patches>
<Patch name="Test">
<AddAtom name="D" type="D type"/>
<ChangeAtom name="B" type="A type"/>
<RemoveAtom name="A"/>
<AddBond atomName1="B" atomName2="D"/>
<RemoveBond atomName1="A" atomName2="B"/>
<AddExternalBond atomName="D"/>
<RemoveExternalBond atomName="C"/>
<ApplyToResidue name="RES"/>
</Patch>
</Patches>
</ForceField>"""
ff
=
ForceField
(
StringIO
(
xml
))
self
.
assertEqual
(
1
,
len
(
ff
.
_patches
))
patch
=
ff
.
_patches
[
'Test'
]
template
=
ff
.
_templates
[
'RES'
]
newTemplates
=
patch
.
createPatchedTemplates
([
template
])
self
.
assertEqual
(
1
,
len
(
newTemplates
))
t
=
newTemplates
[
0
]
self
.
assertEqual
(
3
,
len
(
t
.
atoms
))
self
.
assertTrue
(
any
(
a
.
name
==
'B'
and
a
.
type
==
'A type'
for
a
in
t
.
atoms
))
self
.
assertTrue
(
any
(
a
.
name
==
'C'
and
a
.
type
==
'C type'
for
a
in
t
.
atoms
))
self
.
assertTrue
(
any
(
a
.
name
==
'D'
and
a
.
type
==
'D type'
for
a
in
t
.
atoms
))
indexMap
=
dict
([(
a
.
name
,
i
)
for
i
,
a
in
enumerate
(
t
.
atoms
)])
self
.
assertEqual
(
2
,
len
(
t
.
bonds
))
self
.
assertTrue
((
indexMap
[
'B'
],
indexMap
[
'C'
])
in
t
.
bonds
)
self
.
assertTrue
((
indexMap
[
'B'
],
indexMap
[
'D'
])
in
t
.
bonds
)
self
.
assertEqual
(
1
,
len
(
t
.
externalBonds
))
self
.
assertTrue
(
indexMap
[
'D'
]
in
t
.
externalBonds
)
self
.
assertEqual
(
1
,
len
(
t
.
virtualSites
))
v
=
t
.
virtualSites
[
0
]
self
.
assertEqual
(
'average2'
,
v
.
type
)
self
.
assertEqual
(
0.6
,
v
.
weights
[
0
])
self
.
assertEqual
(
0.4
,
v
.
weights
[
1
])
self
.
assertEqual
(
indexMap
[
'C'
],
v
.
index
)
self
.
assertEqual
(
indexMap
[
'B'
],
v
.
atoms
[
0
])
self
.
assertEqual
(
indexMap
[
'C'
],
v
.
atoms
[
1
])
def
testAlaAlaAla
(
self
):
"""Test constructing a System that involves two patches."""
xml
=
"""
<ForceField>
<AtomTypes>
<Type name="N" class="N" element="N" mass="14.00672"/>
<Type name="H" class="H" element="H" mass="1.007947"/>
<Type name="CT" class="CT" element="C" mass="12.01078"/>
<Type name="H1" class="H1" element="H" mass="1.007947"/>
<Type name="HC" class="HC" element="H" mass="1.007947"/>
<Type name="C" class="C" element="C" mass="12.01078"/>
<Type name="O" class="O" element="O" mass="15.99943"/>
<Type name="O2" class="O2" element="O" mass="15.99943"/>
<Type name="N3" class="N3" element="N" mass="14.00672"/>
</AtomTypes>
<Residues>
<Residue name="ALA">
<Atom name="N" type="N"/>
<Atom name="H" type="H"/>
<Atom name="CA" type="CT"/>
<Atom name="HA" type="H1"/>
<Atom name="CB" type="CT"/>
<Atom name="HB1" type="HC"/>
<Atom name="HB2" type="HC"/>
<Atom name="HB3" type="HC"/>
<Atom name="C" type="C"/>
<Atom name="O" type="O"/>
<Bond from="0" to="1"/>
<Bond from="0" to="2"/>
<Bond from="2" to="3"/>
<Bond from="2" to="4"/>
<Bond from="2" to="8"/>
<Bond from="4" to="5"/>
<Bond from="4" to="6"/>
<Bond from="4" to="7"/>
<Bond from="8" to="9"/>
<ExternalBond from="0"/>
<ExternalBond from="8"/>
<AllowPatch name="CTER"/>
<AllowPatch name="NTER"/>
</Residue>
</Residues>
<Patches>
<Patch name="CTER">
<AddAtom name="OXT" type="O2"/>
<ChangeAtom name="O" type="O2"/>
<AddBond atomName1="C" atomName2="OXT"/>
<RemoveExternalBond atomName="C"/>
</Patch>
<Patch name="NTER">
<RemoveAtom name="H"/>
<AddAtom name="H1" type="H"/>
<AddAtom name="H2" type="H"/>
<AddAtom name="H3" type="H"/>
<ChangeAtom name="N" type="N3"/>
<RemoveBond atomName1="N" atomName2="H"/>
<AddBond atomName1="N" atomName2="H1"/>
<AddBond atomName1="N" atomName2="H2"/>
<AddBond atomName1="N" atomName2="H3"/>
<RemoveExternalBond atomName="N"/>
</Patch>
</Patches>
<NonbondedForce coulomb14scale="0.833333" lj14scale="0.5">
<Atom type="N" charge="-0.4157" sigma="0.324999852378" epsilon="0.71128"/>
<Atom type="H" charge="0.2719" sigma="0.106907846177" epsilon="0.0656888"/>
<Atom type="CT" charge="0.0337" sigma="0.339966950842" epsilon="0.4577296"/>
<Atom type="H1" charge="0.0823" sigma="0.247135304412" epsilon="0.0656888"/>
<Atom type="HC" charge="0.0603" sigma="0.264953278775" epsilon="0.0656888"/>
<Atom type="C" charge="0.5973" sigma="0.339966950842" epsilon="0.359824"/>
<Atom type="O" charge="-0.5679" sigma="0.295992190115" epsilon="0.87864"/>
<Atom type="O2" charge="-0.8055" sigma="0.295992190115" epsilon="0.87864"/>
<Atom type="N3" charge="0.1414" sigma="0.324999852378" epsilon="0.71128"/>
</NonbondedForce>
</ForceField>"""
ff
=
ForceField
(
StringIO
(
xml
))
pdb
=
PDBFile
(
os
.
path
.
join
(
'systems'
,
'ala_ala_ala.pdb'
))
system
=
ff
.
createSystem
(
pdb
.
topology
)
nb
=
system
.
getForce
(
0
)
expectedCharges
=
[
0.1414
,
0.2719
,
0.2719
,
0.2719
,
0.0337
,
0.0823
,
0.0337
,
0.0603
,
0.0603
,
0.0603
,
0.5973
,
-
0.5679
,
-
0.4157
,
0.2719
,
0.0337
,
0.0823
,
0.0337
,
0.0603
,
0.0603
,
0.0603
,
0.5973
,
-
0.5679
,
0.5973
,
-
0.8055
,
-
0.8055
,
-
0.4157
,
0.2719
,
0.0337
,
0.0823
,
0.0337
,
0.0603
,
0.0603
,
0.0603
]
for
i
in
range
(
system
.
getNumParticles
()):
self
.
assertEqual
(
expectedCharges
[
i
],
nb
.
getParticleParameters
(
i
)[
0
].
value_in_unit
(
elementary_charge
))
def
testDisulfidePatch
(
self
):
pdb
=
PDBFile
(
os
.
path
.
join
(
'systems'
,
'bpti.pdb'
))
ff
=
ForceField
(
'amber99sb.xml'
)
system1
=
ff
.
createSystem
(
pdb
.
topology
)
# Override the CYX template so it will no longer match.
xml
=
"""
<ForceField>
<Residues>
<Residue name="CYX" override="1">
</Residue>
</Residues>
</ForceField>"""
ff
.
loadFile
(
StringIO
(
xml
))
try
:
ff
.
createSystem
(
pdb
.
topology
)
failed
=
False
except
:
failed
=
True
self
.
assertTrue
(
failed
)
# Now add a patch for matching disulfides.
xml
=
"""
<ForceField>
<Patches>
<Patch name="Disulfide" residues="2">
<RemoveAtom name="1:HG"/>
<RemoveAtom name="2:HG"/>
<ChangeAtom name="1:CA" type="83"/>
<ChangeAtom name="2:CA" type="83"/>
<ChangeAtom name="1:HA" type="84"/>
<ChangeAtom name="2:HA" type="84"/>
<ChangeAtom name="1:CB" type="85"/>
<ChangeAtom name="2:CB" type="85"/>
<ChangeAtom name="1:HB2" type="86"/>
<ChangeAtom name="2:HB2" type="86"/>
<ChangeAtom name="1:HB3" type="86"/>
<ChangeAtom name="2:HB3" type="86"/>
<ChangeAtom name="1:SG" type="87"/>
<ChangeAtom name="2:SG" type="87"/>
<AddBond atomName1="1:SG" atomName2="2:SG"/>
<ApplyToResidue name="1:CYS"/>
<ApplyToResidue name="2:CYS"/>
</Patch>
</Patches>
</ForceField>"""
ff
.
loadFile
(
StringIO
(
xml
))
system2
=
ff
.
createSystem
(
pdb
.
topology
)
self
.
assertEqual
(
XmlSerializer
.
serialize
(
system1
),
XmlSerializer
.
serialize
(
system2
))
if
__name__
==
'__main__'
:
unittest
.
main
()
wrappers/python/tests/systems/bpti.pdb
0 → 100644
View file @
d4d25d46
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