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
c5ad2202
Commit
c5ad2202
authored
May 21, 2013
by
peastman
Browse files
ForceField supports DrudeForce
parent
6185317a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
167 additions
and
38 deletions
+167
-38
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+151
-37
wrappers/python/simtk/openmm/app/modeller.py
wrappers/python/simtk/openmm/app/modeller.py
+16
-1
No files found.
wrappers/python/simtk/openmm/app/forcefield.py
View file @
c5ad2202
...
@@ -158,18 +158,20 @@ class ForceField(object):
...
@@ -158,18 +158,20 @@ class ForceField(object):
if
typeAttrib
in
attrib
:
if
typeAttrib
in
attrib
:
raise
ValueError
(
'Tag specifies both a type and a class for the same atom: '
+
etree
.
tostring
(
node
))
raise
ValueError
(
'Tag specifies both a type and a class for the same atom: '
+
etree
.
tostring
(
node
))
if
attrib
[
classAttrib
]
not
in
self
.
_atomClasses
:
if
attrib
[
classAttrib
]
not
in
self
.
_atomClasses
:
return
None
# Unknown atom class
types
.
append
(
None
)
# Unknown atom class
types
.
append
(
self
.
_atomClasses
[
attrib
[
classAttrib
]])
else
:
types
.
append
(
self
.
_atomClasses
[
attrib
[
classAttrib
]])
else
:
else
:
if
typeAttrib
not
in
attrib
or
attrib
[
typeAttrib
]
not
in
self
.
_atomTypes
:
if
typeAttrib
not
in
attrib
or
attrib
[
typeAttrib
]
not
in
self
.
_atomTypes
:
return
None
# Unknown atom type
types
.
append
(
None
)
# Unknown atom type
types
.
append
([
attrib
[
typeAttrib
]])
else
:
types
.
append
([
attrib
[
typeAttrib
]])
return
types
return
types
def
_parseTorsion
(
self
,
node
):
def
_parseTorsion
(
self
,
node
):
"""Parse the node defining a torsion."""
"""Parse the node defining a torsion."""
types
=
self
.
_findAtomTypes
(
node
,
4
)
types
=
self
.
_findAtomTypes
(
node
,
4
)
if
types
is
None
:
if
None
in
types
:
return
None
return
None
torsion
=
PeriodicTorsion
(
types
)
torsion
=
PeriodicTorsion
(
types
)
attrib
=
node
.
attrib
attrib
=
node
.
attrib
...
@@ -416,6 +418,12 @@ class ForceField(object):
...
@@ -416,6 +418,12 @@ class ForceField(object):
if
removeCMMotion
:
if
removeCMMotion
:
sys
.
addForce
(
mm
.
CMMotionRemover
())
sys
.
addForce
(
mm
.
CMMotionRemover
())
# Let generators do postprocessing
for
force
in
self
.
_forces
:
if
'postprocessSystem'
in
dir
(
force
):
force
.
postprocessSystem
(
sys
,
data
,
args
)
# Execute scripts found in the XML files.
# Execute scripts found in the XML files.
for
script
in
self
.
_scripts
:
for
script
in
self
.
_scripts
:
...
@@ -483,9 +491,10 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
...
@@ -483,9 +491,10 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
if
position
==
len
(
atoms
):
if
position
==
len
(
atoms
):
return
True
return
True
elem
=
atoms
[
position
].
element
elem
=
atoms
[
position
].
element
name
=
atoms
[
position
].
name
for
i
in
range
(
len
(
atoms
)):
for
i
in
range
(
len
(
atoms
)):
atom
=
template
.
atoms
[
i
]
atom
=
template
.
atoms
[
i
]
if
(
atom
.
element
==
elem
or
atom
.
element
is
None
)
and
not
hasMatch
[
i
]
and
len
(
atom
.
bondedTo
)
==
len
(
bondedTo
[
position
])
and
atom
.
externalBonds
==
externalBonds
[
position
]:
if
(
atom
.
element
==
elem
or
(
atom
.
element
is
None
and
atom
.
name
==
name
)
)
and
not
hasMatch
[
i
]
and
len
(
atom
.
bondedTo
)
==
len
(
bondedTo
[
position
])
and
atom
.
externalBonds
==
externalBonds
[
position
]:
# See if the bonds for this identification are consistent
# See if the bonds for this identification are consistent
allBondsMatch
=
all
((
bonded
>
position
or
matches
[
bonded
]
in
atom
.
bondedTo
for
bonded
in
bondedTo
[
position
]))
allBondsMatch
=
all
((
bonded
>
position
or
matches
[
bonded
]
in
atom
.
bondedTo
for
bonded
in
bondedTo
[
position
]))
...
@@ -521,7 +530,7 @@ class HarmonicBondGenerator:
...
@@ -521,7 +530,7 @@ class HarmonicBondGenerator:
ff
.
_forces
.
append
(
generator
)
ff
.
_forces
.
append
(
generator
)
for
bond
in
element
.
findall
(
'Bond'
):
for
bond
in
element
.
findall
(
'Bond'
):
types
=
ff
.
_findAtomTypes
(
bond
,
2
)
types
=
ff
.
_findAtomTypes
(
bond
,
2
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
length
.
append
(
float
(
bond
.
attrib
[
'length'
]))
generator
.
length
.
append
(
float
(
bond
.
attrib
[
'length'
]))
...
@@ -569,7 +578,7 @@ class HarmonicAngleGenerator:
...
@@ -569,7 +578,7 @@ class HarmonicAngleGenerator:
ff
.
_forces
.
append
(
generator
)
ff
.
_forces
.
append
(
generator
)
for
angle
in
element
.
findall
(
'Angle'
):
for
angle
in
element
.
findall
(
'Angle'
):
types
=
ff
.
_findAtomTypes
(
angle
,
3
)
types
=
ff
.
_findAtomTypes
(
angle
,
3
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types3
.
append
(
types
[
2
])
generator
.
types3
.
append
(
types
[
2
])
...
@@ -748,11 +757,11 @@ class RBTorsionGenerator:
...
@@ -748,11 +757,11 @@ class RBTorsionGenerator:
ff
.
_forces
.
append
(
generator
)
ff
.
_forces
.
append
(
generator
)
for
torsion
in
element
.
findall
(
'Proper'
):
for
torsion
in
element
.
findall
(
'Proper'
):
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
proper
.
append
(
RBTorsion
(
types
,
[
float
(
torsion
.
attrib
[
'c'
+
str
(
i
)])
for
i
in
range
(
6
)]))
generator
.
proper
.
append
(
RBTorsion
(
types
,
[
float
(
torsion
.
attrib
[
'c'
+
str
(
i
)])
for
i
in
range
(
6
)]))
for
torsion
in
element
.
findall
(
'Improper'
):
for
torsion
in
element
.
findall
(
'Improper'
):
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
improper
.
append
(
RBTorsion
(
types
,
[
float
(
torsion
.
attrib
[
'c'
+
str
(
i
)])
for
i
in
range
(
6
)]))
generator
.
improper
.
append
(
RBTorsion
(
types
,
[
float
(
torsion
.
attrib
[
'c'
+
str
(
i
)])
for
i
in
range
(
6
)]))
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
...
@@ -850,7 +859,7 @@ class CMAPTorsionGenerator:
...
@@ -850,7 +859,7 @@ class CMAPTorsionGenerator:
generator
.
maps
.
append
(
values
)
generator
.
maps
.
append
(
values
)
for
torsion
in
element
.
findall
(
'Torsion'
):
for
torsion
in
element
.
findall
(
'Torsion'
):
types
=
ff
.
_findAtomTypes
(
torsion
,
5
)
types
=
ff
.
_findAtomTypes
(
torsion
,
5
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
torsions
.
append
(
CMAPTorsion
(
types
,
int
(
torsion
.
attrib
[
'map'
])))
generator
.
torsions
.
append
(
CMAPTorsion
(
types
,
int
(
torsion
.
attrib
[
'map'
])))
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
...
@@ -931,7 +940,7 @@ class NonbondedGenerator:
...
@@ -931,7 +940,7 @@ class NonbondedGenerator:
raise
ValueError
(
'Found multiple NonbondedForce tags with different 1-4 scales'
)
raise
ValueError
(
'Found multiple NonbondedForce tags with different 1-4 scales'
)
for
atom
in
element
.
findall
(
'Atom'
):
for
atom
in
element
.
findall
(
'Atom'
):
types
=
ff
.
_findAtomTypes
(
atom
,
1
)
types
=
ff
.
_findAtomTypes
(
atom
,
1
)
if
types
is
not
None
:
if
None
not
in
types
:
values
=
(
float
(
atom
.
attrib
[
'charge'
]),
float
(
atom
.
attrib
[
'sigma'
]),
float
(
atom
.
attrib
[
'epsilon'
]))
values
=
(
float
(
atom
.
attrib
[
'charge'
]),
float
(
atom
.
attrib
[
'sigma'
]),
float
(
atom
.
attrib
[
'epsilon'
]))
for
t
in
types
[
0
]:
for
t
in
types
[
0
]:
generator
.
typeMap
[
t
]
=
values
generator
.
typeMap
[
t
]
=
values
...
@@ -952,7 +961,14 @@ class NonbondedGenerator:
...
@@ -952,7 +961,14 @@ class NonbondedGenerator:
force
.
addParticle
(
values
[
0
],
values
[
1
],
values
[
2
])
force
.
addParticle
(
values
[
0
],
values
[
1
],
values
[
2
])
else
:
else
:
raise
ValueError
(
'No nonbonded parameters defined for atom type '
+
t
)
raise
ValueError
(
'No nonbonded parameters defined for atom type '
+
t
)
# Create exceptions based on bonds and virtual sites.
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
force
.
setCutoffDistance
(
nonbondedCutoff
)
if
'ewaldErrorTolerance'
in
args
:
force
.
setEwaldErrorTolerance
(
args
[
'ewaldErrorTolerance'
])
sys
.
addForce
(
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# Create exceptions based on bonds, virtual sites, and Drude particles.
bondIndices
=
[]
bondIndices
=
[]
for
bond
in
data
.
bonds
:
for
bond
in
data
.
bonds
:
bondIndices
.
append
((
bond
.
atom1
,
bond
.
atom2
))
bondIndices
.
append
((
bond
.
atom1
,
bond
.
atom2
))
...
@@ -961,12 +977,26 @@ class NonbondedGenerator:
...
@@ -961,12 +977,26 @@ class NonbondedGenerator:
site
=
sys
.
getVirtualSite
(
i
)
site
=
sys
.
getVirtualSite
(
i
)
for
j
in
range
(
site
.
getNumParticles
()):
for
j
in
range
(
site
.
getNumParticles
()):
bondIndices
.
append
((
i
,
site
.
getParticle
(
j
)))
bondIndices
.
append
((
i
,
site
.
getParticle
(
j
)))
force
.
createExceptionsFromBonds
(
bondIndices
,
self
.
coulomb14scale
,
self
.
lj14scale
)
drude
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
DrudeForce
)]
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
if
len
(
drude
)
>
0
:
force
.
setCutoffDistance
(
nonbondedCutoff
)
drude
=
drude
[
0
]
if
'ewaldErrorTolerance'
in
args
:
# For purposes of creating exceptions, a Drude particle is "bonded" to anything
force
.
setEwaldErrorTolerance
(
args
[
'ewaldErrorTolerance'
])
# its parent atom is bonded to.
sys
.
addForce
(
force
)
drudeMap
=
{}
for
i
in
range
(
drude
.
getNumParticles
()):
params
=
drude
.
getParticleParameters
(
i
)
drudeMap
[
params
[
1
]]
=
params
[
0
]
for
atom1
,
atom2
in
bondIndices
:
drude1
=
drudeMap
[
atom1
]
if
atom1
in
drudeMap
else
None
drude2
=
drudeMap
[
atom2
]
if
atom2
in
drudeMap
else
None
if
drude1
is
not
None
:
bondIndices
.
append
((
drude1
,
atom2
))
if
drude2
is
not
None
:
bondIndices
.
append
((
drude1
,
drude2
))
if
drude2
is
not
None
:
bondIndices
.
append
((
atom1
,
drude2
))
nonbonded
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
NonbondedForce
)][
0
]
nonbonded
.
createExceptionsFromBonds
(
bondIndices
,
self
.
coulomb14scale
,
self
.
lj14scale
)
parsers
[
"NonbondedForce"
]
=
NonbondedGenerator
.
parseElement
parsers
[
"NonbondedForce"
]
=
NonbondedGenerator
.
parseElement
...
@@ -989,7 +1019,7 @@ class GBSAOBCGenerator:
...
@@ -989,7 +1019,7 @@ class GBSAOBCGenerator:
generator
=
existing
[
0
]
generator
=
existing
[
0
]
for
atom
in
element
.
findall
(
'Atom'
):
for
atom
in
element
.
findall
(
'Atom'
):
types
=
ff
.
_findAtomTypes
(
atom
,
1
)
types
=
ff
.
_findAtomTypes
(
atom
,
1
)
if
types
is
not
None
:
if
None
not
in
types
:
values
=
(
float
(
atom
.
attrib
[
'charge'
]),
float
(
atom
.
attrib
[
'radius'
]),
float
(
atom
.
attrib
[
'scale'
]))
values
=
(
float
(
atom
.
attrib
[
'charge'
]),
float
(
atom
.
attrib
[
'radius'
]),
float
(
atom
.
attrib
[
'scale'
]))
for
t
in
types
[
0
]:
for
t
in
types
[
0
]:
generator
.
typeMap
[
t
]
=
values
generator
.
typeMap
[
t
]
=
values
...
@@ -1046,7 +1076,7 @@ class GBVIGenerator:
...
@@ -1046,7 +1076,7 @@ class GBVIGenerator:
ff
.
_forces
.
append
(
generator
)
ff
.
_forces
.
append
(
generator
)
for
atom
in
element
.
findall
(
'Atom'
):
for
atom
in
element
.
findall
(
'Atom'
):
types
=
ff
.
_findAtomTypes
(
atom
,
1
)
types
=
ff
.
_findAtomTypes
(
atom
,
1
)
if
types
is
not
None
:
if
None
not
in
types
:
values
=
(
float
(
atom
.
attrib
[
'charge'
]),
float
(
atom
.
attrib
[
'radius'
]),
float
(
atom
.
attrib
[
'gamma'
]))
values
=
(
float
(
atom
.
attrib
[
'charge'
]),
float
(
atom
.
attrib
[
'radius'
]),
float
(
atom
.
attrib
[
'gamma'
]))
for
t
in
types
[
0
]:
for
t
in
types
[
0
]:
generator
.
typeMap
[
t
]
=
values
generator
.
typeMap
[
t
]
=
values
...
@@ -1129,7 +1159,7 @@ class CustomBondGenerator:
...
@@ -1129,7 +1159,7 @@ class CustomBondGenerator:
generator
.
perBondParams
.
append
(
param
.
attrib
[
'name'
])
generator
.
perBondParams
.
append
(
param
.
attrib
[
'name'
])
for
bond
in
element
.
findall
(
'Bond'
):
for
bond
in
element
.
findall
(
'Bond'
):
types
=
ff
.
_findAtomTypes
(
bond
,
2
)
types
=
ff
.
_findAtomTypes
(
bond
,
2
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
paramValues
.
append
([
float
(
bond
.
attrib
[
param
])
for
param
in
generator
.
perBondParams
])
generator
.
paramValues
.
append
([
float
(
bond
.
attrib
[
param
])
for
param
in
generator
.
perBondParams
])
...
@@ -1177,7 +1207,7 @@ class CustomAngleGenerator:
...
@@ -1177,7 +1207,7 @@ class CustomAngleGenerator:
generator
.
perAngleParams
.
append
(
param
.
attrib
[
'name'
])
generator
.
perAngleParams
.
append
(
param
.
attrib
[
'name'
])
for
angle
in
element
.
findall
(
'Angle'
):
for
angle
in
element
.
findall
(
'Angle'
):
types
=
ff
.
_findAtomTypes
(
angle
,
3
)
types
=
ff
.
_findAtomTypes
(
angle
,
3
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types3
.
append
(
types
[
2
])
generator
.
types3
.
append
(
types
[
2
])
...
@@ -1238,11 +1268,11 @@ class CustomTorsionGenerator:
...
@@ -1238,11 +1268,11 @@ class CustomTorsionGenerator:
generator
.
perTorsionParams
.
append
(
param
.
attrib
[
'name'
])
generator
.
perTorsionParams
.
append
(
param
.
attrib
[
'name'
])
for
torsion
in
element
.
findall
(
'Proper'
):
for
torsion
in
element
.
findall
(
'Proper'
):
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
proper
.
append
(
CustomTorsion
(
types
,
[
float
(
torsion
.
attrib
[
param
])
for
param
in
generator
.
perTorsionParams
]))
generator
.
proper
.
append
(
CustomTorsion
(
types
,
[
float
(
torsion
.
attrib
[
param
])
for
param
in
generator
.
perTorsionParams
]))
for
torsion
in
element
.
findall
(
'Improper'
):
for
torsion
in
element
.
findall
(
'Improper'
):
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
improper
.
append
(
CustomTorsion
(
types
,
[
float
(
torsion
.
attrib
[
param
])
for
param
in
generator
.
perTorsionParams
]))
generator
.
improper
.
append
(
CustomTorsion
(
types
,
[
float
(
torsion
.
attrib
[
param
])
for
param
in
generator
.
perTorsionParams
]))
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
...
@@ -1329,7 +1359,7 @@ class CustomGBGenerator:
...
@@ -1329,7 +1359,7 @@ class CustomGBGenerator:
generator
.
perParticleParams
.
append
(
param
.
attrib
[
'name'
])
generator
.
perParticleParams
.
append
(
param
.
attrib
[
'name'
])
for
atom
in
element
.
findall
(
'Atom'
):
for
atom
in
element
.
findall
(
'Atom'
):
types
=
ff
.
_findAtomTypes
(
atom
,
1
)
types
=
ff
.
_findAtomTypes
(
atom
,
1
)
if
types
is
not
None
:
if
None
not
in
types
:
values
=
[
float
(
atom
.
attrib
[
param
])
for
param
in
generator
.
perParticleParams
]
values
=
[
float
(
atom
.
attrib
[
param
])
for
param
in
generator
.
perParticleParams
]
for
t
in
types
[
0
]:
for
t
in
types
[
0
]:
generator
.
typeMap
[
t
]
=
values
generator
.
typeMap
[
t
]
=
values
...
@@ -1431,7 +1461,7 @@ class AmoebaBondGenerator:
...
@@ -1431,7 +1461,7 @@ class AmoebaBondGenerator:
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
for
bond
in
element
.
findall
(
'Bond'
):
for
bond
in
element
.
findall
(
'Bond'
):
types
=
forceField
.
_findAtomTypes
(
bond
,
2
)
types
=
forceField
.
_findAtomTypes
(
bond
,
2
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
length
.
append
(
float
(
bond
.
attrib
[
'length'
]))
generator
.
length
.
append
(
float
(
bond
.
attrib
[
'length'
]))
...
@@ -1544,7 +1574,7 @@ class AmoebaAngleGenerator:
...
@@ -1544,7 +1574,7 @@ class AmoebaAngleGenerator:
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
for
angle
in
element
.
findall
(
'Angle'
):
for
angle
in
element
.
findall
(
'Angle'
):
types
=
forceField
.
_findAtomTypes
(
angle
,
3
)
types
=
forceField
.
_findAtomTypes
(
angle
,
3
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
...
@@ -2029,7 +2059,7 @@ class AmoebaTorsionGenerator:
...
@@ -2029,7 +2059,7 @@ class AmoebaTorsionGenerator:
for
torsion
in
element
.
findall
(
'Torsion'
):
for
torsion
in
element
.
findall
(
'Torsion'
):
types
=
forceField
.
_findAtomTypes
(
torsion
,
4
)
types
=
forceField
.
_findAtomTypes
(
torsion
,
4
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
...
@@ -2140,7 +2170,7 @@ class AmoebaPiTorsionGenerator:
...
@@ -2140,7 +2170,7 @@ class AmoebaPiTorsionGenerator:
for
piTorsion
in
element
.
findall
(
'PiTorsion'
):
for
piTorsion
in
element
.
findall
(
'PiTorsion'
):
types
=
forceField
.
_findAtomTypes
(
piTorsion
,
2
)
types
=
forceField
.
_findAtomTypes
(
piTorsion
,
2
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
k
.
append
(
float
(
piTorsion
.
attrib
[
'k'
]))
generator
.
k
.
append
(
float
(
piTorsion
.
attrib
[
'k'
]))
...
@@ -2259,7 +2289,7 @@ class AmoebaTorsionTorsionGenerator:
...
@@ -2259,7 +2289,7 @@ class AmoebaTorsionTorsionGenerator:
for
torsionTorsion
in
element
.
findall
(
'TorsionTorsion'
):
for
torsionTorsion
in
element
.
findall
(
'TorsionTorsion'
):
types
=
forceField
.
_findAtomTypes
(
torsionTorsion
,
5
)
types
=
forceField
.
_findAtomTypes
(
torsionTorsion
,
5
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
...
@@ -2496,7 +2526,7 @@ class AmoebaStretchBendGenerator:
...
@@ -2496,7 +2526,7 @@ class AmoebaStretchBendGenerator:
for
stretchBend
in
element
.
findall
(
'StretchBend'
):
for
stretchBend
in
element
.
findall
(
'StretchBend'
):
types
=
forceField
.
_findAtomTypes
(
stretchBend
,
3
)
types
=
forceField
.
_findAtomTypes
(
stretchBend
,
3
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
...
@@ -2653,7 +2683,7 @@ class AmoebaVdwGenerator:
...
@@ -2653,7 +2683,7 @@ class AmoebaVdwGenerator:
for
atom
in
element
.
findall
(
'Vdw'
):
for
atom
in
element
.
findall
(
'Vdw'
):
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
if
types
is
not
None
:
if
None
not
in
types
:
values
=
[
float
(
atom
.
attrib
[
'sigma'
]),
float
(
atom
.
attrib
[
'epsilon'
]),
float
(
atom
.
attrib
[
'reduction'
])]
values
=
[
float
(
atom
.
attrib
[
'sigma'
]),
float
(
atom
.
attrib
[
'epsilon'
]),
float
(
atom
.
attrib
[
'reduction'
])]
...
@@ -2926,7 +2956,7 @@ class AmoebaMultipoleGenerator:
...
@@ -2926,7 +2956,7 @@ class AmoebaMultipoleGenerator:
for
atom
in
element
.
findall
(
'Multipole'
):
for
atom
in
element
.
findall
(
'Multipole'
):
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
if
types
is
not
None
:
if
None
not
in
types
:
# k-indices not provided default to 0
# k-indices not provided default to 0
...
@@ -2983,7 +3013,7 @@ class AmoebaMultipoleGenerator:
...
@@ -2983,7 +3013,7 @@ class AmoebaMultipoleGenerator:
for
atom
in
element
.
findall
(
'Polarize'
):
for
atom
in
element
.
findall
(
'Polarize'
):
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
if
types
is
not
None
:
if
None
not
in
types
:
classIndex
=
atom
.
attrib
[
'type'
]
classIndex
=
atom
.
attrib
[
'type'
]
polarizability
=
float
(
atom
.
attrib
[
'polarizability'
])
polarizability
=
float
(
atom
.
attrib
[
'polarizability'
])
...
@@ -3511,7 +3541,7 @@ class AmoebaWcaDispersionGenerator:
...
@@ -3511,7 +3541,7 @@ class AmoebaWcaDispersionGenerator:
for
atom
in
element
.
findall
(
'WcaDispersion'
):
for
atom
in
element
.
findall
(
'WcaDispersion'
):
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
if
types
is
not
None
:
if
None
not
in
types
:
values
=
[
float
(
atom
.
attrib
[
'radius'
]),
float
(
atom
.
attrib
[
'epsilon'
])]
values
=
[
float
(
atom
.
attrib
[
'radius'
]),
float
(
atom
.
attrib
[
'epsilon'
])]
for
t
in
types
[
0
]:
for
t
in
types
[
0
]:
...
@@ -3855,7 +3885,7 @@ class AmoebaUreyBradleyGenerator:
...
@@ -3855,7 +3885,7 @@ class AmoebaUreyBradleyGenerator:
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
for
bond
in
element
.
findall
(
'UreyBradley'
):
for
bond
in
element
.
findall
(
'UreyBradley'
):
types
=
forceField
.
_findAtomTypes
(
bond
,
3
)
types
=
forceField
.
_findAtomTypes
(
bond
,
3
)
if
types
is
not
None
:
if
None
not
in
types
:
generator
.
types1
.
append
(
types
[
0
])
generator
.
types1
.
append
(
types
[
0
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
...
@@ -3899,3 +3929,87 @@ class AmoebaUreyBradleyGenerator:
...
@@ -3899,3 +3929,87 @@ class AmoebaUreyBradleyGenerator:
parsers
[
"AmoebaUreyBradleyForce"
]
=
AmoebaUreyBradleyGenerator
.
parseElement
parsers
[
"AmoebaUreyBradleyForce"
]
=
AmoebaUreyBradleyGenerator
.
parseElement
#=============================================================================================
#=============================================================================================
## @private
class
DrudeGenerator
:
"""A DrudeGenerator constructs a DrudeForce."""
def
__init__
(
self
):
self
.
typeMap
=
{}
@
staticmethod
def
parseElement
(
element
,
ff
):
existing
=
[
f
for
f
in
ff
.
_forces
if
isinstance
(
f
,
DrudeGenerator
)]
if
len
(
existing
)
==
0
:
generator
=
DrudeGenerator
()
ff
.
_forces
.
append
(
generator
)
else
:
# Multiple <DrudeForce> tags were found, probably in different files. Simply add more types to the existing one.
generator
=
existing
[
0
]
for
particle
in
element
.
findall
(
'Particle'
):
types
=
ff
.
_findAtomTypes
(
particle
,
5
)
if
None
not
in
types
[:
2
]:
aniso12
=
0.0
aniso34
=
0.0
if
'aniso12'
in
particle
.
attrib
:
aniso12
=
float
(
particle
.
attrib
[
'aniso12'
])
if
'aniso34'
in
particle
.
attrib
:
aniso34
=
float
(
particle
.
attrib
[
'aniso34'
])
values
=
(
types
[
1
],
types
[
2
],
types
[
3
],
types
[
4
],
float
(
particle
.
attrib
[
'charge'
]),
float
(
particle
.
attrib
[
'polarizability'
]),
aniso12
,
aniso34
,
float
(
particle
.
attrib
[
'thole'
]))
for
t
in
types
[
0
]:
generator
.
typeMap
[
t
]
=
values
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
force
=
mm
.
DrudeForce
()
if
not
any
(
isinstance
(
f
,
mm
.
NonbondedForce
)
for
f
in
sys
.
getForces
()):
raise
ValueError
(
'<DrudeForce> must come after <NonbondedForce> in XML file'
)
# Add Drude particles.
drudeMap
=
{}
parentMap
=
{}
for
atom
in
data
.
atoms
:
t
=
data
.
atomType
[
atom
]
if
t
in
self
.
typeMap
:
# Find other atoms in the residue that affect the Drude particle.
p
=
[
-
1
,
-
1
,
-
1
,
-
1
]
values
=
self
.
typeMap
[
t
]
for
atom2
in
atom
.
residue
.
atoms
():
type2
=
data
.
atomType
[
atom2
]
if
type2
in
values
[
0
]:
p
[
0
]
=
atom2
.
index
elif
values
[
1
]
is
not
None
and
type2
in
values
[
1
]:
p
[
1
]
=
atom2
.
index
elif
values
[
2
]
is
not
None
and
type2
in
values
[
2
]:
p
[
2
]
=
atom2
.
index
elif
values
[
3
]
is
not
None
and
type2
in
values
[
3
]:
p
[
3
]
=
atom2
.
index
drudeIndex
=
force
.
addParticle
(
atom
.
index
,
p
[
0
],
p
[
1
],
p
[
2
],
p
[
3
],
values
[
4
],
values
[
5
],
values
[
6
],
values
[
7
])
drudeMap
[
atom
.
index
]
=
p
[
0
]
parentMap
[
p
[
0
]]
=
(
atom
.
index
,
drudeIndex
)
sys
.
addForce
(
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# For every nonbonded exclusion between Drude particles, add a screened pair.
drude
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
DrudeForce
)][
0
]
nonbonded
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
NonbondedForce
)][
0
]
particleMap
=
{}
for
i
in
range
(
drude
.
getNumParticles
()):
particleMap
[
drude
.
getParticleParameters
(
i
)[
0
]]
=
i
for
i
in
range
(
nonbonded
.
getNumExceptions
()):
(
particle1
,
particle2
,
charge
,
sigma
,
epsilon
)
=
nonbonded
.
getExceptionParameters
(
i
)
if
charge
==
0
and
epsilon
==
0
:
# This is an exclusion.
if
particle1
in
particleMap
and
particle2
in
particleMap
:
# It connects two Drude particles, so add a screened pair.
drude1
=
particleMap
[
particle1
]
drude2
=
particleMap
[
particle2
]
type1
=
data
.
atomType
[
data
.
atoms
[
drude1
]]
type2
=
data
.
atomType
[
data
.
atoms
[
drude2
]]
thole1
=
self
.
typeMap
[
type1
][
8
]
thole2
=
self
.
typeMap
[
type2
][
8
]
drude
.
addScreenedPair
(
drude1
,
drude2
,
thole1
+
thole2
)
parsers
[
"DrudeForce"
]
=
DrudeGenerator
.
parseElement
\ No newline at end of file
wrappers/python/simtk/openmm/app/modeller.py
View file @
c5ad2202
...
@@ -34,7 +34,7 @@ __author__ = "Peter Eastman"
...
@@ -34,7 +34,7 @@ __author__ = "Peter Eastman"
__version__
=
"1.0"
__version__
=
"1.0"
from
simtk.openmm.app
import
Topology
,
PDBFile
,
ForceField
from
simtk.openmm.app
import
Topology
,
PDBFile
,
ForceField
from
simtk.openmm.app.forcefield
import
HAngles
,
_createResidueSignature
,
_matchResidue
from
simtk.openmm.app.forcefield
import
HAngles
,
_createResidueSignature
,
_matchResidue
,
DrudeGenerator
from
simtk.openmm.app.topology
import
Residue
from
simtk.openmm.app.topology
import
Residue
from
simtk.openmm.vec3
import
Vec3
from
simtk.openmm.vec3
import
Vec3
from
simtk.openmm
import
System
,
Context
,
NonbondedForce
,
VerletIntegrator
,
LocalEnergyMinimizer
from
simtk.openmm
import
System
,
Context
,
NonbondedForce
,
VerletIntegrator
,
LocalEnergyMinimizer
...
@@ -817,6 +817,15 @@ class Modeller(object):
...
@@ -817,6 +817,15 @@ class Modeller(object):
bondedToAtomNoEP
[
atom1
.
index
].
add
(
atom2
.
index
)
bondedToAtomNoEP
[
atom1
.
index
].
add
(
atom2
.
index
)
bondedToAtomNoEP
[
atom2
.
index
].
add
(
atom1
.
index
)
bondedToAtomNoEP
[
atom2
.
index
].
add
(
atom1
.
index
)
# If the force field has a DrudeForce, record the types of Drude particles and their parents since we'll
# need them for picking particle positions.
drudeTypeMap
=
{}
for
force
in
forcefield
.
_forces
:
if
isinstance
(
force
,
DrudeGenerator
):
for
type
in
force
.
typeMap
:
drudeTypeMap
[
type
]
=
force
.
typeMap
[
type
][
0
]
# Create the new Topology.
# Create the new Topology.
newTopology
=
Topology
()
newTopology
=
Topology
()
...
@@ -894,6 +903,12 @@ class Modeller(object):
...
@@ -894,6 +903,12 @@ class Modeller(object):
position
=
site
.
weights
[
0
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
0
]]
+
site
.
weights
[
1
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
1
]]
+
site
.
weights
[
2
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
2
]]
position
=
site
.
weights
[
0
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
0
]]
+
site
.
weights
[
1
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
1
]]
+
site
.
weights
[
2
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
2
]]
elif
site
.
type
==
'outOfPlane'
:
elif
site
.
type
==
'outOfPlane'
:
position
=
site
.
weights
[
0
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
0
]]
+
site
.
weights
[
1
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
1
]]
+
site
.
weights
[
2
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
2
]]
position
=
site
.
weights
[
0
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
0
]]
+
site
.
weights
[
1
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
1
]]
+
site
.
weights
[
2
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
2
]]
if
position
is
None
and
atom
.
type
in
drudeTypeMap
:
# This is a Drude particle. Put it on top of its parent atom.
for
atom2
,
pos
in
zip
(
template
.
atoms
,
templateAtomPositions
):
if
atom2
.
type
in
drudeTypeMap
[
atom
.
type
]:
position
=
deepcopy
(
pos
)
if
position
is
None
:
if
position
is
None
:
# We couldn't figure out the correct position. As a wild guess, just put it at the center of the residue
# We couldn't figure out the correct position. As a wild guess, just put it at the center of the residue
# and hope that energy minimization will fix it.
# and hope that energy minimization will fix 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