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
4941cc7d
Commit
4941cc7d
authored
Jul 12, 2013
by
Justin MacCallum
Browse files
Removed trailing whitespace
parent
3862202e
Changes
31
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
824 additions
and
824 deletions
+824
-824
wrappers/python/simtk/openmm/__init__.py
wrappers/python/simtk/openmm/__init__.py
+1
-1
wrappers/python/simtk/openmm/app/amberinpcrdfile.py
wrappers/python/simtk/openmm/app/amberinpcrdfile.py
+10
-10
wrappers/python/simtk/openmm/app/amberprmtopfile.py
wrappers/python/simtk/openmm/app/amberprmtopfile.py
+11
-11
wrappers/python/simtk/openmm/app/dcdfile.py
wrappers/python/simtk/openmm/app/dcdfile.py
+12
-12
wrappers/python/simtk/openmm/app/dcdreporter.py
wrappers/python/simtk/openmm/app/dcdreporter.py
+10
-10
wrappers/python/simtk/openmm/app/element.py
wrappers/python/simtk/openmm/app/element.py
+3
-3
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+335
-335
wrappers/python/simtk/openmm/app/gromacsgrofile.py
wrappers/python/simtk/openmm/app/gromacsgrofile.py
+15
-15
wrappers/python/simtk/openmm/app/gromacstopfile.py
wrappers/python/simtk/openmm/app/gromacstopfile.py
+56
-56
wrappers/python/simtk/openmm/app/internal/amber_file_parser.py
...ers/python/simtk/openmm/app/internal/amber_file_parser.py
+31
-31
wrappers/python/simtk/openmm/app/internal/customgbforces.py
wrappers/python/simtk/openmm/app/internal/customgbforces.py
+126
-126
wrappers/python/simtk/openmm/app/internal/pdbstructure.py
wrappers/python/simtk/openmm/app/internal/pdbstructure.py
+8
-8
wrappers/python/simtk/openmm/app/modeller.py
wrappers/python/simtk/openmm/app/modeller.py
+112
-112
wrappers/python/simtk/openmm/app/pdbfile.py
wrappers/python/simtk/openmm/app/pdbfile.py
+21
-21
wrappers/python/simtk/openmm/app/pdbreporter.py
wrappers/python/simtk/openmm/app/pdbreporter.py
+10
-10
wrappers/python/simtk/openmm/app/simulation.py
wrappers/python/simtk/openmm/app/simulation.py
+10
-10
wrappers/python/simtk/openmm/app/statedatareporter.py
wrappers/python/simtk/openmm/app/statedatareporter.py
+2
-2
wrappers/python/simtk/openmm/app/topology.py
wrappers/python/simtk/openmm/app/topology.py
+35
-35
wrappers/python/simtk/openmm/vec3.py
wrappers/python/simtk/openmm/vec3.py
+10
-10
wrappers/python/simtk/unit/basedimension.py
wrappers/python/simtk/unit/basedimension.py
+6
-6
No files found.
wrappers/python/simtk/openmm/__init__.py
View file @
4941cc7d
...
@@ -35,4 +35,4 @@ else:
...
@@ -35,4 +35,4 @@ else:
from
simtk.openmm.openmm
import
*
from
simtk.openmm.openmm
import
*
from
simtk.openmm.vec3
import
Vec3
from
simtk.openmm.vec3
import
Vec3
pluginLoadedLibNames
=
Platform
.
loadPluginsFromDirectory
(
Platform
.
getDefaultPluginsDirectory
())
pluginLoadedLibNames
=
Platform
.
loadPluginsFromDirectory
(
Platform
.
getDefaultPluginsDirectory
())
\ No newline at end of file
wrappers/python/simtk/openmm/app/amberinpcrdfile.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -40,15 +40,15 @@ except:
...
@@ -40,15 +40,15 @@ except:
class
AmberInpcrdFile
(
object
):
class
AmberInpcrdFile
(
object
):
"""AmberInpcrdFile parses an AMBER inpcrd file and loads the data stored in it."""
"""AmberInpcrdFile parses an AMBER inpcrd file and loads the data stored in it."""
def
__init__
(
self
,
file
,
loadVelocities
=
False
,
loadBoxVectors
=
False
):
def
__init__
(
self
,
file
,
loadVelocities
=
False
,
loadBoxVectors
=
False
):
"""Load an inpcrd file.
"""Load an inpcrd file.
An inpcrd file contains atom positions and, optionally, velocities and periodic box dimensions.
An inpcrd file contains atom positions and, optionally, velocities and periodic box dimensions.
Unfortunately, it is sometimes impossible to determine from the file itself exactly what data
Unfortunately, it is sometimes impossible to determine from the file itself exactly what data
it contains. You therefore must specify in advance what data to load. It is stored into this
it contains. You therefore must specify in advance what data to load. It is stored into this
object's "positions", "velocities", and "boxVectors" fields.
object's "positions", "velocities", and "boxVectors" fields.
Parameters:
Parameters:
- file (string) the name of the file to load
- file (string) the name of the file to load
- loadVelocities (boolean=False) whether to load velocities from the file
- loadVelocities (boolean=False) whether to load velocities from the file
...
@@ -78,7 +78,7 @@ class AmberInpcrdFile(object):
...
@@ -78,7 +78,7 @@ class AmberInpcrdFile(object):
def
getPositions
(
self
,
asNumpy
=
False
):
def
getPositions
(
self
,
asNumpy
=
False
):
"""Get the atomic positions.
"""Get the atomic positions.
Parameters:
Parameters:
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s
"""
"""
...
@@ -87,10 +87,10 @@ class AmberInpcrdFile(object):
...
@@ -87,10 +87,10 @@ class AmberInpcrdFile(object):
self
.
_numpyPositions
=
Quantity
(
numpy
.
array
(
self
.
positions
.
value_in_unit
(
nanometers
)),
nanometers
)
self
.
_numpyPositions
=
Quantity
(
numpy
.
array
(
self
.
positions
.
value_in_unit
(
nanometers
)),
nanometers
)
return
self
.
_numpyPositions
return
self
.
_numpyPositions
return
self
.
positions
return
self
.
positions
def
getVelocities
(
self
,
asNumpy
=
False
):
def
getVelocities
(
self
,
asNumpy
=
False
):
"""Get the atomic velocities.
"""Get the atomic velocities.
Parameters:
Parameters:
- asNumpy (boolean=False) if true, the vectors are returned as numpy arrays instead of Vec3s
- asNumpy (boolean=False) if true, the vectors are returned as numpy arrays instead of Vec3s
"""
"""
...
@@ -99,10 +99,10 @@ class AmberInpcrdFile(object):
...
@@ -99,10 +99,10 @@ class AmberInpcrdFile(object):
self
.
_numpyVelocities
=
Quantity
(
numpy
.
array
(
self
.
velocities
.
value_in_unit
(
nanometers
/
picoseconds
)),
nanometers
/
picoseconds
)
self
.
_numpyVelocities
=
Quantity
(
numpy
.
array
(
self
.
velocities
.
value_in_unit
(
nanometers
/
picoseconds
)),
nanometers
/
picoseconds
)
return
self
.
_numpyVelocities
return
self
.
_numpyVelocities
return
self
.
velocities
return
self
.
velocities
def
getBoxVectors
(
self
,
asNumpy
=
False
):
def
getBoxVectors
(
self
,
asNumpy
=
False
):
"""Get the periodic box vectors.
"""Get the periodic box vectors.
Parameters:
Parameters:
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s
"""
"""
...
@@ -114,4 +114,4 @@ class AmberInpcrdFile(object):
...
@@ -114,4 +114,4 @@ class AmberInpcrdFile(object):
self
.
_numpyBoxVectors
.
append
(
Quantity
(
numpy
.
array
(
self
.
boxVectors
[
2
].
value_in_unit
(
nanometers
)),
nanometers
))
self
.
_numpyBoxVectors
.
append
(
Quantity
(
numpy
.
array
(
self
.
boxVectors
[
2
].
value_in_unit
(
nanometers
)),
nanometers
))
return
self
.
_numpyBoxVectors
return
self
.
_numpyBoxVectors
return
self
.
boxVectors
return
self
.
boxVectors
wrappers/python/simtk/openmm/app/amberprmtopfile.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -48,15 +48,15 @@ GBn = object()
...
@@ -48,15 +48,15 @@ GBn = object()
class
AmberPrmtopFile
(
object
):
class
AmberPrmtopFile
(
object
):
"""AmberPrmtopFile parses an AMBER prmtop file and constructs a Topology and (optionally) an OpenMM System from it."""
"""AmberPrmtopFile parses an AMBER prmtop file and constructs a Topology and (optionally) an OpenMM System from it."""
def
__init__
(
self
,
file
):
def
__init__
(
self
,
file
):
"""Load a prmtop file."""
"""Load a prmtop file."""
top
=
Topology
()
top
=
Topology
()
## The Topology read from the prmtop file
## The Topology read from the prmtop file
self
.
topology
=
top
self
.
topology
=
top
# Load the prmtop file
# Load the prmtop file
prmtop
=
amber_file_parser
.
PrmtopLoader
(
file
)
prmtop
=
amber_file_parser
.
PrmtopLoader
(
file
)
self
.
_prmtop
=
prmtop
self
.
_prmtop
=
prmtop
...
@@ -82,7 +82,7 @@ class AmberPrmtopFile(object):
...
@@ -82,7 +82,7 @@ class AmberPrmtopFile(object):
atomName
=
atomReplacements
[
atomName
]
atomName
=
atomReplacements
[
atomName
]
# Try to guess the element.
# Try to guess the element.
upper
=
atomName
.
upper
()
upper
=
atomName
.
upper
()
if
upper
.
startswith
(
'CL'
):
if
upper
.
startswith
(
'CL'
):
element
=
elem
.
chlorine
element
=
elem
.
chlorine
...
@@ -96,17 +96,17 @@ class AmberPrmtopFile(object):
...
@@ -96,17 +96,17 @@ class AmberPrmtopFile(object):
except
KeyError
:
except
KeyError
:
element
=
None
element
=
None
top
.
addAtom
(
atomName
,
element
,
r
)
top
.
addAtom
(
atomName
,
element
,
r
)
# Add bonds to the topology
# Add bonds to the topology
atoms
=
list
(
top
.
atoms
())
atoms
=
list
(
top
.
atoms
())
for
bond
in
prmtop
.
getBondsWithH
():
for
bond
in
prmtop
.
getBondsWithH
():
top
.
addBond
(
atoms
[
bond
[
0
]],
atoms
[
bond
[
1
]])
top
.
addBond
(
atoms
[
bond
[
0
]],
atoms
[
bond
[
1
]])
for
bond
in
prmtop
.
getBondsNoH
():
for
bond
in
prmtop
.
getBondsNoH
():
top
.
addBond
(
atoms
[
bond
[
0
]],
atoms
[
bond
[
1
]])
top
.
addBond
(
atoms
[
bond
[
0
]],
atoms
[
bond
[
1
]])
# Set the periodic box size.
# Set the periodic box size.
if
prmtop
.
getIfBox
():
if
prmtop
.
getIfBox
():
top
.
setUnitCellDimensions
(
tuple
(
x
.
value_in_unit
(
unit
.
nanometer
)
for
x
in
prmtop
.
getBoxBetaAndDimensions
()[
1
:
4
])
*
unit
.
nanometer
)
top
.
setUnitCellDimensions
(
tuple
(
x
.
value_in_unit
(
unit
.
nanometer
)
for
x
in
prmtop
.
getBoxBetaAndDimensions
()[
1
:
4
])
*
unit
.
nanometer
)
...
@@ -114,7 +114,7 @@ class AmberPrmtopFile(object):
...
@@ -114,7 +114,7 @@ class AmberPrmtopFile(object):
constraints
=
None
,
rigidWater
=
True
,
implicitSolvent
=
None
,
soluteDielectric
=
1.0
,
solventDielectric
=
78.5
,
removeCMMotion
=
True
,
constraints
=
None
,
rigidWater
=
True
,
implicitSolvent
=
None
,
soluteDielectric
=
1.0
,
solventDielectric
=
78.5
,
removeCMMotion
=
True
,
ewaldErrorTolerance
=
0.0005
):
ewaldErrorTolerance
=
0.0005
):
"""Construct an OpenMM System representing the topology described by this prmtop file.
"""Construct an OpenMM System representing the topology described by this prmtop file.
Parameters:
Parameters:
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
...
@@ -168,4 +168,4 @@ class AmberPrmtopFile(object):
...
@@ -168,4 +168,4 @@ class AmberPrmtopFile(object):
force
.
setEwaldErrorTolerance
(
ewaldErrorTolerance
)
force
.
setEwaldErrorTolerance
(
ewaldErrorTolerance
)
if
removeCMMotion
:
if
removeCMMotion
:
sys
.
addForce
(
mm
.
CMMotionRemover
())
sys
.
addForce
(
mm
.
CMMotionRemover
())
return
sys
return
sys
\ No newline at end of file
wrappers/python/simtk/openmm/app/dcdfile.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -40,18 +40,18 @@ from simtk.unit import picoseconds, nanometers, angstroms, is_quantity, norm
...
@@ -40,18 +40,18 @@ from simtk.unit import picoseconds, nanometers, angstroms, is_quantity, norm
class
DCDFile
(
object
):
class
DCDFile
(
object
):
"""DCDFile provides methods for creating DCD files.
"""DCDFile provides methods for creating DCD files.
DCD is a file format for storing simulation trajectories. It is supported by many programs, such
DCD is a file format for storing simulation trajectories. It is supported by many programs, such
as CHARMM, NAMD, and X-PLOR. Note, however, that different programs produce subtly different
as CHARMM, NAMD, and X-PLOR. Note, however, that different programs produce subtly different
versions of the format. This class generates the CHARMM version. Also note that there is no
versions of the format. This class generates the CHARMM version. Also note that there is no
standard byte ordering (big-endian or little-endian) for this format. This class always generates
standard byte ordering (big-endian or little-endian) for this format. This class always generates
files with little-endian ordering.
files with little-endian ordering.
To use this class, create a DCDFile object, then call writeModel() once for each model in the file."""
To use this class, create a DCDFile object, then call writeModel() once for each model in the file."""
def
__init__
(
self
,
file
,
topology
,
dt
,
firstStep
=
0
,
interval
=
1
):
def
__init__
(
self
,
file
,
topology
,
dt
,
firstStep
=
0
,
interval
=
1
):
"""Create a DCD file and write out the header.
"""Create a DCD file and write out the header.
Parameters:
Parameters:
- file (file) A file to write to
- file (file) A file to write to
- topology (Topology) The Topology defining the molecular system being written
- topology (Topology) The Topology defining the molecular system being written
...
@@ -76,10 +76,10 @@ class DCDFile(object):
...
@@ -76,10 +76,10 @@ class DCDFile(object):
header
+=
struct
.
pack
(
'<80s'
,
'Created '
+
time
.
asctime
(
time
.
localtime
(
time
.
time
())))
header
+=
struct
.
pack
(
'<80s'
,
'Created '
+
time
.
asctime
(
time
.
localtime
(
time
.
time
())))
header
+=
struct
.
pack
(
'<4i'
,
164
,
4
,
len
(
list
(
topology
.
atoms
())),
4
)
header
+=
struct
.
pack
(
'<4i'
,
164
,
4
,
len
(
list
(
topology
.
atoms
())),
4
)
file
.
write
(
header
)
file
.
write
(
header
)
def
writeModel
(
self
,
positions
,
unitCellDimensions
=
None
):
def
writeModel
(
self
,
positions
,
unitCellDimensions
=
None
):
"""Write out a model to the DCD file.
"""Write out a model to the DCD file.
Parameters:
Parameters:
- positions (list) The list of atomic positions to write
- positions (list) The list of atomic positions to write
- unitCellDimensions (Vec3=None) The dimensions of the crystallographic unit cell. If None, the dimensions specified in
- unitCellDimensions (Vec3=None) The dimensions of the crystallographic unit cell. If None, the dimensions specified in
...
@@ -87,7 +87,7 @@ class DCDFile(object):
...
@@ -87,7 +87,7 @@ class DCDFile(object):
represent a periodic system.
represent a periodic system.
"""
"""
if
len
(
list
(
self
.
_topology
.
atoms
()))
!=
len
(
positions
):
if
len
(
list
(
self
.
_topology
.
atoms
()))
!=
len
(
positions
):
raise
ValueError
(
'The number of positions must match the number of atoms'
)
raise
ValueError
(
'The number of positions must match the number of atoms'
)
if
is_quantity
(
positions
):
if
is_quantity
(
positions
):
positions
=
positions
.
value_in_unit
(
nanometers
)
positions
=
positions
.
value_in_unit
(
nanometers
)
if
any
(
math
.
isnan
(
norm
(
pos
))
for
pos
in
positions
):
if
any
(
math
.
isnan
(
norm
(
pos
))
for
pos
in
positions
):
...
@@ -95,17 +95,17 @@ class DCDFile(object):
...
@@ -95,17 +95,17 @@ class DCDFile(object):
if
any
(
math
.
isinf
(
norm
(
pos
))
for
pos
in
positions
):
if
any
(
math
.
isinf
(
norm
(
pos
))
for
pos
in
positions
):
raise
ValueError
(
'Particle position is infinite'
)
raise
ValueError
(
'Particle position is infinite'
)
file
=
self
.
_file
file
=
self
.
_file
# Update the header.
# Update the header.
self
.
_modelCount
+=
1
self
.
_modelCount
+=
1
file
.
seek
(
8
,
os
.
SEEK_SET
)
file
.
seek
(
8
,
os
.
SEEK_SET
)
file
.
write
(
struct
.
pack
(
'<i'
,
self
.
_modelCount
))
file
.
write
(
struct
.
pack
(
'<i'
,
self
.
_modelCount
))
file
.
seek
(
20
,
os
.
SEEK_SET
)
file
.
seek
(
20
,
os
.
SEEK_SET
)
file
.
write
(
struct
.
pack
(
'<i'
,
self
.
_firstStep
+
self
.
_modelCount
*
self
.
_interval
))
file
.
write
(
struct
.
pack
(
'<i'
,
self
.
_firstStep
+
self
.
_modelCount
*
self
.
_interval
))
# Write the data.
# Write the data.
file
.
seek
(
0
,
os
.
SEEK_END
)
file
.
seek
(
0
,
os
.
SEEK_END
)
boxSize
=
self
.
_topology
.
getUnitCellDimensions
()
boxSize
=
self
.
_topology
.
getUnitCellDimensions
()
if
boxSize
is
not
None
:
if
boxSize
is
not
None
:
...
...
wrappers/python/simtk/openmm/app/dcdreporter.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -34,16 +34,16 @@ __version__ = "1.0"
...
@@ -34,16 +34,16 @@ __version__ = "1.0"
import
simtk.openmm
as
mm
import
simtk.openmm
as
mm
from
simtk.openmm.app
import
DCDFile
from
simtk.openmm.app
import
DCDFile
from
simtk.unit
import
nanometer
from
simtk.unit
import
nanometer
class
DCDReporter
(
object
):
class
DCDReporter
(
object
):
"""DCDReporter outputs a series of frames from a Simulation to a DCD file.
"""DCDReporter outputs a series of frames from a Simulation to a DCD file.
To use it, create a DCDReporter, then add it to the Simulation's list of reporters.
To use it, create a DCDReporter, then add it to the Simulation's list of reporters.
"""
"""
def
__init__
(
self
,
file
,
reportInterval
):
def
__init__
(
self
,
file
,
reportInterval
):
"""Create a DCDReporter.
"""Create a DCDReporter.
Parameters:
Parameters:
- file (string) The file to write to
- file (string) The file to write to
- reportInterval (int) The interval (in time steps) at which to write frames
- reportInterval (int) The interval (in time steps) at which to write frames
...
@@ -51,10 +51,10 @@ class DCDReporter(object):
...
@@ -51,10 +51,10 @@ class DCDReporter(object):
self
.
_reportInterval
=
reportInterval
self
.
_reportInterval
=
reportInterval
self
.
_out
=
open
(
file
,
'wb'
)
self
.
_out
=
open
(
file
,
'wb'
)
self
.
_dcd
=
None
self
.
_dcd
=
None
def
describeNextReport
(
self
,
simulation
):
def
describeNextReport
(
self
,
simulation
):
"""Get information about the next report this object will generate.
"""Get information about the next report this object will generate.
Parameters:
Parameters:
- simulation (Simulation) The Simulation to generate a report for
- simulation (Simulation) The Simulation to generate a report for
Returns: A five element tuple. The first element is the number of steps until the
Returns: A five element tuple. The first element is the number of steps until the
...
@@ -63,10 +63,10 @@ class DCDReporter(object):
...
@@ -63,10 +63,10 @@ class DCDReporter(object):
"""
"""
steps
=
self
.
_reportInterval
-
simulation
.
currentStep
%
self
.
_reportInterval
steps
=
self
.
_reportInterval
-
simulation
.
currentStep
%
self
.
_reportInterval
return
(
steps
,
True
,
False
,
False
,
False
)
return
(
steps
,
True
,
False
,
False
,
False
)
def
report
(
self
,
simulation
,
state
):
def
report
(
self
,
simulation
,
state
):
"""Generate a report.
"""Generate a report.
Parameters:
Parameters:
- simulation (Simulation) The Simulation to generate a report for
- simulation (Simulation) The Simulation to generate a report for
- state (State) The current state of the simulation
- state (State) The current state of the simulation
...
@@ -75,6 +75,6 @@ class DCDReporter(object):
...
@@ -75,6 +75,6 @@ class DCDReporter(object):
self
.
_dcd
=
DCDFile
(
self
.
_out
,
simulation
.
topology
,
simulation
.
integrator
.
getStepSize
(),
0
,
self
.
_reportInterval
)
self
.
_dcd
=
DCDFile
(
self
.
_out
,
simulation
.
topology
,
simulation
.
integrator
.
getStepSize
(),
0
,
self
.
_reportInterval
)
a
,
b
,
c
=
state
.
getPeriodicBoxVectors
()
a
,
b
,
c
=
state
.
getPeriodicBoxVectors
()
self
.
_dcd
.
writeModel
(
state
.
getPositions
(),
mm
.
Vec3
(
a
[
0
].
value_in_unit
(
nanometer
),
b
[
1
].
value_in_unit
(
nanometer
),
c
[
2
].
value_in_unit
(
nanometer
))
*
nanometer
)
self
.
_dcd
.
writeModel
(
state
.
getPositions
(),
mm
.
Vec3
(
a
[
0
].
value_in_unit
(
nanometer
),
b
[
1
].
value_in_unit
(
nanometer
),
c
[
2
].
value_in_unit
(
nanometer
))
*
nanometer
)
def
__del__
(
self
):
def
__del__
(
self
):
self
.
_out
.
close
()
self
.
_out
.
close
()
wrappers/python/simtk/openmm/app/element.py
View file @
4941cc7d
...
@@ -12,7 +12,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -12,7 +12,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns
Authors: Christopher M. Bruns
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -38,13 +38,13 @@ from simtk.unit import daltons
...
@@ -38,13 +38,13 @@ from simtk.unit import daltons
class
Element
:
class
Element
:
"""An Element represents a chemical element.
"""An Element represents a chemical element.
The simtk.openmm.app.element module contains objects for all the standard chemical elements,
The simtk.openmm.app.element module contains objects for all the standard chemical elements,
such as element.hydrogen or element.carbon. You can also call the static method Element.getBySymbol() to
such as element.hydrogen or element.carbon. You can also call the static method Element.getBySymbol() to
look up the Element with a particular chemical symbol."""
look up the Element with a particular chemical symbol."""
_elements_by_symbol
=
{}
_elements_by_symbol
=
{}
def
__init__
(
self
,
number
,
name
,
symbol
,
mass
):
def
__init__
(
self
,
number
,
name
,
symbol
,
mass
):
## The atomic number of the element
## The atomic number of the element
self
.
atomic_number
=
number
self
.
atomic_number
=
number
...
...
wrappers/python/simtk/openmm/app/forcefield.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
Authors: Peter Eastman, Mark Friedrichs
Authors: Peter Eastman, Mark Friedrichs
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -63,7 +63,7 @@ class ForceField(object):
...
@@ -63,7 +63,7 @@ class ForceField(object):
def
__init__
(
self
,
*
files
):
def
__init__
(
self
,
*
files
):
"""Load one or more XML files and create a ForceField object based on them.
"""Load one or more XML files and create a ForceField object based on them.
Parameters:
Parameters:
- files A list of XML files defining the force field. Each entry may be an absolute file path, a path relative to the
- files A list of XML files defining the force field. Each entry may be an absolute file path, a path relative to the
current working directory, or a path relative to this module's data subdirectory (for built in force fields).
current working directory, or a path relative to this module's data subdirectory (for built in force fields).
...
@@ -80,9 +80,9 @@ class ForceField(object):
...
@@ -80,9 +80,9 @@ class ForceField(object):
except
IOError
:
except
IOError
:
tree
=
etree
.
parse
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'data'
,
file
))
tree
=
etree
.
parse
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'data'
,
file
))
root
=
tree
.
getroot
()
root
=
tree
.
getroot
()
# Load the atom types.
# Load the atom types.
if
tree
.
getroot
().
find
(
'AtomTypes'
)
is
not
None
:
if
tree
.
getroot
().
find
(
'AtomTypes'
)
is
not
None
:
for
type
in
tree
.
getroot
().
find
(
'AtomTypes'
).
findall
(
'Type'
):
for
type
in
tree
.
getroot
().
find
(
'AtomTypes'
).
findall
(
'Type'
):
element
=
None
element
=
None
...
@@ -92,9 +92,9 @@ class ForceField(object):
...
@@ -92,9 +92,9 @@ class ForceField(object):
if
name
in
self
.
_atomTypes
:
if
name
in
self
.
_atomTypes
:
raise
ValueError
(
'Found multiple definitions for atom type: '
+
name
)
raise
ValueError
(
'Found multiple definitions for atom type: '
+
name
)
self
.
_atomTypes
[
name
]
=
(
type
.
attrib
[
'class'
],
float
(
type
.
attrib
[
'mass'
]),
element
)
self
.
_atomTypes
[
name
]
=
(
type
.
attrib
[
'class'
],
float
(
type
.
attrib
[
'mass'
]),
element
)
# Load the residue templates.
# Load the residue templates.
if
tree
.
getroot
().
find
(
'Residues'
)
is
not
None
:
if
tree
.
getroot
().
find
(
'Residues'
)
is
not
None
:
for
residue
in
root
.
find
(
'Residues'
).
findall
(
'Residue'
):
for
residue
in
root
.
find
(
'Residues'
).
findall
(
'Residue'
):
resName
=
residue
.
attrib
[
'name'
]
resName
=
residue
.
attrib
[
'name'
]
...
@@ -119,9 +119,9 @@ class ForceField(object):
...
@@ -119,9 +119,9 @@ class ForceField(object):
self
.
_templateSignatures
[
signature
].
append
(
template
)
self
.
_templateSignatures
[
signature
].
append
(
template
)
else
:
else
:
self
.
_templateSignatures
[
signature
]
=
[
template
]
self
.
_templateSignatures
[
signature
]
=
[
template
]
# Build sets of every atom type belonging to each class
# Build sets of every atom type belonging to each class
for
type
in
self
.
_atomTypes
:
for
type
in
self
.
_atomTypes
:
atomClass
=
self
.
_atomTypes
[
type
][
0
]
atomClass
=
self
.
_atomTypes
[
type
][
0
]
if
atomClass
in
self
.
_atomClasses
:
if
atomClass
in
self
.
_atomClasses
:
...
@@ -131,15 +131,15 @@ class ForceField(object):
...
@@ -131,15 +131,15 @@ class ForceField(object):
self
.
_atomClasses
[
atomClass
]
=
typeSet
self
.
_atomClasses
[
atomClass
]
=
typeSet
typeSet
.
add
(
type
)
typeSet
.
add
(
type
)
self
.
_atomClasses
[
''
].
add
(
type
)
self
.
_atomClasses
[
''
].
add
(
type
)
# Load force definitions
# Load force definitions
for
child
in
root
:
for
child
in
root
:
if
child
.
tag
in
parsers
:
if
child
.
tag
in
parsers
:
parsers
[
child
.
tag
](
child
,
self
)
parsers
[
child
.
tag
](
child
,
self
)
# Load scripts
# Load scripts
for
node
in
tree
.
getroot
().
findall
(
'Script'
):
for
node
in
tree
.
getroot
().
findall
(
'Script'
):
self
.
_scripts
.
append
(
node
.
text
)
self
.
_scripts
.
append
(
node
.
text
)
...
@@ -181,8 +181,8 @@ class ForceField(object):
...
@@ -181,8 +181,8 @@ class ForceField(object):
torsion
.
phase
.
append
(
float
(
attrib
[
'phase%d'
%
index
]))
torsion
.
phase
.
append
(
float
(
attrib
[
'phase%d'
%
index
]))
torsion
.
k
.
append
(
float
(
attrib
[
'k%d'
%
index
]))
torsion
.
k
.
append
(
float
(
attrib
[
'k%d'
%
index
]))
index
+=
1
index
+=
1
return
torsion
return
torsion
class
_SystemData
:
class
_SystemData
:
"""Inner class used to encapsulate data about the system being created."""
"""Inner class used to encapsulate data about the system being created."""
def
__init__
(
self
):
def
__init__
(
self
):
...
@@ -221,7 +221,7 @@ class ForceField(object):
...
@@ -221,7 +221,7 @@ class ForceField(object):
self
.
atom2
=
atom2
self
.
atom2
=
atom2
self
.
isConstrained
=
False
self
.
isConstrained
=
False
self
.
length
=
0.0
self
.
length
=
0.0
class
_VirtualSiteData
:
class
_VirtualSiteData
:
"""Inner class used to encapsulate data about a virtual site."""
"""Inner class used to encapsulate data about a virtual site."""
def
__init__
(
self
,
node
):
def
__init__
(
self
,
node
):
...
@@ -244,7 +244,7 @@ class ForceField(object):
...
@@ -244,7 +244,7 @@ class ForceField(object):
def
createSystem
(
self
,
topology
,
nonbondedMethod
=
NoCutoff
,
nonbondedCutoff
=
1.0
*
unit
.
nanometer
,
def
createSystem
(
self
,
topology
,
nonbondedMethod
=
NoCutoff
,
nonbondedCutoff
=
1.0
*
unit
.
nanometer
,
constraints
=
None
,
rigidWater
=
True
,
removeCMMotion
=
True
,
**
args
):
constraints
=
None
,
rigidWater
=
True
,
removeCMMotion
=
True
,
**
args
):
"""Construct an OpenMM System representing a Topology with this force field.
"""Construct an OpenMM System representing a Topology with this force field.
Parameters:
Parameters:
- topology (Topology) The Topology for which to create a System
- topology (Topology) The Topology for which to create a System
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are
...
@@ -262,12 +262,12 @@ class ForceField(object):
...
@@ -262,12 +262,12 @@ class ForceField(object):
data
.
atoms
=
list
(
topology
.
atoms
())
data
.
atoms
=
list
(
topology
.
atoms
())
# Make a list of all bonds
# Make a list of all bonds
for
bond
in
topology
.
bonds
():
for
bond
in
topology
.
bonds
():
data
.
bonds
.
append
(
ForceField
.
_BondData
(
bond
[
0
].
index
,
bond
[
1
].
index
))
data
.
bonds
.
append
(
ForceField
.
_BondData
(
bond
[
0
].
index
,
bond
[
1
].
index
))
# Record which atoms are bonded to each other atom
# Record which atoms are bonded to each other atom
bondedToAtom
=
[]
bondedToAtom
=
[]
for
i
in
range
(
len
(
data
.
atoms
)):
for
i
in
range
(
len
(
data
.
atoms
)):
bondedToAtom
.
append
(
set
())
bondedToAtom
.
append
(
set
())
...
@@ -280,7 +280,7 @@ class ForceField(object):
...
@@ -280,7 +280,7 @@ class ForceField(object):
data
.
atomBonds
[
bond
.
atom2
].
append
(
i
)
data
.
atomBonds
[
bond
.
atom2
].
append
(
i
)
# Find the template matching each residue and assign atom types.
# Find the template matching each residue and assign atom types.
for
chain
in
topology
.
chains
():
for
chain
in
topology
.
chains
():
for
res
in
chain
.
residues
():
for
res
in
chain
.
residues
():
template
=
None
template
=
None
...
@@ -301,13 +301,13 @@ class ForceField(object):
...
@@ -301,13 +301,13 @@ class ForceField(object):
data
.
virtualSites
[
atom
]
=
site
data
.
virtualSites
[
atom
]
=
site
# Create the System and add atoms
# Create the System and add atoms
sys
=
mm
.
System
()
sys
=
mm
.
System
()
for
atom
in
topology
.
atoms
():
for
atom
in
topology
.
atoms
():
sys
.
addParticle
(
self
.
_atomTypes
[
data
.
atomType
[
atom
]][
1
])
sys
.
addParticle
(
self
.
_atomTypes
[
data
.
atomType
[
atom
]][
1
])
# Set periodic boundary conditions.
# Set periodic boundary conditions.
boxSize
=
topology
.
getUnitCellDimensions
()
boxSize
=
topology
.
getUnitCellDimensions
()
if
boxSize
is
not
None
:
if
boxSize
is
not
None
:
sys
.
setDefaultPeriodicBoxVectors
((
boxSize
[
0
],
0
,
0
),
(
0
,
boxSize
[
1
],
0
),
(
0
,
0
,
boxSize
[
2
]))
sys
.
setDefaultPeriodicBoxVectors
((
boxSize
[
0
],
0
,
0
),
(
0
,
boxSize
[
1
],
0
),
(
0
,
0
,
boxSize
[
2
]))
...
@@ -315,7 +315,7 @@ class ForceField(object):
...
@@ -315,7 +315,7 @@ class ForceField(object):
raise
ValueError
(
'Requested periodic boundary conditions for a Topology that does not specify periodic box dimensions'
)
raise
ValueError
(
'Requested periodic boundary conditions for a Topology that does not specify periodic box dimensions'
)
# Make a list of all unique angles
# Make a list of all unique angles
uniqueAngles
=
set
()
uniqueAngles
=
set
()
for
bond
in
data
.
bonds
:
for
bond
in
data
.
bonds
:
for
atom
in
bondedToAtom
[
bond
.
atom1
]:
for
atom
in
bondedToAtom
[
bond
.
atom1
]:
...
@@ -331,9 +331,9 @@ class ForceField(object):
...
@@ -331,9 +331,9 @@ class ForceField(object):
else
:
else
:
uniqueAngles
.
add
((
atom
,
bond
.
atom2
,
bond
.
atom1
))
uniqueAngles
.
add
((
atom
,
bond
.
atom2
,
bond
.
atom1
))
data
.
angles
=
sorted
(
list
(
uniqueAngles
))
data
.
angles
=
sorted
(
list
(
uniqueAngles
))
# Make a list of all unique proper torsions
# Make a list of all unique proper torsions
uniquePropers
=
set
()
uniquePropers
=
set
()
for
angle
in
data
.
angles
:
for
angle
in
data
.
angles
:
for
atom
in
bondedToAtom
[
angle
[
0
]]:
for
atom
in
bondedToAtom
[
angle
[
0
]]:
...
@@ -349,17 +349,17 @@ class ForceField(object):
...
@@ -349,17 +349,17 @@ class ForceField(object):
else
:
else
:
uniquePropers
.
add
((
atom
,
angle
[
2
],
angle
[
1
],
angle
[
0
]))
uniquePropers
.
add
((
atom
,
angle
[
2
],
angle
[
1
],
angle
[
0
]))
data
.
propers
=
sorted
(
list
(
uniquePropers
))
data
.
propers
=
sorted
(
list
(
uniquePropers
))
# Make a list of all unique improper torsions
# Make a list of all unique improper torsions
for
atom
in
range
(
len
(
bondedToAtom
)):
for
atom
in
range
(
len
(
bondedToAtom
)):
bondedTo
=
bondedToAtom
[
atom
]
bondedTo
=
bondedToAtom
[
atom
]
if
len
(
bondedTo
)
>
2
:
if
len
(
bondedTo
)
>
2
:
for
subset
in
itertools
.
combinations
(
bondedTo
,
3
):
for
subset
in
itertools
.
combinations
(
bondedTo
,
3
):
data
.
impropers
.
append
((
atom
,
subset
[
0
],
subset
[
1
],
subset
[
2
]))
data
.
impropers
.
append
((
atom
,
subset
[
0
],
subset
[
1
],
subset
[
2
]))
# Identify bonds that should be implemented with constraints
# Identify bonds that should be implemented with constraints
if
constraints
==
AllBonds
or
constraints
==
HAngles
:
if
constraints
==
AllBonds
or
constraints
==
HAngles
:
for
bond
in
data
.
bonds
:
for
bond
in
data
.
bonds
:
bond
.
isConstrained
=
True
bond
.
isConstrained
=
True
...
@@ -374,9 +374,9 @@ class ForceField(object):
...
@@ -374,9 +374,9 @@ class ForceField(object):
atom2
=
data
.
atoms
[
bond
.
atom2
]
atom2
=
data
.
atoms
[
bond
.
atom2
]
if
atom1
.
residue
.
name
==
'HOH'
and
atom2
.
residue
.
name
==
'HOH'
:
if
atom1
.
residue
.
name
==
'HOH'
and
atom2
.
residue
.
name
==
'HOH'
:
bond
.
isConstrained
=
True
bond
.
isConstrained
=
True
# Identify angles that should be implemented with constraints
# Identify angles that should be implemented with constraints
if
constraints
==
HAngles
:
if
constraints
==
HAngles
:
for
angle
in
data
.
angles
:
for
angle
in
data
.
angles
:
atom1
=
data
.
atoms
[
angle
[
0
]]
atom1
=
data
.
atoms
[
angle
[
0
]]
...
@@ -398,9 +398,9 @@ class ForceField(object):
...
@@ -398,9 +398,9 @@ class ForceField(object):
atom3
=
data
.
atoms
[
angle
[
2
]]
atom3
=
data
.
atoms
[
angle
[
2
]]
if
atom1
.
residue
.
name
==
'HOH'
and
atom2
.
residue
.
name
==
'HOH'
and
atom3
.
residue
.
name
==
'HOH'
:
if
atom1
.
residue
.
name
==
'HOH'
and
atom2
.
residue
.
name
==
'HOH'
and
atom3
.
residue
.
name
==
'HOH'
:
data
.
isAngleConstrained
[
i
]
=
True
data
.
isAngleConstrained
[
i
]
=
True
# Add virtual sites
# Add virtual sites
for
atom
in
data
.
virtualSites
:
for
atom
in
data
.
virtualSites
:
site
=
data
.
virtualSites
[
atom
]
site
=
data
.
virtualSites
[
atom
]
index
=
atom
.
index
index
=
atom
.
index
...
@@ -410,22 +410,22 @@ class ForceField(object):
...
@@ -410,22 +410,22 @@ class ForceField(object):
sys
.
setVirtualSite
(
index
,
mm
.
ThreeParticleAverageSite
(
index
+
site
.
atoms
[
0
],
index
+
site
.
atoms
[
1
],
index
+
site
.
atoms
[
2
],
site
.
weights
[
0
],
site
.
weights
[
1
],
site
.
weights
[
2
]))
sys
.
setVirtualSite
(
index
,
mm
.
ThreeParticleAverageSite
(
index
+
site
.
atoms
[
0
],
index
+
site
.
atoms
[
1
],
index
+
site
.
atoms
[
2
],
site
.
weights
[
0
],
site
.
weights
[
1
],
site
.
weights
[
2
]))
elif
site
.
type
==
'outOfPlane'
:
elif
site
.
type
==
'outOfPlane'
:
sys
.
setVirtualSite
(
index
,
mm
.
OutOfPlaneSite
(
index
+
site
.
atoms
[
0
],
index
+
site
.
atoms
[
1
],
index
+
site
.
atoms
[
2
],
site
.
weights
[
0
],
site
.
weights
[
1
],
site
.
weights
[
2
]))
sys
.
setVirtualSite
(
index
,
mm
.
OutOfPlaneSite
(
index
+
site
.
atoms
[
0
],
index
+
site
.
atoms
[
1
],
index
+
site
.
atoms
[
2
],
site
.
weights
[
0
],
site
.
weights
[
1
],
site
.
weights
[
2
]))
# Add forces to the System
# Add forces to the System
for
force
in
self
.
_forces
:
for
force
in
self
.
_forces
:
force
.
createForce
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
)
force
.
createForce
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
)
if
removeCMMotion
:
if
removeCMMotion
:
sys
.
addForce
(
mm
.
CMMotionRemover
())
sys
.
addForce
(
mm
.
CMMotionRemover
())
# Let generators do postprocessing
# Let generators do postprocessing
for
force
in
self
.
_forces
:
for
force
in
self
.
_forces
:
if
'postprocessSystem'
in
dir
(
force
):
if
'postprocessSystem'
in
dir
(
force
):
force
.
postprocessSystem
(
sys
,
data
,
args
)
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
:
exec
script
exec
script
return
sys
return
sys
...
@@ -445,7 +445,7 @@ def _createResidueSignature(elements):
...
@@ -445,7 +445,7 @@ def _createResidueSignature(elements):
for
c
in
counts
:
for
c
in
counts
:
sig
.
append
((
c
,
counts
[
c
]))
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.
s
=
''
s
=
''
...
@@ -456,7 +456,7 @@ def _createResidueSignature(elements):
...
@@ -456,7 +456,7 @@ def _createResidueSignature(elements):
def
_matchResidue
(
res
,
template
,
bondedToAtom
):
def
_matchResidue
(
res
,
template
,
bondedToAtom
):
"""Determine whether a residue matches a template and return a list of corresponding atoms.
"""Determine whether a residue matches a template and return a list of corresponding atoms.
Parameters:
Parameters:
- res (Residue) The residue to check
- res (Residue) The residue to check
- template (_TemplateData) The template to compare it to
- template (_TemplateData) The template to compare it to
...
@@ -469,9 +469,9 @@ def _matchResidue(res, template, bondedToAtom):
...
@@ -469,9 +469,9 @@ def _matchResidue(res, template, bondedToAtom):
return
None
return
None
matches
=
len
(
atoms
)
*
[
0
]
matches
=
len
(
atoms
)
*
[
0
]
hasMatch
=
len
(
atoms
)
*
[
False
]
hasMatch
=
len
(
atoms
)
*
[
False
]
# Translate from global to local atom indices, and record the bonds for each atom.
# Translate from global to local atom indices, and record the bonds for each atom.
renumberAtoms
=
{}
renumberAtoms
=
{}
for
i
in
range
(
len
(
atoms
)):
for
i
in
range
(
len
(
atoms
)):
renumberAtoms
[
atoms
[
i
].
index
]
=
i
renumberAtoms
[
atoms
[
i
].
index
]
=
i
...
@@ -496,11 +496,11 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
...
@@ -496,11 +496,11 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
atom
=
template
.
atoms
[
i
]
atom
=
template
.
atoms
[
i
]
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
]:
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
]))
if
allBondsMatch
:
if
allBondsMatch
:
# This is a possible match, so trying matching the rest of the residue.
# This is a possible match, so trying matching the rest of the residue.
matches
[
position
]
=
i
matches
[
position
]
=
i
hasMatch
[
i
]
=
True
hasMatch
[
i
]
=
True
if
_findAtomMatches
(
atoms
,
template
,
bondedTo
,
externalBonds
,
matches
,
hasMatch
,
position
+
1
):
if
_findAtomMatches
(
atoms
,
template
,
bondedTo
,
externalBonds
,
matches
,
hasMatch
,
position
+
1
):
...
@@ -517,13 +517,13 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
...
@@ -517,13 +517,13 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
## @private
## @private
class
HarmonicBondGenerator
:
class
HarmonicBondGenerator
:
"""A HarmonicBondGenerator constructs a HarmonicBondForce."""
"""A HarmonicBondGenerator constructs a HarmonicBondForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
types1
=
[]
self
.
types1
=
[]
self
.
types2
=
[]
self
.
types2
=
[]
self
.
length
=
[]
self
.
length
=
[]
self
.
k
=
[]
self
.
k
=
[]
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
generator
=
HarmonicBondGenerator
()
generator
=
HarmonicBondGenerator
()
...
@@ -535,7 +535,7 @@ class HarmonicBondGenerator:
...
@@ -535,7 +535,7 @@ class HarmonicBondGenerator:
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
length
.
append
(
float
(
bond
.
attrib
[
'length'
]))
generator
.
length
.
append
(
float
(
bond
.
attrib
[
'length'
]))
generator
.
k
.
append
(
float
(
bond
.
attrib
[
'k'
]))
generator
.
k
.
append
(
float
(
bond
.
attrib
[
'k'
]))
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
HarmonicBondForce
]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
HarmonicBondForce
]
...
@@ -564,14 +564,14 @@ parsers["HarmonicBondForce"] = HarmonicBondGenerator.parseElement
...
@@ -564,14 +564,14 @@ parsers["HarmonicBondForce"] = HarmonicBondGenerator.parseElement
## @private
## @private
class
HarmonicAngleGenerator
:
class
HarmonicAngleGenerator
:
"""A HarmonicAngleGenerator constructs a HarmonicAngleForce."""
"""A HarmonicAngleGenerator constructs a HarmonicAngleForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
types1
=
[]
self
.
types1
=
[]
self
.
types2
=
[]
self
.
types2
=
[]
self
.
types3
=
[]
self
.
types3
=
[]
self
.
angle
=
[]
self
.
angle
=
[]
self
.
k
=
[]
self
.
k
=
[]
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
generator
=
HarmonicAngleGenerator
()
generator
=
HarmonicAngleGenerator
()
...
@@ -584,7 +584,7 @@ class HarmonicAngleGenerator:
...
@@ -584,7 +584,7 @@ class HarmonicAngleGenerator:
generator
.
types3
.
append
(
types
[
2
])
generator
.
types3
.
append
(
types
[
2
])
generator
.
angle
.
append
(
float
(
angle
.
attrib
[
'angle'
]))
generator
.
angle
.
append
(
float
(
angle
.
attrib
[
'angle'
]))
generator
.
k
.
append
(
float
(
angle
.
attrib
[
'k'
]))
generator
.
k
.
append
(
float
(
angle
.
attrib
[
'k'
]))
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
HarmonicAngleForce
]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
HarmonicAngleForce
]
...
@@ -604,7 +604,7 @@ class HarmonicAngleGenerator:
...
@@ -604,7 +604,7 @@ class HarmonicAngleGenerator:
if
(
type1
in
types1
and
type2
in
types2
and
type3
in
types3
)
or
(
type1
in
types3
and
type2
in
types2
and
type3
in
types1
):
if
(
type1
in
types1
and
type2
in
types2
and
type3
in
types3
)
or
(
type1
in
types3
and
type2
in
types2
and
type3
in
types1
):
if
isConstrained
:
if
isConstrained
:
# Find the two bonds that make this angle.
# Find the two bonds that make this angle.
bond1
=
None
bond1
=
None
bond2
=
None
bond2
=
None
for
bond
in
data
.
atomBonds
[
angle
[
1
]]:
for
bond
in
data
.
atomBonds
[
angle
[
1
]]:
...
@@ -614,9 +614,9 @@ class HarmonicAngleGenerator:
...
@@ -614,9 +614,9 @@ class HarmonicAngleGenerator:
bond1
=
bond
bond1
=
bond
elif
atom1
==
angle
[
2
]
or
atom2
==
angle
[
2
]:
elif
atom1
==
angle
[
2
]
or
atom2
==
angle
[
2
]:
bond2
=
bond
bond2
=
bond
# Compute the distance between atoms and add a constraint
# Compute the distance between atoms and add a constraint
if
bond1
is
not
None
and
bond2
is
not
None
:
if
bond1
is
not
None
and
bond2
is
not
None
:
l1
=
data
.
bonds
[
bond1
].
length
l1
=
data
.
bonds
[
bond1
].
length
l2
=
data
.
bonds
[
bond2
].
length
l2
=
data
.
bonds
[
bond2
].
length
...
@@ -646,11 +646,11 @@ class PeriodicTorsion:
...
@@ -646,11 +646,11 @@ class PeriodicTorsion:
## @private
## @private
class
PeriodicTorsionGenerator
:
class
PeriodicTorsionGenerator
:
"""A PeriodicTorsionGenerator constructs a PeriodicTorsionForce."""
"""A PeriodicTorsionGenerator constructs a PeriodicTorsionForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
proper
=
[]
self
.
proper
=
[]
self
.
improper
=
[]
self
.
improper
=
[]
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
generator
=
PeriodicTorsionGenerator
()
generator
=
PeriodicTorsionGenerator
()
...
@@ -664,7 +664,7 @@ class PeriodicTorsionGenerator:
...
@@ -664,7 +664,7 @@ class PeriodicTorsionGenerator:
torsion
=
ff
.
_parseTorsion
(
torsion
)
torsion
=
ff
.
_parseTorsion
(
torsion
)
if
torsion
is
not
None
:
if
torsion
is
not
None
:
generator
.
improper
.
append
(
torsion
)
generator
.
improper
.
append
(
torsion
)
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
PeriodicTorsionForce
]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
PeriodicTorsionForce
]
...
@@ -745,11 +745,11 @@ class RBTorsion:
...
@@ -745,11 +745,11 @@ class RBTorsion:
## @private
## @private
class
RBTorsionGenerator
:
class
RBTorsionGenerator
:
"""An RBTorsionGenerator constructs an RBTorsionForce."""
"""An RBTorsionGenerator constructs an RBTorsionForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
proper
=
[]
self
.
proper
=
[]
self
.
improper
=
[]
self
.
improper
=
[]
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
generator
=
RBTorsionGenerator
()
generator
=
RBTorsionGenerator
()
...
@@ -763,7 +763,7 @@ class RBTorsionGenerator:
...
@@ -763,7 +763,7 @@ class RBTorsionGenerator:
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
if
None
not
in
types
:
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
):
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
RBTorsionForce
]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
RBTorsionForce
]
...
@@ -841,11 +841,11 @@ class CMAPTorsion:
...
@@ -841,11 +841,11 @@ class CMAPTorsion:
## @private
## @private
class
CMAPTorsionGenerator
:
class
CMAPTorsionGenerator
:
"""A CMAPTorsionGenerator constructs a CMAPTorsionForce."""
"""A CMAPTorsionGenerator constructs a CMAPTorsionForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
torsions
=
[]
self
.
torsions
=
[]
self
.
maps
=
[]
self
.
maps
=
[]
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
generator
=
CMAPTorsionGenerator
()
generator
=
CMAPTorsionGenerator
()
...
@@ -861,7 +861,7 @@ class CMAPTorsionGenerator:
...
@@ -861,7 +861,7 @@ class CMAPTorsionGenerator:
types
=
ff
.
_findAtomTypes
(
torsion
,
5
)
types
=
ff
.
_findAtomTypes
(
torsion
,
5
)
if
None
not
in
types
:
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
):
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
CMAPTorsionForce
]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
CMAPTorsionForce
]
...
@@ -872,9 +872,9 @@ class CMAPTorsionGenerator:
...
@@ -872,9 +872,9 @@ class CMAPTorsionGenerator:
force
=
existing
[
0
]
force
=
existing
[
0
]
for
map
in
self
.
maps
:
for
map
in
self
.
maps
:
force
.
addMap
(
int
(
sqrt
(
len
(
map
))),
map
)
force
.
addMap
(
int
(
sqrt
(
len
(
map
))),
map
)
# Find all chains of length 5
# Find all chains of length 5
uniqueTorsions
=
set
()
uniqueTorsions
=
set
()
for
torsion
in
data
.
propers
:
for
torsion
in
data
.
propers
:
for
bond
in
(
data
.
bonds
[
x
]
for
x
in
data
.
atomBonds
[
torsion
[
0
]]):
for
bond
in
(
data
.
bonds
[
x
]
for
x
in
data
.
atomBonds
[
torsion
[
0
]]):
...
@@ -921,7 +921,7 @@ parsers["CMAPTorsionForce"] = CMAPTorsionGenerator.parseElement
...
@@ -921,7 +921,7 @@ parsers["CMAPTorsionForce"] = CMAPTorsionGenerator.parseElement
## @private
## @private
class
NonbondedGenerator
:
class
NonbondedGenerator
:
"""A NonbondedGenerator constructs a NonbondedForce."""
"""A NonbondedGenerator constructs a NonbondedForce."""
def
__init__
(
self
,
coulomb14scale
,
lj14scale
):
def
__init__
(
self
,
coulomb14scale
,
lj14scale
):
self
.
coulomb14scale
=
coulomb14scale
self
.
coulomb14scale
=
coulomb14scale
self
.
lj14scale
=
lj14scale
self
.
lj14scale
=
lj14scale
...
@@ -937,14 +937,14 @@ class NonbondedGenerator:
...
@@ -937,14 +937,14 @@ class NonbondedGenerator:
# Multiple <NonbondedForce> tags were found, probably in different files. Simply add more types to the existing one.
# Multiple <NonbondedForce> tags were found, probably in different files. Simply add more types to the existing one.
generator
=
existing
[
0
]
generator
=
existing
[
0
]
if
generator
.
coulomb14scale
!=
float
(
element
.
attrib
[
'coulomb14scale'
])
or
generator
.
lj14scale
!=
float
(
element
.
attrib
[
'lj14scale'
]):
if
generator
.
coulomb14scale
!=
float
(
element
.
attrib
[
'coulomb14scale'
])
or
generator
.
lj14scale
!=
float
(
element
.
attrib
[
'lj14scale'
]):
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
None
not
in
types
:
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
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
methodMap
=
{
NoCutoff
:
mm
.
NonbondedForce
.
NoCutoff
,
methodMap
=
{
NoCutoff
:
mm
.
NonbondedForce
.
NoCutoff
,
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
...
@@ -952,7 +952,7 @@ class NonbondedGenerator:
...
@@ -952,7 +952,7 @@ class NonbondedGenerator:
Ewald
:
mm
.
NonbondedForce
.
Ewald
,
Ewald
:
mm
.
NonbondedForce
.
Ewald
,
PME
:
mm
.
NonbondedForce
.
PME
}
PME
:
mm
.
NonbondedForce
.
PME
}
if
nonbondedMethod
not
in
methodMap
:
if
nonbondedMethod
not
in
methodMap
:
raise
ValueError
(
'Illegal nonbonded method for NonbondedForce'
)
raise
ValueError
(
'Illegal nonbonded method for NonbondedForce'
)
force
=
mm
.
NonbondedForce
()
force
=
mm
.
NonbondedForce
()
for
atom
in
data
.
atoms
:
for
atom
in
data
.
atoms
:
t
=
data
.
atomType
[
atom
]
t
=
data
.
atomType
[
atom
]
...
@@ -966,7 +966,7 @@ class NonbondedGenerator:
...
@@ -966,7 +966,7 @@ class NonbondedGenerator:
if
'ewaldErrorTolerance'
in
args
:
if
'ewaldErrorTolerance'
in
args
:
force
.
setEwaldErrorTolerance
(
args
[
'ewaldErrorTolerance'
])
force
.
setEwaldErrorTolerance
(
args
[
'ewaldErrorTolerance'
])
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# Create exceptions based on bonds, virtual sites, and Drude particles.
# Create exceptions based on bonds, virtual sites, and Drude particles.
bondIndices
=
[]
bondIndices
=
[]
...
@@ -996,7 +996,7 @@ class NonbondedGenerator:
...
@@ -996,7 +996,7 @@ class NonbondedGenerator:
if
drude2
is
not
None
:
if
drude2
is
not
None
:
bondIndices
.
append
((
atom1
,
drude2
))
bondIndices
.
append
((
atom1
,
drude2
))
nonbonded
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
NonbondedForce
)][
0
]
nonbonded
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
NonbondedForce
)][
0
]
nonbonded
.
createExceptionsFromBonds
(
bondIndices
,
self
.
coulomb14scale
,
self
.
lj14scale
)
nonbonded
.
createExceptionsFromBonds
(
bondIndices
,
self
.
coulomb14scale
,
self
.
lj14scale
)
parsers
[
"NonbondedForce"
]
=
NonbondedGenerator
.
parseElement
parsers
[
"NonbondedForce"
]
=
NonbondedGenerator
.
parseElement
...
@@ -1004,7 +1004,7 @@ parsers["NonbondedForce"] = NonbondedGenerator.parseElement
...
@@ -1004,7 +1004,7 @@ parsers["NonbondedForce"] = NonbondedGenerator.parseElement
## @private
## @private
class
GBSAOBCGenerator
:
class
GBSAOBCGenerator
:
"""A GBSAOBCGenerator constructs a GBSAOBCForce."""
"""A GBSAOBCGenerator constructs a GBSAOBCForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
typeMap
=
{}
self
.
typeMap
=
{}
...
@@ -1023,13 +1023,13 @@ class GBSAOBCGenerator:
...
@@ -1023,13 +1023,13 @@ class GBSAOBCGenerator:
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
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
methodMap
=
{
NoCutoff
:
mm
.
NonbondedForce
.
NoCutoff
,
methodMap
=
{
NoCutoff
:
mm
.
NonbondedForce
.
NoCutoff
,
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
}
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
}
if
nonbondedMethod
not
in
methodMap
:
if
nonbondedMethod
not
in
methodMap
:
raise
ValueError
(
'Illegal nonbonded method for GBSAOBCForce'
)
raise
ValueError
(
'Illegal nonbonded method for GBSAOBCForce'
)
force
=
mm
.
GBSAOBCForce
()
force
=
mm
.
GBSAOBCForce
()
for
atom
in
data
.
atoms
:
for
atom
in
data
.
atoms
:
t
=
data
.
atomType
[
atom
]
t
=
data
.
atomType
[
atom
]
...
@@ -1037,7 +1037,7 @@ class GBSAOBCGenerator:
...
@@ -1037,7 +1037,7 @@ class GBSAOBCGenerator:
values
=
self
.
typeMap
[
t
]
values
=
self
.
typeMap
[
t
]
force
.
addParticle
(
values
[
0
],
values
[
1
],
values
[
2
])
force
.
addParticle
(
values
[
0
],
values
[
1
],
values
[
2
])
else
:
else
:
raise
ValueError
(
'No GBSAOBC parameters defined for atom type '
+
t
)
raise
ValueError
(
'No GBSAOBC parameters defined for atom type '
+
t
)
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
force
.
setCutoffDistance
(
nonbondedCutoff
)
force
.
setCutoffDistance
(
nonbondedCutoff
)
if
'soluteDielectric'
in
args
:
if
'soluteDielectric'
in
args
:
...
@@ -1048,7 +1048,7 @@ class GBSAOBCGenerator:
...
@@ -1048,7 +1048,7 @@ class GBSAOBCGenerator:
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# Disable the reaction field approximation, since it produces bad results when combined with GB.
# Disable the reaction field approximation, since it produces bad results when combined with GB.
for
force
in
sys
.
getForces
():
for
force
in
sys
.
getForces
():
if
isinstance
(
force
,
mm
.
NonbondedForce
):
if
isinstance
(
force
,
mm
.
NonbondedForce
):
force
.
setReactionFieldDielectric
(
1.0
)
force
.
setReactionFieldDielectric
(
1.0
)
...
@@ -1060,7 +1060,7 @@ parsers["GBSAOBCForce"] = GBSAOBCGenerator.parseElement
...
@@ -1060,7 +1060,7 @@ parsers["GBSAOBCForce"] = GBSAOBCGenerator.parseElement
class
GBVIGenerator
:
class
GBVIGenerator
:
"""A GBVIGenerator constructs a GBVIForce."""
"""A GBVIGenerator constructs a GBVIForce."""
def
__init__
(
self
,
ff
):
def
__init__
(
self
,
ff
):
self
.
ff
=
ff
self
.
ff
=
ff
...
@@ -1087,7 +1087,7 @@ class GBVIGenerator:
...
@@ -1087,7 +1087,7 @@ class GBVIGenerator:
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
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
methodMap
=
{
NoCutoff
:
mm
.
NonbondedForce
.
NoCutoff
,
methodMap
=
{
NoCutoff
:
mm
.
NonbondedForce
.
NoCutoff
,
...
@@ -1095,7 +1095,7 @@ class GBVIGenerator:
...
@@ -1095,7 +1095,7 @@ class GBVIGenerator:
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
}
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
}
if
nonbondedMethod
not
in
methodMap
:
if
nonbondedMethod
not
in
methodMap
:
raise
ValueError
(
'Illegal nonbonded method for GB/VI Force'
)
raise
ValueError
(
'Illegal nonbonded method for GB/VI Force'
)
# add particles
# add particles
...
@@ -1106,18 +1106,18 @@ class GBVIGenerator:
...
@@ -1106,18 +1106,18 @@ class GBVIGenerator:
values
=
self
.
typeMap
[
t
]
values
=
self
.
typeMap
[
t
]
force
.
addParticle
(
values
[
0
],
values
[
1
],
values
[
2
])
force
.
addParticle
(
values
[
0
],
values
[
1
],
values
[
2
])
else
:
else
:
raise
ValueError
(
'No GB/VI parameters defined for atom type '
+
t
)
raise
ValueError
(
'No GB/VI parameters defined for atom type '
+
t
)
# get HarmonicBond generator -- exit if not found
# get HarmonicBond generator -- exit if not found
hbGenerator
=
0
hbGenerator
=
0
for
generator
in
self
.
ff
.
_forces
:
for
generator
in
self
.
ff
.
_forces
:
if
(
generator
.
__class__
.
__name__
==
'HarmonicBondGenerator'
):
if
(
generator
.
__class__
.
__name__
==
'HarmonicBondGenerator'
):
hbGenerator
=
generator
hbGenerator
=
generator
break
break
if
(
hbGenerator
==
0
):
if
(
hbGenerator
==
0
):
raise
ValueError
(
'HarmonicBondGenerator not found.'
)
raise
ValueError
(
'HarmonicBondGenerator not found.'
)
# add bonds
# add bonds
...
@@ -1139,7 +1139,7 @@ class GBVIGenerator:
...
@@ -1139,7 +1139,7 @@ class GBVIGenerator:
force
.
setBornRadiusScalingMethod
(
self
.
fixedParameters
[
'scalingMethod'
])
force
.
setBornRadiusScalingMethod
(
self
.
fixedParameters
[
'scalingMethod'
])
force
.
setQuinticLowerLimitFactor
(
self
.
fixedParameters
[
'quinticLowerLimitFactor'
])
force
.
setQuinticLowerLimitFactor
(
self
.
fixedParameters
[
'quinticLowerLimitFactor'
])
force
.
setQuinticUpperBornRadiusLimit
(
self
.
fixedParameters
[
'quinticUpperBornRadiusLimit'
])
force
.
setQuinticUpperBornRadiusLimit
(
self
.
fixedParameters
[
'quinticUpperBornRadiusLimit'
])
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
parsers
[
"GBVIForce"
]
=
GBVIGenerator
.
parseElement
parsers
[
"GBVIForce"
]
=
GBVIGenerator
.
parseElement
...
@@ -1147,14 +1147,14 @@ parsers["GBVIForce"] = GBVIGenerator.parseElement
...
@@ -1147,14 +1147,14 @@ parsers["GBVIForce"] = GBVIGenerator.parseElement
## @private
## @private
class
CustomBondGenerator
:
class
CustomBondGenerator
:
"""A CustomBondGenerator constructs a CustomBondForce."""
"""A CustomBondGenerator constructs a CustomBondForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
types1
=
[]
self
.
types1
=
[]
self
.
types2
=
[]
self
.
types2
=
[]
self
.
globalParams
=
{}
self
.
globalParams
=
{}
self
.
perBondParams
=
[]
self
.
perBondParams
=
[]
self
.
paramValues
=
[]
self
.
paramValues
=
[]
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
generator
=
CustomBondGenerator
()
generator
=
CustomBondGenerator
()
...
@@ -1170,7 +1170,7 @@ class CustomBondGenerator:
...
@@ -1170,7 +1170,7 @@ class CustomBondGenerator:
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
])
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
force
=
mm
.
CustomBondForce
(
self
.
energy
)
force
=
mm
.
CustomBondForce
(
self
.
energy
)
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
...
@@ -1194,7 +1194,7 @@ parsers["CustomBondForce"] = CustomBondGenerator.parseElement
...
@@ -1194,7 +1194,7 @@ parsers["CustomBondForce"] = CustomBondGenerator.parseElement
## @private
## @private
class
CustomAngleGenerator
:
class
CustomAngleGenerator
:
"""A CustomAngleGenerator constructs a CustomAngleForce."""
"""A CustomAngleGenerator constructs a CustomAngleForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
types1
=
[]
self
.
types1
=
[]
self
.
types2
=
[]
self
.
types2
=
[]
...
@@ -1202,7 +1202,7 @@ class CustomAngleGenerator:
...
@@ -1202,7 +1202,7 @@ class CustomAngleGenerator:
self
.
globalParams
=
{}
self
.
globalParams
=
{}
self
.
perAngleParams
=
[]
self
.
perAngleParams
=
[]
self
.
paramValues
=
[]
self
.
paramValues
=
[]
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
generator
=
CustomAngleGenerator
()
generator
=
CustomAngleGenerator
()
...
@@ -1219,7 +1219,7 @@ class CustomAngleGenerator:
...
@@ -1219,7 +1219,7 @@ class CustomAngleGenerator:
generator
.
types2
.
append
(
types
[
1
])
generator
.
types2
.
append
(
types
[
1
])
generator
.
types3
.
append
(
types
[
2
])
generator
.
types3
.
append
(
types
[
2
])
generator
.
paramValues
.
append
([
float
(
angle
.
attrib
[
param
])
for
param
in
generator
.
perAngleParams
])
generator
.
paramValues
.
append
([
float
(
angle
.
attrib
[
param
])
for
param
in
generator
.
perAngleParams
])
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
force
=
mm
.
CustomAngleForce
(
self
.
energy
)
force
=
mm
.
CustomAngleForce
(
self
.
energy
)
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
...
@@ -1256,13 +1256,13 @@ class CustomTorsion:
...
@@ -1256,13 +1256,13 @@ class CustomTorsion:
## @private
## @private
class
CustomTorsionGenerator
:
class
CustomTorsionGenerator
:
"""A CustomTorsionGenerator constructs a CustomTorsionForce."""
"""A CustomTorsionGenerator constructs a CustomTorsionForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
proper
=
[]
self
.
proper
=
[]
self
.
improper
=
[]
self
.
improper
=
[]
self
.
globalParams
=
{}
self
.
globalParams
=
{}
self
.
perTorsionParams
=
[]
self
.
perTorsionParams
=
[]
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
generator
=
CustomTorsionGenerator
()
generator
=
CustomTorsionGenerator
()
...
@@ -1281,7 +1281,7 @@ class CustomTorsionGenerator:
...
@@ -1281,7 +1281,7 @@ class CustomTorsionGenerator:
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
types
=
ff
.
_findAtomTypes
(
torsion
,
4
)
if
None
not
in
types
:
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
):
force
=
mm
.
CustomTorsionForce
(
self
.
energy
)
force
=
mm
.
CustomTorsionForce
(
self
.
energy
)
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
...
@@ -1346,7 +1346,7 @@ parsers["CustomTorsionForce"] = CustomTorsionGenerator.parseElement
...
@@ -1346,7 +1346,7 @@ parsers["CustomTorsionForce"] = CustomTorsionGenerator.parseElement
## @private
## @private
class
CustomGBGenerator
:
class
CustomGBGenerator
:
"""A CustomGBGenerator constructs a CustomGBForce."""
"""A CustomGBGenerator constructs a CustomGBForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
typeMap
=
{}
self
.
typeMap
=
{}
self
.
globalParams
=
{}
self
.
globalParams
=
{}
...
@@ -1380,13 +1380,13 @@ class CustomGBGenerator:
...
@@ -1380,13 +1380,13 @@ class CustomGBGenerator:
for
function
in
element
.
findall
(
"Function"
):
for
function
in
element
.
findall
(
"Function"
):
values
=
[
float
(
x
)
for
x
in
function
.
text
.
split
()]
values
=
[
float
(
x
)
for
x
in
function
.
text
.
split
()]
generator
.
functions
.
append
((
function
.
attrib
[
'name'
],
values
,
float
(
function
.
attrib
[
'min'
]),
float
(
function
.
attrib
[
'max'
])))
generator
.
functions
.
append
((
function
.
attrib
[
'name'
],
values
,
float
(
function
.
attrib
[
'min'
]),
float
(
function
.
attrib
[
'max'
])))
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
methodMap
=
{
NoCutoff
:
mm
.
CustomGBForce
.
NoCutoff
,
methodMap
=
{
NoCutoff
:
mm
.
CustomGBForce
.
NoCutoff
,
CutoffNonPeriodic
:
mm
.
CustomGBForce
.
CutoffNonPeriodic
,
CutoffNonPeriodic
:
mm
.
CustomGBForce
.
CutoffNonPeriodic
,
CutoffPeriodic
:
mm
.
CustomGBForce
.
CutoffPeriodic
}
CutoffPeriodic
:
mm
.
CustomGBForce
.
CutoffPeriodic
}
if
nonbondedMethod
not
in
methodMap
:
if
nonbondedMethod
not
in
methodMap
:
raise
ValueError
(
'Illegal nonbonded method for CustomGBForce'
)
raise
ValueError
(
'Illegal nonbonded method for CustomGBForce'
)
force
=
mm
.
CustomGBForce
()
force
=
mm
.
CustomGBForce
()
for
param
in
self
.
globalParams
:
for
param
in
self
.
globalParams
:
force
.
addGlobalParameter
(
param
,
self
.
globalParams
[
param
])
force
.
addGlobalParameter
(
param
,
self
.
globalParams
[
param
])
...
@@ -1404,7 +1404,7 @@ class CustomGBGenerator:
...
@@ -1404,7 +1404,7 @@ class CustomGBGenerator:
values
=
self
.
typeMap
[
t
]
values
=
self
.
typeMap
[
t
]
force
.
addParticle
(
self
.
typeMap
[
t
])
force
.
addParticle
(
self
.
typeMap
[
t
])
else
:
else
:
raise
ValueError
(
'No CustomGB parameters defined for atom type '
+
t
)
raise
ValueError
(
'No CustomGB parameters defined for atom type '
+
t
)
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
force
.
setCutoffDistance
(
nonbondedCutoff
)
force
.
setCutoffDistance
(
nonbondedCutoff
)
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
...
@@ -1435,7 +1435,7 @@ def countConstraint(data):
...
@@ -1435,7 +1435,7 @@ def countConstraint(data):
for
(
angle
,
isConstrained
)
in
zip
(
data
.
angles
,
data
.
isAngleConstrained
):
for
(
angle
,
isConstrained
)
in
zip
(
data
.
angles
,
data
.
isAngleConstrained
):
if
(
isConstrained
):
if
(
isConstrained
):
angleCount
+=
1
angleCount
+=
1
print
"Constraints bond=%d angle=%d total=%d"
%
(
bondCount
,
angleCount
,
(
bondCount
+
angleCount
))
print
"Constraints bond=%d angle=%d total=%d"
%
(
bondCount
,
angleCount
,
(
bondCount
+
angleCount
))
## @private
## @private
...
@@ -1446,7 +1446,7 @@ class AmoebaBondGenerator:
...
@@ -1446,7 +1446,7 @@ class AmoebaBondGenerator:
"""An AmoebaBondGenerator constructs a AmoebaBondForce."""
"""An AmoebaBondGenerator constructs a AmoebaBondForce."""
#=============================================================================================
#=============================================================================================
def
__init__
(
self
,
cubic
,
quartic
):
def
__init__
(
self
,
cubic
,
quartic
):
self
.
cubic
=
cubic
self
.
cubic
=
cubic
...
@@ -1455,7 +1455,7 @@ class AmoebaBondGenerator:
...
@@ -1455,7 +1455,7 @@ class AmoebaBondGenerator:
self
.
types2
=
[]
self
.
types2
=
[]
self
.
length
=
[]
self
.
length
=
[]
self
.
k
=
[]
self
.
k
=
[]
#=============================================================================================
#=============================================================================================
@
staticmethod
@
staticmethod
...
@@ -1463,7 +1463,7 @@ class AmoebaBondGenerator:
...
@@ -1463,7 +1463,7 @@ class AmoebaBondGenerator:
# <AmoebaBondForce bond-cubic="-25.5" bond-quartic="379.3125">
# <AmoebaBondForce bond-cubic="-25.5" bond-quartic="379.3125">
# <Bond class1="1" class2="2" length="0.1437" k="156900.0"/>
# <Bond class1="1" class2="2" length="0.1437" k="156900.0"/>
generator
=
AmoebaBondGenerator
(
float
(
element
.
attrib
[
'bond-cubic'
]),
float
(
element
.
attrib
[
'bond-quartic'
]))
generator
=
AmoebaBondGenerator
(
float
(
element
.
attrib
[
'bond-cubic'
]),
float
(
element
.
attrib
[
'bond-quartic'
]))
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
for
bond
in
element
.
findall
(
'Bond'
):
for
bond
in
element
.
findall
(
'Bond'
):
...
@@ -1477,8 +1477,8 @@ class AmoebaBondGenerator:
...
@@ -1477,8 +1477,8 @@ class AmoebaBondGenerator:
outputString
=
"AmoebaBondGenerator: error getting types: %s %s"
%
(
outputString
=
"AmoebaBondGenerator: error getting types: %s %s"
%
(
bond
.
attrib
[
'class1'
],
bond
.
attrib
[
'class1'
],
bond
.
attrib
[
'class2'
])
bond
.
attrib
[
'class2'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
...
@@ -1512,20 +1512,20 @@ class AmoebaBondGenerator:
...
@@ -1512,20 +1512,20 @@ class AmoebaBondGenerator:
force
.
addBond
(
bond
.
atom1
,
bond
.
atom2
,
self
.
length
[
i
],
self
.
k
[
i
])
force
.
addBond
(
bond
.
atom1
,
bond
.
atom2
,
self
.
length
[
i
],
self
.
k
[
i
])
break
break
if
(
hit
==
0
):
if
(
hit
==
0
):
outputString
=
"AmoebaBondGenerator missing: types=[%5s %5s] atoms=[%6d %6d] "
%
(
type1
,
type2
,
bond
.
atom1
,
bond
.
atom2
)
outputString
=
"AmoebaBondGenerator missing: types=[%5s %5s] atoms=[%6d %6d] "
%
(
type1
,
type2
,
bond
.
atom1
,
bond
.
atom2
)
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
parsers
[
"AmoebaBondForce"
]
=
AmoebaBondGenerator
.
parseElement
parsers
[
"AmoebaBondForce"
]
=
AmoebaBondGenerator
.
parseElement
#=============================================================================================
#=============================================================================================
# Add angle constraint
# Add angle constraint
#=============================================================================================
#=============================================================================================
def
addAngleConstraint
(
angle
,
idealAngle
,
data
,
sys
):
def
addAngleConstraint
(
angle
,
idealAngle
,
data
,
sys
):
# Find the two bonds that make this angle.
# Find the two bonds that make this angle.
bond1
=
None
bond1
=
None
bond2
=
None
bond2
=
None
for
bond
in
data
.
atomBonds
[
angle
[
1
]]:
for
bond
in
data
.
atomBonds
[
angle
[
1
]]:
...
@@ -1535,9 +1535,9 @@ def addAngleConstraint(angle, idealAngle, data, sys):
...
@@ -1535,9 +1535,9 @@ def addAngleConstraint(angle, idealAngle, data, sys):
bond1
=
bond
bond1
=
bond
elif
atom1
==
angle
[
2
]
or
atom2
==
angle
[
2
]:
elif
atom1
==
angle
[
2
]
or
atom2
==
angle
[
2
]:
bond2
=
bond
bond2
=
bond
# Compute the distance between atoms and add a constraint
# Compute the distance between atoms and add a constraint
if
bond1
is
not
None
and
bond2
is
not
None
:
if
bond1
is
not
None
and
bond2
is
not
None
:
l1
=
data
.
bonds
[
bond1
].
length
l1
=
data
.
bonds
[
bond1
].
length
l2
=
data
.
bonds
[
bond2
].
length
l2
=
data
.
bonds
[
bond2
].
length
...
@@ -1553,7 +1553,7 @@ class AmoebaAngleGenerator:
...
@@ -1553,7 +1553,7 @@ class AmoebaAngleGenerator:
#=============================================================================================
#=============================================================================================
"""An AmoebaAngleGenerator constructs a AmoebaAngleForce."""
"""An AmoebaAngleGenerator constructs a AmoebaAngleForce."""
#=============================================================================================
#=============================================================================================
def
__init__
(
self
,
forceField
,
cubic
,
quartic
,
pentic
,
sextic
):
def
__init__
(
self
,
forceField
,
cubic
,
quartic
,
pentic
,
sextic
):
self
.
forceField
=
forceField
self
.
forceField
=
forceField
...
@@ -1568,7 +1568,7 @@ class AmoebaAngleGenerator:
...
@@ -1568,7 +1568,7 @@ class AmoebaAngleGenerator:
self
.
angle
=
[]
self
.
angle
=
[]
self
.
k
=
[]
self
.
k
=
[]
#=============================================================================================
#=============================================================================================
@
staticmethod
@
staticmethod
...
@@ -1605,13 +1605,13 @@ class AmoebaAngleGenerator:
...
@@ -1605,13 +1605,13 @@ class AmoebaAngleGenerator:
angle
.
attrib
[
'class1'
],
angle
.
attrib
[
'class1'
],
angle
.
attrib
[
'class2'
],
angle
.
attrib
[
'class2'
],
angle
.
attrib
[
'class3'
])
angle
.
attrib
[
'class3'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
# createForce is bypassed here since the AmoebaOutOfPlaneBendForce generator must first execute
# createForce is bypassed here since the AmoebaOutOfPlaneBendForce generator must first execute
# and partition angles into in-plane and non-in-plane angles
# and partition angles into in-plane and non-in-plane angles
#=============================================================================================
#=============================================================================================
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
pass
pass
...
@@ -1619,7 +1619,7 @@ class AmoebaAngleGenerator:
...
@@ -1619,7 +1619,7 @@ class AmoebaAngleGenerator:
# createForcePostOpBendAngle is called by AmoebaOutOfPlaneBendForce with the list of
# createForcePostOpBendAngle is called by AmoebaOutOfPlaneBendForce with the list of
# non-in-plane angles
# non-in-plane angles
#=============================================================================================
#=============================================================================================
def
createForcePostOpBendAngle
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
angleList
,
args
):
def
createForcePostOpBendAngle
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
angleList
,
args
):
# get force
# get force
...
@@ -1674,26 +1674,26 @@ class AmoebaAngleGenerator:
...
@@ -1674,26 +1674,26 @@ class AmoebaAngleGenerator:
angleValue
=
self
.
angle
[
i
][
numberOfHydrogens
]
angleValue
=
self
.
angle
[
i
][
numberOfHydrogens
]
else
:
else
:
outputString
=
"AmoebaAngleGenerator angle index=%d is out of range: [0, %5d] "
%
(
numberOfHydrogens
,
lenAngle
)
outputString
=
"AmoebaAngleGenerator angle index=%d is out of range: [0, %5d] "
%
(
numberOfHydrogens
,
lenAngle
)
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
else
:
else
:
angleValue
=
self
.
angle
[
i
][
0
]
angleValue
=
self
.
angle
[
i
][
0
]
angleDict
[
'idealAngle'
]
=
angleValue
angleDict
[
'idealAngle'
]
=
angleValue
force
.
addAngle
(
angle
[
0
],
angle
[
1
],
angle
[
2
],
angleValue
,
self
.
k
[
i
])
force
.
addAngle
(
angle
[
0
],
angle
[
1
],
angle
[
2
],
angleValue
,
self
.
k
[
i
])
break
break
if
(
hit
==
0
):
if
(
hit
==
0
):
outputString
=
"AmoebaAngleGenerator missing types: [%s %s %s] for atoms: "
%
(
type1
,
type2
,
type3
)
outputString
=
"AmoebaAngleGenerator missing types: [%s %s %s] for atoms: "
%
(
type1
,
type2
,
type3
)
outputString
+=
getAtomPrint
(
data
,
angle
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
2
]
)
outputString
+=
getAtomPrint
(
data
,
angle
[
2
]
)
outputString
+=
" indices: [%6d %6d %6d]"
%
(
angle
[
0
],
angle
[
1
],
angle
[
2
])
outputString
+=
" indices: [%6d %6d %6d]"
%
(
angle
[
0
],
angle
[
1
],
angle
[
2
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
# createForcePostOpBendInPlaneAngle is called by AmoebaOutOfPlaneBendForce with the list of
# createForcePostOpBendInPlaneAngle is called by AmoebaOutOfPlaneBendForce with the list of
# in-plane angles
# in-plane angles
#=============================================================================================
#=============================================================================================
def
createForcePostOpBendInPlaneAngle
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
angleList
,
args
):
def
createForcePostOpBendInPlaneAngle
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
angleList
,
args
):
# get force
# get force
...
@@ -1715,7 +1715,7 @@ class AmoebaAngleGenerator:
...
@@ -1715,7 +1715,7 @@ class AmoebaAngleGenerator:
force
.
setAmoebaGlobalInPlaneAngleSextic
(
self
.
sextic
)
force
.
setAmoebaGlobalInPlaneAngleSextic
(
self
.
sextic
)
for
angleDict
in
angleList
:
for
angleDict
in
angleList
:
angle
=
angleDict
[
'angle'
]
angle
=
angleDict
[
'angle'
]
isConstrained
=
angleDict
[
'isConstrained'
]
isConstrained
=
angleDict
[
'isConstrained'
]
...
@@ -1739,13 +1739,13 @@ class AmoebaAngleGenerator:
...
@@ -1739,13 +1739,13 @@ class AmoebaAngleGenerator:
force
.
addAngle
(
angle
[
0
],
angle
[
1
],
angle
[
2
],
angle
[
3
],
self
.
angle
[
i
][
0
],
self
.
k
[
i
])
force
.
addAngle
(
angle
[
0
],
angle
[
1
],
angle
[
2
],
angle
[
3
],
self
.
angle
[
i
][
0
],
self
.
k
[
i
])
break
break
if
(
hit
==
0
):
if
(
hit
==
0
):
outputString
=
"AmoebaInPlaneAngleGenerator missing types: [%s %s %s] atoms: "
%
(
type1
,
type2
,
type3
)
outputString
=
"AmoebaInPlaneAngleGenerator missing types: [%s %s %s] atoms: "
%
(
type1
,
type2
,
type3
)
outputString
+=
getAtomPrint
(
data
,
angle
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
2
]
)
outputString
+=
getAtomPrint
(
data
,
angle
[
2
]
)
outputString
+=
" indices: [%6d %6d %6d]"
%
(
angle
[
0
],
angle
[
1
],
angle
[
2
])
outputString
+=
" indices: [%6d %6d %6d]"
%
(
angle
[
0
],
angle
[
1
],
angle
[
2
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
parsers
[
"AmoebaAngleForce"
]
=
AmoebaAngleGenerator
.
parseElement
parsers
[
"AmoebaAngleForce"
]
=
AmoebaAngleGenerator
.
parseElement
...
@@ -1761,7 +1761,7 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -1761,7 +1761,7 @@ class AmoebaOutOfPlaneBendGenerator:
#=============================================================================================
#=============================================================================================
"""An AmoebaOutOfPlaneBendGenerator constructs a AmoebaOutOfPlaneBendForce."""
"""An AmoebaOutOfPlaneBendGenerator constructs a AmoebaOutOfPlaneBendForce."""
#=============================================================================================
#=============================================================================================
def
__init__
(
self
,
forceField
,
type
,
cubic
,
quartic
,
pentic
,
sextic
):
def
__init__
(
self
,
forceField
,
type
,
cubic
,
quartic
,
pentic
,
sextic
):
...
@@ -1784,7 +1784,7 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -1784,7 +1784,7 @@ class AmoebaOutOfPlaneBendGenerator:
# Local version of findAtomTypes needed since class indices are 0 (i.e., not recognized)
# Local version of findAtomTypes needed since class indices are 0 (i.e., not recognized)
# for types3 and 4
# for types3 and 4
#=============================================================================================
#=============================================================================================
def
findAtomTypes
(
self
,
forceField
,
node
,
num
):
def
findAtomTypes
(
self
,
forceField
,
node
,
num
):
"""Parse the attributes on an XML tag to find the set of atom types for each atom it involves."""
"""Parse the attributes on an XML tag to find the set of atom types for each atom it involves."""
types
=
[]
types
=
[]
...
@@ -1810,7 +1810,7 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -1810,7 +1810,7 @@ class AmoebaOutOfPlaneBendGenerator:
# <AmoebaOutOfPlaneBendForce type="ALLINGER" opbend-cubic="-0.014" opbend-quartic="5.6e-05" opbend-pentic="-7e-07" opbend-sextic="2.2e-08">
# <AmoebaOutOfPlaneBendForce type="ALLINGER" opbend-cubic="-0.014" opbend-quartic="5.6e-05" opbend-pentic="-7e-07" opbend-sextic="2.2e-08">
# <Angle class1="2" class2="1" class3="0" class4="0" k="0.0531474541591"/>
# <Angle class1="2" class2="1" class3="0" class4="0" k="0.0531474541591"/>
# <Angle class1="3" class2="1" class3="0" class4="0" k="0.0898536095496"/>
# <Angle class1="3" class2="1" class3="0" class4="0" k="0.0898536095496"/>
# get global scalar parameters
# get global scalar parameters
generator
=
AmoebaOutOfPlaneBendGenerator
(
forceField
,
element
.
attrib
[
'type'
],
generator
=
AmoebaOutOfPlaneBendGenerator
(
forceField
,
element
.
attrib
[
'type'
],
...
@@ -1835,21 +1835,21 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -1835,21 +1835,21 @@ class AmoebaOutOfPlaneBendGenerator:
else
:
else
:
outputString
=
"AmoebaOutOfPlaneBendGenerator error getting types: %s %s %s %s."
%
(
outputString
=
"AmoebaOutOfPlaneBendGenerator error getting types: %s %s %s %s."
%
(
angle
.
attrib
[
'class1'
],
angle
.
attrib
[
'class2'
],
angle
.
attrib
[
'class3'
],
angle
.
attrib
[
'class4'
])
angle
.
attrib
[
'class1'
],
angle
.
attrib
[
'class2'
],
angle
.
attrib
[
'class3'
],
angle
.
attrib
[
'class4'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
# Get middle atom in a angle
# Get middle atom in a angle
# return index of middle atom or -1 if no middle is found
# return index of middle atom or -1 if no middle is found
# This method appears not to be needed since the angle[1] entry appears to always
# This method appears not to be needed since the angle[1] entry appears to always
# be the middle atom. However, was unsure if this is guaranteed
# be the middle atom. However, was unsure if this is guaranteed
#=============================================================================================
#=============================================================================================
def
getMiddleAtom
(
self
,
angle
,
data
):
def
getMiddleAtom
(
self
,
angle
,
data
):
# find atom shared by both bonds making up the angle
# find atom shared by both bonds making up the angle
middleAtom
=
-
1
middleAtom
=
-
1
for
atomIndex
in
angle
:
for
atomIndex
in
angle
:
isMiddle
=
0
isMiddle
=
0
for
bond
in
data
.
atomBonds
[
atomIndex
]:
for
bond
in
data
.
atomBonds
[
atomIndex
]:
atom1
=
data
.
bonds
[
bond
].
atom1
atom1
=
data
.
bonds
[
bond
].
atom1
...
@@ -1858,7 +1858,7 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -1858,7 +1858,7 @@ class AmoebaOutOfPlaneBendGenerator:
partner
=
atom1
partner
=
atom1
else
:
else
:
partner
=
atom2
partner
=
atom2
if
(
partner
==
angle
[
0
]
or
partner
==
angle
[
1
]
or
partner
==
angle
[
2
]):
if
(
partner
==
angle
[
0
]
or
partner
==
angle
[
1
]
or
partner
==
angle
[
2
]):
isMiddle
+=
1
isMiddle
+=
1
if
(
isMiddle
==
2
):
if
(
isMiddle
==
2
):
...
@@ -1909,10 +1909,10 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -1909,10 +1909,10 @@ class AmoebaOutOfPlaneBendGenerator:
middleType
=
-
1
middleType
=
-
1
middleCovalency
=
-
1
middleCovalency
=
-
1
# if middle atom has covalency of 3 and
# if middle atom has covalency of 3 and
# the types of the middle atom and the partner atom (atom bonded to
# the types of the middle atom and the partner atom (atom bonded to
# middle atom, but not in angle) match types1 and types2, then
# middle atom, but not in angle) match types1 and types2, then
# three out-of-plane bend angles are generated. Three in-plane angle
# three out-of-plane bend angles are generated. Three in-plane angle
# are also generated. If the conditions are not satisfied, the angle is marked as 'generic' angle (not a in-plane angle)
# are also generated. If the conditions are not satisfied, the angle is marked as 'generic' angle (not a in-plane angle)
if
(
middleAtom
>
-
1
and
middleCovalency
==
3
and
middleAtom
not
in
skipAtoms
):
if
(
middleAtom
>
-
1
and
middleCovalency
==
3
and
middleAtom
not
in
skipAtoms
):
...
@@ -1939,7 +1939,7 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -1939,7 +1939,7 @@ class AmoebaOutOfPlaneBendGenerator:
partnerSet
.
add
(
partner
)
partnerSet
.
add
(
partner
)
partnerTypes
.
append
(
partnerType
)
partnerTypes
.
append
(
partnerType
)
partnerK
.
append
(
self
.
ks
[
i
])
partnerK
.
append
(
self
.
ks
[
i
])
if
(
len
(
partners
)
==
3
):
if
(
len
(
partners
)
==
3
):
force
.
addOutOfPlaneBend
(
partners
[
0
],
middleAtom
,
partners
[
1
],
partners
[
2
],
partnerK
[
2
])
force
.
addOutOfPlaneBend
(
partners
[
0
],
middleAtom
,
partners
[
1
],
partners
[
2
],
partnerK
[
2
])
...
@@ -1984,7 +1984,7 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -1984,7 +1984,7 @@ class AmoebaOutOfPlaneBendGenerator:
if
(
middleAtom
>
-
1
and
middleCovalency
==
3
and
middleAtom
in
skipAtoms
):
if
(
middleAtom
>
-
1
and
middleCovalency
==
3
and
middleAtom
in
skipAtoms
):
partnerSet
=
skipAtoms
[
middleAtom
]
partnerSet
=
skipAtoms
[
middleAtom
]
angleDict
=
{}
angleDict
=
{}
angleList
=
[]
angleList
=
[]
...
@@ -2015,12 +2015,12 @@ class AmoebaOutOfPlaneBendGenerator:
...
@@ -2015,12 +2015,12 @@ class AmoebaOutOfPlaneBendGenerator:
# get AmoebaAngleGenerator and add AmoebaAngle and AmoebaInPlaneAngle forces
# get AmoebaAngleGenerator and add AmoebaAngle and AmoebaInPlaneAngle forces
for
force
in
self
.
forceField
.
_forces
:
for
force
in
self
.
forceField
.
_forces
:
if
(
force
.
__class__
.
__name__
==
'AmoebaAngleGenerator'
):
if
(
force
.
__class__
.
__name__
==
'AmoebaAngleGenerator'
):
force
.
createForcePostOpBendAngle
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
nonInPlaneAngles
,
args
)
force
.
createForcePostOpBendAngle
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
nonInPlaneAngles
,
args
)
force
.
createForcePostOpBendInPlaneAngle
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
inPlaneAngles
,
args
)
force
.
createForcePostOpBendInPlaneAngle
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
inPlaneAngles
,
args
)
for
force
in
self
.
forceField
.
_forces
:
for
force
in
self
.
forceField
.
_forces
:
if
(
force
.
__class__
.
__name__
==
'AmoebaStretchBendGenerator'
):
if
(
force
.
__class__
.
__name__
==
'AmoebaStretchBendGenerator'
):
for
angleDict
in
inPlaneAngles
:
for
angleDict
in
inPlaneAngles
:
nonInPlaneAngles
.
append
(
angleDict
)
nonInPlaneAngles
.
append
(
angleDict
)
force
.
createForcePostAmoebaBondForce
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
nonInPlaneAngles
,
args
)
force
.
createForcePostAmoebaBondForce
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
nonInPlaneAngles
,
args
)
...
@@ -2048,7 +2048,7 @@ class AmoebaTorsionGenerator:
...
@@ -2048,7 +2048,7 @@ class AmoebaTorsionGenerator:
self
.
t1
=
[]
self
.
t1
=
[]
self
.
t2
=
[]
self
.
t2
=
[]
self
.
t3
=
[]
self
.
t3
=
[]
#=============================================================================================
#=============================================================================================
@
staticmethod
@
staticmethod
...
@@ -2057,7 +2057,7 @@ class AmoebaTorsionGenerator:
...
@@ -2057,7 +2057,7 @@ class AmoebaTorsionGenerator:
# <AmoebaTorsionForce torsionUnit="0.5">
# <AmoebaTorsionForce torsionUnit="0.5">
# <Torsion class1="3" class2="1" class3="2" class4="3" amp1="0.0" angle1="0.0" amp2="0.0" angle2="3.14159265359" amp3="0.0" angle3="0.0" />
# <Torsion class1="3" class2="1" class3="2" class4="3" amp1="0.0" angle1="0.0" amp2="0.0" angle2="3.14159265359" amp3="0.0" angle3="0.0" />
# <Torsion class1="3" class2="1" class3="2" class4="6" amp1="0.0" angle1="0.0" amp2="0.0" angle2="3.14159265359" amp3="-0.263592" angle3="0.0" />
# <Torsion class1="3" class2="1" class3="2" class4="6" amp1="0.0" angle1="0.0" amp2="0.0" angle2="3.14159265359" amp3="-0.263592" angle3="0.0" />
generator
=
AmoebaTorsionGenerator
(
float
(
element
.
attrib
[
'torsionUnit'
]))
generator
=
AmoebaTorsionGenerator
(
float
(
element
.
attrib
[
'torsionUnit'
]))
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
...
@@ -2095,8 +2095,8 @@ class AmoebaTorsionGenerator:
...
@@ -2095,8 +2095,8 @@ class AmoebaTorsionGenerator:
stretchBend
.
attrib
[
'class2'
],
stretchBend
.
attrib
[
'class2'
],
stretchBend
.
attrib
[
'class3'
],
stretchBend
.
attrib
[
'class3'
],
stretchBend
.
attrib
[
'class4'
])
stretchBend
.
attrib
[
'class4'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
def
createForce
(
self
,
sys
,
data
,
nontorsionedMethod
,
nontorsionedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nontorsionedMethod
,
nontorsionedCutoff
,
args
):
...
@@ -2136,14 +2136,14 @@ class AmoebaTorsionGenerator:
...
@@ -2136,14 +2136,14 @@ class AmoebaTorsionGenerator:
force
.
addTorsion
(
torsion
[
0
],
torsion
[
1
],
torsion
[
2
],
torsion
[
3
],
3
,
self
.
t3
[
i
][
1
],
self
.
t3
[
i
][
0
])
force
.
addTorsion
(
torsion
[
0
],
torsion
[
1
],
torsion
[
2
],
torsion
[
3
],
3
,
self
.
t3
[
i
][
1
],
self
.
t3
[
i
][
0
])
break
break
if
(
hit
==
0
):
if
(
hit
==
0
):
outputString
=
"AmoebaTorsionGenerator missing type: [%s %s %s %s] atoms: "
%
(
type1
,
type2
,
type3
,
type4
)
outputString
=
"AmoebaTorsionGenerator missing type: [%s %s %s %s] atoms: "
%
(
type1
,
type2
,
type3
,
type4
)
outputString
+=
getAtomPrint
(
data
,
torsion
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
torsion
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
torsion
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
torsion
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
torsion
[
2
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
torsion
[
2
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
torsion
[
3
]
)
outputString
+=
getAtomPrint
(
data
,
torsion
[
3
]
)
outputString
+=
" indices: [%6d %6d %6d %6d]"
%
(
torsion
[
0
],
torsion
[
1
],
torsion
[
2
],
torsion
[
3
])
outputString
+=
" indices: [%6d %6d %6d %6d]"
%
(
torsion
[
0
],
torsion
[
1
],
torsion
[
2
],
torsion
[
3
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
parsers
[
"AmoebaTorsionForce"
]
=
AmoebaTorsionGenerator
.
parseElement
parsers
[
"AmoebaTorsionForce"
]
=
AmoebaTorsionGenerator
.
parseElement
...
@@ -2157,13 +2157,13 @@ class AmoebaPiTorsionGenerator:
...
@@ -2157,13 +2157,13 @@ class AmoebaPiTorsionGenerator:
"""An AmoebaPiTorsionGenerator constructs a AmoebaPiTorsionForce."""
"""An AmoebaPiTorsionGenerator constructs a AmoebaPiTorsionForce."""
#=============================================================================================
#=============================================================================================
def
__init__
(
self
,
piTorsionUnit
):
def
__init__
(
self
,
piTorsionUnit
):
self
.
piTorsionUnit
=
piTorsionUnit
self
.
piTorsionUnit
=
piTorsionUnit
self
.
types1
=
[]
self
.
types1
=
[]
self
.
types2
=
[]
self
.
types2
=
[]
self
.
k
=
[]
self
.
k
=
[]
#=============================================================================================
#=============================================================================================
@
staticmethod
@
staticmethod
...
@@ -2185,8 +2185,8 @@ class AmoebaPiTorsionGenerator:
...
@@ -2185,8 +2185,8 @@ class AmoebaPiTorsionGenerator:
outputString
=
"AmoebaPiTorsionGenerator: error getting types: %s %s "
%
(
outputString
=
"AmoebaPiTorsionGenerator: error getting types: %s %s "
%
(
piTorsion
.
attrib
[
'class1'
],
piTorsion
.
attrib
[
'class1'
],
piTorsion
.
attrib
[
'class2'
])
piTorsion
.
attrib
[
'class2'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
def
createForce
(
self
,
sys
,
data
,
nonpiTorsionedMethod
,
nonpiTorsionedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonpiTorsionedMethod
,
nonpiTorsionedCutoff
,
args
):
...
@@ -2203,10 +2203,10 @@ class AmoebaPiTorsionGenerator:
...
@@ -2203,10 +2203,10 @@ class AmoebaPiTorsionGenerator:
for
bond
in
data
.
bonds
:
for
bond
in
data
.
bonds
:
# search for bonds with both atoms in bond having covalency == 3
# search for bonds with both atoms in bond having covalency == 3
atom1
=
bond
.
atom1
atom1
=
bond
.
atom1
atom2
=
bond
.
atom2
atom2
=
bond
.
atom2
if
(
len
(
data
.
atomBonds
[
atom1
])
==
3
and
len
(
data
.
atomBonds
[
atom1
])
==
3
):
if
(
len
(
data
.
atomBonds
[
atom1
])
==
3
and
len
(
data
.
atomBonds
[
atom1
])
==
3
):
type1
=
data
.
atomType
[
data
.
atoms
[
atom1
]]
type1
=
data
.
atomType
[
data
.
atoms
[
atom1
]]
...
@@ -2219,8 +2219,8 @@ class AmoebaPiTorsionGenerator:
...
@@ -2219,8 +2219,8 @@ class AmoebaPiTorsionGenerator:
if
(
type1
in
types1
and
type2
in
types2
)
or
(
type1
in
types2
and
type2
in
types1
):
if
(
type1
in
types1
and
type2
in
types2
)
or
(
type1
in
types2
and
type2
in
types1
):
# piTorsionAtom1, piTorsionAtom2 are the atoms bonded to atom1, excluding atom2
# piTorsionAtom1, piTorsionAtom2 are the atoms bonded to atom1, excluding atom2
# piTorsionAtom5, piTorsionAtom6 are the atoms bonded to atom2, excluding atom1
# piTorsionAtom5, piTorsionAtom6 are the atoms bonded to atom2, excluding atom1
piTorsionAtom1
=
-
1
piTorsionAtom1
=
-
1
piTorsionAtom2
=
-
1
piTorsionAtom2
=
-
1
...
@@ -2239,7 +2239,7 @@ class AmoebaPiTorsionGenerator:
...
@@ -2239,7 +2239,7 @@ class AmoebaPiTorsionGenerator:
b1
=
bondedAtom2
b1
=
bondedAtom2
if
(
b1
!=
atom2
):
if
(
b1
!=
atom2
):
if
(
piTorsionAtom1
==
-
1
):
if
(
piTorsionAtom1
==
-
1
):
piTorsionAtom1
=
b1
piTorsionAtom1
=
b1
else
:
else
:
piTorsionAtom2
=
b1
piTorsionAtom2
=
b1
...
@@ -2253,10 +2253,10 @@ class AmoebaPiTorsionGenerator:
...
@@ -2253,10 +2253,10 @@ class AmoebaPiTorsionGenerator:
if
(
b1
!=
atom1
):
if
(
b1
!=
atom1
):
if
(
piTorsionAtom5
==
-
1
):
if
(
piTorsionAtom5
==
-
1
):
piTorsionAtom5
=
b1
piTorsionAtom5
=
b1
else
:
else
:
piTorsionAtom6
=
b1
piTorsionAtom6
=
b1
force
.
addPiTorsion
(
piTorsionAtom1
,
piTorsionAtom2
,
piTorsionAtom3
,
piTorsionAtom4
,
piTorsionAtom5
,
piTorsionAtom6
,
self
.
k
[
i
])
force
.
addPiTorsion
(
piTorsionAtom1
,
piTorsionAtom2
,
piTorsionAtom3
,
piTorsionAtom4
,
piTorsionAtom5
,
piTorsionAtom6
,
self
.
k
[
i
])
parsers
[
"AmoebaPiTorsionForce"
]
=
AmoebaPiTorsionGenerator
.
parseElement
parsers
[
"AmoebaPiTorsionForce"
]
=
AmoebaPiTorsionGenerator
.
parseElement
...
@@ -2281,7 +2281,7 @@ class AmoebaTorsionTorsionGenerator:
...
@@ -2281,7 +2281,7 @@ class AmoebaTorsionTorsionGenerator:
self
.
gridIndex
=
[]
self
.
gridIndex
=
[]
self
.
grids
=
[]
self
.
grids
=
[]
#=============================================================================================
#=============================================================================================
@
staticmethod
@
staticmethod
...
@@ -2316,8 +2316,8 @@ class AmoebaTorsionTorsionGenerator:
...
@@ -2316,8 +2316,8 @@ class AmoebaTorsionTorsionGenerator:
torsionTorsion
.
attrib
[
'class3'
],
torsionTorsion
.
attrib
[
'class3'
],
torsionTorsion
.
attrib
[
'class4'
],
torsionTorsion
.
attrib
[
'class4'
],
torsionTorsion
.
attrib
[
'class5'
]
)
torsionTorsion
.
attrib
[
'class5'
]
)
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
# load grid
# load grid
# xml source
# xml source
...
@@ -2328,12 +2328,12 @@ class AmoebaTorsionTorsionGenerator:
...
@@ -2328,12 +2328,12 @@ class AmoebaTorsionTorsionGenerator:
# output grid:
# output grid:
# grid[x][y][0] = x value
# grid[x][y][0] = x value
# grid[x][y][1] = y value
# grid[x][y][1] = y value
# grid[x][y][2] = function value
# grid[x][y][2] = function value
# grid[x][y][3] = dfdx value
# grid[x][y][3] = dfdx value
# grid[x][y][4] = dfdy value
# grid[x][y][4] = dfdy value
# grid[x][y][5] = dfd(xy) value
# grid[x][y][5] = dfd(xy) value
maxGridIndex
+=
1
maxGridIndex
+=
1
generator
.
grids
=
maxGridIndex
*
[]
generator
.
grids
=
maxGridIndex
*
[]
...
@@ -2365,7 +2365,7 @@ class AmoebaTorsionTorsionGenerator:
...
@@ -2365,7 +2365,7 @@ class AmoebaTorsionTorsionGenerator:
gridCol
=
[]
gridCol
=
[]
gridColIndex
=
0
gridColIndex
=
0
if
(
gridIndex
==
len
(
generator
.
grids
)):
if
(
gridIndex
==
len
(
generator
.
grids
)):
generator
.
grids
.
append
(
grid
)
generator
.
grids
.
append
(
grid
)
else
:
else
:
...
@@ -2401,33 +2401,33 @@ class AmoebaTorsionTorsionGenerator:
...
@@ -2401,33 +2401,33 @@ class AmoebaTorsionTorsionGenerator:
atomE
=
hit
atomE
=
hit
else
:
else
:
atomF
=
hit
atomF
=
hit
# raise error if atoms E or F not found
# raise error if atoms E or F not found
if
(
atomE
==
-
1
or
atomF
==
-
1
):
if
(
atomE
==
-
1
or
atomF
==
-
1
):
outputString
=
"getChiralAtomIndex: error getting bonded partners of atomC=%s %d %s"
%
(
atomC
.
name
,
atomC
.
resiude
.
index
,
atomC
.
resiude
.
name
,)
outputString
=
"getChiralAtomIndex: error getting bonded partners of atomC=%s %d %s"
%
(
atomC
.
name
,
atomC
.
resiude
.
index
,
atomC
.
resiude
.
name
,)
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
# check for different type/mass between atoms E & F
# check for different type/mass between atoms E & F
typeE
=
int
(
data
.
atomType
[
data
.
atoms
[
atomE
]])
typeE
=
int
(
data
.
atomType
[
data
.
atoms
[
atomE
]])
typeF
=
int
(
data
.
atomType
[
data
.
atoms
[
atomF
]])
typeF
=
int
(
data
.
atomType
[
data
.
atoms
[
atomF
]])
if
(
typeE
>
typeF
):
if
(
typeE
>
typeF
):
chiralAtomIndex
=
atomE
chiralAtomIndex
=
atomE
if
(
typeF
>
typeE
):
if
(
typeF
>
typeE
):
chiralAtomIndex
=
atomF
chiralAtomIndex
=
atomF
massE
=
sys
.
getParticleMass
(
atomE
)
/
unit
.
dalton
massE
=
sys
.
getParticleMass
(
atomE
)
/
unit
.
dalton
massF
=
sys
.
getParticleMass
(
atomE
)
/
unit
.
dalton
massF
=
sys
.
getParticleMass
(
atomE
)
/
unit
.
dalton
if
(
massE
>
massF
):
if
(
massE
>
massF
):
chiralAtomIndex
=
massE
chiralAtomIndex
=
massE
if
(
massF
>
massE
):
if
(
massF
>
massE
):
chiralAtomIndex
=
massF
chiralAtomIndex
=
massF
return
chiralAtomIndex
return
chiralAtomIndex
#=============================================================================================
#=============================================================================================
def
createForce
(
self
,
sys
,
data
,
nonpiTorsionedMethod
,
nonpiTorsionedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonpiTorsionedMethod
,
nonpiTorsionedCutoff
,
args
):
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
existing
=
[
sys
.
getForce
(
i
)
for
i
in
range
(
sys
.
getNumForces
())]
...
@@ -2441,8 +2441,8 @@ class AmoebaTorsionTorsionGenerator:
...
@@ -2441,8 +2441,8 @@ class AmoebaTorsionTorsionGenerator:
for
angle
in
data
.
angles
:
for
angle
in
data
.
angles
:
# search for bitorsions; based on TINKER subroutine bitors()
# search for bitorsions; based on TINKER subroutine bitors()
ib
=
angle
[
0
]
ib
=
angle
[
0
]
ic
=
angle
[
1
]
ic
=
angle
[
1
]
id
=
angle
[
2
]
id
=
angle
[
2
]
...
@@ -2499,7 +2499,7 @@ class AmoebaTorsionTorsionGenerator:
...
@@ -2499,7 +2499,7 @@ class AmoebaTorsionTorsionGenerator:
for
(
index
,
grid
)
in
enumerate
(
self
.
grids
):
for
(
index
,
grid
)
in
enumerate
(
self
.
grids
):
force
.
setTorsionTorsionGrid
(
index
,
grid
)
force
.
setTorsionTorsionGrid
(
index
,
grid
)
parsers
[
"AmoebaTorsionTorsionForce"
]
=
AmoebaTorsionTorsionGenerator
.
parseElement
parsers
[
"AmoebaTorsionTorsionForce"
]
=
AmoebaTorsionTorsionGenerator
.
parseElement
#=============================================================================================
#=============================================================================================
...
@@ -2519,7 +2519,7 @@ class AmoebaStretchBendGenerator:
...
@@ -2519,7 +2519,7 @@ class AmoebaStretchBendGenerator:
self
.
k1
=
[]
self
.
k1
=
[]
self
.
k2
=
[]
self
.
k2
=
[]
#=============================================================================================
#=============================================================================================
@
staticmethod
@
staticmethod
...
@@ -2547,15 +2547,15 @@ class AmoebaStretchBendGenerator:
...
@@ -2547,15 +2547,15 @@ class AmoebaStretchBendGenerator:
stretchBend
.
attrib
[
'class1'
],
stretchBend
.
attrib
[
'class1'
],
stretchBend
.
attrib
[
'class2'
],
stretchBend
.
attrib
[
'class2'
],
stretchBend
.
attrib
[
'class3'
])
stretchBend
.
attrib
[
'class3'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
# The setup of this force is dependent on AmoebaBondForce and AmoebaAngleForce
# The setup of this force is dependent on AmoebaBondForce and AmoebaAngleForce
# having been called since the ideal bond lengths and angle are needed here.
# having been called since the ideal bond lengths and angle are needed here.
# As a conseqeunce, createForce() is not implemented since it is not guaranteed that the generator for
# As a conseqeunce, createForce() is not implemented since it is not guaranteed that the generator for
# AmoebaBondForce and AmoebaAngleForce have been called prior to AmoebaStretchBendGenerator().
# AmoebaBondForce and AmoebaAngleForce have been called prior to AmoebaStretchBendGenerator().
# Instead, createForcePostAmoebaBondForce() is called
# Instead, createForcePostAmoebaBondForce() is called
# after the generators for AmoebaBondForce and AmoebaAngleForce have been called
# after the generators for AmoebaBondForce and AmoebaAngleForce have been called
#=============================================================================================
#=============================================================================================
...
@@ -2602,7 +2602,7 @@ class AmoebaStretchBendGenerator:
...
@@ -2602,7 +2602,7 @@ class AmoebaStretchBendGenerator:
# get ideal bond lengths, bondAB, bondCB
# get ideal bond lengths, bondAB, bondCB
# get ideal angle
# get ideal angle
if
(
type2
in
types2
and
((
type1
in
types1
and
type3
in
types3
)
or
(
type3
in
types1
and
type1
in
types3
))):
if
(
type2
in
types2
and
((
type1
in
types1
and
type3
in
types3
)
or
(
type3
in
types1
and
type1
in
types3
))):
bondAB
=
-
1.0
bondAB
=
-
1.0
bondCB
=
-
1.0
bondCB
=
-
1.0
swap
=
0
swap
=
0
...
@@ -2618,7 +2618,7 @@ class AmoebaStretchBendGenerator:
...
@@ -2618,7 +2618,7 @@ class AmoebaStretchBendGenerator:
bondCB
=
length
bondCB
=
length
if
(
atom2
==
angle
[
0
]):
if
(
atom2
==
angle
[
0
]):
bondAB
=
length
bondAB
=
length
# check that ideal angle and bonds are set
# check that ideal angle and bonds are set
if
(
'idealAngle'
not
in
angleDict
):
if
(
'idealAngle'
not
in
angleDict
):
...
@@ -2628,7 +2628,7 @@ class AmoebaStretchBendGenerator:
...
@@ -2628,7 +2628,7 @@ class AmoebaStretchBendGenerator:
outputString
+=
getAtomPrint
(
data
,
angle
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
2
]
)
outputString
+=
getAtomPrint
(
data
,
angle
[
2
]
)
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
elif
(
bondAB
<
0
or
bondCB
<
0
):
elif
(
bondAB
<
0
or
bondCB
<
0
):
...
@@ -2637,7 +2637,7 @@ class AmoebaStretchBendGenerator:
...
@@ -2637,7 +2637,7 @@ class AmoebaStretchBendGenerator:
outputString
+=
getAtomPrint
(
data
,
angle
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
0
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
1
]
)
+
' '
outputString
+=
getAtomPrint
(
data
,
angle
[
2
]
)
outputString
+=
getAtomPrint
(
data
,
angle
[
2
]
)
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
else
:
else
:
force
.
addStretchBend
(
angle
[
0
],
angle
[
1
],
angle
[
2
],
bondAB
,
bondCB
,
angleDict
[
'idealAngle'
]
/
radian
,
self
.
k1
[
i
])
force
.
addStretchBend
(
angle
[
0
],
angle
[
1
],
angle
[
2
],
bondAB
,
bondCB
,
angleDict
[
'idealAngle'
]
/
radian
,
self
.
k1
[
i
])
...
@@ -2652,12 +2652,12 @@ parsers["AmoebaStretchBendForce"] = AmoebaStretchBendGenerator.parseElement
...
@@ -2652,12 +2652,12 @@ parsers["AmoebaStretchBendForce"] = AmoebaStretchBendGenerator.parseElement
class
AmoebaVdwGenerator
:
class
AmoebaVdwGenerator
:
"""A AmoebaVdwGenerator constructs a AmoebaVdwForce."""
"""A AmoebaVdwGenerator constructs a AmoebaVdwForce."""
#=============================================================================================
#=============================================================================================
def
__init__
(
self
,
type
,
radiusrule
,
radiustype
,
radiussize
,
epsilonrule
,
vdw13Scale
,
vdw14Scale
,
vdw15Scale
):
def
__init__
(
self
,
type
,
radiusrule
,
radiustype
,
radiussize
,
epsilonrule
,
vdw13Scale
,
vdw14Scale
,
vdw15Scale
):
self
.
type
=
type
self
.
type
=
type
self
.
radiusrule
=
radiusrule
self
.
radiusrule
=
radiusrule
self
.
radiustype
=
radiustype
self
.
radiustype
=
radiustype
...
@@ -2677,11 +2677,11 @@ class AmoebaVdwGenerator:
...
@@ -2677,11 +2677,11 @@ class AmoebaVdwGenerator:
def
parseElement
(
element
,
forceField
):
def
parseElement
(
element
,
forceField
):
# <AmoebaVdwForce type="BUFFERED-14-7" radiusrule="CUBIC-MEAN" radiustype="R-MIN" radiussize="DIAMETER" epsilonrule="HHG" vdw-13-scale="0.0" vdw-14-scale="1.0" vdw-15-scale="1.0" >
# <AmoebaVdwForce type="BUFFERED-14-7" radiusrule="CUBIC-MEAN" radiustype="R-MIN" radiussize="DIAMETER" epsilonrule="HHG" vdw-13-scale="0.0" vdw-14-scale="1.0" vdw-15-scale="1.0" >
# <Vdw class="1" sigma="0.371" epsilon="0.46024" reduction="1.0" />
# <Vdw class="1" sigma="0.371" epsilon="0.46024" reduction="1.0" />
# <Vdw class="2" sigma="0.382" epsilon="0.422584" reduction="1.0" />
# <Vdw class="2" sigma="0.382" epsilon="0.422584" reduction="1.0" />
generator
=
AmoebaVdwGenerator
(
element
.
attrib
[
'type'
],
element
.
attrib
[
'radiusrule'
],
element
.
attrib
[
'radiustype'
],
element
.
attrib
[
'radiussize'
],
element
.
attrib
[
'epsilonrule'
],
generator
=
AmoebaVdwGenerator
(
element
.
attrib
[
'type'
],
element
.
attrib
[
'radiusrule'
],
element
.
attrib
[
'radiustype'
],
element
.
attrib
[
'radiussize'
],
element
.
attrib
[
'epsilonrule'
],
float
(
element
.
attrib
[
'vdw-13-scale'
]),
float
(
element
.
attrib
[
'vdw-14-scale'
]),
float
(
element
.
attrib
[
'vdw-15-scale'
]))
float
(
element
.
attrib
[
'vdw-13-scale'
]),
float
(
element
.
attrib
[
'vdw-14-scale'
]),
float
(
element
.
attrib
[
'vdw-15-scale'
]))
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
two_six
=
1.122462048309372
two_six
=
1.122462048309372
...
@@ -2697,17 +2697,17 @@ class AmoebaVdwGenerator:
...
@@ -2697,17 +2697,17 @@ class AmoebaVdwGenerator:
if
(
generator
.
radiustype
==
'SIGMA'
):
if
(
generator
.
radiustype
==
'SIGMA'
):
values
[
0
]
*=
two_six
values
[
0
]
*=
two_six
if
(
generator
.
radiussize
==
'DIAMETER'
):
if
(
generator
.
radiussize
==
'DIAMETER'
):
values
[
0
]
*=
0.5
values
[
0
]
*=
0.5
for
t
in
types
[
0
]:
for
t
in
types
[
0
]:
generator
.
typeMap
[
t
]
=
values
generator
.
typeMap
[
t
]
=
values
else
:
else
:
outputString
=
"AmoebaVdwGenerator: error getting type: %s"
%
(
atom
.
attrib
[
'class'
])
outputString
=
"AmoebaVdwGenerator: error getting type: %s"
%
(
atom
.
attrib
[
'class'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
# Return a set containing the indices of particles bonded to particle with index=particleIndex
# Return a set containing the indices of particles bonded to particle with index=particleIndex
...
@@ -2728,7 +2728,7 @@ class AmoebaVdwGenerator:
...
@@ -2728,7 +2728,7 @@ class AmoebaVdwGenerator:
bondedParticleSet
.
add
(
atom2
)
bondedParticleSet
.
add
(
atom2
)
return
bondedParticleSet
return
bondedParticleSet
#=============================================================================================
#=============================================================================================
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
...
@@ -2762,10 +2762,10 @@ class AmoebaVdwGenerator:
...
@@ -2762,10 +2762,10 @@ class AmoebaVdwGenerator:
force
.
setEpsilonCombiningRule
(
epsilonRule
.
upper
())
force
.
setEpsilonCombiningRule
(
epsilonRule
.
upper
())
else
:
else
:
stringList
=
' '
.
join
(
str
(
x
)
for
x
in
epsilonMap
.
keys
())
stringList
=
' '
.
join
(
str
(
x
)
for
x
in
epsilonMap
.
keys
())
raise
ValueError
(
"AmoebaVdwGenerator: epsilon combining rule %s not recognized; valid values are %s; using default."
%
(
epsilonRule
,
stringList
)
)
raise
ValueError
(
"AmoebaVdwGenerator: epsilon combining rule %s not recognized; valid values are %s; using default."
%
(
epsilonRule
,
stringList
)
)
else
:
else
:
force
.
setEpsilonCombiningRule
(
self
.
epsilonrule
)
force
.
setEpsilonCombiningRule
(
self
.
epsilonrule
)
# cutoff
# cutoff
if
(
'vdwCutoff'
in
args
):
if
(
'vdwCutoff'
in
args
):
...
@@ -2780,19 +2780,19 @@ class AmoebaVdwGenerator:
...
@@ -2780,19 +2780,19 @@ class AmoebaVdwGenerator:
if
(
nonbondedMethod
==
PME
):
if
(
nonbondedMethod
==
PME
):
force
.
setNonbondedMethod
(
mm
.
AmoebaVdwForce
.
CutoffPeriodic
)
force
.
setNonbondedMethod
(
mm
.
AmoebaVdwForce
.
CutoffPeriodic
)
else
:
else
:
force
=
existing
[
0
]
force
=
existing
[
0
]
# add particles to force
# add particles to force
# throw error if particle type not available
# throw error if particle type not available
for
(
i
,
atom
)
in
enumerate
(
data
.
atoms
):
for
(
i
,
atom
)
in
enumerate
(
data
.
atoms
):
t
=
data
.
atomType
[
atom
]
t
=
data
.
atomType
[
atom
]
if
t
in
self
.
typeMap
:
if
t
in
self
.
typeMap
:
values
=
self
.
typeMap
[
t
]
values
=
self
.
typeMap
[
t
]
# ivIndex = index of bonded partner for hydrogens; otherwise ivIndex = particle index
# ivIndex = index of bonded partner for hydrogens; otherwise ivIndex = particle index
ivIndex
=
i
ivIndex
=
i
...
@@ -2819,7 +2819,7 @@ class AmoebaVdwGenerator:
...
@@ -2819,7 +2819,7 @@ class AmoebaVdwGenerator:
bondedParticleSets
.
append
(
AmoebaVdwGenerator
.
getBondedParticleSet
(
i
,
data
))
bondedParticleSets
.
append
(
AmoebaVdwGenerator
.
getBondedParticleSet
(
i
,
data
))
for
(
i
,
atom
)
in
enumerate
(
data
.
atoms
):
for
(
i
,
atom
)
in
enumerate
(
data
.
atoms
):
# 1-2 partners
# 1-2 partners
exclusionSet
=
bondedParticleSets
[
i
].
copy
()
exclusionSet
=
bondedParticleSets
[
i
].
copy
()
...
@@ -2846,7 +2846,7 @@ class AmoebaMultipoleGenerator:
...
@@ -2846,7 +2846,7 @@ class AmoebaMultipoleGenerator:
#=============================================================================================
#=============================================================================================
"""A AmoebaMultipoleGenerator constructs a AmoebaMultipoleForce."""
"""A AmoebaMultipoleGenerator constructs a AmoebaMultipoleForce."""
#=============================================================================================
#=============================================================================================
def
__init__
(
self
,
forceField
,
def
__init__
(
self
,
forceField
,
...
@@ -2857,25 +2857,25 @@ class AmoebaMultipoleGenerator:
...
@@ -2857,25 +2857,25 @@ class AmoebaMultipoleGenerator:
self
.
forceField
=
forceField
self
.
forceField
=
forceField
self
.
direct11Scale
=
direct11Scale
self
.
direct11Scale
=
direct11Scale
self
.
direct12Scale
=
direct12Scale
self
.
direct12Scale
=
direct12Scale
self
.
direct13Scale
=
direct13Scale
self
.
direct13Scale
=
direct13Scale
self
.
direct14Scale
=
direct14Scale
self
.
direct14Scale
=
direct14Scale
self
.
mpole12Scale
=
mpole12Scale
self
.
mpole12Scale
=
mpole12Scale
self
.
mpole13Scale
=
mpole13Scale
self
.
mpole13Scale
=
mpole13Scale
self
.
mpole14Scale
=
mpole14Scale
self
.
mpole14Scale
=
mpole14Scale
self
.
mpole15Scale
=
mpole15Scale
self
.
mpole15Scale
=
mpole15Scale
self
.
mutual11Scale
=
mutual11Scale
self
.
mutual11Scale
=
mutual11Scale
self
.
mutual12Scale
=
mutual12Scale
self
.
mutual12Scale
=
mutual12Scale
self
.
mutual13Scale
=
mutual13Scale
self
.
mutual13Scale
=
mutual13Scale
self
.
mutual14Scale
=
mutual14Scale
self
.
mutual14Scale
=
mutual14Scale
self
.
polar12Scale
=
polar12Scale
self
.
polar12Scale
=
polar12Scale
self
.
polar13Scale
=
polar13Scale
self
.
polar13Scale
=
polar13Scale
self
.
polar14Scale
=
polar14Scale
self
.
polar14Scale
=
polar14Scale
self
.
polar15Scale
=
polar15Scale
self
.
polar15Scale
=
polar15Scale
self
.
typeMap
=
{}
self
.
typeMap
=
{}
...
@@ -2893,12 +2893,12 @@ class AmoebaMultipoleGenerator:
...
@@ -2893,12 +2893,12 @@ class AmoebaMultipoleGenerator:
ky
=
kIndices
[
3
]
ky
=
kIndices
[
3
]
else
:
else
:
ky
=
0
ky
=
0
if
(
kIndicesLen
>
2
):
if
(
kIndicesLen
>
2
):
kx
=
kIndices
[
2
]
kx
=
kIndices
[
2
]
else
:
else
:
kx
=
0
kx
=
0
if
(
kIndicesLen
>
1
):
if
(
kIndicesLen
>
1
):
kz
=
kIndices
[
1
]
kz
=
kIndices
[
1
]
else
:
else
:
...
@@ -2919,9 +2919,9 @@ class AmoebaMultipoleGenerator:
...
@@ -2919,9 +2919,9 @@ class AmoebaMultipoleGenerator:
if
(
kz
<
0
and
kx
<
0
and
ky
<
0
):
if
(
kz
<
0
and
kx
<
0
and
ky
<
0
):
axisType
=
mm
.
AmoebaMultipoleForce
.
ThreeFold
axisType
=
mm
.
AmoebaMultipoleForce
.
ThreeFold
kIndices
[
1
]
=
abs
(
kz
)
kIndices
[
1
]
=
abs
(
kz
)
kIndices
[
2
]
=
abs
(
kx
)
kIndices
[
2
]
=
abs
(
kx
)
kIndices
[
3
]
=
abs
(
ky
)
kIndices
[
3
]
=
abs
(
ky
)
return
axisType
return
axisType
...
@@ -2930,7 +2930,7 @@ class AmoebaMultipoleGenerator:
...
@@ -2930,7 +2930,7 @@ class AmoebaMultipoleGenerator:
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
forceField
):
def
parseElement
(
element
,
forceField
):
# <AmoebaMultipoleForce direct11Scale="0.0" direct12Scale="1.0" direct13Scale="1.0" direct14Scale="1.0" mpole12Scale="0.0" mpole13Scale="0.0" mpole14Scale="0.4" mpole15Scale="0.8" mutual11Scale="1.0" mutual12Scale="1.0" mutual13Scale="1.0" mutual14Scale="1.0" polar12Scale="0.0" polar13Scale="0.0" polar14Intra="0.5" polar14Scale="1.0" polar15Scale="1.0" >
# <AmoebaMultipoleForce direct11Scale="0.0" direct12Scale="1.0" direct13Scale="1.0" direct14Scale="1.0" mpole12Scale="0.0" mpole13Scale="0.0" mpole14Scale="0.4" mpole15Scale="0.8" mutual11Scale="1.0" mutual12Scale="1.0" mutual13Scale="1.0" mutual14Scale="1.0" polar12Scale="0.0" polar13Scale="0.0" polar14Intra="0.5" polar14Scale="1.0" polar15Scale="1.0" >
# <Multipole class="1" kz="2" kx="4" c0="-0.22620" d1="0.08214" d2="0.00000" d3="0.34883" q11="0.11775" q21="0.00000" q22="-1.02185" q31="-0.17555" q32="0.00000" q33="0.90410" />
# <Multipole class="1" kz="2" kx="4" c0="-0.22620" d1="0.08214" d2="0.00000" d3="0.34883" q11="0.11775" q21="0.00000" q22="-1.02185" q31="-0.17555" q32="0.00000" q33="0.90410" />
# <Multipole class="2" kz="1" kx="3" c0="-0.15245" d1="0.19517" d2="0.00000" d3="0.19687" q11="-0.20677" q21="0.00000" q22="-0.48084" q31="-0.01672" q32="0.00000" q33="0.68761" />
# <Multipole class="2" kz="1" kx="3" c0="-0.15245" d1="0.19517" d2="0.00000" d3="0.19687" q11="-0.20677" q21="0.00000" q22="-0.48084" q31="-0.01672" q32="0.00000" q33="0.68761" />
...
@@ -2974,17 +2974,17 @@ class AmoebaMultipoleGenerator:
...
@@ -2974,17 +2974,17 @@ class AmoebaMultipoleGenerator:
try
:
try
:
if
(
atom
.
attrib
[
kString
]):
if
(
atom
.
attrib
[
kString
]):
kIndices
.
append
(
int
(
atom
.
attrib
[
kString
]))
kIndices
.
append
(
int
(
atom
.
attrib
[
kString
]))
except
:
except
:
pass
pass
# set axis type based on k-Indices
# set axis type based on k-Indices
axisType
=
AmoebaMultipoleGenerator
.
setAxisType
(
kIndices
)
axisType
=
AmoebaMultipoleGenerator
.
setAxisType
(
kIndices
)
# set multipole
# set multipole
charge
=
float
(
atom
.
attrib
[
'c0'
])
charge
=
float
(
atom
.
attrib
[
'c0'
])
conversion
=
1.0
conversion
=
1.0
dipole
=
[
conversion
*
float
(
atom
.
attrib
[
'd1'
]),
conversion
*
float
(
atom
.
attrib
[
'd2'
]),
conversion
*
float
(
atom
.
attrib
[
'd3'
])]
dipole
=
[
conversion
*
float
(
atom
.
attrib
[
'd1'
]),
conversion
*
float
(
atom
.
attrib
[
'd2'
]),
conversion
*
float
(
atom
.
attrib
[
'd3'
])]
...
@@ -3006,18 +3006,18 @@ class AmoebaMultipoleGenerator:
...
@@ -3006,18 +3006,18 @@ class AmoebaMultipoleGenerator:
valueMap
=
dict
()
valueMap
=
dict
()
valueMap
[
'classIndex'
]
=
atom
.
attrib
[
'type'
]
valueMap
[
'classIndex'
]
=
atom
.
attrib
[
'type'
]
valueMap
[
'kIndices'
]
=
kIndices
valueMap
[
'kIndices'
]
=
kIndices
valueMap
[
'charge'
]
=
charge
valueMap
[
'charge'
]
=
charge
valueMap
[
'dipole'
]
=
dipole
valueMap
[
'dipole'
]
=
dipole
valueMap
[
'quadrupole'
]
=
quadrupole
valueMap
[
'quadrupole'
]
=
quadrupole
valueMap
[
'axisType'
]
=
axisType
valueMap
[
'axisType'
]
=
axisType
generator
.
typeMap
[
t
].
append
(
valueMap
)
generator
.
typeMap
[
t
].
append
(
valueMap
)
else
:
else
:
outputString
=
"AmoebaMultipoleGenerator: error getting type for multipole: %s"
%
(
atom
.
attrib
[
'class'
])
outputString
=
"AmoebaMultipoleGenerator: error getting type for multipole: %s"
%
(
atom
.
attrib
[
'class'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
# polarization parameters
# polarization parameters
for
atom
in
element
.
findall
(
'Polarize'
):
for
atom
in
element
.
findall
(
'Polarize'
):
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
types
=
forceField
.
_findAtomTypes
(
atom
,
1
)
if
None
not
in
types
:
if
None
not
in
types
:
...
@@ -3039,7 +3039,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3039,7 +3039,7 @@ class AmoebaMultipoleGenerator:
for
t
in
types
[
0
]:
for
t
in
types
[
0
]:
if
(
t
not
in
generator
.
typeMap
):
if
(
t
not
in
generator
.
typeMap
):
outputString
=
"AmoebaMultipoleGenerator: polarize type not present: %s"
%
(
atom
.
attrib
[
'type'
])
outputString
=
"AmoebaMultipoleGenerator: polarize type not present: %s"
%
(
atom
.
attrib
[
'type'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
else
:
else
:
typeMapList
=
generator
.
typeMap
[
t
]
typeMapList
=
generator
.
typeMap
[
t
]
hit
=
0
hit
=
0
...
@@ -3049,18 +3049,18 @@ class AmoebaMultipoleGenerator:
...
@@ -3049,18 +3049,18 @@ class AmoebaMultipoleGenerator:
typeMap
[
'polarizability'
]
=
polarizability
typeMap
[
'polarizability'
]
=
polarizability
typeMap
[
'thole'
]
=
thole
typeMap
[
'thole'
]
=
thole
typeMap
[
'pdamp'
]
=
pdamp
typeMap
[
'pdamp'
]
=
pdamp
typeMap
[
'pgrpMap'
]
=
pgrpMap
typeMap
[
'pgrpMap'
]
=
pgrpMap
typeMapList
[
ii
]
=
typeMap
typeMapList
[
ii
]
=
typeMap
hit
=
1
hit
=
1
if
(
hit
==
0
):
if
(
hit
==
0
):
outputString
=
"AmoebaMultipoleGenerator: error getting type for polarize: class index=%s not in multipole list?"
%
(
atom
.
attrib
[
'class'
])
outputString
=
"AmoebaMultipoleGenerator: error getting type for polarize: class index=%s not in multipole list?"
%
(
atom
.
attrib
[
'class'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
else
:
else
:
outputString
=
"AmoebaMultipoleGenerator: error getting type for polarize: %s"
%
(
atom
.
attrib
[
'class'
])
outputString
=
"AmoebaMultipoleGenerator: error getting type for polarize: %s"
%
(
atom
.
attrib
[
'class'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
def
setPolarGroups
(
self
,
data
,
bonded12ParticleSets
,
force
):
def
setPolarGroups
(
self
,
data
,
bonded12ParticleSets
,
force
):
...
@@ -3081,7 +3081,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3081,7 +3081,7 @@ class AmoebaMultipoleGenerator:
if
(
bondedAtomType
in
pgrpMap
):
if
(
bondedAtomType
in
pgrpMap
):
atom
.
polarizationGroups
[
bondedAtomIndex
]
=
1
atom
.
polarizationGroups
[
bondedAtomIndex
]
=
1
bondedAtom
.
polarizationGroups
[
atomIndex
]
=
1
bondedAtom
.
polarizationGroups
[
atomIndex
]
=
1
# pgrp11
# pgrp11
for
(
atomIndex
,
atom
)
in
enumerate
(
data
.
atoms
):
for
(
atomIndex
,
atom
)
in
enumerate
(
data
.
atoms
):
...
@@ -3128,7 +3128,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3128,7 +3128,7 @@ class AmoebaMultipoleGenerator:
pgrp12
=
pgrp12
-
pgrp11
pgrp12
=
pgrp12
-
pgrp11
for
pgrpAtomIndex
in
pgrp11
:
for
pgrpAtomIndex
in
pgrp11
:
data
.
atoms
[
pgrpAtomIndex
].
polarizationGroupSet
.
append
(
pgrp12
)
data
.
atoms
[
pgrpAtomIndex
].
polarizationGroupSet
.
append
(
pgrp12
)
for
(
atomIndex
,
atom
)
in
enumerate
(
data
.
atoms
):
for
(
atomIndex
,
atom
)
in
enumerate
(
data
.
atoms
):
atom
.
polarizationGroupSet
[
1
]
=
sorted
(
atom
.
polarizationGroupSet
[
1
])
atom
.
polarizationGroupSet
[
1
]
=
sorted
(
atom
.
polarizationGroupSet
[
1
])
force
.
setCovalentMap
(
atomIndex
,
mm
.
AmoebaMultipoleForce
.
PolarizationCovalent12
,
atom
.
polarizationGroupSet
[
1
])
force
.
setCovalentMap
(
atomIndex
,
mm
.
AmoebaMultipoleForce
.
PolarizationCovalent12
,
atom
.
polarizationGroupSet
[
1
])
...
@@ -3150,7 +3150,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3150,7 +3150,7 @@ class AmoebaMultipoleGenerator:
pgrp13
=
pgrp13
-
set
(
pgrp11
)
pgrp13
=
pgrp13
-
set
(
pgrp11
)
for
pgrpAtomIndex
in
pgrp11
:
for
pgrpAtomIndex
in
pgrp11
:
data
.
atoms
[
pgrpAtomIndex
].
polarizationGroupSet
.
append
(
pgrp13
)
data
.
atoms
[
pgrpAtomIndex
].
polarizationGroupSet
.
append
(
pgrp13
)
for
(
atomIndex
,
atom
)
in
enumerate
(
data
.
atoms
):
for
(
atomIndex
,
atom
)
in
enumerate
(
data
.
atoms
):
atom
.
polarizationGroupSet
[
2
]
=
sorted
(
atom
.
polarizationGroupSet
[
2
])
atom
.
polarizationGroupSet
[
2
]
=
sorted
(
atom
.
polarizationGroupSet
[
2
])
force
.
setCovalentMap
(
atomIndex
,
mm
.
AmoebaMultipoleForce
.
PolarizationCovalent13
,
atom
.
polarizationGroupSet
[
2
])
force
.
setCovalentMap
(
atomIndex
,
mm
.
AmoebaMultipoleForce
.
PolarizationCovalent13
,
atom
.
polarizationGroupSet
[
2
])
...
@@ -3176,7 +3176,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3176,7 +3176,7 @@ class AmoebaMultipoleGenerator:
for
pgrpAtomIndex
in
pgrp11
:
for
pgrpAtomIndex
in
pgrp11
:
data
.
atoms
[
pgrpAtomIndex
].
polarizationGroupSet
.
append
(
pgrp14
)
data
.
atoms
[
pgrpAtomIndex
].
polarizationGroupSet
.
append
(
pgrp14
)
for
(
atomIndex
,
atom
)
in
enumerate
(
data
.
atoms
):
for
(
atomIndex
,
atom
)
in
enumerate
(
data
.
atoms
):
atom
.
polarizationGroupSet
[
3
]
=
sorted
(
atom
.
polarizationGroupSet
[
3
])
atom
.
polarizationGroupSet
[
3
]
=
sorted
(
atom
.
polarizationGroupSet
[
3
])
force
.
setCovalentMap
(
atomIndex
,
mm
.
AmoebaMultipoleForce
.
PolarizationCovalent14
,
atom
.
polarizationGroupSet
[
3
])
force
.
setCovalentMap
(
atomIndex
,
mm
.
AmoebaMultipoleForce
.
PolarizationCovalent14
,
atom
.
polarizationGroupSet
[
3
])
...
@@ -3195,7 +3195,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3195,7 +3195,7 @@ class AmoebaMultipoleGenerator:
if
len
(
existing
)
==
0
:
if
len
(
existing
)
==
0
:
force
=
mm
.
AmoebaMultipoleForce
()
force
=
mm
.
AmoebaMultipoleForce
()
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
if
(
nonbondedMethod
not
in
methodMap
):
if
(
nonbondedMethod
not
in
methodMap
):
raise
ValueError
(
"AmoebaMultipoleForce: input cutoff method not available."
)
raise
ValueError
(
"AmoebaMultipoleForce: input cutoff method not available."
)
else
:
else
:
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
...
@@ -3227,7 +3227,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3227,7 +3227,7 @@ class AmoebaMultipoleGenerator:
force
=
existing
[
0
]
force
=
existing
[
0
]
# add particles to force
# add particles to force
# throw error if particle type not available
# throw error if particle type not available
# get 1-2, 1-3, 1-4, 1-5 bonded sets
# get 1-2, 1-3, 1-4, 1-5 bonded sets
...
@@ -3245,7 +3245,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3245,7 +3245,7 @@ class AmoebaMultipoleGenerator:
for
i
in
range
(
len
(
data
.
atoms
)):
for
i
in
range
(
len
(
data
.
atoms
)):
bonded13Set
=
set
()
bonded13Set
=
set
()
bonded12ParticleSet
=
bonded12ParticleSets
[
i
]
bonded12ParticleSet
=
bonded12ParticleSets
[
i
]
for
j
in
bonded12ParticleSet
:
for
j
in
bonded12ParticleSet
:
bonded13Set
=
bonded13Set
.
union
(
bonded12ParticleSets
[
j
])
bonded13Set
=
bonded13Set
.
union
(
bonded12ParticleSets
[
j
])
# remove 1-2 and self from set
# remove 1-2 and self from set
...
@@ -3263,9 +3263,9 @@ class AmoebaMultipoleGenerator:
...
@@ -3263,9 +3263,9 @@ class AmoebaMultipoleGenerator:
for
i
in
range
(
len
(
data
.
atoms
)):
for
i
in
range
(
len
(
data
.
atoms
)):
bonded14Set
=
set
()
bonded14Set
=
set
()
bonded13ParticleSet
=
bonded13ParticleSets
[
i
]
bonded13ParticleSet
=
bonded13ParticleSets
[
i
]
for
j
in
bonded13ParticleSet
:
for
j
in
bonded13ParticleSet
:
bonded14Set
=
bonded14Set
.
union
(
bonded12ParticleSets
[
j
])
bonded14Set
=
bonded14Set
.
union
(
bonded12ParticleSets
[
j
])
# remove 1-3, 1-2 and self from set
# remove 1-3, 1-2 and self from set
bonded14Set
=
bonded14Set
-
bonded12ParticleSets
[
i
]
bonded14Set
=
bonded14Set
-
bonded12ParticleSets
[
i
]
...
@@ -3282,7 +3282,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3282,7 +3282,7 @@ class AmoebaMultipoleGenerator:
for
i
in
range
(
len
(
data
.
atoms
)):
for
i
in
range
(
len
(
data
.
atoms
)):
bonded15Set
=
set
()
bonded15Set
=
set
()
bonded14ParticleSet
=
bonded14ParticleSets
[
i
]
bonded14ParticleSet
=
bonded14ParticleSets
[
i
]
for
j
in
bonded14ParticleSet
:
for
j
in
bonded14ParticleSet
:
bonded15Set
=
bonded15Set
.
union
(
bonded12ParticleSets
[
j
])
bonded15Set
=
bonded15Set
.
union
(
bonded12ParticleSets
[
j
])
# remove 1-4, 1-3, 1-2 and self from set
# remove 1-4, 1-3, 1-2 and self from set
...
@@ -3312,15 +3312,15 @@ class AmoebaMultipoleGenerator:
...
@@ -3312,15 +3312,15 @@ class AmoebaMultipoleGenerator:
break
break
kIndices
=
multipoleDict
[
'kIndices'
]
kIndices
=
multipoleDict
[
'kIndices'
]
kz
=
kIndices
[
1
]
kz
=
kIndices
[
1
]
kx
=
kIndices
[
2
]
kx
=
kIndices
[
2
]
ky
=
kIndices
[
3
]
ky
=
kIndices
[
3
]
# assign multipole parameters
# assign multipole parameters
# (1) get bonded partners
# (1) get bonded partners
# (2) match parameter types
# (2) match parameter types
bondedAtomIndices
=
bonded12ParticleSets
[
atomIndex
]
bondedAtomIndices
=
bonded12ParticleSets
[
atomIndex
]
zaxis
=
-
1
zaxis
=
-
1
xaxis
=
-
1
xaxis
=
-
1
...
@@ -3364,7 +3364,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3364,7 +3364,7 @@ class AmoebaMultipoleGenerator:
yaxis
=
bondedAtomYIndex
yaxis
=
bondedAtomYIndex
savedMultipoleDict
=
multipoleDict
savedMultipoleDict
=
multipoleDict
hit
=
2
hit
=
2
# assign multipole parameters via 1-2 and 1-3 connected atoms
# assign multipole parameters via 1-2 and 1-3 connected atoms
for
multipoleDict
in
multipoleList
:
for
multipoleDict
in
multipoleList
:
...
@@ -3373,15 +3373,15 @@ class AmoebaMultipoleGenerator:
...
@@ -3373,15 +3373,15 @@ class AmoebaMultipoleGenerator:
break
break
kIndices
=
multipoleDict
[
'kIndices'
]
kIndices
=
multipoleDict
[
'kIndices'
]
kz
=
kIndices
[
1
]
kz
=
kIndices
[
1
]
kx
=
kIndices
[
2
]
kx
=
kIndices
[
2
]
ky
=
kIndices
[
3
]
ky
=
kIndices
[
3
]
# assign multipole parameters
# assign multipole parameters
# (1) get bonded partners
# (1) get bonded partners
# (2) match parameter types
# (2) match parameter types
bondedAtom12Indices
=
bonded12ParticleSets
[
atomIndex
]
bondedAtom12Indices
=
bonded12ParticleSets
[
atomIndex
]
bondedAtom13Indices
=
bonded13ParticleSets
[
atomIndex
]
bondedAtom13Indices
=
bonded13ParticleSets
[
atomIndex
]
...
@@ -3428,7 +3428,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3428,7 +3428,7 @@ class AmoebaMultipoleGenerator:
yaxis
=
bondedAtomYIndex
yaxis
=
bondedAtomYIndex
savedMultipoleDict
=
multipoleDict
savedMultipoleDict
=
multipoleDict
hit
=
4
hit
=
4
# assign multipole parameters via only a z-defining atom
# assign multipole parameters via only a z-defining atom
for
multipoleDict
in
multipoleList
:
for
multipoleDict
in
multipoleList
:
...
@@ -3437,10 +3437,10 @@ class AmoebaMultipoleGenerator:
...
@@ -3437,10 +3437,10 @@ class AmoebaMultipoleGenerator:
break
break
kIndices
=
multipoleDict
[
'kIndices'
]
kIndices
=
multipoleDict
[
'kIndices'
]
kz
=
kIndices
[
1
]
kz
=
kIndices
[
1
]
kx
=
kIndices
[
2
]
kx
=
kIndices
[
2
]
zaxis
=
-
1
zaxis
=
-
1
xaxis
=
-
1
xaxis
=
-
1
yaxis
=
-
1
yaxis
=
-
1
...
@@ -3466,9 +3466,9 @@ class AmoebaMultipoleGenerator:
...
@@ -3466,9 +3466,9 @@ class AmoebaMultipoleGenerator:
break
break
kIndices
=
multipoleDict
[
'kIndices'
]
kIndices
=
multipoleDict
[
'kIndices'
]
kz
=
kIndices
[
1
]
kz
=
kIndices
[
1
]
zaxis
=
-
1
zaxis
=
-
1
xaxis
=
-
1
xaxis
=
-
1
yaxis
=
-
1
yaxis
=
-
1
...
@@ -3476,7 +3476,7 @@ class AmoebaMultipoleGenerator:
...
@@ -3476,7 +3476,7 @@ class AmoebaMultipoleGenerator:
if
(
kz
==
0
):
if
(
kz
==
0
):
savedMultipoleDict
=
multipoleDict
savedMultipoleDict
=
multipoleDict
hit
=
6
hit
=
6
# add particle if there was a hit
# add particle if there was a hit
if
(
hit
!=
0
):
if
(
hit
!=
0
):
...
@@ -3509,19 +3509,19 @@ parsers["AmoebaMultipoleForce"] = AmoebaMultipoleGenerator.parseElement
...
@@ -3509,19 +3509,19 @@ parsers["AmoebaMultipoleForce"] = AmoebaMultipoleGenerator.parseElement
class
AmoebaWcaDispersionGenerator
:
class
AmoebaWcaDispersionGenerator
:
"""A AmoebaWcaDispersionGenerator constructs a AmoebaWcaDispersionForce."""
"""A AmoebaWcaDispersionGenerator constructs a AmoebaWcaDispersionForce."""
#=========================================================================================
#=========================================================================================
def
__init__
(
self
,
epso
,
epsh
,
rmino
,
rminh
,
awater
,
slevy
,
dispoff
,
shctd
):
def
__init__
(
self
,
epso
,
epsh
,
rmino
,
rminh
,
awater
,
slevy
,
dispoff
,
shctd
):
self
.
epso
=
epso
self
.
epso
=
epso
self
.
epsh
=
epsh
self
.
epsh
=
epsh
self
.
rmino
=
rmino
self
.
rmino
=
rmino
self
.
rminh
=
rminh
self
.
rminh
=
rminh
self
.
awater
=
awater
self
.
awater
=
awater
self
.
slevy
=
slevy
self
.
slevy
=
slevy
self
.
dispoff
=
dispoff
self
.
dispoff
=
dispoff
self
.
shctd
=
shctd
self
.
shctd
=
shctd
self
.
typeMap
=
{}
self
.
typeMap
=
{}
...
@@ -3533,15 +3533,15 @@ class AmoebaWcaDispersionGenerator:
...
@@ -3533,15 +3533,15 @@ class AmoebaWcaDispersionGenerator:
# <AmoebaWcaDispersionForce epso="0.46024" epsh="0.056484" rmino="0.17025" rminh="0.13275" awater="33.428" slevy="1.0" dispoff="0.026" shctd="0.81" >
# <AmoebaWcaDispersionForce epso="0.46024" epsh="0.056484" rmino="0.17025" rminh="0.13275" awater="33.428" slevy="1.0" dispoff="0.026" shctd="0.81" >
# <WcaDispersion class="1" radius="0.1855" epsilon="0.46024" />
# <WcaDispersion class="1" radius="0.1855" epsilon="0.46024" />
# <WcaDispersion class="2" radius="0.191" epsilon="0.422584" />
# <WcaDispersion class="2" radius="0.191" epsilon="0.422584" />
generator
=
AmoebaWcaDispersionGenerator
(
element
.
attrib
[
'epso'
],
generator
=
AmoebaWcaDispersionGenerator
(
element
.
attrib
[
'epso'
],
element
.
attrib
[
'epsh'
],
element
.
attrib
[
'epsh'
],
element
.
attrib
[
'rmino'
],
element
.
attrib
[
'rmino'
],
element
.
attrib
[
'rminh'
],
element
.
attrib
[
'rminh'
],
element
.
attrib
[
'awater'
],
element
.
attrib
[
'awater'
],
element
.
attrib
[
'slevy'
],
element
.
attrib
[
'slevy'
],
element
.
attrib
[
'dispoff'
],
element
.
attrib
[
'dispoff'
],
element
.
attrib
[
'shctd'
])
element
.
attrib
[
'shctd'
])
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
# typeMap[] = [ radius, epsilon ]
# typeMap[] = [ radius, epsilon ]
...
@@ -3555,10 +3555,10 @@ class AmoebaWcaDispersionGenerator:
...
@@ -3555,10 +3555,10 @@ class AmoebaWcaDispersionGenerator:
generator
.
typeMap
[
t
]
=
values
generator
.
typeMap
[
t
]
=
values
else
:
else
:
outputString
=
"AmoebaWcaDispersionGenerator: error getting type: %s"
%
(
atom
.
attrib
[
'class'
])
outputString
=
"AmoebaWcaDispersionGenerator: error getting type: %s"
%
(
atom
.
attrib
[
'class'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=========================================================================================
#=========================================================================================
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
# get or create force depending on whether it has already been added to the system
# get or create force depending on whether it has already been added to the system
...
@@ -3572,7 +3572,7 @@ class AmoebaWcaDispersionGenerator:
...
@@ -3572,7 +3572,7 @@ class AmoebaWcaDispersionGenerator:
force
=
existing
[
0
]
force
=
existing
[
0
]
# add particles to force
# add particles to force
# throw error if particle type not available
# throw error if particle type not available
force
.
setEpso
(
float
(
self
.
epso
))
force
.
setEpso
(
float
(
self
.
epso
))
force
.
setEpsh
(
float
(
self
.
epsh
))
force
.
setEpsh
(
float
(
self
.
epsh
))
...
@@ -3600,7 +3600,7 @@ parsers["AmoebaWcaDispersionForce"] = AmoebaWcaDispersionGenerator.parseElement
...
@@ -3600,7 +3600,7 @@ parsers["AmoebaWcaDispersionForce"] = AmoebaWcaDispersionGenerator.parseElement
class
AmoebaGeneralizedKirkwoodGenerator
:
class
AmoebaGeneralizedKirkwoodGenerator
:
"""A AmoebaGeneralizedKirkwoodGenerator constructs a AmoebaGeneralizedKirkwoodForce."""
"""A AmoebaGeneralizedKirkwoodGenerator constructs a AmoebaGeneralizedKirkwoodForce."""
#=========================================================================================
#=========================================================================================
def
__init__
(
self
,
forceField
,
solventDielectric
,
soluteDielectric
,
includeCavityTerm
,
probeRadius
,
surfaceAreaFactor
):
def
__init__
(
self
,
forceField
,
solventDielectric
,
soluteDielectric
,
includeCavityTerm
,
probeRadius
,
surfaceAreaFactor
):
...
@@ -3614,7 +3614,7 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3614,7 +3614,7 @@ class AmoebaGeneralizedKirkwoodGenerator:
self
.
radiusTypeMap
=
{}
self
.
radiusTypeMap
=
{}
self
.
radiusTypeMap
[
'Bondi'
]
=
{}
self
.
radiusTypeMap
[
'Bondi'
]
=
{}
bondiMap
=
self
.
radiusTypeMap
[
'Bondi'
]
bondiMap
=
self
.
radiusTypeMap
[
'Bondi'
]
rscale
=
1.03
rscale
=
1.03
bondiMap
[
0
]
=
0.00
bondiMap
[
0
]
=
0.00
...
@@ -3650,28 +3650,28 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3650,28 +3650,28 @@ class AmoebaGeneralizedKirkwoodGenerator:
shct
=
-
1.0
shct
=
-
1.0
# shct
# shct
if
(
atomicNumber
==
1
):
# H(1)
if
(
atomicNumber
==
1
):
# H(1)
shct
=
0.85
shct
=
0.85
elif
(
atomicNumber
==
6
):
# C(6)
elif
(
atomicNumber
==
6
):
# C(6)
shct
=
0.72
shct
=
0.72
elif
(
atomicNumber
==
7
):
# N(7)
elif
(
atomicNumber
==
7
):
# N(7)
shct
=
0.79
shct
=
0.79
elif
(
atomicNumber
==
8
):
# O(8)
elif
(
atomicNumber
==
8
):
# O(8)
shct
=
0.85
shct
=
0.85
elif
(
atomicNumber
==
9
):
# F(9)
elif
(
atomicNumber
==
9
):
# F(9)
shct
=
0.88
shct
=
0.88
elif
(
atomicNumber
==
15
):
# P(15)
elif
(
atomicNumber
==
15
):
# P(15)
shct
=
0.86
shct
=
0.86
elif
(
atomicNumber
==
16
):
# S(16)
elif
(
atomicNumber
==
16
):
# S(16)
shct
=
0.96
shct
=
0.96
elif
(
atomicNumber
==
26
):
# Fe(26)
elif
(
atomicNumber
==
26
):
# Fe(26)
shct
=
0.88
shct
=
0.88
if
(
shct
<
0.0
):
if
(
shct
<
0.0
):
raise
ValueError
(
"getObcShct: no GK overlap scale factor for atom %s of %s %d"
%
(
atom
.
name
,
atom
.
residue
.
name
,
atom
.
residue
.
index
)
)
raise
ValueError
(
"getObcShct: no GK overlap scale factor for atom %s of %s %d"
%
(
atom
.
name
,
atom
.
residue
.
name
,
atom
.
residue
.
index
)
)
return
shct
return
shct
#=========================================================================================
#=========================================================================================
...
@@ -3682,12 +3682,12 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3682,12 +3682,12 @@ class AmoebaGeneralizedKirkwoodGenerator:
radius
=
-
1.0
radius
=
-
1.0
if
(
atomicNumber
==
1
):
# H(1)
if
(
atomicNumber
==
1
):
# H(1)
radius
=
0.132
radius
=
0.132
if
(
len
(
bondedAtomIndices
)
<
1
):
if
(
len
(
bondedAtomIndices
)
<
1
):
raise
ValueError
(
"AmoebaGeneralizedKirkwoodGenerator: error getting atom bonded to %s of %s %d "
%
(
atom
.
name
,
atom
.
residue
.
name
,
atom
.
residue
.
index
)
)
raise
ValueError
(
"AmoebaGeneralizedKirkwoodGenerator: error getting atom bonded to %s of %s %d "
%
(
atom
.
name
,
atom
.
residue
.
name
,
atom
.
residue
.
index
)
)
for
bondedAtomIndex
in
bondedAtomIndices
:
for
bondedAtomIndex
in
bondedAtomIndices
:
bondedAtomAtomicNumber
=
data
.
atoms
[
bondedAtomIndex
].
element
.
atomic_number
bondedAtomAtomicNumber
=
data
.
atoms
[
bondedAtomIndex
].
element
.
atomic_number
...
@@ -3695,11 +3695,11 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3695,11 +3695,11 @@ class AmoebaGeneralizedKirkwoodGenerator:
radius
=
0.11
radius
=
0.11
if
(
bondedAtomAtomicNumber
==
8
):
if
(
bondedAtomAtomicNumber
==
8
):
radius
=
0.105
radius
=
0.105
elif
(
atomicNumber
==
3
):
# Li(3)
elif
(
atomicNumber
==
3
):
# Li(3)
radius
=
0.15
radius
=
0.15
elif
(
atomicNumber
==
6
):
# C(6)
elif
(
atomicNumber
==
6
):
# C(6)
radius
=
0.20
radius
=
0.20
if
(
len
(
bondedAtomIndices
)
==
3
):
if
(
len
(
bondedAtomIndices
)
==
3
):
radius
=
0.205
radius
=
0.205
...
@@ -3718,60 +3718,60 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3718,60 +3718,60 @@ class AmoebaGeneralizedKirkwoodGenerator:
radius
=
0.145
radius
=
0.145
elif
(
atomicNumber
==
9
):
# F(9)
elif
(
atomicNumber
==
9
):
# F(9)
radius
=
0.154
radius
=
0.154
elif
(
atomicNumber
==
10
):
elif
(
atomicNumber
==
10
):
radius
=
0.146
radius
=
0.146
elif
(
atomicNumber
==
11
):
elif
(
atomicNumber
==
11
):
radius
=
0.209
radius
=
0.209
elif
(
atomicNumber
==
12
):
elif
(
atomicNumber
==
12
):
radius
=
0.179
radius
=
0.179
elif
(
atomicNumber
==
14
):
elif
(
atomicNumber
==
14
):
radius
=
0.189
radius
=
0.189
elif
(
atomicNumber
==
15
):
# P(15)
elif
(
atomicNumber
==
15
):
# P(15)
radius
=
0.196
radius
=
0.196
elif
(
atomicNumber
==
16
):
# S(16)
elif
(
atomicNumber
==
16
):
# S(16)
radius
=
0.186
radius
=
0.186
elif
(
atomicNumber
==
17
):
elif
(
atomicNumber
==
17
):
radius
=
0.182
radius
=
0.182
elif
(
atomicNumber
==
18
):
elif
(
atomicNumber
==
18
):
radius
=
0.179
radius
=
0.179
elif
(
atomicNumber
==
19
):
elif
(
atomicNumber
==
19
):
radius
=
0.223
radius
=
0.223
elif
(
atomicNumber
==
20
):
elif
(
atomicNumber
==
20
):
radius
=
0.191
radius
=
0.191
elif
(
atomicNumber
==
35
):
elif
(
atomicNumber
==
35
):
radius
=
2.00
radius
=
2.00
elif
(
atomicNumber
==
36
):
elif
(
atomicNumber
==
36
):
radius
=
0.190
radius
=
0.190
elif
(
atomicNumber
==
37
):
elif
(
atomicNumber
==
37
):
radius
=
0.226
radius
=
0.226
elif
(
atomicNumber
==
53
):
elif
(
atomicNumber
==
53
):
radius
=
0.237
radius
=
0.237
elif
(
atomicNumber
==
54
):
elif
(
atomicNumber
==
54
):
radius
=
0.207
radius
=
0.207
elif
(
atomicNumber
==
55
):
elif
(
atomicNumber
==
55
):
radius
=
0.263
radius
=
0.263
elif
(
atomicNumber
==
56
):
elif
(
atomicNumber
==
56
):
radius
=
0.230
radius
=
0.230
if
(
radius
<
0.0
):
if
(
radius
<
0.0
):
outputString
=
"No GK radius for atom %s of %s %d"
%
(
atom
.
name
,
atom
.
residue
.
name
,
atom
.
residue
.
index
)
outputString
=
"No GK radius for atom %s of %s %d"
%
(
atom
.
name
,
atom
.
residue
.
name
,
atom
.
residue
.
index
)
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
return
radius
return
radius
#=========================================================================================
#=========================================================================================
def
getBondiTypeRadius
(
self
,
data
,
bondedAtomIndices
,
atomIndex
):
def
getBondiTypeRadius
(
self
,
data
,
bondedAtomIndices
,
atomIndex
):
bondiMap
=
self
.
radiusTypeMap
[
'Bondi'
]
bondiMap
=
self
.
radiusTypeMap
[
'Bondi'
]
atom
=
data
.
atoms
[
atomIndex
]
atom
=
data
.
atoms
[
atomIndex
]
atomicNumber
=
atom
.
element
.
atomic_number
atomicNumber
=
atom
.
element
.
atomic_number
if
(
atomicNumber
in
bondiMap
):
if
(
atomicNumber
in
bondiMap
):
radius
=
bondiMap
[
atomicNumber
]
radius
=
bondiMap
[
atomicNumber
]
else
:
else
:
outputString
=
"Warning no Bondi radius for atom %s of %s %d using default value=%f"
%
(
atom
.
name
,
atom
.
residue
.
name
,
atom
.
residue
.
index
,
radius
)
outputString
=
"Warning no Bondi radius for atom %s of %s %d using default value=%f"
%
(
atom
.
name
,
atom
.
residue
.
name
,
atom
.
residue
.
index
,
radius
)
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
return
radius
return
radius
#=========================================================================================
#=========================================================================================
...
@@ -3782,14 +3782,14 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3782,14 +3782,14 @@ class AmoebaGeneralizedKirkwoodGenerator:
# <AmoebaGeneralizedKirkwoodForce solventDielectric="78.3" soluteDielectric="1.0" includeCavityTerm="1" probeRadius="0.14" surfaceAreaFactor="-170.351730663">
# <AmoebaGeneralizedKirkwoodForce solventDielectric="78.3" soluteDielectric="1.0" includeCavityTerm="1" probeRadius="0.14" surfaceAreaFactor="-170.351730663">
# <GeneralizedKirkwood type="1" charge="-0.22620" shct="0.79" />
# <GeneralizedKirkwood type="1" charge="-0.22620" shct="0.79" />
# <GeneralizedKirkwood type="2" charge="-0.15245" shct="0.72" />
# <GeneralizedKirkwood type="2" charge="-0.15245" shct="0.72" />
generator
=
AmoebaGeneralizedKirkwoodGenerator
(
forceField
,
element
.
attrib
[
'solventDielectric'
],
element
.
attrib
[
'soluteDielectric'
],
generator
=
AmoebaGeneralizedKirkwoodGenerator
(
forceField
,
element
.
attrib
[
'solventDielectric'
],
element
.
attrib
[
'soluteDielectric'
],
element
.
attrib
[
'includeCavityTerm'
],
element
.
attrib
[
'includeCavityTerm'
],
element
.
attrib
[
'probeRadius'
],
element
.
attrib
[
'surfaceAreaFactor'
])
element
.
attrib
[
'probeRadius'
],
element
.
attrib
[
'surfaceAreaFactor'
])
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
#=========================================================================================
#=========================================================================================
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
if
(
nonbondedMethod
!=
NoCutoff
):
if
(
nonbondedMethod
!=
NoCutoff
):
...
@@ -3806,9 +3806,9 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3806,9 +3806,9 @@ class AmoebaGeneralizedKirkwoodGenerator:
# call AmoebaMultipoleForceGenerator.createForce() to ensure charges have been set
# call AmoebaMultipoleForceGenerator.createForce() to ensure charges have been set
for
force
in
self
.
forceField
.
_forces
:
for
force
in
self
.
forceField
.
_forces
:
if
(
force
.
__class__
.
__name__
==
'AmoebaMultipoleGenerator'
):
if
(
force
.
__class__
.
__name__
==
'AmoebaMultipoleGenerator'
):
force
.
createForce
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
)
force
.
createForce
(
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
)
# get or create force depending on whether it has already been added to the system
# get or create force depending on whether it has already been added to the system
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
AmoebaGeneralizedKirkwoodForce
]
existing
=
[
f
for
f
in
existing
if
type
(
f
)
==
mm
.
AmoebaGeneralizedKirkwoodForce
]
...
@@ -3816,7 +3816,7 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3816,7 +3816,7 @@ class AmoebaGeneralizedKirkwoodGenerator:
force
=
mm
.
AmoebaGeneralizedKirkwoodForce
()
force
=
mm
.
AmoebaGeneralizedKirkwoodForce
()
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
if
(
'solventDielectric'
in
args
):
if
(
'solventDielectric'
in
args
):
force
.
setSolventDielectric
(
float
(
args
[
'solventDielectric'
]))
force
.
setSolventDielectric
(
float
(
args
[
'solventDielectric'
]))
else
:
else
:
...
@@ -3836,7 +3836,7 @@ class AmoebaGeneralizedKirkwoodGenerator:
...
@@ -3836,7 +3836,7 @@ class AmoebaGeneralizedKirkwoodGenerator:
force
=
existing
[
0
]
force
=
existing
[
0
]
# add particles to force
# add particles to force
# throw error if particle type not available
# throw error if particle type not available
force
.
setProbeRadius
(
float
(
self
.
probeRadius
))
force
.
setProbeRadius
(
float
(
self
.
probeRadius
))
force
.
setSurfaceAreaFactor
(
float
(
self
.
surfaceAreaFactor
))
force
.
setSurfaceAreaFactor
(
float
(
self
.
surfaceAreaFactor
))
...
@@ -3870,7 +3870,7 @@ class AmoebaUreyBradleyGenerator:
...
@@ -3870,7 +3870,7 @@ class AmoebaUreyBradleyGenerator:
#=============================================================================================
#=============================================================================================
"""An AmoebaUreyBradleyGenerator constructs a AmoebaUreyBradleyForce."""
"""An AmoebaUreyBradleyGenerator constructs a AmoebaUreyBradleyForce."""
#=============================================================================================
#=============================================================================================
def
__init__
(
self
):
def
__init__
(
self
):
self
.
types1
=
[]
self
.
types1
=
[]
...
@@ -3886,7 +3886,7 @@ class AmoebaUreyBradleyGenerator:
...
@@ -3886,7 +3886,7 @@ class AmoebaUreyBradleyGenerator:
def
parseElement
(
element
,
forceField
):
def
parseElement
(
element
,
forceField
):
# <AmoebaUreyBradleyForce>
# <AmoebaUreyBradleyForce>
# <UreyBradley class1="74" class2="73" class3="74" k="16003.8" d="0.15537" />
# <UreyBradley class1="74" class2="73" class3="74" k="16003.8" d="0.15537" />
generator
=
AmoebaUreyBradleyGenerator
()
generator
=
AmoebaUreyBradleyGenerator
()
forceField
.
_forces
.
append
(
generator
)
forceField
.
_forces
.
append
(
generator
)
...
@@ -3904,8 +3904,8 @@ class AmoebaUreyBradleyGenerator:
...
@@ -3904,8 +3904,8 @@ class AmoebaUreyBradleyGenerator:
else
:
else
:
outputString
=
"AmoebaUreyBradleyGenerator: error getting types: %s %s %s"
%
(
outputString
=
"AmoebaUreyBradleyGenerator: error getting types: %s %s %s"
%
(
bond
.
attrib
[
'class1'
],
bond
.
attrib
[
'class2'
],
bond
.
attrib
[
'class3'
])
bond
.
attrib
[
'class1'
],
bond
.
attrib
[
'class2'
],
bond
.
attrib
[
'class3'
])
raise
ValueError
(
outputString
)
raise
ValueError
(
outputString
)
#=============================================================================================
#=============================================================================================
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
...
@@ -3941,7 +3941,7 @@ parsers["AmoebaUreyBradleyForce"] = AmoebaUreyBradleyGenerator.parseElement
...
@@ -3941,7 +3941,7 @@ parsers["AmoebaUreyBradleyForce"] = AmoebaUreyBradleyGenerator.parseElement
## @private
## @private
class
DrudeGenerator
:
class
DrudeGenerator
:
"""A DrudeGenerator constructs a DrudeForce."""
"""A DrudeGenerator constructs a DrudeForce."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
typeMap
=
{}
self
.
typeMap
=
{}
...
@@ -3966,14 +3966,14 @@ class DrudeGenerator:
...
@@ -3966,14 +3966,14 @@ class DrudeGenerator:
values
=
(
types
[
1
],
types
[
2
],
types
[
3
],
types
[
4
],
float
(
particle
.
attrib
[
'charge'
]),
float
(
particle
.
attrib
[
'polarizability'
]),
aniso12
,
aniso34
,
float
(
particle
.
attrib
[
'thole'
]))
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
]:
for
t
in
types
[
0
]:
generator
.
typeMap
[
t
]
=
values
generator
.
typeMap
[
t
]
=
values
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
force
=
mm
.
DrudeForce
()
force
=
mm
.
DrudeForce
()
if
not
any
(
isinstance
(
f
,
mm
.
NonbondedForce
)
for
f
in
sys
.
getForces
()):
if
not
any
(
isinstance
(
f
,
mm
.
NonbondedForce
)
for
f
in
sys
.
getForces
()):
raise
ValueError
(
'<DrudeForce> must come after <NonbondedForce> in XML file'
)
raise
ValueError
(
'<DrudeForce> must come after <NonbondedForce> in XML file'
)
# Add Drude particles.
# Add Drude particles.
drudeMap
=
{}
drudeMap
=
{}
parentMap
=
{}
parentMap
=
{}
for
atom
in
data
.
atoms
:
for
atom
in
data
.
atoms
:
...
@@ -3996,10 +3996,10 @@ class DrudeGenerator:
...
@@ -3996,10 +3996,10 @@ class DrudeGenerator:
drudeMap
[
atom
.
index
]
=
p
[
0
]
drudeMap
[
atom
.
index
]
=
p
[
0
]
parentMap
[
p
[
0
]]
=
(
atom
.
index
,
drudeIndex
)
parentMap
[
p
[
0
]]
=
(
atom
.
index
,
drudeIndex
)
sys
.
addForce
(
force
)
sys
.
addForce
(
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# For every nonbonded exclusion between Drude particles, add a screened pair.
# For every nonbonded exclusion between Drude particles, add a screened pair.
drude
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
DrudeForce
)][
0
]
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
]
nonbonded
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
NonbondedForce
)][
0
]
particleMap
=
{}
particleMap
=
{}
...
@@ -4019,4 +4019,4 @@ class DrudeGenerator:
...
@@ -4019,4 +4019,4 @@ class DrudeGenerator:
thole2
=
self
.
typeMap
[
type2
][
8
]
thole2
=
self
.
typeMap
[
type2
][
8
]
drude
.
addScreenedPair
(
drude1
,
drude2
,
thole1
+
thole2
)
drude
.
addScreenedPair
(
drude1
,
drude2
,
thole1
+
thole2
)
parsers
[
"DrudeForce"
]
=
DrudeGenerator
.
parseElement
parsers
[
"DrudeForce"
]
=
DrudeGenerator
.
parseElement
\ No newline at end of file
wrappers/python/simtk/openmm/app/gromacsgrofile.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Lee-Ping Wang, Peter Eastman
Authors: Lee-Ping Wang, Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -47,7 +47,7 @@ def _isint(word):
...
@@ -47,7 +47,7 @@ def _isint(word):
@param[in] word String (for instance, '123', '153.0', '2.', '-354')
@param[in] word String (for instance, '123', '153.0', '2.', '-354')
@return answer Boolean which specifies whether the string is an integer (only +/- sign followed by digits)
@return answer Boolean which specifies whether the string is an integer (only +/- sign followed by digits)
"""
"""
return
match
(
'^[-+]?[0-9]+$'
,
word
)
return
match
(
'^[-+]?[0-9]+$'
,
word
)
...
@@ -57,7 +57,7 @@ def _isfloat(word):
...
@@ -57,7 +57,7 @@ def _isfloat(word):
@param[in] word String (for instance, '123', '153.0', '2.', '-354')
@param[in] word String (for instance, '123', '153.0', '2.', '-354')
@return answer Boolean which specifies whether the string is any number
@return answer Boolean which specifies whether the string is any number
"""
"""
return
match
(
'^[-+]?[0-9]*\.?[0-9]*([eEdD][-+]?[0-9]+)?$'
,
word
)
return
match
(
'^[-+]?[0-9]*\.?[0-9]*([eEdD][-+]?[0-9]+)?$'
,
word
)
...
@@ -65,7 +65,7 @@ def _is_gro_coord(line):
...
@@ -65,7 +65,7 @@ def _is_gro_coord(line):
""" Determines whether a line contains GROMACS data or not
""" Determines whether a line contains GROMACS data or not
@param[in] line The line to be tested
@param[in] line The line to be tested
"""
"""
sline
=
line
.
split
()
sline
=
line
.
split
()
if
len
(
sline
)
==
6
or
len
(
sline
)
==
9
:
if
len
(
sline
)
==
6
or
len
(
sline
)
==
9
:
...
@@ -79,7 +79,7 @@ def _is_gro_box(line):
...
@@ -79,7 +79,7 @@ def _is_gro_box(line):
""" Determines whether a line contains a GROMACS box vector or not
""" Determines whether a line contains a GROMACS box vector or not
@param[in] line The line to be tested
@param[in] line The line to be tested
"""
"""
sline
=
line
.
split
()
sline
=
line
.
split
()
if
len
(
sline
)
==
9
and
all
([
_isfloat
(
i
)
for
i
in
sline
]):
if
len
(
sline
)
==
9
and
all
([
_isfloat
(
i
)
for
i
in
sline
]):
...
@@ -91,16 +91,16 @@ def _is_gro_box(line):
...
@@ -91,16 +91,16 @@ def _is_gro_box(line):
class
GromacsGroFile
(
object
):
class
GromacsGroFile
(
object
):
"""GromacsGroFile parses a Gromacs .gro file and constructs a set of atom positions from it.
"""GromacsGroFile parses a Gromacs .gro file and constructs a set of atom positions from it.
A .gro file also contains some topological information, such as elements and residue names,
A .gro file also contains some topological information, such as elements and residue names,
but not enough to construct a full Topology object. This information is recorded and stored
but not enough to construct a full Topology object. This information is recorded and stored
in the object's public fields."""
in the object's public fields."""
def
__init__
(
self
,
file
):
def
__init__
(
self
,
file
):
"""Load a .gro file.
"""Load a .gro file.
The atom positions can be retrieved by calling getPositions().
The atom positions can be retrieved by calling getPositions().
Parameters:
Parameters:
- file (string) the name of the file to load
- file (string) the name of the file to load
"""
"""
...
@@ -145,7 +145,7 @@ class GromacsGroFile(object):
...
@@ -145,7 +145,7 @@ class GromacsGroFile(object):
else
:
else
:
raise
Exception
(
"Unexpected line in .gro file: "
+
line
)
raise
Exception
(
"Unexpected line in .gro file: "
+
line
)
ln
+=
1
ln
+=
1
## The atom positions read from the file. If the file contains multiple frames, these are the positions in the first frame.
## The atom positions read from the file. If the file contains multiple frames, these are the positions in the first frame.
self
.
positions
=
xyzs
[
0
]
self
.
positions
=
xyzs
[
0
]
## A list containing the element of each atom stored in the file
## A list containing the element of each atom stored in the file
...
@@ -159,14 +159,14 @@ class GromacsGroFile(object):
...
@@ -159,14 +159,14 @@ class GromacsGroFile(object):
self
.
_positions
=
xyzs
self
.
_positions
=
xyzs
self
.
_unitCellDimensions
=
boxes
self
.
_unitCellDimensions
=
boxes
self
.
_numpyPositions
=
None
self
.
_numpyPositions
=
None
def
getNumFrames
(
self
):
def
getNumFrames
(
self
):
"""Get the number of frames stored in the file."""
"""Get the number of frames stored in the file."""
return
len
(
self
.
_positions
)
return
len
(
self
.
_positions
)
def
getPositions
(
self
,
asNumpy
=
False
,
frame
=
0
):
def
getPositions
(
self
,
asNumpy
=
False
,
frame
=
0
):
"""Get the atomic positions.
"""Get the atomic positions.
Parameters:
Parameters:
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s
- frame (int=0) the index of the frame for which to get positions
- frame (int=0) the index of the frame for which to get positions
...
@@ -178,10 +178,10 @@ class GromacsGroFile(object):
...
@@ -178,10 +178,10 @@ class GromacsGroFile(object):
self
.
_numpyPositions
[
frame
]
=
Quantity
(
numpy
.
array
(
self
.
_positions
[
frame
].
value_in_unit
(
nanometers
)),
nanometers
)
self
.
_numpyPositions
[
frame
]
=
Quantity
(
numpy
.
array
(
self
.
_positions
[
frame
].
value_in_unit
(
nanometers
)),
nanometers
)
return
self
.
_numpyPositions
[
frame
]
return
self
.
_numpyPositions
[
frame
]
return
self
.
_positions
[
frame
]
return
self
.
_positions
[
frame
]
def
getUnitCellDimensions
(
self
,
frame
=
0
):
def
getUnitCellDimensions
(
self
,
frame
=
0
):
"""Get the dimensions of the crystallographic unit cell.
"""Get the dimensions of the crystallographic unit cell.
Parameters:
Parameters:
- frame (int=0) the index of the frame for which to get the unit cell dimensions
- frame (int=0) the index of the frame for which to get the unit cell dimensions
"""
"""
...
...
wrappers/python/simtk/openmm/app/gromacstopfile.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -49,7 +49,7 @@ OBC2 = prmtop.OBC2
...
@@ -49,7 +49,7 @@ OBC2 = prmtop.OBC2
class
GromacsTopFile
(
object
):
class
GromacsTopFile
(
object
):
"""GromacsTopFile parses a Gromacs top file and constructs a Topology and (optionally) an OpenMM System from it."""
"""GromacsTopFile parses a Gromacs top file and constructs a Topology and (optionally) an OpenMM System from it."""
class
_MoleculeType
(
object
):
class
_MoleculeType
(
object
):
"""Inner class to store information about a molecule type."""
"""Inner class to store information about a molecule type."""
def
__init__
(
self
):
def
__init__
(
self
):
...
@@ -60,7 +60,7 @@ class GromacsTopFile(object):
...
@@ -60,7 +60,7 @@ class GromacsTopFile(object):
self
.
exclusions
=
[]
self
.
exclusions
=
[]
self
.
pairs
=
[]
self
.
pairs
=
[]
self
.
cmaps
=
[]
self
.
cmaps
=
[]
def
_processFile
(
self
,
file
):
def
_processFile
(
self
,
file
):
append
=
''
append
=
''
for
line
in
open
(
file
):
for
line
in
open
(
file
):
...
@@ -69,7 +69,7 @@ class GromacsTopFile(object):
...
@@ -69,7 +69,7 @@ class GromacsTopFile(object):
else
:
else
:
self
.
_processLine
(
append
+
' '
+
line
,
file
)
self
.
_processLine
(
append
+
' '
+
line
,
file
)
append
=
''
append
=
''
def
_processLine
(
self
,
line
,
file
):
def
_processLine
(
self
,
line
,
file
):
"""Process one line from a file."""
"""Process one line from a file."""
if
';'
in
line
:
if
';'
in
line
:
...
@@ -79,13 +79,13 @@ class GromacsTopFile(object):
...
@@ -79,13 +79,13 @@ class GromacsTopFile(object):
if
stripped
.
startswith
(
'*'
)
or
len
(
stripped
)
==
0
:
if
stripped
.
startswith
(
'*'
)
or
len
(
stripped
)
==
0
:
# A comment or empty line.
# A comment or empty line.
return
return
elif
stripped
.
startswith
(
'['
)
and
not
ignore
:
elif
stripped
.
startswith
(
'['
)
and
not
ignore
:
# The start of a category.
# The start of a category.
if
not
stripped
.
endswith
(
']'
):
if
not
stripped
.
endswith
(
']'
):
raise
ValueError
(
'Illegal line in .top file: '
+
line
)
raise
ValueError
(
'Illegal line in .top file: '
+
line
)
self
.
_currentCategory
=
stripped
[
1
:
-
1
].
strip
()
self
.
_currentCategory
=
stripped
[
1
:
-
1
].
strip
()
elif
stripped
.
startswith
(
'#'
):
elif
stripped
.
startswith
(
'#'
):
# A preprocessor command.
# A preprocessor command.
fields
=
stripped
.
split
()
fields
=
stripped
.
split
()
...
@@ -127,7 +127,7 @@ class GromacsTopFile(object):
...
@@ -127,7 +127,7 @@ class GromacsTopFile(object):
if
len
(
self
.
_ifStack
)
==
0
:
if
len
(
self
.
_ifStack
)
==
0
:
raise
ValueError
(
'Unexpected line in .top file: '
+
line
)
raise
ValueError
(
'Unexpected line in .top file: '
+
line
)
del
(
self
.
_ifStack
[
-
1
])
del
(
self
.
_ifStack
[
-
1
])
elif
not
ignore
:
elif
not
ignore
:
# A line of data for the current category
# A line of data for the current category
if
self
.
_currentCategory
is
None
:
if
self
.
_currentCategory
is
None
:
...
@@ -166,7 +166,7 @@ class GromacsTopFile(object):
...
@@ -166,7 +166,7 @@ class GromacsTopFile(object):
self
.
_processPairType
(
line
)
self
.
_processPairType
(
line
)
elif
self
.
_currentCategory
==
'cmaptypes'
:
elif
self
.
_currentCategory
==
'cmaptypes'
:
self
.
_processCmapType
(
line
)
self
.
_processCmapType
(
line
)
def
_processDefaults
(
self
,
line
):
def
_processDefaults
(
self
,
line
):
"""Process the [ defaults ] line."""
"""Process the [ defaults ] line."""
fields
=
line
.
split
()
fields
=
line
.
split
()
...
@@ -179,7 +179,7 @@ class GromacsTopFile(object):
...
@@ -179,7 +179,7 @@ class GromacsTopFile(object):
if
fields
[
2
].
lower
()
==
'no'
:
if
fields
[
2
].
lower
()
==
'no'
:
raise
ValueError
(
'gen_pairs=no is not supported'
)
raise
ValueError
(
'gen_pairs=no is not supported'
)
self
.
_defaults
=
fields
self
.
_defaults
=
fields
def
_processMoleculeType
(
self
,
line
):
def
_processMoleculeType
(
self
,
line
):
"""Process a line in the [ moleculetypes ] category."""
"""Process a line in the [ moleculetypes ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
...
@@ -188,14 +188,14 @@ class GromacsTopFile(object):
...
@@ -188,14 +188,14 @@ class GromacsTopFile(object):
type
=
GromacsTopFile
.
_MoleculeType
()
type
=
GromacsTopFile
.
_MoleculeType
()
self
.
_moleculeTypes
[
fields
[
0
]]
=
type
self
.
_moleculeTypes
[
fields
[
0
]]
=
type
self
.
_currentMoleculeType
=
type
self
.
_currentMoleculeType
=
type
def
_processMolecule
(
self
,
line
):
def
_processMolecule
(
self
,
line
):
"""Process a line in the [ molecules ] category."""
"""Process a line in the [ molecules ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
if
len
(
fields
)
<
2
:
if
len
(
fields
)
<
2
:
raise
ValueError
(
'Too few fields in [ molecules ] line: '
+
line
);
raise
ValueError
(
'Too few fields in [ molecules ] line: '
+
line
);
self
.
_molecules
.
append
((
fields
[
0
],
int
(
fields
[
1
])))
self
.
_molecules
.
append
((
fields
[
0
],
int
(
fields
[
1
])))
def
_processAtom
(
self
,
line
):
def
_processAtom
(
self
,
line
):
"""Process a line in the [ atoms ] category."""
"""Process a line in the [ atoms ] category."""
if
self
.
_currentMoleculeType
is
None
:
if
self
.
_currentMoleculeType
is
None
:
...
@@ -204,7 +204,7 @@ class GromacsTopFile(object):
...
@@ -204,7 +204,7 @@ class GromacsTopFile(object):
if
len
(
fields
)
<
5
:
if
len
(
fields
)
<
5
:
raise
ValueError
(
'Too few fields in [ atoms ] line: '
+
line
);
raise
ValueError
(
'Too few fields in [ atoms ] line: '
+
line
);
self
.
_currentMoleculeType
.
atoms
.
append
(
fields
)
self
.
_currentMoleculeType
.
atoms
.
append
(
fields
)
def
_processBond
(
self
,
line
):
def
_processBond
(
self
,
line
):
"""Process a line in the [ bonds ] category."""
"""Process a line in the [ bonds ] category."""
if
self
.
_currentMoleculeType
is
None
:
if
self
.
_currentMoleculeType
is
None
:
...
@@ -215,7 +215,7 @@ class GromacsTopFile(object):
...
@@ -215,7 +215,7 @@ class GromacsTopFile(object):
if
fields
[
2
]
!=
'1'
:
if
fields
[
2
]
!=
'1'
:
raise
ValueError
(
'Unsupported function type in [ bonds ] line: '
+
line
);
raise
ValueError
(
'Unsupported function type in [ bonds ] line: '
+
line
);
self
.
_currentMoleculeType
.
bonds
.
append
(
fields
)
self
.
_currentMoleculeType
.
bonds
.
append
(
fields
)
def
_processAngle
(
self
,
line
):
def
_processAngle
(
self
,
line
):
"""Process a line in the [ angles ] category."""
"""Process a line in the [ angles ] category."""
if
self
.
_currentMoleculeType
is
None
:
if
self
.
_currentMoleculeType
is
None
:
...
@@ -226,7 +226,7 @@ class GromacsTopFile(object):
...
@@ -226,7 +226,7 @@ class GromacsTopFile(object):
if
fields
[
3
]
not
in
(
'1'
,
'5'
):
if
fields
[
3
]
not
in
(
'1'
,
'5'
):
raise
ValueError
(
'Unsupported function type in [ angles ] line: '
+
line
);
raise
ValueError
(
'Unsupported function type in [ angles ] line: '
+
line
);
self
.
_currentMoleculeType
.
angles
.
append
(
fields
)
self
.
_currentMoleculeType
.
angles
.
append
(
fields
)
def
_processDihedral
(
self
,
line
):
def
_processDihedral
(
self
,
line
):
"""Process a line in the [ dihedrals ] category."""
"""Process a line in the [ dihedrals ] category."""
if
self
.
_currentMoleculeType
is
None
:
if
self
.
_currentMoleculeType
is
None
:
...
@@ -237,7 +237,7 @@ class GromacsTopFile(object):
...
@@ -237,7 +237,7 @@ class GromacsTopFile(object):
if
fields
[
4
]
not
in
(
'1'
,
'2'
,
'3'
,
'4'
,
'9'
):
if
fields
[
4
]
not
in
(
'1'
,
'2'
,
'3'
,
'4'
,
'9'
):
raise
ValueError
(
'Unsupported function type in [ dihedrals ] line: '
+
line
);
raise
ValueError
(
'Unsupported function type in [ dihedrals ] line: '
+
line
);
self
.
_currentMoleculeType
.
dihedrals
.
append
(
fields
)
self
.
_currentMoleculeType
.
dihedrals
.
append
(
fields
)
def
_processExclusion
(
self
,
line
):
def
_processExclusion
(
self
,
line
):
"""Process a line in the [ exclusions ] category."""
"""Process a line in the [ exclusions ] category."""
if
self
.
_currentMoleculeType
is
None
:
if
self
.
_currentMoleculeType
is
None
:
...
@@ -246,7 +246,7 @@ class GromacsTopFile(object):
...
@@ -246,7 +246,7 @@ class GromacsTopFile(object):
if
len
(
fields
)
<
2
:
if
len
(
fields
)
<
2
:
raise
ValueError
(
'Too few fields in [ exclusions ] line: '
+
line
);
raise
ValueError
(
'Too few fields in [ exclusions ] line: '
+
line
);
self
.
_currentMoleculeType
.
exclusions
.
append
(
fields
)
self
.
_currentMoleculeType
.
exclusions
.
append
(
fields
)
def
_processPair
(
self
,
line
):
def
_processPair
(
self
,
line
):
"""Process a line in the [ pairs ] category."""
"""Process a line in the [ pairs ] category."""
if
self
.
_currentMoleculeType
is
None
:
if
self
.
_currentMoleculeType
is
None
:
...
@@ -257,7 +257,7 @@ class GromacsTopFile(object):
...
@@ -257,7 +257,7 @@ class GromacsTopFile(object):
if
fields
[
2
]
!=
'1'
:
if
fields
[
2
]
!=
'1'
:
raise
ValueError
(
'Unsupported function type in [ pairs ] line: '
+
line
);
raise
ValueError
(
'Unsupported function type in [ pairs ] line: '
+
line
);
self
.
_currentMoleculeType
.
pairs
.
append
(
fields
)
self
.
_currentMoleculeType
.
pairs
.
append
(
fields
)
def
_processCmap
(
self
,
line
):
def
_processCmap
(
self
,
line
):
"""Process a line in the [ cmaps ] category."""
"""Process a line in the [ cmaps ] category."""
if
self
.
_currentMoleculeType
is
None
:
if
self
.
_currentMoleculeType
is
None
:
...
@@ -266,14 +266,14 @@ class GromacsTopFile(object):
...
@@ -266,14 +266,14 @@ class GromacsTopFile(object):
if
len
(
fields
)
<
6
:
if
len
(
fields
)
<
6
:
raise
ValueError
(
'Too few fields in [ pairs ] line: '
+
line
);
raise
ValueError
(
'Too few fields in [ pairs ] line: '
+
line
);
self
.
_currentMoleculeType
.
cmaps
.
append
(
fields
)
self
.
_currentMoleculeType
.
cmaps
.
append
(
fields
)
def
_processAtomType
(
self
,
line
):
def
_processAtomType
(
self
,
line
):
"""Process a line in the [ atomtypes ] category."""
"""Process a line in the [ atomtypes ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
if
len
(
fields
)
<
7
:
if
len
(
fields
)
<
7
:
raise
ValueError
(
'Too few fields in [ atomtypes ] line: '
+
line
);
raise
ValueError
(
'Too few fields in [ atomtypes ] line: '
+
line
);
self
.
_atomTypes
[
fields
[
0
]]
=
fields
self
.
_atomTypes
[
fields
[
0
]]
=
fields
def
_processBondType
(
self
,
line
):
def
_processBondType
(
self
,
line
):
"""Process a line in the [ bondtypes ] category."""
"""Process a line in the [ bondtypes ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
...
@@ -282,7 +282,7 @@ class GromacsTopFile(object):
...
@@ -282,7 +282,7 @@ class GromacsTopFile(object):
if
fields
[
2
]
!=
'1'
:
if
fields
[
2
]
!=
'1'
:
raise
ValueError
(
'Unsupported function type in [ bondtypes ] line: '
+
line
);
raise
ValueError
(
'Unsupported function type in [ bondtypes ] line: '
+
line
);
self
.
_bondTypes
[
tuple
(
fields
[:
2
])]
=
fields
self
.
_bondTypes
[
tuple
(
fields
[:
2
])]
=
fields
def
_processAngleType
(
self
,
line
):
def
_processAngleType
(
self
,
line
):
"""Process a line in the [ angletypes ] category."""
"""Process a line in the [ angletypes ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
...
@@ -291,7 +291,7 @@ class GromacsTopFile(object):
...
@@ -291,7 +291,7 @@ class GromacsTopFile(object):
if
fields
[
3
]
not
in
(
'1'
,
'5'
):
if
fields
[
3
]
not
in
(
'1'
,
'5'
):
raise
ValueError
(
'Unsupported function type in [ angletypes ] line: '
+
line
);
raise
ValueError
(
'Unsupported function type in [ angletypes ] line: '
+
line
);
self
.
_angleTypes
[
tuple
(
fields
[:
3
])]
=
fields
self
.
_angleTypes
[
tuple
(
fields
[:
3
])]
=
fields
def
_processDihedralType
(
self
,
line
):
def
_processDihedralType
(
self
,
line
):
"""Process a line in the [ dihedraltypes ] category."""
"""Process a line in the [ dihedraltypes ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
...
@@ -305,14 +305,14 @@ class GromacsTopFile(object):
...
@@ -305,14 +305,14 @@ class GromacsTopFile(object):
self
.
_dihedralTypes
[
key
].
append
(
fields
)
self
.
_dihedralTypes
[
key
].
append
(
fields
)
else
:
else
:
self
.
_dihedralTypes
[
key
]
=
[
fields
]
self
.
_dihedralTypes
[
key
]
=
[
fields
]
def
_processImplicitType
(
self
,
line
):
def
_processImplicitType
(
self
,
line
):
"""Process a line in the [ implicit_genborn_params ] category."""
"""Process a line in the [ implicit_genborn_params ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
if
len
(
fields
)
<
6
:
if
len
(
fields
)
<
6
:
raise
ValueError
(
'Too few fields in [ implicit_genborn_params ] line: '
+
line
);
raise
ValueError
(
'Too few fields in [ implicit_genborn_params ] line: '
+
line
);
self
.
_implicitTypes
[
fields
[
0
]]
=
fields
self
.
_implicitTypes
[
fields
[
0
]]
=
fields
def
_processPairType
(
self
,
line
):
def
_processPairType
(
self
,
line
):
"""Process a line in the [ pairtypes ] category."""
"""Process a line in the [ pairtypes ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
...
@@ -321,7 +321,7 @@ class GromacsTopFile(object):
...
@@ -321,7 +321,7 @@ class GromacsTopFile(object):
if
fields
[
2
]
!=
'1'
:
if
fields
[
2
]
!=
'1'
:
raise
ValueError
(
'Unsupported function type in [ pairtypes ] line: '
+
line
);
raise
ValueError
(
'Unsupported function type in [ pairtypes ] line: '
+
line
);
self
.
_pairTypes
[
tuple
(
fields
[:
2
])]
=
fields
self
.
_pairTypes
[
tuple
(
fields
[:
2
])]
=
fields
def
_processCmapType
(
self
,
line
):
def
_processCmapType
(
self
,
line
):
"""Process a line in the [ cmaptypes ] category."""
"""Process a line in the [ cmaptypes ] category."""
fields
=
line
.
split
()
fields
=
line
.
split
()
...
@@ -330,10 +330,10 @@ class GromacsTopFile(object):
...
@@ -330,10 +330,10 @@ class GromacsTopFile(object):
if
fields
[
5
]
!=
'1'
:
if
fields
[
5
]
!=
'1'
:
raise
ValueError
(
'Unsupported function type in [ cmaptypes ] line: '
+
line
);
raise
ValueError
(
'Unsupported function type in [ cmaptypes ] line: '
+
line
);
self
.
_cmapTypes
[
tuple
(
fields
[:
5
])]
=
fields
self
.
_cmapTypes
[
tuple
(
fields
[:
5
])]
=
fields
def
__init__
(
self
,
file
,
unitCellDimensions
=
None
,
includeDir
=
'/usr/local/gromacs/share/gromacs/top'
,
defines
=
{}):
def
__init__
(
self
,
file
,
unitCellDimensions
=
None
,
includeDir
=
'/usr/local/gromacs/share/gromacs/top'
,
defines
=
{}):
"""Load a top file.
"""Load a top file.
Parameters:
Parameters:
- file (string) the name of the file to load
- file (string) the name of the file to load
- unitCellDimensions (Vec3=None) the dimensions of the crystallographic unit cell
- unitCellDimensions (Vec3=None) the dimensions of the crystallographic unit cell
...
@@ -343,9 +343,9 @@ class GromacsTopFile(object):
...
@@ -343,9 +343,9 @@ class GromacsTopFile(object):
"""
"""
self
.
_includeDirs
=
(
os
.
path
.
dirname
(
file
),
includeDir
)
self
.
_includeDirs
=
(
os
.
path
.
dirname
(
file
),
includeDir
)
self
.
_defines
=
defines
self
.
_defines
=
defines
# Parse the file.
# Parse the file.
self
.
_currentCategory
=
None
self
.
_currentCategory
=
None
self
.
_ifStack
=
[]
self
.
_ifStack
=
[]
self
.
_moleculeTypes
=
{}
self
.
_moleculeTypes
=
{}
...
@@ -359,9 +359,9 @@ class GromacsTopFile(object):
...
@@ -359,9 +359,9 @@ class GromacsTopFile(object):
self
.
_pairTypes
=
{}
self
.
_pairTypes
=
{}
self
.
_cmapTypes
=
{}
self
.
_cmapTypes
=
{}
self
.
_processFile
(
file
)
self
.
_processFile
(
file
)
# Create the Topology from it.
# Create the Topology from it.
top
=
Topology
()
top
=
Topology
()
## The Topology read from the prmtop file
## The Topology read from the prmtop file
self
.
topology
=
top
self
.
topology
=
top
...
@@ -371,9 +371,9 @@ class GromacsTopFile(object):
...
@@ -371,9 +371,9 @@ class GromacsTopFile(object):
if
moleculeName
not
in
self
.
_moleculeTypes
:
if
moleculeName
not
in
self
.
_moleculeTypes
:
raise
ValueError
(
"Unknown molecule type: "
+
moleculeName
)
raise
ValueError
(
"Unknown molecule type: "
+
moleculeName
)
moleculeType
=
self
.
_moleculeTypes
[
moleculeName
]
moleculeType
=
self
.
_moleculeTypes
[
moleculeName
]
# Create the specified number of molecules of this type.
# Create the specified number of molecules of this type.
for
i
in
range
(
moleculeCount
):
for
i
in
range
(
moleculeCount
):
atoms
=
[]
atoms
=
[]
lastResidue
=
None
lastResidue
=
None
...
@@ -393,9 +393,9 @@ class GromacsTopFile(object):
...
@@ -393,9 +393,9 @@ class GromacsTopFile(object):
atomName
=
fields
[
4
]
atomName
=
fields
[
4
]
if
atomName
in
atomReplacements
:
if
atomName
in
atomReplacements
:
atomName
=
atomReplacements
[
atomName
]
atomName
=
atomReplacements
[
atomName
]
# Try to guess the element.
# Try to guess the element.
upper
=
atomName
.
upper
()
upper
=
atomName
.
upper
()
if
upper
.
startswith
(
'CL'
):
if
upper
.
startswith
(
'CL'
):
element
=
elem
.
chlorine
element
=
elem
.
chlorine
...
@@ -409,16 +409,16 @@ class GromacsTopFile(object):
...
@@ -409,16 +409,16 @@ class GromacsTopFile(object):
except
KeyError
:
except
KeyError
:
element
=
None
element
=
None
atoms
.
append
(
top
.
addAtom
(
atomName
,
element
,
r
))
atoms
.
append
(
top
.
addAtom
(
atomName
,
element
,
r
))
# Add bonds to the topology
# Add bonds to the topology
for
fields
in
moleculeType
.
bonds
:
for
fields
in
moleculeType
.
bonds
:
top
.
addBond
(
atoms
[
int
(
fields
[
0
])
-
1
],
atoms
[
int
(
fields
[
1
])
-
1
])
top
.
addBond
(
atoms
[
int
(
fields
[
0
])
-
1
],
atoms
[
int
(
fields
[
1
])
-
1
])
def
createSystem
(
self
,
nonbondedMethod
=
ff
.
NoCutoff
,
nonbondedCutoff
=
1.0
*
unit
.
nanometer
,
def
createSystem
(
self
,
nonbondedMethod
=
ff
.
NoCutoff
,
nonbondedCutoff
=
1.0
*
unit
.
nanometer
,
constraints
=
None
,
rigidWater
=
True
,
implicitSolvent
=
None
,
soluteDielectric
=
1.0
,
solventDielectric
=
78.5
,
ewaldErrorTolerance
=
0.0005
,
removeCMMotion
=
True
):
constraints
=
None
,
rigidWater
=
True
,
implicitSolvent
=
None
,
soluteDielectric
=
1.0
,
solventDielectric
=
78.5
,
ewaldErrorTolerance
=
0.0005
,
removeCMMotion
=
True
):
"""Construct an OpenMM System representing the topology described by this prmtop file.
"""Construct an OpenMM System representing the topology described by this prmtop file.
Parameters:
Parameters:
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
...
@@ -434,7 +434,7 @@ class GromacsTopFile(object):
...
@@ -434,7 +434,7 @@ class GromacsTopFile(object):
Returns: the newly created System
Returns: the newly created System
"""
"""
# Create the System.
# Create the System.
sys
=
mm
.
System
()
sys
=
mm
.
System
()
boxSize
=
self
.
topology
.
getUnitCellDimensions
()
boxSize
=
self
.
topology
.
getUnitCellDimensions
()
if
boxSize
is
not
None
:
if
boxSize
is
not
None
:
...
@@ -462,33 +462,33 @@ class GromacsTopFile(object):
...
@@ -462,33 +462,33 @@ class GromacsTopFile(object):
topologyAtoms
=
list
(
self
.
topology
.
atoms
())
topologyAtoms
=
list
(
self
.
topology
.
atoms
())
exceptions
=
[]
exceptions
=
[]
fudgeQQ
=
float
(
self
.
_defaults
[
4
])
fudgeQQ
=
float
(
self
.
_defaults
[
4
])
# Loop over molecules and create the specified number of each type.
# Loop over molecules and create the specified number of each type.
for
moleculeName
,
moleculeCount
in
self
.
_molecules
:
for
moleculeName
,
moleculeCount
in
self
.
_molecules
:
moleculeType
=
self
.
_moleculeTypes
[
moleculeName
]
moleculeType
=
self
.
_moleculeTypes
[
moleculeName
]
for
i
in
range
(
moleculeCount
):
for
i
in
range
(
moleculeCount
):
# Record the types of all atoms.
# Record the types of all atoms.
baseAtomIndex
=
sys
.
getNumParticles
()
baseAtomIndex
=
sys
.
getNumParticles
()
atomTypes
=
[
atom
[
1
]
for
atom
in
moleculeType
.
atoms
]
atomTypes
=
[
atom
[
1
]
for
atom
in
moleculeType
.
atoms
]
try
:
try
:
[
self
.
_atomTypes
[
t
][
1
]
for
t
in
atomTypes
]
[
self
.
_atomTypes
[
t
][
1
]
for
t
in
atomTypes
]
except
KeyError
as
e
:
except
KeyError
as
e
:
raise
ValueError
(
'Unknown atom type: '
+
e
.
message
)
raise
ValueError
(
'Unknown atom type: '
+
e
.
message
)
# Add atoms.
# Add atoms.
for
fields
in
moleculeType
.
atoms
:
for
fields
in
moleculeType
.
atoms
:
if
len
(
fields
)
>=
8
:
if
len
(
fields
)
>=
8
:
mass
=
float
(
fields
[
7
])
mass
=
float
(
fields
[
7
])
else
:
else
:
mass
=
float
(
self
.
_atomTypes
[
fields
[
1
]][
2
])
mass
=
float
(
self
.
_atomTypes
[
fields
[
1
]][
2
])
sys
.
addParticle
(
mass
)
sys
.
addParticle
(
mass
)
# Add bonds.
# Add bonds.
atomBonds
=
[{}
for
x
in
range
(
len
(
moleculeType
.
atoms
))]
atomBonds
=
[{}
for
x
in
range
(
len
(
moleculeType
.
atoms
))]
for
fields
in
moleculeType
.
bonds
:
for
fields
in
moleculeType
.
bonds
:
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
2
]]
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
2
]]
...
@@ -523,9 +523,9 @@ class GromacsTopFile(object):
...
@@ -523,9 +523,9 @@ class GromacsTopFile(object):
# Record information that will be needed for constraining angles.
# Record information that will be needed for constraining angles.
atomBonds
[
atoms
[
0
]][
atoms
[
1
]]
=
length
atomBonds
[
atoms
[
0
]][
atoms
[
1
]]
=
length
atomBonds
[
atoms
[
1
]][
atoms
[
0
]]
=
length
atomBonds
[
atoms
[
1
]][
atoms
[
0
]]
=
length
# Add angles.
# Add angles.
degToRad
=
math
.
pi
/
180
degToRad
=
math
.
pi
/
180
for
fields
in
moleculeType
.
angles
:
for
fields
in
moleculeType
.
angles
:
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
3
]]
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
3
]]
...
@@ -572,7 +572,7 @@ class GromacsTopFile(object):
...
@@ -572,7 +572,7 @@ class GromacsTopFile(object):
bonds
.
addBond
(
baseAtomIndex
+
atoms
[
0
],
baseAtomIndex
+
atoms
[
2
],
float
(
params
[
2
]),
k
)
bonds
.
addBond
(
baseAtomIndex
+
atoms
[
0
],
baseAtomIndex
+
atoms
[
2
],
float
(
params
[
2
]),
k
)
# Add torsions.
# Add torsions.
for
fields
in
moleculeType
.
dihedrals
:
for
fields
in
moleculeType
.
dihedrals
:
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
4
]]
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
4
]]
types
=
tuple
(
atomTypes
[
i
]
for
i
in
atoms
)
types
=
tuple
(
atomTypes
[
i
]
for
i
in
atoms
)
...
@@ -618,7 +618,7 @@ class GromacsTopFile(object):
...
@@ -618,7 +618,7 @@ class GromacsTopFile(object):
rb
=
mm
.
RBTorsionForce
()
rb
=
mm
.
RBTorsionForce
()
sys
.
addForce
(
rb
)
sys
.
addForce
(
rb
)
rb
.
addTorsion
(
baseAtomIndex
+
atoms
[
0
],
baseAtomIndex
+
atoms
[
1
],
baseAtomIndex
+
atoms
[
2
],
baseAtomIndex
+
atoms
[
3
],
c
[
0
],
c
[
1
],
c
[
2
],
c
[
3
],
c
[
4
],
c
[
5
])
rb
.
addTorsion
(
baseAtomIndex
+
atoms
[
0
],
baseAtomIndex
+
atoms
[
1
],
baseAtomIndex
+
atoms
[
2
],
baseAtomIndex
+
atoms
[
3
],
c
[
0
],
c
[
1
],
c
[
2
],
c
[
3
],
c
[
4
],
c
[
5
])
# Add CMAP terms.
# Add CMAP terms.
for
fields
in
moleculeType
.
cmaps
:
for
fields
in
moleculeType
.
cmaps
:
...
@@ -649,7 +649,7 @@ class GromacsTopFile(object):
...
@@ -649,7 +649,7 @@ class GromacsTopFile(object):
baseAtomIndex
+
atoms
[
1
],
baseAtomIndex
+
atoms
[
2
],
baseAtomIndex
+
atoms
[
3
],
baseAtomIndex
+
atoms
[
4
])
baseAtomIndex
+
atoms
[
1
],
baseAtomIndex
+
atoms
[
2
],
baseAtomIndex
+
atoms
[
3
],
baseAtomIndex
+
atoms
[
4
])
# Set nonbonded parameters for particles.
# Set nonbonded parameters for particles.
for
fields
in
moleculeType
.
atoms
:
for
fields
in
moleculeType
.
atoms
:
params
=
self
.
_atomTypes
[
fields
[
1
]]
params
=
self
.
_atomTypes
[
fields
[
1
]]
if
len
(
fields
)
>
6
:
if
len
(
fields
)
>
6
:
...
@@ -665,9 +665,9 @@ class GromacsTopFile(object):
...
@@ -665,9 +665,9 @@ class GromacsTopFile(object):
for
fields
in
moleculeType
.
bonds
:
for
fields
in
moleculeType
.
bonds
:
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
2
]]
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
2
]]
bondIndices
.
append
((
baseAtomIndex
+
atoms
[
0
],
baseAtomIndex
+
atoms
[
1
]))
bondIndices
.
append
((
baseAtomIndex
+
atoms
[
0
],
baseAtomIndex
+
atoms
[
1
]))
# Record nonbonded exceptions.
# Record nonbonded exceptions.
for
fields
in
moleculeType
.
pairs
:
for
fields
in
moleculeType
.
pairs
:
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
2
]]
atoms
=
[
int
(
x
)
-
1
for
x
in
fields
[:
2
]]
types
=
tuple
(
atomTypes
[
i
]
for
i
in
atoms
)
types
=
tuple
(
atomTypes
[
i
]
for
i
in
atoms
)
...
@@ -682,15 +682,15 @@ class GromacsTopFile(object):
...
@@ -682,15 +682,15 @@ class GromacsTopFile(object):
atom1params
=
nb
.
getParticleParameters
(
baseAtomIndex
+
atoms
[
0
])
atom1params
=
nb
.
getParticleParameters
(
baseAtomIndex
+
atoms
[
0
])
atom2params
=
nb
.
getParticleParameters
(
baseAtomIndex
+
atoms
[
1
])
atom2params
=
nb
.
getParticleParameters
(
baseAtomIndex
+
atoms
[
1
])
exceptions
.
append
((
baseAtomIndex
+
atoms
[
0
],
baseAtomIndex
+
atoms
[
1
],
atom1params
[
0
]
*
atom2params
[
0
]
*
fudgeQQ
,
params
[
0
],
params
[
1
]))
exceptions
.
append
((
baseAtomIndex
+
atoms
[
0
],
baseAtomIndex
+
atoms
[
1
],
atom1params
[
0
]
*
atom2params
[
0
]
*
fudgeQQ
,
params
[
0
],
params
[
1
]))
# Create nonbonded exceptions.
# Create nonbonded exceptions.
nb
.
createExceptionsFromBonds
(
bondIndices
,
fudgeQQ
,
float
(
self
.
_defaults
[
3
]))
nb
.
createExceptionsFromBonds
(
bondIndices
,
fudgeQQ
,
float
(
self
.
_defaults
[
3
]))
for
exception
in
exceptions
:
for
exception
in
exceptions
:
nb
.
addException
(
exception
[
0
],
exception
[
1
],
exception
[
2
],
float
(
exception
[
3
]),
float
(
exception
[
4
]),
True
)
nb
.
addException
(
exception
[
0
],
exception
[
1
],
exception
[
2
],
float
(
exception
[
3
]),
float
(
exception
[
4
]),
True
)
# Finish configuring the NonbondedForce.
# Finish configuring the NonbondedForce.
methodMap
=
{
ff
.
NoCutoff
:
mm
.
NonbondedForce
.
NoCutoff
,
methodMap
=
{
ff
.
NoCutoff
:
mm
.
NonbondedForce
.
NoCutoff
,
ff
.
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
ff
.
CutoffNonPeriodic
:
mm
.
NonbondedForce
.
CutoffNonPeriodic
,
ff
.
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
,
ff
.
CutoffPeriodic
:
mm
.
NonbondedForce
.
CutoffPeriodic
,
...
...
wrappers/python/simtk/openmm/app/internal/amber_file_parser.py
View file @
4941cc7d
...
@@ -16,7 +16,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
...
@@ -16,7 +16,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
Authors: Randall J. Radmer, John D. Chodera, Peter Eastman
Authors: Randall J. Radmer, John D. Chodera, Peter Eastman
Contributors: Christoph Klein, Michael R. Shirts
Contributors: Christoph Klein, Michael R. Shirts
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -92,7 +92,7 @@ class PrmtopLoader(object):
...
@@ -92,7 +92,7 @@ class PrmtopLoader(object):
>>> import os, os.path
>>> import os, os.path
>>> directory = os.path.join(os.getenv('YANK_INSTALL_DIR'), 'test', 'systems', 'alanine-dipeptide-explicit')
>>> directory = os.path.join(os.getenv('YANK_INSTALL_DIR'), 'test', 'systems', 'alanine-dipeptide-explicit')
>>> prmtop_filename = os.path.join(directory, 'alanine-dipeptide.prmtop')
>>> prmtop_filename = os.path.join(directory, 'alanine-dipeptide.prmtop')
>>> prmtop = PrmtopLoader(prmtop_filename)
>>> prmtop = PrmtopLoader(prmtop_filename)
"""
"""
def
__init__
(
self
,
inFilename
):
def
__init__
(
self
,
inFilename
):
...
@@ -101,7 +101,7 @@ class PrmtopLoader(object):
...
@@ -101,7 +101,7 @@ class PrmtopLoader(object):
ARGUMENTS
ARGUMENTS
inFilename (string) - AMBER 'new-style' prmtop file, probably generated with one of the AMBER tleap/xleap/sleap
inFilename (string) - AMBER 'new-style' prmtop file, probably generated with one of the AMBER tleap/xleap/sleap
"""
"""
...
@@ -152,7 +152,7 @@ class PrmtopLoader(object):
...
@@ -152,7 +152,7 @@ class PrmtopLoader(object):
Parameter:
Parameter:
- pointerLabel: a string matching one of the following:
- pointerLabel: a string matching one of the following:
NATOM : total number of atoms
NATOM : total number of atoms
NTYPES : total number of distinct atom types
NTYPES : total number of distinct atom types
NBONH : number of bonds containing hydrogen
NBONH : number of bonds containing hydrogen
MBONA : number of bonds not containing hydrogen
MBONA : number of bonds not containing hydrogen
...
@@ -183,7 +183,7 @@ class PrmtopLoader(object):
...
@@ -183,7 +183,7 @@ class PrmtopLoader(object):
NMXRS : number of atoms in the largest residue
NMXRS : number of atoms in the largest residue
IFCAP : set to 1 if the CAP option from edit was specified
IFCAP : set to 1 if the CAP option from edit was specified
"""
"""
index
=
POINTER_LABEL_LIST
.
index
(
pointerLabel
)
index
=
POINTER_LABEL_LIST
.
index
(
pointerLabel
)
return
float
(
self
.
_raw_data
[
'POINTERS'
][
index
])
return
float
(
self
.
_raw_data
[
'POINTERS'
][
index
])
def
getNumAtoms
(
self
):
def
getNumAtoms
(
self
):
...
@@ -350,7 +350,7 @@ class PrmtopLoader(object):
...
@@ -350,7 +350,7 @@ class PrmtopLoader(object):
bondPointers
=
self
.
_raw_data
[
"BONDS_INC_HYDROGEN"
]
bondPointers
=
self
.
_raw_data
[
"BONDS_INC_HYDROGEN"
]
self
.
_bondListWithH
=
self
.
_getBonds
(
bondPointers
)
self
.
_bondListWithH
=
self
.
_getBonds
(
bondPointers
)
return
self
.
_bondListWithH
return
self
.
_bondListWithH
def
getBondsNoH
(
self
):
def
getBondsNoH
(
self
):
"""Return list of bonded atom pairs, K, and Rmin for each bond with no hydrogen"""
"""Return list of bonded atom pairs, K, and Rmin for each bond with no hydrogen"""
...
@@ -509,11 +509,11 @@ class PrmtopLoader(object):
...
@@ -509,11 +509,11 @@ class PrmtopLoader(object):
def
readAmberSystem
(
prmtop_filename
=
None
,
prmtop_loader
=
None
,
shake
=
None
,
gbmodel
=
None
,
soluteDielectric
=
1.0
,
solventDielectric
=
78.5
,
nonbondedCutoff
=
None
,
nonbondedMethod
=
'NoCutoff'
,
scee
=
1.2
,
scnb
=
2.0
,
mm
=
None
,
verbose
=
False
,
EwaldErrorTolerance
=
None
,
flexibleConstraints
=
True
,
rigidWater
=
True
):
def
readAmberSystem
(
prmtop_filename
=
None
,
prmtop_loader
=
None
,
shake
=
None
,
gbmodel
=
None
,
soluteDielectric
=
1.0
,
solventDielectric
=
78.5
,
nonbondedCutoff
=
None
,
nonbondedMethod
=
'NoCutoff'
,
scee
=
1.2
,
scnb
=
2.0
,
mm
=
None
,
verbose
=
False
,
EwaldErrorTolerance
=
None
,
flexibleConstraints
=
True
,
rigidWater
=
True
):
"""
"""
Create an OpenMM System from an Amber prmtop file.
Create an OpenMM System from an Amber prmtop file.
ARGUMENTS (specify one or the other, but not both)
ARGUMENTS (specify one or the other, but not both)
prmtop_filename (String) - name of Amber prmtop file (new-style only)
prmtop_filename (String) - name of Amber prmtop file (new-style only)
prmtop_loader (PrmtopLoader) - the loaded prmtop file
prmtop_loader (PrmtopLoader) - the loaded prmtop file
OPTIONAL ARGUMENTS
OPTIONAL ARGUMENTS
shake (String) - if 'h-bonds', will SHAKE all bonds to hydrogen and water; if 'all-bonds', will SHAKE all bonds and water (default: None)
shake (String) - if 'h-bonds', will SHAKE all bonds to hydrogen and water; if 'all-bonds', will SHAKE all bonds and water (default: None)
gbmodel (String) - if 'OBC', OBC GBSA will be used; if 'GBVI', GB/VI will be used (default: None)
gbmodel (String) - if 'OBC', OBC GBSA will be used; if 'GBVI', GB/VI will be used (default: None)
...
@@ -547,10 +547,10 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -547,10 +547,10 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
>>> directory = os.path.join(os.getenv('YANK_INSTALL_DIR'), 'test', 'systems', 'alanine-dipeptide-explicit')
>>> directory = os.path.join(os.getenv('YANK_INSTALL_DIR'), 'test', 'systems', 'alanine-dipeptide-explicit')
>>> prmtop_filename = os.path.join(directory, 'alanine-dipeptide.prmtop')
>>> prmtop_filename = os.path.join(directory, 'alanine-dipeptide.prmtop')
>>> system = readAmberSystem(prmtop_filename)
>>> system = readAmberSystem(prmtop_filename)
"""
"""
if
prmtop_filename
is
None
and
prmtop_loader
is
None
:
if
prmtop_filename
is
None
and
prmtop_loader
is
None
:
raise
Exception
(
"Must specify a filename or loader"
)
raise
Exception
(
"Must specify a filename or loader"
)
if
prmtop_filename
is
not
None
and
prmtop_loader
is
not
None
:
if
prmtop_filename
is
not
None
and
prmtop_loader
is
not
None
:
...
@@ -567,7 +567,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -567,7 +567,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
if
prmtop
.
getIfPert
()
>
0
:
if
prmtop
.
getIfPert
()
>
0
:
raise
Exception
(
"perturbation not currently supported"
)
raise
Exception
(
"perturbation not currently supported"
)
if
prmtop
.
getIfBox
()
>
1
:
if
prmtop
.
getIfBox
()
>
1
:
raise
Exception
(
"only standard periodic boxes are currently supported"
)
raise
Exception
(
"only standard periodic boxes are currently supported"
)
...
@@ -596,9 +596,9 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -596,9 +596,9 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
for
(
iAtom
,
jAtom
,
k
,
rMin
)
in
prmtop
.
getBondsWithH
():
for
(
iAtom
,
jAtom
,
k
,
rMin
)
in
prmtop
.
getBondsWithH
():
if
isWater
[
iAtom
]
and
isWater
[
jAtom
]:
if
isWater
[
iAtom
]
and
isWater
[
jAtom
]:
system
.
addConstraint
(
iAtom
,
jAtom
,
rMin
)
system
.
addConstraint
(
iAtom
,
jAtom
,
rMin
)
# Add harmonic bonds.
# Add harmonic bonds.
if
verbose
:
print
"Adding bonds..."
if
verbose
:
print
"Adding bonds..."
force
=
mm
.
HarmonicBondForce
()
force
=
mm
.
HarmonicBondForce
()
if
flexibleConstraints
or
(
shake
not
in
(
'h-bonds'
,
'all-bonds'
,
'h-angles'
)):
if
flexibleConstraints
or
(
shake
not
in
(
'h-bonds'
,
'all-bonds'
,
'h-angles'
)):
for
(
iAtom
,
jAtom
,
k
,
rMin
)
in
prmtop
.
getBondsWithH
():
for
(
iAtom
,
jAtom
,
k
,
rMin
)
in
prmtop
.
getBondsWithH
():
...
@@ -610,7 +610,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -610,7 +610,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
system
.
addForce
(
force
)
system
.
addForce
(
force
)
# Add harmonic angles.
# Add harmonic angles.
if
verbose
:
print
"Adding angles..."
if
verbose
:
print
"Adding angles..."
force
=
mm
.
HarmonicAngleForce
()
force
=
mm
.
HarmonicAngleForce
()
if
shake
==
'h-angles'
:
if
shake
==
'h-angles'
:
numConstrainedBonds
=
system
.
getNumConstraints
()
numConstrainedBonds
=
system
.
getNumConstraints
()
...
@@ -638,7 +638,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -638,7 +638,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
l1
=
bond
[
1
]
l1
=
bond
[
1
]
elif
bond
[
0
]
==
kAtom
:
elif
bond
[
0
]
==
kAtom
:
l2
=
bond
[
1
]
l2
=
bond
[
1
]
# Compute the distance between atoms and add a constraint
# Compute the distance between atoms and add a constraint
length
=
math
.
sqrt
(
l1
*
l1
+
l2
*
l2
-
2
*
l1
*
l2
*
math
.
cos
(
aMin
))
length
=
math
.
sqrt
(
l1
*
l1
+
l2
*
l2
-
2
*
l1
*
l2
*
math
.
cos
(
aMin
))
system
.
addConstraint
(
iAtom
,
kAtom
,
length
)
system
.
addConstraint
(
iAtom
,
kAtom
,
length
)
...
@@ -647,14 +647,14 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -647,14 +647,14 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
system
.
addForce
(
force
)
system
.
addForce
(
force
)
# Add torsions.
# Add torsions.
if
verbose
:
print
"Adding torsions..."
if
verbose
:
print
"Adding torsions..."
force
=
mm
.
PeriodicTorsionForce
()
force
=
mm
.
PeriodicTorsionForce
()
for
(
iAtom
,
jAtom
,
kAtom
,
lAtom
,
forceConstant
,
phase
,
periodicity
)
in
prmtop
.
getDihedrals
():
for
(
iAtom
,
jAtom
,
kAtom
,
lAtom
,
forceConstant
,
phase
,
periodicity
)
in
prmtop
.
getDihedrals
():
force
.
addTorsion
(
iAtom
,
jAtom
,
kAtom
,
lAtom
,
periodicity
,
phase
,
forceConstant
)
force
.
addTorsion
(
iAtom
,
jAtom
,
kAtom
,
lAtom
,
periodicity
,
phase
,
forceConstant
)
system
.
addForce
(
force
)
system
.
addForce
(
force
)
# Add nonbonded interactions.
# Add nonbonded interactions.
if
verbose
:
print
"Adding nonbonded interactions..."
if
verbose
:
print
"Adding nonbonded interactions..."
force
=
mm
.
NonbondedForce
()
force
=
mm
.
NonbondedForce
()
if
(
prmtop
.
getIfBox
()
==
0
):
if
(
prmtop
.
getIfBox
()
==
0
):
# System is non-periodic.
# System is non-periodic.
...
@@ -663,12 +663,12 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -663,12 +663,12 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
elif
nonbondedMethod
==
'CutoffNonPeriodic'
:
elif
nonbondedMethod
==
'CutoffNonPeriodic'
:
if
nonbondedCutoff
is
None
:
if
nonbondedCutoff
is
None
:
raise
Exception
(
"No cutoff value specified"
)
raise
Exception
(
"No cutoff value specified"
)
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
CutoffNonPeriodic
)
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
CutoffNonPeriodic
)
force
.
setCutoffDistance
(
nonbondedCutoff
)
force
.
setCutoffDistance
(
nonbondedCutoff
)
else
:
else
:
raise
Exception
(
"Illegal nonbonded method for a non-periodic system"
)
raise
Exception
(
"Illegal nonbonded method for a non-periodic system"
)
else
:
else
:
# System is periodic.
# System is periodic.
# Set periodic box vectors for periodic system
# Set periodic box vectors for periodic system
(
boxBeta
,
boxX
,
boxY
,
boxZ
)
=
prmtop
.
getBoxBetaAndDimensions
()
(
boxBeta
,
boxX
,
boxY
,
boxZ
)
=
prmtop
.
getBoxBetaAndDimensions
()
d0
=
units
.
Quantity
(
0.0
,
units
.
angstroms
)
d0
=
units
.
Quantity
(
0.0
,
units
.
angstroms
)
...
@@ -676,16 +676,16 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -676,16 +676,16 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
yVec
=
units
.
Quantity
((
d0
,
boxY
,
d0
))
yVec
=
units
.
Quantity
((
d0
,
boxY
,
d0
))
zVec
=
units
.
Quantity
((
d0
,
d0
,
boxZ
))
zVec
=
units
.
Quantity
((
d0
,
d0
,
boxZ
))
system
.
setDefaultPeriodicBoxVectors
(
xVec
,
yVec
,
zVec
)
system
.
setDefaultPeriodicBoxVectors
(
xVec
,
yVec
,
zVec
)
# Set cutoff.
# Set cutoff.
if
nonbondedCutoff
is
None
:
if
nonbondedCutoff
is
None
:
# Compute cutoff automatically.
# Compute cutoff automatically.
min_box_width
=
min
([
boxX
/
units
.
nanometers
,
boxY
/
units
.
nanometers
,
boxZ
/
units
.
nanometers
])
min_box_width
=
min
([
boxX
/
units
.
nanometers
,
boxY
/
units
.
nanometers
,
boxZ
/
units
.
nanometers
])
CLEARANCE_FACTOR
=
0.97
# reduce the cutoff to be a bit smaller than 1/2 smallest box length
CLEARANCE_FACTOR
=
0.97
# reduce the cutoff to be a bit smaller than 1/2 smallest box length
nonbondedCutoff
=
units
.
Quantity
((
min_box_width
*
CLEARANCE_FACTOR
)
/
2.0
,
units
.
nanometers
)
nonbondedCutoff
=
units
.
Quantity
((
min_box_width
*
CLEARANCE_FACTOR
)
/
2.0
,
units
.
nanometers
)
if
nonbondedMethod
!=
'NoCutoff'
:
if
nonbondedMethod
!=
'NoCutoff'
:
force
.
setCutoffDistance
(
nonbondedCutoff
)
force
.
setCutoffDistance
(
nonbondedCutoff
)
# Set nonbonded method.
# Set nonbonded method.
if
nonbondedMethod
==
'NoCutoff'
:
if
nonbondedMethod
==
'NoCutoff'
:
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
NoCutoff
)
force
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
NoCutoff
)
...
@@ -724,7 +724,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -724,7 +724,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
excludeParams
=
(
0.0
,
0.1
,
0.0
)
excludeParams
=
(
0.0
,
0.1
,
0.0
)
for
iAtom
in
range
(
prmtop
.
getNumAtoms
()):
for
iAtom
in
range
(
prmtop
.
getNumAtoms
()):
for
jAtom
in
excludedAtoms
[
iAtom
]:
for
jAtom
in
excludedAtoms
[
iAtom
]:
if
min
((
iAtom
,
jAtom
),
(
jAtom
,
iAtom
))
in
excludedAtomPairs
:
continue
if
min
((
iAtom
,
jAtom
),
(
jAtom
,
iAtom
))
in
excludedAtomPairs
:
continue
force
.
addException
(
iAtom
,
jAtom
,
excludeParams
[
0
],
excludeParams
[
1
],
excludeParams
[
2
])
force
.
addException
(
iAtom
,
jAtom
,
excludeParams
[
0
],
excludeParams
[
1
],
excludeParams
[
2
])
system
.
addForce
(
force
)
system
.
addForce
(
force
)
...
@@ -812,7 +812,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -812,7 +812,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
if
gbmodel
==
'OBC2'
:
if
gbmodel
==
'OBC2'
:
gb
.
addParticle
(
charges
[
iAtom
],
gb_parms
[
iAtom
][
0
],
gb_parms
[
iAtom
][
1
])
gb
.
addParticle
(
charges
[
iAtom
],
gb_parms
[
iAtom
][
0
],
gb_parms
[
iAtom
][
1
])
else
:
else
:
gb
.
addParticle
([
charges
[
iAtom
],
gb_parms
[
iAtom
][
0
],
gb_parms
[
iAtom
][
1
]])
gb
.
addParticle
([
charges
[
iAtom
],
gb_parms
[
iAtom
][
0
],
gb_parms
[
iAtom
][
1
]])
system
.
addForce
(
gb
)
system
.
addForce
(
gb
)
if
nonbondedMethod
==
'NoCutoff'
:
if
nonbondedMethod
==
'NoCutoff'
:
gb
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
NoCutoff
)
gb
.
setNonbondedMethod
(
mm
.
NonbondedForce
.
NoCutoff
)
...
@@ -836,7 +836,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -836,7 +836,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
def
readAmberCoordinates
(
filename
,
read_box
=
False
,
read_velocities
=
False
,
verbose
=
False
,
asNumpy
=
False
):
def
readAmberCoordinates
(
filename
,
read_box
=
False
,
read_velocities
=
False
,
verbose
=
False
,
asNumpy
=
False
):
"""
"""
Read atomic coordinates (and optionally, box vectors) from Amber formatted coordinate file.
Read atomic coordinates (and optionally, box vectors) from Amber formatted coordinate file.
ARGUMENTS
ARGUMENTS
...
@@ -853,13 +853,13 @@ def readAmberCoordinates(filename, read_box=False, read_velocities=False, verbos
...
@@ -853,13 +853,13 @@ def readAmberCoordinates(filename, read_box=False, read_velocities=False, verbos
Read coordinates in vacuum.
Read coordinates in vacuum.
>>> directory = os.path.join(os.getenv('YANK_INSTALL_DIR'), 'test', 'systems', 'alanine-dipeptide-gbsa')
>>> directory = os.path.join(os.getenv('YANK_INSTALL_DIR'), 'test', 'systems', 'alanine-dipeptide-gbsa')
>>> crd_filename = os.path.join(directory, 'alanine-dipeptide.inpcrd')
>>> crd_filename = os.path.join(directory, 'alanine-dipeptide.inpcrd')
>>> coordinates = readAmberCoordinates(crd_filename)
>>> coordinates = readAmberCoordinates(crd_filename)
Read coordinates in solvent.
Read coordinates in solvent.
>>> directory = os.path.join(os.getenv('YANK_INSTALL_DIR'), 'test', 'systems', 'alanine-dipeptide-explicit')
>>> directory = os.path.join(os.getenv('YANK_INSTALL_DIR'), 'test', 'systems', 'alanine-dipeptide-explicit')
>>> crd_filename = os.path.join(directory, 'alanine-dipeptide.inpcrd')
>>> crd_filename = os.path.join(directory, 'alanine-dipeptide.inpcrd')
>>> [coordinates, box_vectors] = readAmberCoordinates(crd_filename, read_box=True)
>>> [coordinates, box_vectors] = readAmberCoordinates(crd_filename, read_box=True)
"""
"""
...
@@ -922,7 +922,7 @@ def readAmberCoordinates(filename, read_box=False, read_velocities=False, verbos
...
@@ -922,7 +922,7 @@ def readAmberCoordinates(filename, read_box=False, read_velocities=False, verbos
velocities
=
newvel
velocities
=
newvel
# Assign units.
# Assign units.
velocities
=
units
.
Quantity
(
velocities
,
units
.
angstroms
/
units
.
picoseconds
)
velocities
=
units
.
Quantity
(
velocities
,
units
.
angstroms
/
units
.
picoseconds
)
# Read box size if present
# Read box size if present
box_vectors
=
None
box_vectors
=
None
if
(
read_box
):
if
(
read_box
):
...
@@ -944,20 +944,20 @@ def readAmberCoordinates(filename, read_box=False, read_velocities=False, verbos
...
@@ -944,20 +944,20 @@ def readAmberCoordinates(filename, read_box=False, read_velocities=False, verbos
else
:
else
:
a
=
units
.
Quantity
(
mm
.
Vec3
(
box_dimensions
[
0
],
0.0
,
0.0
),
units
.
angstroms
)
a
=
units
.
Quantity
(
mm
.
Vec3
(
box_dimensions
[
0
],
0.0
,
0.0
),
units
.
angstroms
)
b
=
units
.
Quantity
(
mm
.
Vec3
(
0.0
,
box_dimensions
[
1
],
0.0
),
units
.
angstroms
)
b
=
units
.
Quantity
(
mm
.
Vec3
(
0.0
,
box_dimensions
[
1
],
0.0
),
units
.
angstroms
)
c
=
units
.
Quantity
(
mm
.
Vec3
(
0.0
,
0.0
,
box_dimensions
[
2
]),
units
.
angstroms
)
c
=
units
.
Quantity
(
mm
.
Vec3
(
0.0
,
0.0
,
box_dimensions
[
2
]),
units
.
angstroms
)
box_vectors
=
[
a
,
b
,
c
]
box_vectors
=
[
a
,
b
,
c
]
else
:
else
:
raise
Exception
(
"Don't know what to do with box vectors: %s"
%
line
)
raise
Exception
(
"Don't know what to do with box vectors: %s"
%
line
)
# Close file
# Close file
infile
.
close
()
infile
.
close
()
if
box_vectors
and
velocities
:
if
box_vectors
and
velocities
:
return
(
coordinates
,
box_vectors
,
velocities
)
return
(
coordinates
,
box_vectors
,
velocities
)
if
box_vectors
:
if
box_vectors
:
return
(
coordinates
,
box_vectors
)
return
(
coordinates
,
box_vectors
)
if
velocities
:
if
velocities
:
return
(
coordinates
,
velocities
)
return
(
coordinates
,
velocities
)
return
coordinates
return
coordinates
#=============================================================================================
#=============================================================================================
...
...
wrappers/python/simtk/openmm/app/internal/customgbforces.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 University of Virginia and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 University of Virginia and the Authors.
Authors: Christoph Klein, Michael R. Shirts
Authors: Christoph Klein, Michael R. Shirts
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -35,15 +35,15 @@ import sys, pdb, pickle
...
@@ -35,15 +35,15 @@ import sys, pdb, pickle
d0
=
[
2.26685
,
2.32548
,
2.38397
,
2.44235
,
2.50057
,
2.55867
,
2.61663
,
2.67444
,
d0
=
[
2.26685
,
2.32548
,
2.38397
,
2.44235
,
2.50057
,
2.55867
,
2.61663
,
2.67444
,
2.73212
,
2.78965
,
2.84705
,
2.9043
,
2.96141
,
3.0184
,
3.07524
,
3.13196
,
2.73212
,
2.78965
,
2.84705
,
2.9043
,
2.96141
,
3.0184
,
3.07524
,
3.13196
,
3.18854
,
3.24498
,
3.30132
,
3.35752
,
3.4136
,
3.18854
,
3.24498
,
3.30132
,
3.35752
,
3.4136
,
2.31191
,
2.37017
,
2.4283
,
2.48632
,
2.5442
,
2.60197
,
2.65961
,
2.71711
,
2.31191
,
2.37017
,
2.4283
,
2.48632
,
2.5442
,
2.60197
,
2.65961
,
2.71711
,
2.77449
,
2.83175
,
2.88887
,
2.94586
,
3.00273
,
3.05948
,
3.1161
,
3.1726
,
2.77449
,
2.83175
,
2.88887
,
2.94586
,
3.00273
,
3.05948
,
3.1161
,
3.1726
,
3.22897
,
3.28522
,
3.34136
,
3.39738
,
3.45072
,
3.22897
,
3.28522
,
3.34136
,
3.39738
,
3.45072
,
2.35759
,
2.41549
,
2.47329
,
2.53097
,
2.58854
,
2.646
,
2.70333
,
2.76056
,
2.35759
,
2.41549
,
2.47329
,
2.53097
,
2.58854
,
2.646
,
2.70333
,
2.76056
,
2.81766
,
2.87465
,
2.93152
,
2.98827
,
3.0449
,
3.10142
,
3.15782
,
3.21411
,
2.81766
,
2.87465
,
2.93152
,
2.98827
,
3.0449
,
3.10142
,
3.15782
,
3.21411
,
3.27028
,
3.32634
,
3.3823
,
3.43813
,
3.49387
,
3.27028
,
3.32634
,
3.3823
,
3.43813
,
3.49387
,
2.4038
,
2.46138
,
2.51885
,
2.57623
,
2.63351
,
2.69067
,
2.74773
,
2.80469
,
2.4038
,
2.46138
,
2.51885
,
2.57623
,
2.63351
,
2.69067
,
2.74773
,
2.80469
,
2.86152
,
2.91826
,
2.97489
,
3.0314
,
3.08781
,
3.1441
,
3.20031
,
3.25638
,
2.86152
,
2.91826
,
2.97489
,
3.0314
,
3.08781
,
3.1441
,
3.20031
,
3.25638
,
3.31237
,
3.36825
,
3.42402
,
3.4797
,
3.53527
,
3.31237
,
3.36825
,
3.42402
,
3.4797
,
3.53527
,
2.45045
,
2.50773
,
2.56492
,
2.62201
,
2.679
,
2.7359
,
2.7927
,
2.8494
,
2.90599
,
2.45045
,
2.50773
,
2.56492
,
2.62201
,
2.679
,
2.7359
,
2.7927
,
2.8494
,
2.90599
,
2.9625
,
3.0189
,
3.07518
,
3.13138
,
3.18748
,
3.24347
,
3.29937
,
3.35515
,
2.9625
,
3.0189
,
3.07518
,
3.13138
,
3.18748
,
3.24347
,
3.29937
,
3.35515
,
3.41085
,
3.46646
,
3.52196
,
3.57738
,
3.41085
,
3.46646
,
3.52196
,
3.57738
,
...
@@ -53,134 +53,134 @@ d0=[2.26685,2.32548,2.38397,2.44235,2.50057,2.55867,2.61663,2.67444,
...
@@ -53,134 +53,134 @@ d0=[2.26685,2.32548,2.38397,2.44235,2.50057,2.55867,2.61663,2.67444,
2.54489
,
2.60164
,
2.6583
,
2.71488
,
2.77134
,
2.8278
,
2.88412
,
2.94034
,
2.54489
,
2.60164
,
2.6583
,
2.71488
,
2.77134
,
2.8278
,
2.88412
,
2.94034
,
2.9965
,
3.05256
,
3.10853
,
3.16442
,
3.22021
,
3.27592
,
3.33154
,
3.38707
,
2.9965
,
3.05256
,
3.10853
,
3.16442
,
3.22021
,
3.27592
,
3.33154
,
3.38707
,
3.44253
,
3.49789
,
3.55316
,
3.60836
,
3.66348
,
3.44253
,
3.49789
,
3.55316
,
3.60836
,
3.66348
,
2.59259
,
2.6491
,
2.70553
,
2.76188
,
2.81815
,
2.87434
,
2.93044
,
2.98646
,
2.59259
,
2.6491
,
2.70553
,
2.76188
,
2.81815
,
2.87434
,
2.93044
,
2.98646
,
3.04241
,
3.09827
,
3.15404
,
3.20974
,
3.26536
,
3.32089
,
3.37633
,
3.4317
,
3.04241
,
3.09827
,
3.15404
,
3.20974
,
3.26536
,
3.32089
,
3.37633
,
3.4317
,
3.48699
,
3.54219
,
3.59731
,
3.65237
,
3.70734
,
3.48699
,
3.54219
,
3.59731
,
3.65237
,
3.70734
,
2.64054
,
2.69684
,
2.75305
,
2.80918
,
2.86523
,
2.92122
,
2.97712
,
3.03295
,
2.64054
,
2.69684
,
2.75305
,
2.80918
,
2.86523
,
2.92122
,
2.97712
,
3.03295
,
3.0887
,
3.14437
,
3.19996
,
3.25548
,
3.31091
,
3.36627
,
3.42156
,
3.47677
,
3.0887
,
3.14437
,
3.19996
,
3.25548
,
3.31091
,
3.36627
,
3.42156
,
3.47677
,
3.5319
,
3.58695
,
3.64193
,
3.69684
,
3.75167
,
3.5319
,
3.58695
,
3.64193
,
3.69684
,
3.75167
,
2.68873
,
2.74482
,
2.80083
,
2.85676
,
2.91262
,
2.96841
,
3.02412
,
3.07976
,
2.68873
,
2.74482
,
2.80083
,
2.85676
,
2.91262
,
2.96841
,
3.02412
,
3.07976
,
3.13533
,
3.19082
,
3.24623
,
3.30157
,
3.35685
,
3.41205
,
3.46718
,
3.52223
,
3.13533
,
3.19082
,
3.24623
,
3.30157
,
3.35685
,
3.41205
,
3.46718
,
3.52223
,
3.57721
,
3.63213
,
3.68696
,
3.74174
,
3.79644
,
3.57721
,
3.63213
,
3.68696
,
3.74174
,
3.79644
,
2.73713
,
2.79302
,
2.84884
,
2.90459
,
2.96027
,
3.01587
,
3.0714
,
3.12686
,
2.73713
,
2.79302
,
2.84884
,
2.90459
,
2.96027
,
3.01587
,
3.0714
,
3.12686
,
3.18225
,
3.23757
,
3.29282
,
3.34801
,
3.40313
,
3.45815
,
3.51315
,
3.56805
,
3.18225
,
3.23757
,
3.29282
,
3.34801
,
3.40313
,
3.45815
,
3.51315
,
3.56805
,
3.6229
,
3.67767
,
3.73237
,
3.78701
,
3.84159
,
3.6229
,
3.67767
,
3.73237
,
3.78701
,
3.84159
,
2.78572
,
2.84143
,
2.89707
,
2.95264
,
3.00813
,
3.06356
,
3.11892
,
3.17422
,
2.78572
,
2.84143
,
2.89707
,
2.95264
,
3.00813
,
3.06356
,
3.11892
,
3.17422
,
3.22946
,
3.28462
,
3.33971
,
3.39474
,
3.44971
,
3.5046
,
3.55944
,
3.61421
,
3.22946
,
3.28462
,
3.33971
,
3.39474
,
3.44971
,
3.5046
,
3.55944
,
3.61421
,
3.66891
,
3.72356
,
3.77814
,
3.83264
,
3.8871
,
3.66891
,
3.72356
,
3.77814
,
3.83264
,
3.8871
,
2.83446
,
2.89
,
2.94547
,
3.00088
,
3.05621
,
3.11147
,
3.16669
,
3.22183
,
2.83446
,
2.89
,
2.94547
,
3.00088
,
3.05621
,
3.11147
,
3.16669
,
3.22183
,
3.27689
,
3.33191
,
3.38685
,
3.44174
,
3.49656
,
3.55132
,
3.60602
,
3.66066
,
3.27689
,
3.33191
,
3.38685
,
3.44174
,
3.49656
,
3.55132
,
3.60602
,
3.66066
,
3.71523
,
3.76975
,
3.82421
,
3.8786
,
3.93293
,
3.71523
,
3.76975
,
3.82421
,
3.8786
,
3.93293
,
2.88335
,
2.93873
,
2.99404
,
3.04929
,
3.10447
,
3.15959
,
3.21464
,
3.26963
,
2.88335
,
2.93873
,
2.99404
,
3.04929
,
3.10447
,
3.15959
,
3.21464
,
3.26963
,
3.32456
,
3.37943
,
3.43424
,
3.48898
,
3.54366
,
3.5983
,
3.65287
,
3.70737
,
3.32456
,
3.37943
,
3.43424
,
3.48898
,
3.54366
,
3.5983
,
3.65287
,
3.70737
,
3.76183
,
3.81622
,
3.87056
,
3.92484
,
3.97905
,
3.76183
,
3.81622
,
3.87056
,
3.92484
,
3.97905
,
2.93234
,
2.9876
,
3.04277
,
3.09786
,
3.15291
,
3.20787
,
3.26278
,
3.31764
,
2.93234
,
2.9876
,
3.04277
,
3.09786
,
3.15291
,
3.20787
,
3.26278
,
3.31764
,
3.37242
,
3.42716
,
3.48184
,
3.53662
,
3.591
,
3.64551
,
3.69995
,
3.75435
,
3.37242
,
3.42716
,
3.48184
,
3.53662
,
3.591
,
3.64551
,
3.69995
,
3.75435
,
3.80867
,
3.86295
,
3.91718
,
3.97134
,
4.02545
,
3.80867
,
3.86295
,
3.91718
,
3.97134
,
4.02545
,
2.98151
,
3.0366
,
3.09163
,
3.14659
,
3.20149
,
3.25632
,
3.3111
,
3.36581
,
2.98151
,
3.0366
,
3.09163
,
3.14659
,
3.20149
,
3.25632
,
3.3111
,
3.36581
,
3.42047
,
3.47507
,
3.52963
,
3.58411
,
3.63855
,
3.69293
,
3.74725
,
3.80153
,
3.42047
,
3.47507
,
3.52963
,
3.58411
,
3.63855
,
3.69293
,
3.74725
,
3.80153
,
3.85575
,
3.90991
,
3.96403
,
4.01809
,
4.07211
,
3.85575
,
3.90991
,
3.96403
,
4.01809
,
4.07211
,
3.03074
,
3.08571
,
3.14061
,
3.19543
,
3.25021
,
3.30491
,
3.35956
,
3.41415
,
3.03074
,
3.08571
,
3.14061
,
3.19543
,
3.25021
,
3.30491
,
3.35956
,
3.41415
,
3.46869
,
3.52317
,
3.57759
,
3.63196
,
3.68628
,
3.74054
,
3.79476
,
3.84893
,
3.46869
,
3.52317
,
3.57759
,
3.63196
,
3.68628
,
3.74054
,
3.79476
,
3.84893
,
3.90303
,
3.95709
,
4.01111
,
4.06506
,
4.11897
,
3.90303
,
3.95709
,
4.01111
,
4.06506
,
4.11897
,
3.08008
,
3.13492
,
3.1897
,
3.2444
,
3.29905
,
3.35363
,
3.40815
,
3.46263
,
3.08008
,
3.13492
,
3.1897
,
3.2444
,
3.29905
,
3.35363
,
3.40815
,
3.46263
,
3.51704
,
3.57141
,
3.62572
,
3.67998
,
3.73418
,
3.78834
,
3.84244
,
3.8965
,
3.51704
,
3.57141
,
3.62572
,
3.67998
,
3.73418
,
3.78834
,
3.84244
,
3.8965
,
3.95051
,
4.00447
,
4.05837
,
4.11224
,
4.16605
,
3.95051
,
4.00447
,
4.05837
,
4.11224
,
4.16605
,
3.12949
,
3.18422
,
3.23888
,
3.29347
,
3.348
,
3.40247
,
3.45688
,
3.51124
,
3.12949
,
3.18422
,
3.23888
,
3.29347
,
3.348
,
3.40247
,
3.45688
,
3.51124
,
3.56554
,
3.6198
,
3.674
,
3.72815
,
3.78225
,
3.83629
,
3.8903
,
3.94425
,
3.56554
,
3.6198
,
3.674
,
3.72815
,
3.78225
,
3.83629
,
3.8903
,
3.94425
,
3.99816
,
4.05203
,
4.10583
,
4.15961
,
4.21333
,
3.99816
,
4.05203
,
4.10583
,
4.15961
,
4.21333
,
3.17899
,
3.23361
,
3.28815
,
3.34264
,
3.39706
,
3.45142
,
3.50571
,
3.55997
,
3.17899
,
3.23361
,
3.28815
,
3.34264
,
3.39706
,
3.45142
,
3.50571
,
3.55997
,
3.61416
,
3.66831
,
3.72241
,
3.77645
,
3.83046
,
3.8844
,
3.93831
,
3.99216
,
3.61416
,
3.66831
,
3.72241
,
3.77645
,
3.83046
,
3.8844
,
3.93831
,
3.99216
,
4.04598
,
4.09974
,
4.15347
,
4.20715
,
4.26078
,
4.04598
,
4.09974
,
4.15347
,
4.20715
,
4.26078
,
3.22855
,
3.28307
,
3.33751
,
3.39188
,
3.4462
,
3.50046
,
3.55466
,
3.6088
,
3.22855
,
3.28307
,
3.33751
,
3.39188
,
3.4462
,
3.50046
,
3.55466
,
3.6088
,
3.6629
,
3.71694
,
3.77095
,
3.82489
,
3.8788
,
3.93265
,
3.98646
,
4.04022
,
3.6629
,
3.71694
,
3.77095
,
3.82489
,
3.8788
,
3.93265
,
3.98646
,
4.04022
,
4.09395
,
4.14762
,
4.20126
,
4.25485
,
4.3084
]
4.09395
,
4.14762
,
4.20126
,
4.25485
,
4.3084
]
m0
=
[
0.0381511
,
0.0338587
,
0.0301776
,
0.027003
,
0.0242506
,
0.0218529
,
m0
=
[
0.0381511
,
0.0338587
,
0.0301776
,
0.027003
,
0.0242506
,
0.0218529
,
0.0197547
,
0.0179109
,
0.0162844
,
0.0148442
,
0.0135647
,
0.0124243
,
0.0197547
,
0.0179109
,
0.0162844
,
0.0148442
,
0.0135647
,
0.0124243
,
0.0114047
,
0.0104906
,
0.00966876
,
0.008928
,
0.0082587
,
0.00765255
,
0.0114047
,
0.0104906
,
0.00966876
,
0.008928
,
0.0082587
,
0.00765255
,
0.00710237
,
0.00660196
,
0.00614589
,
0.00710237
,
0.00660196
,
0.00614589
,
0.0396198
,
0.0351837
,
0.0313767
,
0.0280911
,
0.0252409
,
0.0227563
,
0.0396198
,
0.0351837
,
0.0313767
,
0.0280911
,
0.0252409
,
0.0227563
,
0.0205808
,
0.0186681
,
0.0169799
,
0.0154843
,
0.014155
,
0.0129696
,
0.0205808
,
0.0186681
,
0.0169799
,
0.0154843
,
0.014155
,
0.0129696
,
0.0119094
,
0.0109584
,
0.0101031
,
0.00933189
,
0.0086348
,
0.00800326
,
0.0119094
,
0.0109584
,
0.0101031
,
0.00933189
,
0.0086348
,
0.00800326
,
0.00742986
,
0.00690814
,
0.00643255
,
0.00742986
,
0.00690814
,
0.00643255
,
0.041048
,
0.0364738
,
0.0325456
,
0.0291532
,
0.0262084
,
0.0236399
,
0.041048
,
0.0364738
,
0.0325456
,
0.0291532
,
0.0262084
,
0.0236399
,
0.0213897
,
0.0194102
,
0.0176622
,
0.0161129
,
0.0147351
,
0.0135059
,
0.0213897
,
0.0194102
,
0.0176622
,
0.0161129
,
0.0147351
,
0.0135059
,
0.0124061
,
0.0114192
,
0.0105312
,
0.00973027
,
0.00900602
,
0.00834965
,
0.0124061
,
0.0114192
,
0.0105312
,
0.00973027
,
0.00900602
,
0.00834965
,
0.0077535
,
0.00721091
,
0.00671609
,
0.0077535
,
0.00721091
,
0.00671609
,
0.0424365
,
0.0377295
,
0.0336846
,
0.0301893
,
0.0271533
,
0.0245038
,
0.0424365
,
0.0377295
,
0.0336846
,
0.0301893
,
0.0271533
,
0.0245038
,
0.0221813
,
0.0201371
,
0.018331
,
0.0167295
,
0.0153047
,
0.014033
,
0.0221813
,
0.0201371
,
0.018331
,
0.0167295
,
0.0153047
,
0.014033
,
0.0128946
,
0.0118727
,
0.0109529
,
0.0101229
,
0.00937212
,
0.00869147
,
0.0128946
,
0.0118727
,
0.0109529
,
0.0101229
,
0.00937212
,
0.00869147
,
0.00807306
,
0.00751003
,
0.00699641
,
0.00807306
,
0.00751003
,
0.00699641
,
0.0437861
,
0.0389516
,
0.0347944
,
0.0311998
,
0.0280758
,
0.0253479
,
0.0437861
,
0.0389516
,
0.0347944
,
0.0311998
,
0.0280758
,
0.0253479
,
0.0229555
,
0.0208487
,
0.0189864
,
0.0173343
,
0.0158637
,
0.0145507
,
0.0229555
,
0.0208487
,
0.0189864
,
0.0173343
,
0.0158637
,
0.0145507
,
0.0133748
,
0.0123188
,
0.0113679
,
0.0105096
,
0.0097329
,
0.00902853
,
0.0133748
,
0.0123188
,
0.0113679
,
0.0105096
,
0.0097329
,
0.00902853
,
0.00838835
,
0.00780533
,
0.0072733
,
0.00838835
,
0.00780533
,
0.0072733
,
0.0450979
,
0.0401406
,
0.0358753
,
0.0321851
,
0.0289761
,
0.0261726
,
0.0450979
,
0.0401406
,
0.0358753
,
0.0321851
,
0.0289761
,
0.0261726
,
0.0237125
,
0.0215451
,
0.0196282
,
0.017927
,
0.0164121
,
0.0150588
,
0.0237125
,
0.0215451
,
0.0196282
,
0.017927
,
0.0164121
,
0.0150588
,
0.0138465
,
0.0127573
,
0.0117761
,
0.0108902
,
0.0100882
,
0.00936068
,
0.0138465
,
0.0127573
,
0.0117761
,
0.0108902
,
0.0100882
,
0.00936068
,
0.00869923
,
0.00809665
,
0.00754661
,
0.00869923
,
0.00809665
,
0.00754661
,
0.0463729
,
0.0412976
,
0.0369281
,
0.0331456
,
0.0298547
,
0.026978
,
0.0463729
,
0.0412976
,
0.0369281
,
0.0331456
,
0.0298547
,
0.026978
,
0.0244525
,
0.0222264
,
0.0202567
,
0.0185078
,
0.0169498
,
0.0155575
,
0.0244525
,
0.0222264
,
0.0202567
,
0.0185078
,
0.0169498
,
0.0155575
,
0.0143096
,
0.0131881
,
0.0121775
,
0.0112646
,
0.010438
,
0.00968781
,
0.0143096
,
0.0131881
,
0.0121775
,
0.0112646
,
0.010438
,
0.00968781
,
0.00900559
,
0.00838388
,
0.00781622
,
0.00900559
,
0.00838388
,
0.00781622
,
0.0476123
,
0.0424233
,
0.0379534
,
0.034082
,
0.0307118
,
0.0277645
,
0.0476123
,
0.0424233
,
0.0379534
,
0.034082
,
0.0307118
,
0.0277645
,
0.0251757
,
0.0228927
,
0.0208718
,
0.0190767
,
0.0174768
,
0.0160466
,
0.0251757
,
0.0228927
,
0.0208718
,
0.0190767
,
0.0174768
,
0.0160466
,
0.0147642
,
0.0136112
,
0.0125719
,
0.0116328
,
0.0107821
,
0.0100099
,
0.0147642
,
0.0136112
,
0.0125719
,
0.0116328
,
0.0107821
,
0.0100099
,
0.00930735
,
0.00866695
,
0.00808206
,
0.00930735
,
0.00866695
,
0.00808206
,
0.0488171
,
0.0435186
,
0.038952
,
0.0349947
,
0.0315481
,
0.0285324
,
0.0488171
,
0.0435186
,
0.038952
,
0.0349947
,
0.0315481
,
0.0285324
,
0.0258824
,
0.0235443
,
0.0214738
,
0.0196339
,
0.0179934
,
0.0165262
,
0.0258824
,
0.0235443
,
0.0214738
,
0.0196339
,
0.0179934
,
0.0165262
,
0.0152103
,
0.0140267
,
0.0129595
,
0.0119947
,
0.0111206
,
0.0103268
,
0.0152103
,
0.0140267
,
0.0129595
,
0.0119947
,
0.0111206
,
0.0103268
,
0.00960445
,
0.00894579
,
0.00834405
,
0.00960445
,
0.00894579
,
0.00834405
,
0.0499883
,
0.0445845
,
0.0399246
,
0.0358844
,
0.032364
,
0.0292822
,
0.0499883
,
0.0445845
,
0.0399246
,
0.0358844
,
0.032364
,
0.0292822
,
0.0265729
,
0.0241815
,
0.0220629
,
0.0201794
,
0.0184994
,
0.0169964
,
0.0265729
,
0.0241815
,
0.0220629
,
0.0201794
,
0.0184994
,
0.0169964
,
0.0156479
,
0.0144345
,
0.0133401
,
0.0123504
,
0.0114534
,
0.0106386
,
0.0156479
,
0.0144345
,
0.0133401
,
0.0123504
,
0.0114534
,
0.0106386
,
0.00989687
,
0.00922037
,
0.00860216
,
0.00989687
,
0.00922037
,
0.00860216
,
0.0511272
,
0.0456219
,
0.040872
,
0.0367518
,
0.0331599
,
0.0300142
,
0.0511272
,
0.0456219
,
0.040872
,
0.0367518
,
0.0331599
,
0.0300142
,
0.0272475
,
0.0248045
,
0.0226392
,
0.0207135
,
0.0189952
,
0.0174574
,
0.0272475
,
0.0248045
,
0.0226392
,
0.0207135
,
0.0189952
,
0.0174574
,
0.0160771
,
0.0148348
,
0.0137138
,
0.0126998
,
0.0117805
,
0.0109452
,
0.0160771
,
0.0148348
,
0.0137138
,
0.0126998
,
0.0117805
,
0.0109452
,
0.0101846
,
0.00949067
,
0.00885636
,
0.0101846
,
0.00949067
,
0.00885636
,
0.0522348
,
0.0466315
,
0.0417948
,
0.0375973
,
0.0339365
,
0.030729
,
0.0522348
,
0.0466315
,
0.0417948
,
0.0375973
,
0.0339365
,
0.030729
,
0.0279067
,
0.0254136
,
0.023203
,
0.0212363
,
0.0194809
,
0.0179092
,
0.0279067
,
0.0254136
,
0.023203
,
0.0212363
,
0.0194809
,
0.0179092
,
0.016498
,
0.0152275
,
0.0140807
,
0.013043
,
0.012102
,
0.0112466
,
0.016498
,
0.0152275
,
0.0140807
,
0.013043
,
0.012102
,
0.0112466
,
0.0104676
,
0.00975668
,
0.00910664
,
0.0104676
,
0.00975668
,
0.00910664
,
0.0533123
,
0.0476145
,
0.042694
,
0.0384218
,
0.0346942
,
0.0314268
,
0.0533123
,
0.0476145
,
0.042694
,
0.0384218
,
0.0346942
,
0.0314268
,
0.0285507
,
0.026009
,
0.0237547
,
0.0217482
,
0.0199566
,
0.018352
,
0.0285507
,
0.026009
,
0.0237547
,
0.0217482
,
0.0199566
,
0.018352
,
0.0169108
,
0.0156128
,
0.0144408
,
0.0133801
,
0.0124179
,
0.011543
,
0.0169108
,
0.0156128
,
0.0144408
,
0.0133801
,
0.0124179
,
0.011543
,
0.010746
,
0.0100184
,
0.00935302
,
0.010746
,
0.0100184
,
0.00935302
,
0.0543606
,
0.0485716
,
0.04357
,
0.0392257
,
0.0354335
,
0.0321082
,
0.0543606
,
0.0485716
,
0.04357
,
0.0392257
,
0.0354335
,
0.0321082
,
0.02918
,
0.0265913
,
0.0242943
,
0.0222492
,
0.0204225
,
0.0187859
,
0.02918
,
0.0265913
,
0.0242943
,
0.0222492
,
0.0204225
,
0.0187859
,
0.0173155
,
0.0159908
,
0.0147943
,
0.0137111
,
0.0127282
,
0.0118343
,
0.0173155
,
0.0159908
,
0.0147943
,
0.0137111
,
0.0127282
,
0.0118343
,
0.0110197
,
0.0102759
,
0.00959549
,
0.0110197
,
0.0102759
,
0.00959549
,
0.0553807
,
0.0495037
,
0.0444239
,
0.0400097
,
0.0361551
,
0.0327736
,
0.0553807
,
0.0495037
,
0.0444239
,
0.0400097
,
0.0361551
,
0.0327736
,
0.0297949
,
0.0271605
,
0.0248222
,
0.0227396
,
0.0208788
,
0.0192111
,
0.0297949
,
0.0271605
,
0.0248222
,
0.0227396
,
0.0208788
,
0.0192111
,
0.0177122
,
0.0163615
,
0.0151413
,
0.0140361
,
0.013033
,
0.0121206
,
0.0177122
,
0.0163615
,
0.0151413
,
0.0140361
,
0.013033
,
0.0121206
,
0.0112888
,
0.0105292
,
0.00983409
,
0.0112888
,
0.0105292
,
0.00983409
,
0.0563738
,
0.0504116
,
0.0452562
,
0.0407745
,
0.0368593
,
0.0334235
,
0.0563738
,
0.0504116
,
0.0452562
,
0.0407745
,
0.0368593
,
0.0334235
,
0.0303958
,
0.0277171
,
0.0253387
,
0.0232197
,
0.0213257
,
0.0196277
,
0.0303958
,
0.0277171
,
0.0253387
,
0.0232197
,
0.0213257
,
0.0196277
,
0.0181013
,
0.0167252
,
0.0154817
,
0.0143552
,
0.0133325
,
0.0124019
,
0.0181013
,
0.0167252
,
0.0154817
,
0.0143552
,
0.0133325
,
0.0124019
,
0.0115534
,
0.0107783
,
0.0100688
,
0.0115534
,
0.0107783
,
0.0100688
,
0.0573406
,
0.0512963
,
0.0460676
,
0.0415206
,
0.0375468
,
0.0340583
,
0.0573406
,
0.0512963
,
0.0460676
,
0.0415206
,
0.0375468
,
0.0340583
,
0.030983
,
0.0282614
,
0.0258441
,
0.0236896
,
0.0217634
,
0.020036
,
0.030983
,
0.0282614
,
0.0258441
,
0.0236896
,
0.0217634
,
0.020036
,
0.0184826
,
0.017082
,
0.0158158
,
0.0146685
,
0.0136266
,
0.0126783
,
0.0184826
,
0.017082
,
0.0158158
,
0.0146685
,
0.0136266
,
0.0126783
,
0.0118135
,
0.0110232
,
0.0102998
,
0.0118135
,
0.0110232
,
0.0102998
,
0.0582822
,
0.0521584
,
0.0468589
,
0.0422486
,
0.038218
,
0.0346784
,
0.0582822
,
0.0521584
,
0.0468589
,
0.0422486
,
0.038218
,
0.0346784
,
0.0315571
,
0.0287938
,
0.0263386
,
0.0241497
,
0.0221922
,
0.0204362
,
0.0315571
,
0.0287938
,
0.0263386
,
0.0241497
,
0.0221922
,
0.0204362
,
0.0188566
,
0.0174319
,
0.0161437
,
0.0149761
,
0.0139154
,
0.0129499
,
0.0188566
,
0.0174319
,
0.0161437
,
0.0149761
,
0.0139154
,
0.0129499
,
0.0120691
,
0.0112641
,
0.0105269
,
0.0120691
,
0.0112641
,
0.0105269
,
0.0591994
,
0.0529987
,
0.0476307
,
0.042959
,
0.0388734
,
0.0352843
,
0.0591994
,
0.0529987
,
0.0476307
,
0.042959
,
0.0388734
,
0.0352843
,
0.0321182
,
0.0293144
,
0.0268225
,
0.0246002
,
0.0226121
,
0.0208283
,
0.0321182
,
0.0293144
,
0.0268225
,
0.0246002
,
0.0226121
,
0.0208283
,
0.0192232
,
0.0177751
,
0.0164654
,
0.015278
,
0.0141991
,
0.0132167
,
0.0192232
,
0.0177751
,
0.0164654
,
0.015278
,
0.0141991
,
0.0132167
,
0.0123204
,
0.0115009
,
0.0107504
,
0.0123204
,
0.0115009
,
0.0107504
,
0.0600932
,
0.053818
,
0.0483836
,
0.0436525
,
0.0395136
,
0.0358764
,
0.0600932
,
0.053818
,
0.0483836
,
0.0436525
,
0.0395136
,
0.0358764
,
0.0326669
,
0.0298237
,
0.0272961
,
0.0250413
,
0.0230236
,
0.0212126
,
0.0326669
,
0.0298237
,
0.0272961
,
0.0250413
,
0.0230236
,
0.0212126
,
0.0195826
,
0.0181118
,
0.0167811
,
0.0155744
,
0.0144778
,
0.0134789
,
0.0195826
,
0.0181118
,
0.0167811
,
0.0155744
,
0.0144778
,
0.0134789
,
0.0125673
,
0.0117338
,
0.0109702
,
0.0125673
,
0.0117338
,
0.0109702
,
0.0609642
,
0.0546169
,
0.0491183
,
0.0443295
,
0.0401388
,
0.036455
,
0.0609642
,
0.0546169
,
0.0491183
,
0.0443295
,
0.0401388
,
0.036455
,
0.0332033
,
0.030322
,
0.0277596
,
0.0254732
,
0.0234266
,
0.0215892
,
0.0332033
,
0.030322
,
0.0277596
,
0.0254732
,
0.0234266
,
0.0215892
,
0.0199351
,
0.018442
,
0.0170909
,
0.0158654
,
0.0147514
,
0.0137365
,
0.0199351
,
0.018442
,
0.0170909
,
0.0158654
,
0.0147514
,
0.0137365
,
0.0128101
,
0.0119627
,
0.0111863
]
0.0128101
,
0.0119627
,
0.0111863
]
# Rescale to nm
# Rescale to nm
for
i
in
range
(
len
(
d0
)):
for
i
in
range
(
len
(
d0
)):
...
@@ -196,7 +196,7 @@ Amber Equivalent: igb = 1
...
@@ -196,7 +196,7 @@ Amber Equivalent: igb = 1
def
GBSAHCTForce
(
solventDielectric
=
78.5
,
soluteDielectric
=
1
,
SA
=
None
):
def
GBSAHCTForce
(
solventDielectric
=
78.5
,
soluteDielectric
=
1
,
SA
=
None
):
custom
=
CustomGBForce
()
custom
=
CustomGBForce
()
custom
.
addPerParticleParameter
(
"q"
);
custom
.
addPerParticleParameter
(
"q"
);
custom
.
addPerParticleParameter
(
"radius"
);
custom
.
addPerParticleParameter
(
"radius"
);
custom
.
addPerParticleParameter
(
"scale"
);
custom
.
addPerParticleParameter
(
"scale"
);
...
@@ -213,7 +213,7 @@ def GBSAHCTForce(solventDielectric=78.5, soluteDielectric=1, SA=None):
...
@@ -213,7 +213,7 @@ def GBSAHCTForce(solventDielectric=78.5, soluteDielectric=1, SA=None):
custom
.
addComputedValue
(
"B"
,
"1/(1/or-I);"
custom
.
addComputedValue
(
"B"
,
"1/(1/or-I);"
"or=radius-offset"
,
CustomGBForce
.
SingleParticle
)
"or=radius-offset"
,
CustomGBForce
.
SingleParticle
)
custom
.
addEnergyTerm
(
"-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*q^2/B"
,
CustomGBForce
.
SingleParticle
)
custom
.
addEnergyTerm
(
"-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*q^2/B"
,
CustomGBForce
.
SingleParticle
)
if
SA
==
'ACE'
:
if
SA
==
'ACE'
:
custom
.
addEnergyTerm
(
"28.3919551*(radius+0.14)^2*(radius/B)^6"
,
CustomGBForce
.
SingleParticle
)
custom
.
addEnergyTerm
(
"28.3919551*(radius+0.14)^2*(radius/B)^6"
,
CustomGBForce
.
SingleParticle
)
...
@@ -225,7 +225,7 @@ def GBSAHCTForce(solventDielectric=78.5, soluteDielectric=1, SA=None):
...
@@ -225,7 +225,7 @@ def GBSAHCTForce(solventDielectric=78.5, soluteDielectric=1, SA=None):
return
custom
return
custom
"""
"""
Amber Equivalents: igb = 2
Amber Equivalents: igb = 2
"""
"""
def
GBSAOBC1Force
(
solventDielectric
=
78.5
,
soluteDielectric
=
1
,
SA
=
None
):
def
GBSAOBC1Force
(
solventDielectric
=
78.5
,
soluteDielectric
=
1
,
SA
=
None
):
...
@@ -258,7 +258,7 @@ def GBSAOBC1Force(solventDielectric=78.5, soluteDielectric=1, SA=None):
...
@@ -258,7 +258,7 @@ def GBSAOBC1Force(solventDielectric=78.5, soluteDielectric=1, SA=None):
return
custom
return
custom
"""
"""
Amber Equivalents: igb = 5
Amber Equivalents: igb = 5
"""
"""
def
GBSAOBC2Force
(
solventDielectric
=
78.5
,
soluteDielectric
=
1
,
SA
=
None
):
def
GBSAOBC2Force
(
solventDielectric
=
78.5
,
soluteDielectric
=
1
,
SA
=
None
):
...
@@ -295,27 +295,27 @@ Amber Equivalents: igb = 7
...
@@ -295,27 +295,27 @@ Amber Equivalents: igb = 7
"""
"""
def
GBSAGBnForce
(
solventDielectric
=
78.5
,
soluteDielectric
=
1
,
SA
=
None
):
def
GBSAGBnForce
(
solventDielectric
=
78.5
,
soluteDielectric
=
1
,
SA
=
None
):
"""
"""
Indexing for tables:
Indexing for tables:
input: radius1, radius2
input: radius1, radius2
index = (radius2*200-20)*21 + (radius1*200-20)
index = (radius2*200-20)*21 + (radius1*200-20)
output: index of desired value in row-by-row, 1D version of Tables 3 & 4
output: index of desired value in row-by-row, 1D version of Tables 3 & 4
"""
"""
custom
=
CustomGBForce
()
custom
=
CustomGBForce
()
custom
.
addPerParticleParameter
(
"q"
);
custom
.
addPerParticleParameter
(
"q"
);
custom
.
addPerParticleParameter
(
"radius"
);
custom
.
addPerParticleParameter
(
"radius"
);
custom
.
addPerParticleParameter
(
"scale"
);
custom
.
addPerParticleParameter
(
"scale"
);
custom
.
addGlobalParameter
(
"solventDielectric"
,
solventDielectric
);
custom
.
addGlobalParameter
(
"solventDielectric"
,
solventDielectric
);
custom
.
addGlobalParameter
(
"soluteDielectric"
,
soluteDielectric
);
custom
.
addGlobalParameter
(
"soluteDielectric"
,
soluteDielectric
);
custom
.
addGlobalParameter
(
"offset"
,
0.009
)
custom
.
addGlobalParameter
(
"offset"
,
0.009
)
custom
.
addGlobalParameter
(
"neckScale"
,
0.361825
)
custom
.
addGlobalParameter
(
"neckScale"
,
0.361825
)
custom
.
addGlobalParameter
(
"neckCut"
,
0.68
)
custom
.
addGlobalParameter
(
"neckCut"
,
0.68
)
custom
.
addFunction
(
"getd0"
,
d0
,
0
,
440
)
custom
.
addFunction
(
"getd0"
,
d0
,
0
,
440
)
custom
.
addFunction
(
"getm0"
,
m0
,
0
,
440
)
custom
.
addFunction
(
"getm0"
,
m0
,
0
,
440
)
...
@@ -328,10 +328,10 @@ def GBSAGBnForce(solventDielectric=78.5, soluteDielectric=1, SA=None):
...
@@ -328,10 +328,10 @@ def GBSAGBnForce(solventDielectric=78.5, soluteDielectric=1, SA=None):
"D=abs(r-sr2);"
"D=abs(r-sr2);"
"sr2 = scale2*or2;"
"sr2 = scale2*or2;"
"or1 = radius1-offset; or2 = radius2-offset"
,
CustomGBForce
.
ParticlePairNoExclusions
)
"or1 = radius1-offset; or2 = radius2-offset"
,
CustomGBForce
.
ParticlePairNoExclusions
)
custom
.
addComputedValue
(
"B"
,
"1/(1/or-tanh(1.09511284*psi-1.907992938*psi^2+2.50798245*psi^3)/radius);"
custom
.
addComputedValue
(
"B"
,
"1/(1/or-tanh(1.09511284*psi-1.907992938*psi^2+2.50798245*psi^3)/radius);"
"psi=I*or; or=radius-offset"
,
CustomGBForce
.
SingleParticle
)
"psi=I*or; or=radius-offset"
,
CustomGBForce
.
SingleParticle
)
custom
.
addEnergyTerm
(
"-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*q^2/B"
,
CustomGBForce
.
SingleParticle
)
custom
.
addEnergyTerm
(
"-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*q^2/B"
,
CustomGBForce
.
SingleParticle
)
if
SA
==
'ACE'
:
if
SA
==
'ACE'
:
custom
.
addEnergyTerm
(
"28.3919551*(radius+0.14)^2*(radius/B)^6"
,
CustomGBForce
.
SingleParticle
)
custom
.
addEnergyTerm
(
"28.3919551*(radius+0.14)^2*(radius/B)^6"
,
CustomGBForce
.
SingleParticle
)
...
@@ -340,4 +340,4 @@ def GBSAGBnForce(solventDielectric=78.5, soluteDielectric=1, SA=None):
...
@@ -340,4 +340,4 @@ def GBSAGBnForce(solventDielectric=78.5, soluteDielectric=1, SA=None):
custom
.
addEnergyTerm
(
"-138.935485*(1/soluteDielectric-1/solventDielectric)*q1*q2/f;"
custom
.
addEnergyTerm
(
"-138.935485*(1/soluteDielectric-1/solventDielectric)*q1*q2/f;"
"f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))"
,
CustomGBForce
.
ParticlePairNoExclusions
)
"f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))"
,
CustomGBForce
.
ParticlePairNoExclusions
)
return
custom
return
custom
\ No newline at end of file
wrappers/python/simtk/openmm/app/internal/pdbstructure.py
View file @
4941cc7d
...
@@ -12,7 +12,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -12,7 +12,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns
Authors: Christopher M. Bruns
Contributors: Peter Eastman
Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -260,7 +260,7 @@ class PdbStructure(object):
...
@@ -260,7 +260,7 @@ class PdbStructure(object):
"""Establish first and last residues, atoms, etc."""
"""Establish first and last residues, atoms, etc."""
for
model
in
self
.
models
:
for
model
in
self
.
models
:
model
.
_finalize
()
model
.
_finalize
()
def
get_unit_cell_dimensions
(
self
):
def
get_unit_cell_dimensions
(
self
):
"""Get the dimensions of the crystallographic unit cell (may be None)."""
"""Get the dimensions of the crystallographic unit cell (may be None)."""
return
self
.
_unit_cell_dimensions
return
self
.
_unit_cell_dimensions
...
@@ -547,12 +547,12 @@ class Residue(object):
...
@@ -547,12 +547,12 @@ class Residue(object):
...
...
>>> for atom in res:
>>> for atom in res:
... print atom
... print atom
ATOM 188 N CYS A 42 40.714 -5.292 12.123 1.00 11.29 N
ATOM 188 N CYS A 42 40.714 -5.292 12.123 1.00 11.29 N
ATOM 189 CA CYS A 42 39.736 -5.883 12.911 1.00 10.01 C
ATOM 189 CA CYS A 42 39.736 -5.883 12.911 1.00 10.01 C
ATOM 190 C CYS A 42 40.339 -6.654 14.087 1.00 22.28 C
ATOM 190 C CYS A 42 40.339 -6.654 14.087 1.00 22.28 C
ATOM 191 O CYS A 42 41.181 -7.530 13.859 1.00 13.70 O
ATOM 191 O CYS A 42 41.181 -7.530 13.859 1.00 13.70 O
ATOM 192 CB CYS A 42 38.949 -6.825 12.002 1.00 9.67 C
ATOM 192 CB CYS A 42 38.949 -6.825 12.002 1.00 9.67 C
ATOM 193 SG CYS A 42 37.557 -7.514 12.922 1.00 20.12 S
ATOM 193 SG CYS A 42 37.557 -7.514 12.922 1.00 20.12 S
"""
"""
for
atom
in
self
.
iter_atoms
():
for
atom
in
self
.
iter_atoms
():
yield
atom
yield
atom
...
...
wrappers/python/simtk/openmm/app/modeller.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -48,19 +48,19 @@ from math import ceil, floor
...
@@ -48,19 +48,19 @@ from math import ceil, floor
class
Modeller
(
object
):
class
Modeller
(
object
):
"""Modeller provides tools for editing molecular models, such as adding water or missing hydrogens.
"""Modeller provides tools for editing molecular models, such as adding water or missing hydrogens.
To use it, create a Modeller object, specifying the initial Topology and atom positions. You can
To use it, create a Modeller object, specifying the initial Topology and atom positions. You can
then call various methods to change the model in different ways. Each time you do, a new Topology
then call various methods to change the model in different ways. Each time you do, a new Topology
and list of coordinates is created to represent the changed model. Finally, call getTopology()
and list of coordinates is created to represent the changed model. Finally, call getTopology()
and getPositions() to get the results.
and getPositions() to get the results.
"""
"""
_residueHydrogens
=
{}
_residueHydrogens
=
{}
_hasLoadedStandardHydrogens
=
False
_hasLoadedStandardHydrogens
=
False
def
__init__
(
self
,
topology
,
positions
):
def
__init__
(
self
,
topology
,
positions
):
"""Create a new Modeller object
"""Create a new Modeller object
Parameters:
Parameters:
- topology (Topology) the initial Topology of the model
- topology (Topology) the initial Topology of the model
- positions (list) the initial atomic positions
- positions (list) the initial atomic positions
...
@@ -71,27 +71,27 @@ class Modeller(object):
...
@@ -71,27 +71,27 @@ class Modeller(object):
positions
=
positions
*
nanometer
positions
=
positions
*
nanometer
## The list of atom positions
## The list of atom positions
self
.
positions
=
positions
self
.
positions
=
positions
def
getTopology
(
self
):
def
getTopology
(
self
):
"""Get the Topology of the model."""
"""Get the Topology of the model."""
return
self
.
topology
return
self
.
topology
def
getPositions
(
self
):
def
getPositions
(
self
):
"""Get the atomic positions."""
"""Get the atomic positions."""
return
self
.
positions
return
self
.
positions
def
add
(
self
,
addTopology
,
addPositions
):
def
add
(
self
,
addTopology
,
addPositions
):
"""Add chains, residues, atoms, and bonds to the model.
"""Add chains, residues, atoms, and bonds to the model.
Specify what to add by providing a new Topology object and the corresponding atomic positions.
Specify what to add by providing a new Topology object and the corresponding atomic positions.
All chains, residues, atoms, and bonds contained in the Topology are added to the model.
All chains, residues, atoms, and bonds contained in the Topology are added to the model.
Parameters:
Parameters:
- addTopoology (Topology) a Topology whose contents should be added to the model
- addTopoology (Topology) a Topology whose contents should be added to the model
- addPositions (list) the positions of the atoms to add
- addPositions (list) the positions of the atoms to add
"""
"""
# Copy over the existing model.
# Copy over the existing model.
newTopology
=
Topology
()
newTopology
=
Topology
()
newTopology
.
setUnitCellDimensions
(
deepcopy
(
self
.
topology
.
getUnitCellDimensions
()))
newTopology
.
setUnitCellDimensions
(
deepcopy
(
self
.
topology
.
getUnitCellDimensions
()))
newAtoms
=
{}
newAtoms
=
{}
...
@@ -106,7 +106,7 @@ class Modeller(object):
...
@@ -106,7 +106,7 @@ class Modeller(object):
newPositions
.
append
(
deepcopy
(
self
.
positions
[
atom
.
index
]))
newPositions
.
append
(
deepcopy
(
self
.
positions
[
atom
.
index
]))
for
bond
in
self
.
topology
.
bonds
():
for
bond
in
self
.
topology
.
bonds
():
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
# Add the new model
# Add the new model
newAtoms
=
{}
newAtoms
=
{}
...
@@ -125,16 +125,16 @@ class Modeller(object):
...
@@ -125,16 +125,16 @@ class Modeller(object):
def
delete
(
self
,
toDelete
):
def
delete
(
self
,
toDelete
):
"""Delete chains, residues, atoms, and bonds from the model.
"""Delete chains, residues, atoms, and bonds from the model.
You can specify objects to delete at any granularity: atoms, residues, or chains. Passing
You can specify objects to delete at any granularity: atoms, residues, or chains. Passing
in an Atom object causes that Atom to be deleted. Passing in a Residue object causes that
in an Atom object causes that Atom to be deleted. Passing in a Residue object causes that
Residue and all Atoms it contains to be deleted. Passing in a Chain object causes that
Residue and all Atoms it contains to be deleted. Passing in a Chain object causes that
Chain and all Residues and Atoms it contains to be deleted.
Chain and all Residues and Atoms it contains to be deleted.
In all cases, when an Atom is deleted, any bonds it participates in are also deleted.
In all cases, when an Atom is deleted, any bonds it participates in are also deleted.
You also can specify a bond (as a tuple of Atom objects) to delete just that bond without
You also can specify a bond (as a tuple of Atom objects) to delete just that bond without
deleting the Atoms it connects.
deleting the Atoms it connects.
Parameters:
Parameters:
- toDelete (list) a list of Atoms, Residues, Chains, and bonds (specified as tuples of Atoms) to delete
- toDelete (list) a list of Atoms, Residues, Chains, and bonds (specified as tuples of Atoms) to delete
"""
"""
...
@@ -166,14 +166,14 @@ class Modeller(object):
...
@@ -166,14 +166,14 @@ class Modeller(object):
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
self
.
topology
=
newTopology
self
.
topology
=
newTopology
self
.
positions
=
newPositions
self
.
positions
=
newPositions
def
deleteWater
(
self
):
def
deleteWater
(
self
):
"""Delete all water molecules from the model."""
"""Delete all water molecules from the model."""
self
.
delete
(
res
for
res
in
self
.
topology
.
residues
()
if
res
.
name
==
"HOH"
)
self
.
delete
(
res
for
res
in
self
.
topology
.
residues
()
if
res
.
name
==
"HOH"
)
def
convertWater
(
self
,
model
=
'tip3p'
):
def
convertWater
(
self
,
model
=
'tip3p'
):
"""Convert all water molecules to a different water model.
"""Convert all water molecules to a different water model.
Parameters:
Parameters:
- model (string='tip3p') the water model to convert to. Supported values are 'tip3p', 'spce', 'tip4pew', and 'tip5p'.
- model (string='tip3p') the water model to convert to. Supported values are 'tip3p', 'spce', 'tip4pew', and 'tip5p'.
"""
"""
...
@@ -211,9 +211,9 @@ class Modeller(object):
...
@@ -211,9 +211,9 @@ class Modeller(object):
newPositions
.
append
(
po
)
newPositions
.
append
(
po
)
newPositions
.
append
(
ph1
)
newPositions
.
append
(
ph1
)
newPositions
.
append
(
ph2
)
newPositions
.
append
(
ph2
)
# Add virtual sites.
# Add virtual sites.
if
sites
==
4
:
if
sites
==
4
:
newTopology
.
addAtom
(
'M'
,
None
,
newResidue
)
newTopology
.
addAtom
(
'M'
,
None
,
newResidue
)
newPositions
.
append
(
0.786646558
*
po
+
0.106676721
*
ph1
+
0.106676721
*
ph2
)
newPositions
.
append
(
0.786646558
*
po
+
0.106676721
*
ph1
+
0.106676721
*
ph2
)
...
@@ -239,19 +239,19 @@ class Modeller(object):
...
@@ -239,19 +239,19 @@ class Modeller(object):
def
addSolvent
(
self
,
forcefield
,
model
=
'tip3p'
,
boxSize
=
None
,
padding
=
None
,
positiveIon
=
'Na+'
,
negativeIon
=
'Cl-'
,
ionicStrength
=
0
*
molar
):
def
addSolvent
(
self
,
forcefield
,
model
=
'tip3p'
,
boxSize
=
None
,
padding
=
None
,
positiveIon
=
'Na+'
,
negativeIon
=
'Cl-'
,
ionicStrength
=
0
*
molar
):
"""Add solvent (both water and ions) to the model to fill a rectangular box.
"""Add solvent (both water and ions) to the model to fill a rectangular box.
The algorithm works as follows:
The algorithm works as follows:
1. Water molecules are added to fill the box.
1. Water molecules are added to fill the box.
2. Water molecules are removed if their distance to any solute atom is less than the sum of their van der Waals radii.
2. Water molecules are removed if their distance to any solute atom is less than the sum of their van der Waals radii.
3. If the solute is charged, enough positive or negative ions are added to neutralize it. Each ion is added by
3. If the solute is charged, enough positive or negative ions are added to neutralize it. Each ion is added by
randomly selecting a water molecule and replacing it with the ion.
randomly selecting a water molecule and replacing it with the ion.
4. Ion pairs are added to give the requested total ionic strength.
4. Ion pairs are added to give the requested total ionic strength.
The box size can be specified in three ways. First, you can explicitly give a box size to use. Alternatively, you can
The box size can be specified in three ways. First, you can explicitly give a box size to use. Alternatively, you can
give a padding distance. The largest dimension of the solute (along the x, y, or z axis) is determined, and a cubic
give a padding distance. The largest dimension of the solute (along the x, y, or z axis) is determined, and a cubic
box of size (largest dimension)+2*padding is used. Finally, if neither a box size nor a padding distance is specified,
box of size (largest dimension)+2*padding is used. Finally, if neither a box size nor a padding distance is specified,
the existing Topology's unit cell dimensions are used.
the existing Topology's unit cell dimensions are used.
Parameters:
Parameters:
- forcefield (ForceField) the ForceField to use for determining van der Waals radii and atomic charges
- forcefield (ForceField) the ForceField to use for determining van der Waals radii and atomic charges
- model (string='tip3p') the water model to use. Supported values are 'tip3p', 'spce', 'tip4pew', and 'tip5p'.
- model (string='tip3p') the water model to use. Supported values are 'tip3p', 'spce', 'tip4pew', and 'tip5p'.
...
@@ -264,7 +264,7 @@ class Modeller(object):
...
@@ -264,7 +264,7 @@ class Modeller(object):
does not include ions that are added to neutralize the system.
does not include ions that are added to neutralize the system.
"""
"""
# Pick a unit cell size.
# Pick a unit cell size.
if
boxSize
is
not
None
:
if
boxSize
is
not
None
:
if
is_quantity
(
boxSize
):
if
is_quantity
(
boxSize
):
boxSize
=
boxSize
.
value_in_unit
(
nanometer
)
boxSize
=
boxSize
.
value_in_unit
(
nanometer
)
...
@@ -278,9 +278,9 @@ class Modeller(object):
...
@@ -278,9 +278,9 @@ class Modeller(object):
raise
ValueError
(
'Neither the box size nor padding was specified, and the Topology does not define unit cell dimensions'
)
raise
ValueError
(
'Neither the box size nor padding was specified, and the Topology does not define unit cell dimensions'
)
box
=
box
.
value_in_unit
(
nanometer
)
box
=
box
.
value_in_unit
(
nanometer
)
invBox
=
Vec3
(
1.0
/
box
[
0
],
1.0
/
box
[
1
],
1.0
/
box
[
2
])
invBox
=
Vec3
(
1.0
/
box
[
0
],
1.0
/
box
[
1
],
1.0
/
box
[
2
])
# Identify the ion types.
# Identify the ion types.
posIonElements
=
{
'Cs+'
:
elem
.
cesium
,
'K+'
:
elem
.
potassium
,
'Li+'
:
elem
.
lithium
,
'Na+'
:
elem
.
sodium
,
'Rb+'
:
elem
.
rubidium
}
posIonElements
=
{
'Cs+'
:
elem
.
cesium
,
'K+'
:
elem
.
potassium
,
'Li+'
:
elem
.
lithium
,
'Na+'
:
elem
.
sodium
,
'Rb+'
:
elem
.
rubidium
}
negIonElements
=
{
'Cl-'
:
elem
.
chlorine
,
'Br-'
:
elem
.
bromine
,
'F-'
:
elem
.
fluorine
,
'I-'
:
elem
.
iodine
}
negIonElements
=
{
'Cl-'
:
elem
.
chlorine
,
'Br-'
:
elem
.
bromine
,
'F-'
:
elem
.
fluorine
,
'I-'
:
elem
.
iodine
}
if
positiveIon
not
in
posIonElements
:
if
positiveIon
not
in
posIonElements
:
...
@@ -289,9 +289,9 @@ class Modeller(object):
...
@@ -289,9 +289,9 @@ class Modeller(object):
raise
ValueError
(
'Illegal value for negative ion: %s'
%
negativeIon
)
raise
ValueError
(
'Illegal value for negative ion: %s'
%
negativeIon
)
positiveElement
=
posIonElements
[
positiveIon
]
positiveElement
=
posIonElements
[
positiveIon
]
negativeElement
=
negIonElements
[
negativeIon
]
negativeElement
=
negIonElements
[
negativeIon
]
# Load the pre-equilibrated water box.
# Load the pre-equilibrated water box.
vdwRadiusPerSigma
=
0.5612310241546864907
vdwRadiusPerSigma
=
0.5612310241546864907
if
model
==
'tip3p'
:
if
model
==
'tip3p'
:
waterRadius
=
0.31507524065751241
*
vdwRadiusPerSigma
waterRadius
=
0.31507524065751241
*
vdwRadiusPerSigma
...
@@ -308,9 +308,9 @@ class Modeller(object):
...
@@ -308,9 +308,9 @@ class Modeller(object):
pdbPositions
=
pdb
.
getPositions
().
value_in_unit
(
nanometer
)
pdbPositions
=
pdb
.
getPositions
().
value_in_unit
(
nanometer
)
pdbResidues
=
list
(
pdbTopology
.
residues
())
pdbResidues
=
list
(
pdbTopology
.
residues
())
pdbBoxSize
=
pdbTopology
.
getUnitCellDimensions
().
value_in_unit
(
nanometer
)
pdbBoxSize
=
pdbTopology
.
getUnitCellDimensions
().
value_in_unit
(
nanometer
)
# Have the ForceField build a System for the solute from which we can determine van der Waals radii.
# Have the ForceField build a System for the solute from which we can determine van der Waals radii.
system
=
forcefield
.
createSystem
(
self
.
topology
)
system
=
forcefield
.
createSystem
(
self
.
topology
)
nonbonded
=
None
nonbonded
=
None
for
i
in
range
(
system
.
getNumForces
()):
for
i
in
range
(
system
.
getNumForces
()):
...
@@ -324,7 +324,7 @@ class Modeller(object):
...
@@ -324,7 +324,7 @@ class Modeller(object):
maxCutoff
=
waterCutoff
maxCutoff
=
waterCutoff
else
:
else
:
maxCutoff
=
max
(
waterCutoff
,
max
(
cutoff
))
maxCutoff
=
max
(
waterCutoff
,
max
(
cutoff
))
# Copy the solute over.
# Copy the solute over.
newTopology
=
Topology
()
newTopology
=
Topology
()
...
@@ -341,9 +341,9 @@ class Modeller(object):
...
@@ -341,9 +341,9 @@ class Modeller(object):
newPositions
.
append
(
deepcopy
(
self
.
positions
[
atom
.
index
]))
newPositions
.
append
(
deepcopy
(
self
.
positions
[
atom
.
index
]))
for
bond
in
self
.
topology
.
bonds
():
for
bond
in
self
.
topology
.
bonds
():
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
# Sort the solute atoms into cells for fast lookup.
# Sort the solute atoms into cells for fast lookup.
if
len
(
self
.
positions
)
==
0
:
if
len
(
self
.
positions
)
==
0
:
positions
=
[]
positions
=
[]
else
:
else
:
...
@@ -357,9 +357,9 @@ class Modeller(object):
...
@@ -357,9 +357,9 @@ class Modeller(object):
cells
[
cell
].
append
(
i
)
cells
[
cell
].
append
(
i
)
else
:
else
:
cells
[
cell
]
=
[
i
]
cells
[
cell
]
=
[
i
]
# Create a generator that loops over atoms close to a position.
# Create a generator that loops over atoms close to a position.
def
neighbors
(
pos
):
def
neighbors
(
pos
):
centralCell
=
tuple
((
int
(
floor
(
pos
[
i
]
/
cellSize
[
i
]))
for
i
in
range
(
3
)))
centralCell
=
tuple
((
int
(
floor
(
pos
[
i
]
/
cellSize
[
i
]))
for
i
in
range
(
3
)))
offsets
=
(
-
1
,
0
,
1
)
offsets
=
(
-
1
,
0
,
1
)
...
@@ -370,16 +370,16 @@ class Modeller(object):
...
@@ -370,16 +370,16 @@ class Modeller(object):
if
cell
in
cells
:
if
cell
in
cells
:
for
atom
in
cells
[
cell
]:
for
atom
in
cells
[
cell
]:
yield
atom
yield
atom
# Define a function to compute the distance between two points, taking periodic boundary conditions into account.
# Define a function to compute the distance between two points, taking periodic boundary conditions into account.
def
periodicDistance
(
pos1
,
pos2
):
def
periodicDistance
(
pos1
,
pos2
):
delta
=
pos1
-
pos2
delta
=
pos1
-
pos2
delta
=
[
delta
[
i
]
-
floor
(
delta
[
i
]
*
invBox
[
i
]
+
0.5
)
*
box
[
i
]
for
i
in
range
(
3
)]
delta
=
[
delta
[
i
]
-
floor
(
delta
[
i
]
*
invBox
[
i
]
+
0.5
)
*
box
[
i
]
for
i
in
range
(
3
)]
return
norm
(
delta
)
return
norm
(
delta
)
# Find the list of water molecules to add.
# Find the list of water molecules to add.
newChain
=
newTopology
.
addChain
()
newChain
=
newTopology
.
addChain
()
if
len
(
positions
)
==
0
:
if
len
(
positions
)
==
0
:
center
=
Vec3
(
0
,
0
,
0
)
center
=
Vec3
(
0
,
0
,
0
)
...
@@ -397,18 +397,18 @@ class Modeller(object):
...
@@ -397,18 +397,18 @@ class Modeller(object):
atomPos
=
pdbPositions
[
oxygen
.
index
]
+
offset
atomPos
=
pdbPositions
[
oxygen
.
index
]
+
offset
if
not
any
((
atomPos
[
i
]
>
box
[
i
]
for
i
in
range
(
3
))):
if
not
any
((
atomPos
[
i
]
>
box
[
i
]
for
i
in
range
(
3
))):
# This molecule is inside the box, so see how close to it is to the solute.
# This molecule is inside the box, so see how close to it is to the solute.
atomPos
+=
center
-
box
/
2
atomPos
+=
center
-
box
/
2
for
i
in
neighbors
(
atomPos
):
for
i
in
neighbors
(
atomPos
):
if
periodicDistance
(
atomPos
,
positions
[
i
])
<
cutoff
[
i
]:
if
periodicDistance
(
atomPos
,
positions
[
i
])
<
cutoff
[
i
]:
break
break
else
:
else
:
# Record this water molecule as one to add.
# Record this water molecule as one to add.
addedWaters
.
append
((
residue
.
index
,
atomPos
))
addedWaters
.
append
((
residue
.
index
,
atomPos
))
# There could be clashes between water molecules at the box edges. Find ones to remove.
# There could be clashes between water molecules at the box edges. Find ones to remove.
upperCutoff
=
center
+
box
/
2
-
Vec3
(
waterCutoff
,
waterCutoff
,
waterCutoff
)
upperCutoff
=
center
+
box
/
2
-
Vec3
(
waterCutoff
,
waterCutoff
,
waterCutoff
)
lowerCutoff
=
center
-
box
/
2
+
Vec3
(
waterCutoff
,
waterCutoff
,
waterCutoff
)
lowerCutoff
=
center
-
box
/
2
+
Vec3
(
waterCutoff
,
waterCutoff
,
waterCutoff
)
lowerSkinPositions
=
[
pos
for
index
,
pos
in
addedWaters
if
pos
[
0
]
<
lowerCutoff
[
0
]
or
pos
[
1
]
<
lowerCutoff
[
1
]
or
pos
[
2
]
<
lowerCutoff
[
2
]]
lowerSkinPositions
=
[
pos
for
index
,
pos
in
addedWaters
if
pos
[
0
]
<
lowerCutoff
[
0
]
or
pos
[
1
]
<
lowerCutoff
[
1
]
or
pos
[
2
]
<
lowerCutoff
[
2
]]
...
@@ -428,9 +428,9 @@ class Modeller(object):
...
@@ -428,9 +428,9 @@ class Modeller(object):
if
not
any
((
periodicDistance
(
lowerSkinPositions
[
i
],
pos
)
<
waterCutoff
and
norm
(
lowerSkinPositions
[
i
]
-
pos
)
>
waterCutoff
for
i
in
neighbors
(
pos
))):
if
not
any
((
periodicDistance
(
lowerSkinPositions
[
i
],
pos
)
<
waterCutoff
and
norm
(
lowerSkinPositions
[
i
]
-
pos
)
>
waterCutoff
for
i
in
neighbors
(
pos
))):
filteredWaters
.
append
(
entry
)
filteredWaters
.
append
(
entry
)
addedWaters
=
filteredWaters
addedWaters
=
filteredWaters
# Add ions to neutralize the system.
# Add ions to neutralize the system.
totalCharge
=
int
(
floor
(
0.5
+
sum
((
nonbonded
.
getParticleParameters
(
i
)[
0
].
value_in_unit
(
elementary_charge
)
for
i
in
range
(
system
.
getNumParticles
())))))
totalCharge
=
int
(
floor
(
0.5
+
sum
((
nonbonded
.
getParticleParameters
(
i
)[
0
].
value_in_unit
(
elementary_charge
)
for
i
in
range
(
system
.
getNumParticles
())))))
if
abs
(
totalCharge
)
>
len
(
addedWaters
):
if
abs
(
totalCharge
)
>
len
(
addedWaters
):
raise
Exception
(
'Cannot neutralize the system because the charge is greater than the number of available positions for ions'
)
raise
Exception
(
'Cannot neutralize the system because the charge is greater than the number of available positions for ions'
)
...
@@ -443,18 +443,18 @@ class Modeller(object):
...
@@ -443,18 +443,18 @@ class Modeller(object):
del
addedWaters
[
index
]
del
addedWaters
[
index
]
for
i
in
range
(
abs
(
totalCharge
)):
for
i
in
range
(
abs
(
totalCharge
)):
addIon
(
positiveElement
if
totalCharge
<
0
else
negativeElement
)
addIon
(
positiveElement
if
totalCharge
<
0
else
negativeElement
)
# Add ions based on the desired ionic strength.
# Add ions based on the desired ionic strength.
numIons
=
len
(
addedWaters
)
*
ionicStrength
/
(
55.4
*
molar
)
# Pure water is about 55.4 molar (depending on temperature)
numIons
=
len
(
addedWaters
)
*
ionicStrength
/
(
55.4
*
molar
)
# Pure water is about 55.4 molar (depending on temperature)
numPairs
=
int
(
floor
(
numIons
/
2
+
0.5
))
numPairs
=
int
(
floor
(
numIons
/
2
+
0.5
))
for
i
in
range
(
numPairs
):
for
i
in
range
(
numPairs
):
addIon
(
positiveElement
)
addIon
(
positiveElement
)
for
i
in
range
(
numPairs
):
for
i
in
range
(
numPairs
):
addIon
(
negativeElement
)
addIon
(
negativeElement
)
# Add the water molecules.
# Add the water molecules.
for
index
,
pos
in
addedWaters
:
for
index
,
pos
in
addedWaters
:
newResidue
=
newTopology
.
addResidue
(
residue
.
name
,
newChain
)
newResidue
=
newTopology
.
addResidue
(
residue
.
name
,
newChain
)
residue
=
pdbResidues
[
index
]
residue
=
pdbResidues
[
index
]
...
@@ -472,14 +472,14 @@ class Modeller(object):
...
@@ -472,14 +472,14 @@ class Modeller(object):
newTopology
.
setUnitCellDimensions
(
deepcopy
(
box
)
*
nanometer
)
newTopology
.
setUnitCellDimensions
(
deepcopy
(
box
)
*
nanometer
)
self
.
topology
=
newTopology
self
.
topology
=
newTopology
self
.
positions
=
newPositions
self
.
positions
=
newPositions
class
_ResidueData
:
class
_ResidueData
:
"""Inner class used to encapsulate data about the hydrogens for a residue."""
"""Inner class used to encapsulate data about the hydrogens for a residue."""
def
__init__
(
self
,
name
):
def
__init__
(
self
,
name
):
self
.
name
=
name
self
.
name
=
name
self
.
variants
=
[]
self
.
variants
=
[]
self
.
hydrogens
=
[]
self
.
hydrogens
=
[]
class
_Hydrogen
:
class
_Hydrogen
:
"""Inner class used to encapsulate data about a hydrogen atom."""
"""Inner class used to encapsulate data about a hydrogen atom."""
def
__init__
(
self
,
name
,
parent
,
maxph
,
variants
,
terminal
):
def
__init__
(
self
,
name
,
parent
,
maxph
,
variants
,
terminal
):
...
@@ -488,11 +488,11 @@ class Modeller(object):
...
@@ -488,11 +488,11 @@ class Modeller(object):
self
.
maxph
=
maxph
self
.
maxph
=
maxph
self
.
variants
=
variants
self
.
variants
=
variants
self
.
terminal
=
terminal
self
.
terminal
=
terminal
@
staticmethod
@
staticmethod
def
loadHydrogenDefinitions
(
file
):
def
loadHydrogenDefinitions
(
file
):
"""Load an XML file containing definitions of hydrogens that should be added by addHydrogens().
"""Load an XML file containing definitions of hydrogens that should be added by addHydrogens().
The built in hydrogens.xml file containing definitions for standard amino acids and nucleotides is loaded automatically.
The built in hydrogens.xml file containing definitions for standard amino acids and nucleotides is loaded automatically.
This method can be used to load additional definitions for other residue types. They will then be used in subsequent
This method can be used to load additional definitions for other residue types. They will then be used in subsequent
calls to addHydrogens().
calls to addHydrogens().
...
@@ -516,45 +516,45 @@ class Modeller(object):
...
@@ -516,45 +516,45 @@ class Modeller(object):
if
'terminal'
in
hydrogen
.
attrib
:
if
'terminal'
in
hydrogen
.
attrib
:
terminal
=
hydrogen
.
attrib
[
'terminal'
]
terminal
=
hydrogen
.
attrib
[
'terminal'
]
data
.
hydrogens
.
append
(
Modeller
.
_Hydrogen
(
hydrogen
.
attrib
[
'name'
],
hydrogen
.
attrib
[
'parent'
],
maxph
,
atomVariants
,
terminal
))
data
.
hydrogens
.
append
(
Modeller
.
_Hydrogen
(
hydrogen
.
attrib
[
'name'
],
hydrogen
.
attrib
[
'parent'
],
maxph
,
atomVariants
,
terminal
))
def
addHydrogens
(
self
,
forcefield
,
pH
=
7.0
,
variants
=
None
):
def
addHydrogens
(
self
,
forcefield
,
pH
=
7.0
,
variants
=
None
):
"""Add missing hydrogens to the model.
"""Add missing hydrogens to the model.
Some residues can exist in multiple forms depending on the pH and properties of the local environment. These
Some residues can exist in multiple forms depending on the pH and properties of the local environment. These
variants differ in the presence or absence of particular hydrogens. In particular, the following variants
variants differ in the presence or absence of particular hydrogens. In particular, the following variants
are supported:
are supported:
Aspartic acid:
Aspartic acid:
ASH: Neutral form with a hydrogen on one of the delta oxygens
ASH: Neutral form with a hydrogen on one of the delta oxygens
ASP: Negatively charged form without a hydrogen on either delta oxygen
ASP: Negatively charged form without a hydrogen on either delta oxygen
Cysteine:
Cysteine:
CYS: Neutral form with a hydrogen on the sulfur
CYS: Neutral form with a hydrogen on the sulfur
CYX: No hydrogen on the sulfur (either negatively charged, or part of a disulfide bond)
CYX: No hydrogen on the sulfur (either negatively charged, or part of a disulfide bond)
Glutamic acid:
Glutamic acid:
GLH: Neutral form with a hydrogen on one of the epsilon oxygens
GLH: Neutral form with a hydrogen on one of the epsilon oxygens
GLU: Negatively charged form without a hydrogen on either epsilon oxygen
GLU: Negatively charged form without a hydrogen on either epsilon oxygen
Histidine:
Histidine:
HID: Neutral form with a hydrogen on the ND1 atom
HID: Neutral form with a hydrogen on the ND1 atom
HIE: Neutral form with a hydrogen on the NE2 atom
HIE: Neutral form with a hydrogen on the NE2 atom
HIP: Positively charged form with hydrogens on both ND1 and NE2
HIP: Positively charged form with hydrogens on both ND1 and NE2
Lysine:
Lysine:
LYN: Neutral form with two hydrogens on the zeta nitrogen
LYN: Neutral form with two hydrogens on the zeta nitrogen
LYS: Positively charged form with three hydrogens on the zeta nitrogen
LYS: Positively charged form with three hydrogens on the zeta nitrogen
The variant to use for each residue is determined by the following rules:
The variant to use for each residue is determined by the following rules:
1. The most common variant at the specified pH is selected.
1. The most common variant at the specified pH is selected.
2. Any Cysteine that participates in a disulfide bond uses the CYX variant regardless of pH.
2. Any Cysteine that participates in a disulfide bond uses the CYX variant regardless of pH.
3. For a neutral Histidine residue, the HID or HIE variant is selected based on which one forms a better hydrogen bond.
3. For a neutral Histidine residue, the HID or HIE variant is selected based on which one forms a better hydrogen bond.
You can override these rules by explicitly specifying a variant for any residue. Also keep in mind that this
You can override these rules by explicitly specifying a variant for any residue. Also keep in mind that this
function will only add hydrogens. It will never remove ones that are already present in the model, regardless
function will only add hydrogens. It will never remove ones that are already present in the model, regardless
of the specified pH.
of the specified pH.
Definitions for standard amino acids and nucleotides are built in. You can call loadHydrogenDefinitions() to load
Definitions for standard amino acids and nucleotides are built in. You can call loadHydrogenDefinitions() to load
additional definitions for other residue types.
additional definitions for other residue types.
...
@@ -567,7 +567,7 @@ class Modeller(object):
...
@@ -567,7 +567,7 @@ class Modeller(object):
Returns: a list of what variant was actually selected for each residue, in the same format as the variants parameter
Returns: a list of what variant was actually selected for each residue, in the same format as the variants parameter
"""
"""
# Check the list of variants.
# Check the list of variants.
residues
=
list
(
self
.
topology
.
residues
())
residues
=
list
(
self
.
topology
.
residues
())
if
variants
is
not
None
:
if
variants
is
not
None
:
if
len
(
variants
)
!=
len
(
residues
):
if
len
(
variants
)
!=
len
(
residues
):
...
@@ -575,23 +575,23 @@ class Modeller(object):
...
@@ -575,23 +575,23 @@ class Modeller(object):
else
:
else
:
variants
=
[
None
]
*
len
(
residues
)
variants
=
[
None
]
*
len
(
residues
)
actualVariants
=
[
None
]
*
len
(
residues
)
actualVariants
=
[
None
]
*
len
(
residues
)
# Load the residue specifications.
# Load the residue specifications.
if
not
Modeller
.
_hasLoadedStandardHydrogens
:
if
not
Modeller
.
_hasLoadedStandardHydrogens
:
Modeller
.
loadHydrogenDefinitions
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'data'
,
'hydrogens.xml'
))
Modeller
.
loadHydrogenDefinitions
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'data'
,
'hydrogens.xml'
))
# Make a list of atoms bonded to each atom.
# Make a list of atoms bonded to each atom.
bonded
=
{}
bonded
=
{}
for
atom
in
self
.
topology
.
atoms
():
for
atom
in
self
.
topology
.
atoms
():
bonded
[
atom
]
=
[]
bonded
[
atom
]
=
[]
for
atom1
,
atom2
in
self
.
topology
.
bonds
():
for
atom1
,
atom2
in
self
.
topology
.
bonds
():
bonded
[
atom1
].
append
(
atom2
)
bonded
[
atom1
].
append
(
atom2
)
bonded
[
atom2
].
append
(
atom1
)
bonded
[
atom2
].
append
(
atom1
)
# Define a function that decides whether a set of atoms form a hydrogen bond, using fairly tolerant criteria.
# Define a function that decides whether a set of atoms form a hydrogen bond, using fairly tolerant criteria.
def
isHbond
(
d
,
h
,
a
):
def
isHbond
(
d
,
h
,
a
):
if
norm
(
d
-
a
)
>
0.35
*
nanometer
:
if
norm
(
d
-
a
)
>
0.35
*
nanometer
:
return
False
return
False
...
@@ -600,9 +600,9 @@ class Modeller(object):
...
@@ -600,9 +600,9 @@ class Modeller(object):
deltaDH
/=
norm
(
deltaDH
)
deltaDH
/=
norm
(
deltaDH
)
deltaHA
/=
norm
(
deltaHA
)
deltaHA
/=
norm
(
deltaHA
)
return
acos
(
dot
(
deltaDH
,
deltaHA
))
<
50
*
degree
return
acos
(
dot
(
deltaDH
,
deltaHA
))
<
50
*
degree
# Loop over residues.
# Loop over residues.
newTopology
=
Topology
()
newTopology
=
Topology
()
newTopology
.
setUnitCellDimensions
(
deepcopy
(
self
.
topology
.
getUnitCellDimensions
()))
newTopology
.
setUnitCellDimensions
(
deepcopy
(
self
.
topology
.
getUnitCellDimensions
()))
newAtoms
=
{}
newAtoms
=
{}
...
@@ -617,19 +617,19 @@ class Modeller(object):
...
@@ -617,19 +617,19 @@ class Modeller(object):
isCTerminal
=
(
residue
==
chain
.
_residues
[
-
1
])
isCTerminal
=
(
residue
==
chain
.
_residues
[
-
1
])
if
residue
.
name
in
Modeller
.
_residueHydrogens
:
if
residue
.
name
in
Modeller
.
_residueHydrogens
:
# Add hydrogens. First select which variant to use.
# Add hydrogens. First select which variant to use.
spec
=
Modeller
.
_residueHydrogens
[
residue
.
name
]
spec
=
Modeller
.
_residueHydrogens
[
residue
.
name
]
variant
=
variants
[
residue
.
index
]
variant
=
variants
[
residue
.
index
]
if
variant
is
None
:
if
variant
is
None
:
if
residue
.
name
==
'CYS'
:
if
residue
.
name
==
'CYS'
:
# If this is part of a disulfide, use CYX.
# If this is part of a disulfide, use CYX.
sulfur
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
element
==
elem
.
sulfur
]
sulfur
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
element
==
elem
.
sulfur
]
if
len
(
sulfur
)
==
1
and
any
((
atom
.
residue
!=
residue
for
atom
in
bonded
[
sulfur
[
0
]])):
if
len
(
sulfur
)
==
1
and
any
((
atom
.
residue
!=
residue
for
atom
in
bonded
[
sulfur
[
0
]])):
variant
=
'CYX'
variant
=
'CYX'
if
residue
.
name
==
'HIS'
and
pH
>
6.5
:
if
residue
.
name
==
'HIS'
and
pH
>
6.5
:
# See if either nitrogen already has a hydrogen attached.
# See if either nitrogen already has a hydrogen attached.
nd1
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
name
==
'ND1'
]
nd1
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
name
==
'ND1'
]
ne2
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
name
==
'NE2'
]
ne2
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
name
==
'NE2'
]
if
len
(
nd1
)
!=
1
or
len
(
ne2
)
!=
1
:
if
len
(
nd1
)
!=
1
or
len
(
ne2
)
!=
1
:
...
@@ -646,7 +646,7 @@ class Modeller(object):
...
@@ -646,7 +646,7 @@ class Modeller(object):
variant
=
'HIE'
variant
=
'HIE'
else
:
else
:
# Estimate the hydrogen positions.
# Estimate the hydrogen positions.
nd1Pos
=
self
.
positions
[
nd1
.
index
]
nd1Pos
=
self
.
positions
[
nd1
.
index
]
ne2Pos
=
self
.
positions
[
ne2
.
index
]
ne2Pos
=
self
.
positions
[
ne2
.
index
]
hd1Delta
=
Vec3
(
0
,
0
,
0
)
*
nanometer
hd1Delta
=
Vec3
(
0
,
0
,
0
)
*
nanometer
...
@@ -661,7 +661,7 @@ class Modeller(object):
...
@@ -661,7 +661,7 @@ class Modeller(object):
he2Pos
=
ne2Pos
+
he2Delta
he2Pos
=
ne2Pos
+
he2Delta
# See whether either hydrogen would form a hydrogen bond.
# See whether either hydrogen would form a hydrogen bond.
nd1IsBonded
=
False
nd1IsBonded
=
False
ne2IsBonded
=
False
ne2IsBonded
=
False
for
acceptor
in
acceptors
:
for
acceptor
in
acceptors
:
...
@@ -681,31 +681,31 @@ class Modeller(object):
...
@@ -681,31 +681,31 @@ class Modeller(object):
if
variant
is
not
None
and
variant
not
in
spec
.
variants
:
if
variant
is
not
None
and
variant
not
in
spec
.
variants
:
raise
ValueError
(
'Illegal variant for %s residue: %s'
%
(
residue
.
name
,
variant
))
raise
ValueError
(
'Illegal variant for %s residue: %s'
%
(
residue
.
name
,
variant
))
actualVariants
[
residue
.
index
]
=
variant
actualVariants
[
residue
.
index
]
=
variant
# Make a list of hydrogens that should be present in the residue.
# Make a list of hydrogens that should be present in the residue.
parents
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
element
!=
elem
.
hydrogen
]
parents
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
element
!=
elem
.
hydrogen
]
parentNames
=
[
atom
.
name
for
atom
in
parents
]
parentNames
=
[
atom
.
name
for
atom
in
parents
]
hydrogens
=
[
h
for
h
in
spec
.
hydrogens
if
(
variant
is
None
and
pH
<=
h
.
maxph
)
or
(
h
.
variants
is
None
and
pH
<=
h
.
maxph
)
or
(
h
.
variants
is
not
None
and
variant
in
h
.
variants
)]
hydrogens
=
[
h
for
h
in
spec
.
hydrogens
if
(
variant
is
None
and
pH
<=
h
.
maxph
)
or
(
h
.
variants
is
None
and
pH
<=
h
.
maxph
)
or
(
h
.
variants
is
not
None
and
variant
in
h
.
variants
)]
hydrogens
=
[
h
for
h
in
hydrogens
if
h
.
terminal
is
None
or
(
isNTerminal
and
h
.
terminal
==
'N'
)
or
(
isCTerminal
and
h
.
terminal
==
'C'
)]
hydrogens
=
[
h
for
h
in
hydrogens
if
h
.
terminal
is
None
or
(
isNTerminal
and
h
.
terminal
==
'N'
)
or
(
isCTerminal
and
h
.
terminal
==
'C'
)]
hydrogens
=
[
h
for
h
in
hydrogens
if
h
.
parent
in
parentNames
]
hydrogens
=
[
h
for
h
in
hydrogens
if
h
.
parent
in
parentNames
]
# Loop over atoms in the residue, adding them to the new topology along with required hydrogens.
# Loop over atoms in the residue, adding them to the new topology along with required hydrogens.
for
parent
in
residue
.
atoms
():
for
parent
in
residue
.
atoms
():
# Add the atom.
# Add the atom.
newAtom
=
newTopology
.
addAtom
(
parent
.
name
,
parent
.
element
,
newResidue
)
newAtom
=
newTopology
.
addAtom
(
parent
.
name
,
parent
.
element
,
newResidue
)
newAtoms
[
parent
]
=
newAtom
newAtoms
[
parent
]
=
newAtom
newPositions
.
append
(
deepcopy
(
self
.
positions
[
parent
.
index
]))
newPositions
.
append
(
deepcopy
(
self
.
positions
[
parent
.
index
]))
if
parent
in
parents
:
if
parent
in
parents
:
# Match expected hydrogens with existing ones and find which ones need to be added.
# Match expected hydrogens with existing ones and find which ones need to be added.
existing
=
[
atom
for
atom
in
bonded
[
parent
]
if
atom
.
element
==
elem
.
hydrogen
]
existing
=
[
atom
for
atom
in
bonded
[
parent
]
if
atom
.
element
==
elem
.
hydrogen
]
expected
=
[
h
for
h
in
hydrogens
if
h
.
parent
==
parent
.
name
]
expected
=
[
h
for
h
in
hydrogens
if
h
.
parent
==
parent
.
name
]
if
len
(
existing
)
<
len
(
expected
):
if
len
(
existing
)
<
len
(
expected
):
# Try to match up existing hydrogens to expected ones.
# Try to match up existing hydrogens to expected ones.
matches
=
[]
matches
=
[]
for
e
in
existing
:
for
e
in
existing
:
match
=
[
h
for
h
in
expected
if
h
.
name
==
e
.
name
]
match
=
[
h
for
h
in
expected
if
h
.
name
==
e
.
name
]
...
@@ -714,16 +714,16 @@ class Modeller(object):
...
@@ -714,16 +714,16 @@ class Modeller(object):
expected
.
remove
(
match
[
0
])
expected
.
remove
(
match
[
0
])
else
:
else
:
matches
.
append
(
None
)
matches
.
append
(
None
)
# If any hydrogens couldn't be matched by name, just match them arbitrarily.
# If any hydrogens couldn't be matched by name, just match them arbitrarily.
for
i
in
range
(
len
(
matches
)):
for
i
in
range
(
len
(
matches
)):
if
matches
[
i
]
is
None
:
if
matches
[
i
]
is
None
:
matches
[
i
]
=
expected
[
-
1
]
matches
[
i
]
=
expected
[
-
1
]
expected
.
remove
(
expected
[
-
1
])
expected
.
remove
(
expected
[
-
1
])
# Add the missing hydrogens.
# Add the missing hydrogens.
for
h
in
expected
:
for
h
in
expected
:
newH
=
newTopology
.
addAtom
(
h
.
name
,
elem
.
hydrogen
,
newResidue
)
newH
=
newTopology
.
addAtom
(
h
.
name
,
elem
.
hydrogen
,
newResidue
)
newIndices
.
append
(
newH
.
index
)
newIndices
.
append
(
newH
.
index
)
...
@@ -741,7 +741,7 @@ class Modeller(object):
...
@@ -741,7 +741,7 @@ class Modeller(object):
newTopology
.
addBond
(
newAtom
,
newH
)
newTopology
.
addBond
(
newAtom
,
newH
)
else
:
else
:
# Just copy over the residue.
# Just copy over the residue.
for
atom
in
residue
.
atoms
():
for
atom
in
residue
.
atoms
():
newAtom
=
newTopology
.
addAtom
(
atom
.
name
,
atom
.
element
,
newResidue
)
newAtom
=
newTopology
.
addAtom
(
atom
.
name
,
atom
.
element
,
newResidue
)
newAtoms
[
atom
]
=
newAtom
newAtoms
[
atom
]
=
newAtom
...
@@ -749,9 +749,9 @@ class Modeller(object):
...
@@ -749,9 +749,9 @@ class Modeller(object):
for
bond
in
self
.
topology
.
bonds
():
for
bond
in
self
.
topology
.
bonds
():
if
bond
[
0
]
in
newAtoms
and
bond
[
1
]
in
newAtoms
:
if
bond
[
0
]
in
newAtoms
and
bond
[
1
]
in
newAtoms
:
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
# The hydrogens were added at random positions. Now use the ForceField to fix them up.
# The hydrogens were added at random positions. Now use the ForceField to fix them up.
system
=
forcefield
.
createSystem
(
newTopology
,
rigidWater
=
False
)
system
=
forcefield
.
createSystem
(
newTopology
,
rigidWater
=
False
)
atoms
=
list
(
newTopology
.
atoms
())
atoms
=
list
(
newTopology
.
atoms
())
for
i
in
range
(
system
.
getNumParticles
()):
for
i
in
range
(
system
.
getNumParticles
()):
...
@@ -764,23 +764,23 @@ class Modeller(object):
...
@@ -764,23 +764,23 @@ class Modeller(object):
self
.
topology
=
newTopology
self
.
topology
=
newTopology
self
.
positions
=
context
.
getState
(
getPositions
=
True
).
getPositions
()
self
.
positions
=
context
.
getState
(
getPositions
=
True
).
getPositions
()
return
actualVariants
return
actualVariants
def
addExtraParticles
(
self
,
forcefield
):
def
addExtraParticles
(
self
,
forcefield
):
"""Add missing extra particles to the model that are required by a force field.
"""Add missing extra particles to the model that are required by a force field.
Some force fields use "extra particles" that do not represent actual atoms, but still need to be included in
Some force fields use "extra particles" that do not represent actual atoms, but still need to be included in
the System. Examples include lone pairs, Drude particles, and the virtual sites used in some water models
the System. Examples include lone pairs, Drude particles, and the virtual sites used in some water models
to adjust the charge distribution. Extra particles can be recognized by the fact that their element is None.
to adjust the charge distribution. Extra particles can be recognized by the fact that their element is None.
This method is primarily used to add extra particles, but it can also remove them. It tries to match every
This method is primarily used to add extra particles, but it can also remove them. It tries to match every
residue in the Topology to a template in the force field. If there is no match, it will both add and remove
residue in the Topology to a template in the force field. If there is no match, it will both add and remove
extra particles as necessary to make it match.
extra particles as necessary to make it match.
Parameters:
Parameters:
- forcefield (ForceField) the ForceField defining what extra particles should be present
- forcefield (ForceField) the ForceField defining what extra particles should be present
"""
"""
# Create copies of all residue templates that have had all extra points removed.
# Create copies of all residue templates that have had all extra points removed.
templatesNoEP
=
{}
templatesNoEP
=
{}
for
resName
,
template
in
forcefield
.
_templates
.
iteritems
():
for
resName
,
template
in
forcefield
.
_templates
.
iteritems
():
if
any
(
atom
.
element
is
None
for
atom
in
template
.
atoms
):
if
any
(
atom
.
element
is
None
for
atom
in
template
.
atoms
):
...
@@ -801,9 +801,9 @@ class Modeller(object):
...
@@ -801,9 +801,9 @@ class Modeller(object):
if
b
in
newIndex
:
if
b
in
newIndex
:
newTemplate
.
externalBonds
.
append
(
newIndex
[
b
])
newTemplate
.
externalBonds
.
append
(
newIndex
[
b
])
templatesNoEP
[
template
]
=
newTemplate
templatesNoEP
[
template
]
=
newTemplate
# Record which atoms are bonded to each other atom, with and without extra particles.
# Record which atoms are bonded to each other atom, with and without extra particles.
bondedToAtom
=
[]
bondedToAtom
=
[]
bondedToAtomNoEP
=
[]
bondedToAtomNoEP
=
[]
for
atom
in
self
.
topology
.
atoms
():
for
atom
in
self
.
topology
.
atoms
():
...
@@ -815,18 +815,18 @@ class Modeller(object):
...
@@ -815,18 +815,18 @@ class Modeller(object):
if
atom1
.
element
is
not
None
and
atom2
.
element
is
not
None
:
if
atom1
.
element
is
not
None
and
atom2
.
element
is
not
None
:
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
# 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.
# need them for picking particle positions.
drudeTypeMap
=
{}
drudeTypeMap
=
{}
for
force
in
forcefield
.
_forces
:
for
force
in
forcefield
.
_forces
:
if
isinstance
(
force
,
DrudeGenerator
):
if
isinstance
(
force
,
DrudeGenerator
):
for
type
in
force
.
typeMap
:
for
type
in
force
.
typeMap
:
drudeTypeMap
[
type
]
=
force
.
typeMap
[
type
][
0
]
drudeTypeMap
[
type
]
=
force
.
typeMap
[
type
][
0
]
# Create the new Topology.
# Create the new Topology.
newTopology
=
Topology
()
newTopology
=
Topology
()
newTopology
.
setUnitCellDimensions
(
deepcopy
(
self
.
topology
.
getUnitCellDimensions
()))
newTopology
.
setUnitCellDimensions
(
deepcopy
(
self
.
topology
.
getUnitCellDimensions
()))
newAtoms
=
{}
newAtoms
=
{}
...
@@ -835,9 +835,9 @@ class Modeller(object):
...
@@ -835,9 +835,9 @@ class Modeller(object):
newChain
=
newTopology
.
addChain
()
newChain
=
newTopology
.
addChain
()
for
residue
in
chain
.
residues
():
for
residue
in
chain
.
residues
():
newResidue
=
newTopology
.
addResidue
(
residue
.
name
,
newChain
)
newResidue
=
newTopology
.
addResidue
(
residue
.
name
,
newChain
)
# Look for a matching template.
# Look for a matching template.
matchFound
=
False
matchFound
=
False
signature
=
_createResidueSignature
([
atom
.
element
for
atom
in
residue
.
atoms
()])
signature
=
_createResidueSignature
([
atom
.
element
for
atom
in
residue
.
atoms
()])
if
signature
in
forcefield
.
_templateSignatures
:
if
signature
in
forcefield
.
_templateSignatures
:
...
@@ -846,7 +846,7 @@ class Modeller(object):
...
@@ -846,7 +846,7 @@ class Modeller(object):
matchFound
=
True
matchFound
=
True
if
matchFound
:
if
matchFound
:
# Just copy the residue over.
# Just copy the residue over.
for
atom
in
residue
.
atoms
():
for
atom
in
residue
.
atoms
():
newAtom
=
newTopology
.
addAtom
(
atom
.
name
,
atom
.
element
,
newResidue
)
newAtom
=
newTopology
.
addAtom
(
atom
.
name
,
atom
.
element
,
newResidue
)
newAtoms
[
atom
]
=
newAtom
newAtoms
[
atom
]
=
newAtom
...
@@ -854,7 +854,7 @@ class Modeller(object):
...
@@ -854,7 +854,7 @@ class Modeller(object):
else
:
else
:
# There's no matching template. Try to find one that matches based on everything except
# There's no matching template. Try to find one that matches based on everything except
# extra points.
# extra points.
template
=
None
template
=
None
residueNoEP
=
Residue
(
residue
.
name
,
residue
.
index
,
residue
.
chain
)
residueNoEP
=
Residue
(
residue
.
name
,
residue
.
index
,
residue
.
chain
)
residueNoEP
.
_atoms
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
element
is
not
None
]
residueNoEP
.
_atoms
=
[
atom
for
atom
in
residue
.
atoms
()
if
atom
.
element
is
not
None
]
...
@@ -874,16 +874,16 @@ class Modeller(object):
...
@@ -874,16 +874,16 @@ class Modeller(object):
break
break
if
template
is
None
:
if
template
is
None
:
raise
ValueError
(
'Residue %d (%s) does not match any template defined by the ForceField.'
%
(
residue
.
index
+
1
,
residue
.
name
))
raise
ValueError
(
'Residue %d (%s) does not match any template defined by the ForceField.'
%
(
residue
.
index
+
1
,
residue
.
name
))
# Add the regular atoms.
# Add the regular atoms.
for
atom
in
residue
.
atoms
():
for
atom
in
residue
.
atoms
():
if
atom
.
element
is
not
None
:
if
atom
.
element
is
not
None
:
newAtoms
[
atom
]
=
newTopology
.
addAtom
(
atom
.
name
,
atom
.
element
,
newResidue
)
newAtoms
[
atom
]
=
newTopology
.
addAtom
(
atom
.
name
,
atom
.
element
,
newResidue
)
newPositions
.
append
(
deepcopy
(
self
.
positions
[
atom
.
index
]))
newPositions
.
append
(
deepcopy
(
self
.
positions
[
atom
.
index
]))
# Add the extra points.
# Add the extra points.
templateAtomPositions
=
len
(
template
.
atoms
)
*
[
None
]
templateAtomPositions
=
len
(
template
.
atoms
)
*
[
None
]
for
index
,
atom
in
enumerate
(
template
.
atoms
):
for
index
,
atom
in
enumerate
(
template
.
atoms
):
if
atom
in
matchingAtoms
:
if
atom
in
matchingAtoms
:
...
@@ -895,7 +895,7 @@ class Modeller(object):
...
@@ -895,7 +895,7 @@ class Modeller(object):
for
site
in
template
.
virtualSites
:
for
site
in
template
.
virtualSites
:
if
site
.
index
==
index
:
if
site
.
index
==
index
:
# This is a virtual site. Compute its position by the correct rule.
# This is a virtual site. Compute its position by the correct rule.
if
site
.
type
==
'average2'
:
if
site
.
type
==
'average2'
:
position
=
site
.
weights
[
0
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
0
]]
+
site
.
weights
[
1
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
1
]]
position
=
site
.
weights
[
0
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
0
]]
+
site
.
weights
[
1
]
*
templateAtomPositions
[
index
+
site
.
atoms
[
1
]]
elif
site
.
type
==
'average3'
:
elif
site
.
type
==
'average3'
:
...
@@ -907,14 +907,14 @@ class Modeller(object):
...
@@ -907,14 +907,14 @@ class Modeller(object):
position
=
templateAtomPositions
[
index
+
site
.
atoms
[
0
]]
+
site
.
weights
[
0
]
*
v1
+
site
.
weights
[
1
]
*
v2
+
site
.
weights
[
2
]
*
cross
position
=
templateAtomPositions
[
index
+
site
.
atoms
[
0
]]
+
site
.
weights
[
0
]
*
v1
+
site
.
weights
[
1
]
*
v2
+
site
.
weights
[
2
]
*
cross
if
position
is
None
and
atom
.
type
in
drudeTypeMap
:
if
position
is
None
and
atom
.
type
in
drudeTypeMap
:
# This is a Drude particle. Put it on top of its parent atom.
# This is a Drude particle. Put it on top of its parent atom.
for
atom2
,
pos
in
zip
(
template
.
atoms
,
templateAtomPositions
):
for
atom2
,
pos
in
zip
(
template
.
atoms
,
templateAtomPositions
):
if
atom2
.
type
in
drudeTypeMap
[
atom
.
type
]:
if
atom2
.
type
in
drudeTypeMap
[
atom
.
type
]:
position
=
deepcopy
(
pos
)
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.
knownPositions
=
[
x
for
x
in
templateAtomPositions
if
x
is
not
None
]
knownPositions
=
[
x
for
x
in
templateAtomPositions
if
x
is
not
None
]
position
=
sum
(
knownPositions
)
/
len
(
knownPositions
)
position
=
sum
(
knownPositions
)
/
len
(
knownPositions
)
newPositions
.
append
(
position
*
nanometer
)
newPositions
.
append
(
position
*
nanometer
)
...
@@ -922,4 +922,4 @@ class Modeller(object):
...
@@ -922,4 +922,4 @@ class Modeller(object):
if
bond
[
0
]
in
newAtoms
and
bond
[
1
]
in
newAtoms
:
if
bond
[
0
]
in
newAtoms
and
bond
[
1
]
in
newAtoms
:
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
newTopology
.
addBond
(
newAtoms
[
bond
[
0
]],
newAtoms
[
bond
[
1
]])
self
.
topology
=
newTopology
self
.
topology
=
newTopology
self
.
positions
=
newPositions
self
.
positions
=
newPositions
\ No newline at end of file
wrappers/python/simtk/openmm/app/pdbfile.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -48,28 +48,28 @@ except:
...
@@ -48,28 +48,28 @@ except:
class
PDBFile
(
object
):
class
PDBFile
(
object
):
"""PDBFile parses a Protein Data Bank (PDB) file and constructs a Topology and a set of atom positions from it.
"""PDBFile parses a Protein Data Bank (PDB) file and constructs a Topology and a set of atom positions from it.
This class also provides methods for creating PDB files. To write a file containing a single model, call
This class also provides methods for creating PDB files. To write a file containing a single model, call
writeFile(). You also can create files that contain multiple models. To do this, first call writeHeader(),
writeFile(). You also can create files that contain multiple models. To do this, first call writeHeader(),
then writeModel() once for each model in the file, and finally writeFooter() to complete the file."""
then writeModel() once for each model in the file, and finally writeFooter() to complete the file."""
_residueNameReplacements
=
{}
_residueNameReplacements
=
{}
_atomNameReplacements
=
{}
_atomNameReplacements
=
{}
def
__init__
(
self
,
file
):
def
__init__
(
self
,
file
):
"""Load a PDB file.
"""Load a PDB file.
The atom positions and Topology can be retrieved by calling getPositions() and getTopology().
The atom positions and Topology can be retrieved by calling getPositions() and getTopology().
Parameters:
Parameters:
- file (string) the name of the file to load
- file (string) the name of the file to load
"""
"""
top
=
Topology
()
top
=
Topology
()
## The Topology read from the PDB file
## The Topology read from the PDB file
self
.
topology
=
top
self
.
topology
=
top
# Load the PDB file
# Load the PDB file
pdb
=
PdbStructure
(
open
(
file
),
load_all_models
=
True
)
pdb
=
PdbStructure
(
open
(
file
),
load_all_models
=
True
)
PDBFile
.
_loadNameReplacementTables
()
PDBFile
.
_loadNameReplacementTables
()
...
@@ -95,7 +95,7 @@ class PDBFile(object):
...
@@ -95,7 +95,7 @@ class PDBFile(object):
element
=
atom
.
element
element
=
atom
.
element
if
element
is
None
:
if
element
is
None
:
# Try to guess the element.
# Try to guess the element.
upper
=
atomName
.
upper
()
upper
=
atomName
.
upper
()
if
upper
.
startswith
(
'CL'
):
if
upper
.
startswith
(
'CL'
):
element
=
elem
.
chlorine
element
=
elem
.
chlorine
...
@@ -133,9 +133,9 @@ class PDBFile(object):
...
@@ -133,9 +133,9 @@ class PDBFile(object):
self
.
topology
.
createStandardBonds
()
self
.
topology
.
createStandardBonds
()
self
.
topology
.
createDisulfideBonds
(
self
.
positions
)
self
.
topology
.
createDisulfideBonds
(
self
.
positions
)
self
.
_numpyPositions
=
None
self
.
_numpyPositions
=
None
# Add bonds based on CONECT records.
# Add bonds based on CONECT records.
connectBonds
=
[]
connectBonds
=
[]
for
connect
in
pdb
.
models
[
0
].
connects
:
for
connect
in
pdb
.
models
[
0
].
connects
:
i
=
connect
[
0
]
i
=
connect
[
0
]
...
@@ -152,14 +152,14 @@ class PDBFile(object):
...
@@ -152,14 +152,14 @@ class PDBFile(object):
def
getTopology
(
self
):
def
getTopology
(
self
):
"""Get the Topology of the model."""
"""Get the Topology of the model."""
return
self
.
topology
return
self
.
topology
def
getNumFrames
(
self
):
def
getNumFrames
(
self
):
"""Get the number of frames stored in the file."""
"""Get the number of frames stored in the file."""
return
len
(
self
.
_positions
)
return
len
(
self
.
_positions
)
def
getPositions
(
self
,
asNumpy
=
False
,
frame
=
0
):
def
getPositions
(
self
,
asNumpy
=
False
,
frame
=
0
):
"""Get the atomic positions.
"""Get the atomic positions.
Parameters:
Parameters:
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s
- frame (int=0) the index of the frame for which to get positions
- frame (int=0) the index of the frame for which to get positions
...
@@ -213,11 +213,11 @@ class PDBFile(object):
...
@@ -213,11 +213,11 @@ class PDBFile(object):
name
=
atom
.
attrib
[
'name'
]
name
=
atom
.
attrib
[
'name'
]
for
id
in
atom
.
attrib
:
for
id
in
atom
.
attrib
:
map
[
atom
.
attrib
[
id
]]
=
name
map
[
atom
.
attrib
[
id
]]
=
name
@
staticmethod
@
staticmethod
def
writeFile
(
topology
,
positions
,
file
=
sys
.
stdout
,
modelIndex
=
None
):
def
writeFile
(
topology
,
positions
,
file
=
sys
.
stdout
,
modelIndex
=
None
):
"""Write a PDB file containing a single model.
"""Write a PDB file containing a single model.
Parameters:
Parameters:
- topology (Topology) The Topology defining the model to write
- topology (Topology) The Topology defining the model to write
- positions (list) The list of atomic positions to write
- positions (list) The list of atomic positions to write
...
@@ -230,7 +230,7 @@ class PDBFile(object):
...
@@ -230,7 +230,7 @@ class PDBFile(object):
@
staticmethod
@
staticmethod
def
writeHeader
(
topology
,
file
=
sys
.
stdout
):
def
writeHeader
(
topology
,
file
=
sys
.
stdout
):
"""Write out the header for a PDB file.
"""Write out the header for a PDB file.
Parameters:
Parameters:
- topology (Topology) The Topology defining the molecular system being written
- topology (Topology) The Topology defining the molecular system being written
- file (file=stdout) A file to write the file to
- file (file=stdout) A file to write the file to
...
@@ -239,11 +239,11 @@ class PDBFile(object):
...
@@ -239,11 +239,11 @@ class PDBFile(object):
if
boxSize
is
not
None
:
if
boxSize
is
not
None
:
size
=
boxSize
.
value_in_unit
(
angstroms
)
size
=
boxSize
.
value_in_unit
(
angstroms
)
print
>>
file
,
"CRYST1%9.3f%9.3f%9.3f 90.00 90.00 90.00 P 1 1 "
%
size
print
>>
file
,
"CRYST1%9.3f%9.3f%9.3f 90.00 90.00 90.00 P 1 1 "
%
size
@
staticmethod
@
staticmethod
def
writeModel
(
topology
,
positions
,
file
=
sys
.
stdout
,
modelIndex
=
None
):
def
writeModel
(
topology
,
positions
,
file
=
sys
.
stdout
,
modelIndex
=
None
):
"""Write out a model to a PDB file.
"""Write out a model to a PDB file.
Parameters:
Parameters:
- topology (Topology) The Topology defining the model to write
- topology (Topology) The Topology defining the model to write
- positions (list) The list of atomic positions to write
- positions (list) The list of atomic positions to write
...
@@ -251,7 +251,7 @@ class PDBFile(object):
...
@@ -251,7 +251,7 @@ class PDBFile(object):
- modelIndex (int=None) If not None, the model will be surrounded by MODEL/ENDMDL records with this index
- modelIndex (int=None) If not None, the model will be surrounded by MODEL/ENDMDL records with this index
"""
"""
if
len
(
list
(
topology
.
atoms
()))
!=
len
(
positions
):
if
len
(
list
(
topology
.
atoms
()))
!=
len
(
positions
):
raise
ValueError
(
'The number of positions must match the number of atoms'
)
raise
ValueError
(
'The number of positions must match the number of atoms'
)
if
is_quantity
(
positions
):
if
is_quantity
(
positions
):
positions
=
positions
.
value_in_unit
(
angstroms
)
positions
=
positions
.
value_in_unit
(
angstroms
)
if
any
(
math
.
isnan
(
norm
(
pos
))
for
pos
in
positions
):
if
any
(
math
.
isnan
(
norm
(
pos
))
for
pos
in
positions
):
...
@@ -295,7 +295,7 @@ class PDBFile(object):
...
@@ -295,7 +295,7 @@ class PDBFile(object):
@
staticmethod
@
staticmethod
def
writeFooter
(
topology
,
file
=
sys
.
stdout
):
def
writeFooter
(
topology
,
file
=
sys
.
stdout
):
"""Write out the footer for a PDB file.
"""Write out the footer for a PDB file.
Parameters:
Parameters:
- topology (Topology) The Topology defining the molecular system being written
- topology (Topology) The Topology defining the molecular system being written
- file (file=stdout) A file to write the file to
- file (file=stdout) A file to write the file to
...
...
wrappers/python/simtk/openmm/app/pdbreporter.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -33,16 +33,16 @@ __version__ = "1.0"
...
@@ -33,16 +33,16 @@ __version__ = "1.0"
import
simtk.openmm
as
mm
import
simtk.openmm
as
mm
from
simtk.openmm.app
import
PDBFile
from
simtk.openmm.app
import
PDBFile
class
PDBReporter
(
object
):
class
PDBReporter
(
object
):
"""PDBReporter outputs a series of frames from a Simulation to a PDB file.
"""PDBReporter outputs a series of frames from a Simulation to a PDB file.
To use it, create a PDBReporter, then add it to the Simulation's list of reporters.
To use it, create a PDBReporter, then add it to the Simulation's list of reporters.
"""
"""
def
__init__
(
self
,
file
,
reportInterval
):
def
__init__
(
self
,
file
,
reportInterval
):
"""Create a PDBReporter.
"""Create a PDBReporter.
Parameters:
Parameters:
- file (string) The file to write to
- file (string) The file to write to
- reportInterval (int) The interval (in time steps) at which to write frames
- reportInterval (int) The interval (in time steps) at which to write frames
...
@@ -51,10 +51,10 @@ class PDBReporter(object):
...
@@ -51,10 +51,10 @@ class PDBReporter(object):
self
.
_out
=
open
(
file
,
'w'
)
self
.
_out
=
open
(
file
,
'w'
)
self
.
_topology
=
None
self
.
_topology
=
None
self
.
_nextModel
=
0
self
.
_nextModel
=
0
def
describeNextReport
(
self
,
simulation
):
def
describeNextReport
(
self
,
simulation
):
"""Get information about the next report this object will generate.
"""Get information about the next report this object will generate.
Parameters:
Parameters:
- simulation (Simulation) The Simulation to generate a report for
- simulation (Simulation) The Simulation to generate a report for
Returns: A five element tuple. The first element is the number of steps until the
Returns: A five element tuple. The first element is the number of steps until the
...
@@ -63,10 +63,10 @@ class PDBReporter(object):
...
@@ -63,10 +63,10 @@ class PDBReporter(object):
"""
"""
steps
=
self
.
_reportInterval
-
simulation
.
currentStep
%
self
.
_reportInterval
steps
=
self
.
_reportInterval
-
simulation
.
currentStep
%
self
.
_reportInterval
return
(
steps
,
True
,
False
,
False
,
False
)
return
(
steps
,
True
,
False
,
False
,
False
)
def
report
(
self
,
simulation
,
state
):
def
report
(
self
,
simulation
,
state
):
"""Generate a report.
"""Generate a report.
Parameters:
Parameters:
- simulation (Simulation) The Simulation to generate a report for
- simulation (Simulation) The Simulation to generate a report for
- state (State) The current state of the simulation
- state (State) The current state of the simulation
...
@@ -77,7 +77,7 @@ class PDBReporter(object):
...
@@ -77,7 +77,7 @@ class PDBReporter(object):
self
.
_nextModel
+=
1
self
.
_nextModel
+=
1
PDBFile
.
writeModel
(
simulation
.
topology
,
state
.
getPositions
(),
self
.
_out
,
self
.
_nextModel
)
PDBFile
.
writeModel
(
simulation
.
topology
,
state
.
getPositions
(),
self
.
_out
,
self
.
_nextModel
)
self
.
_nextModel
+=
1
self
.
_nextModel
+=
1
def
__del__
(
self
):
def
__del__
(
self
):
PDBFile
.
writeFooter
(
self
.
_topology
,
self
.
_out
)
PDBFile
.
writeFooter
(
self
.
_topology
,
self
.
_out
)
self
.
_out
.
close
()
self
.
_out
.
close
()
wrappers/python/simtk/openmm/app/simulation.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -33,25 +33,25 @@ __version__ = "1.0"
...
@@ -33,25 +33,25 @@ __version__ = "1.0"
import
simtk.openmm
as
mm
import
simtk.openmm
as
mm
import
simtk.unit
as
unit
import
simtk.unit
as
unit
class
Simulation
(
object
):
class
Simulation
(
object
):
"""Simulation provides a simplified API for running simulations with OpenMM and reporting results.
"""Simulation provides a simplified API for running simulations with OpenMM and reporting results.
A Simulation ties together various objects used for running a simulation: a Topology, System,
A Simulation ties together various objects used for running a simulation: a Topology, System,
Integrator, and Context. To use it, you provide the Topology, System, and Integrator, and it
Integrator, and Context. To use it, you provide the Topology, System, and Integrator, and it
creates the Context automatically.
creates the Context automatically.
Simulation also maintains a list of "reporter" objects that record or analyze data as the simulation
Simulation also maintains a list of "reporter" objects that record or analyze data as the simulation
runs, such as writing coordinates to files or displaying structures on the screen. For example,
runs, such as writing coordinates to files or displaying structures on the screen. For example,
the following line will cause a file called "output.pdb" to be created, and a structure written to
the following line will cause a file called "output.pdb" to be created, and a structure written to
it every 1000 time steps:
it every 1000 time steps:
simulation.reporters.append(PDBReporter('output.pdb', 1000))
simulation.reporters.append(PDBReporter('output.pdb', 1000))
"""
"""
def
__init__
(
self
,
topology
,
system
,
integrator
,
platform
=
None
,
platformProperties
=
None
):
def
__init__
(
self
,
topology
,
system
,
integrator
,
platform
=
None
,
platformProperties
=
None
):
"""Create a Simulation.
"""Create a Simulation.
Parameters:
Parameters:
- topology (Topology) A Topology describing the the system to simulate
- topology (Topology) A Topology describing the the system to simulate
- system (System) The OpenMM System object to simulate
- system (System) The OpenMM System object to simulate
...
@@ -77,17 +77,17 @@ class Simulation(object):
...
@@ -77,17 +77,17 @@ class Simulation(object):
self
.
context
=
mm
.
Context
(
system
,
integrator
,
platform
)
self
.
context
=
mm
.
Context
(
system
,
integrator
,
platform
)
else
:
else
:
self
.
context
=
mm
.
Context
(
system
,
integrator
,
platform
,
platformProperties
)
self
.
context
=
mm
.
Context
(
system
,
integrator
,
platform
,
platformProperties
)
def
minimizeEnergy
(
self
,
tolerance
=
1
*
unit
.
kilojoule
/
unit
.
mole
,
maxIterations
=
0
):
def
minimizeEnergy
(
self
,
tolerance
=
1
*
unit
.
kilojoule
/
unit
.
mole
,
maxIterations
=
0
):
"""Perform a local energy minimization on the system.
"""Perform a local energy minimization on the system.
Parameters:
Parameters:
- tolerance (energy=1*kilojoule/mole) The energy tolerance to which the system should be minimized
- tolerance (energy=1*kilojoule/mole) The energy tolerance to which the system should be minimized
- maxIterations (int=0) The maximum number of iterations to perform. If this is 0, minimization is continued
- maxIterations (int=0) The maximum number of iterations to perform. If this is 0, minimization is continued
until the results converge without regard to how many iterations it takes.
until the results converge without regard to how many iterations it takes.
"""
"""
mm
.
LocalEnergyMinimizer
.
minimize
(
self
.
context
,
tolerance
,
maxIterations
)
mm
.
LocalEnergyMinimizer
.
minimize
(
self
.
context
,
tolerance
,
maxIterations
)
def
step
(
self
,
steps
):
def
step
(
self
,
steps
):
"""Advance the simulation by integrating a specified number of time steps."""
"""Advance the simulation by integrating a specified number of time steps."""
stepTo
=
self
.
currentStep
+
steps
stepTo
=
self
.
currentStep
+
steps
...
...
wrappers/python/simtk/openmm/app/statedatareporter.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors: Robert McGibbon
Contributors: Robert McGibbon
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -35,7 +35,7 @@ import simtk.openmm as mm
...
@@ -35,7 +35,7 @@ import simtk.openmm as mm
import
simtk.unit
as
unit
import
simtk.unit
as
unit
from
simtk.openmm.app
import
PDBFile
from
simtk.openmm.app
import
PDBFile
import
math
import
math
class
StateDataReporter
(
object
):
class
StateDataReporter
(
object
):
"""StateDataReporter outputs information about a simulation, such as energy and temperature, to a file.
"""StateDataReporter outputs information about a simulation, such as energy and temperature, to a file.
...
...
wrappers/python/simtk/openmm/app/topology.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012-2013 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -37,18 +37,18 @@ from simtk.unit import nanometers, sqrt
...
@@ -37,18 +37,18 @@ from simtk.unit import nanometers, sqrt
class
Topology
(
object
):
class
Topology
(
object
):
"""Topology stores the topological information about a system.
"""Topology stores the topological information about a system.
The structure of a Topology object is similar to that of a PDB file. It consists of a set of Chains
The structure of a Topology object is similar to that of a PDB file. It consists of a set of Chains
(often but not always corresponding to polymer chains). Each Chain contains a set of Residues,
(often but not always corresponding to polymer chains). Each Chain contains a set of Residues,
and each Residue contains a set of Atoms. In addition, the Topology stores a list of which atom
and each Residue contains a set of Atoms. In addition, the Topology stores a list of which atom
pairs are bonded to each other, and the dimensions of the crystallographic unit cell.
pairs are bonded to each other, and the dimensions of the crystallographic unit cell.
Atom and residue names should follow the PDB 3.0 nomenclature for all molecules for which one exists.
Atom and residue names should follow the PDB 3.0 nomenclature for all molecules for which one exists.
"""
"""
_standardBonds
=
{}
_standardBonds
=
{}
_hasLoadedStandardBonds
=
False
_hasLoadedStandardBonds
=
False
def
__init__
(
self
):
def
__init__
(
self
):
"""Create a new Topology object"""
"""Create a new Topology object"""
self
.
_chains
=
[]
self
.
_chains
=
[]
...
@@ -56,19 +56,19 @@ class Topology(object):
...
@@ -56,19 +56,19 @@ class Topology(object):
self
.
_numAtoms
=
0
self
.
_numAtoms
=
0
self
.
_bonds
=
[]
self
.
_bonds
=
[]
self
.
_unitCellDimensions
=
None
self
.
_unitCellDimensions
=
None
def
addChain
(
self
):
def
addChain
(
self
):
"""Create a new Chain and add it to the Topology.
"""Create a new Chain and add it to the Topology.
Returns: the newly created Chain
Returns: the newly created Chain
"""
"""
chain
=
Chain
(
len
(
self
.
_chains
),
self
)
chain
=
Chain
(
len
(
self
.
_chains
),
self
)
self
.
_chains
.
append
(
chain
)
self
.
_chains
.
append
(
chain
)
return
chain
return
chain
def
addResidue
(
self
,
name
,
chain
):
def
addResidue
(
self
,
name
,
chain
):
"""Create a new Residue and add it to the Topology.
"""Create a new Residue and add it to the Topology.
Parameters:
Parameters:
- name (string) The name of the residue to add
- name (string) The name of the residue to add
- chain (Chain) The Chain to add it to
- chain (Chain) The Chain to add it to
...
@@ -78,10 +78,10 @@ class Topology(object):
...
@@ -78,10 +78,10 @@ class Topology(object):
self
.
_numResidues
+=
1
self
.
_numResidues
+=
1
chain
.
_residues
.
append
(
residue
)
chain
.
_residues
.
append
(
residue
)
return
residue
return
residue
def
addAtom
(
self
,
name
,
element
,
residue
):
def
addAtom
(
self
,
name
,
element
,
residue
):
"""Create a new Atom and add it to the Topology.
"""Create a new Atom and add it to the Topology.
Parameters:
Parameters:
- name (string) The name of the atom to add
- name (string) The name of the atom to add
- element (Element) The element of the atom to add
- element (Element) The element of the atom to add
...
@@ -92,52 +92,52 @@ class Topology(object):
...
@@ -92,52 +92,52 @@ class Topology(object):
self
.
_numAtoms
+=
1
self
.
_numAtoms
+=
1
residue
.
_atoms
.
append
(
atom
)
residue
.
_atoms
.
append
(
atom
)
return
atom
return
atom
def
addBond
(
self
,
atom1
,
atom2
):
def
addBond
(
self
,
atom1
,
atom2
):
"""Create a new bond and add it to the Topology.
"""Create a new bond and add it to the Topology.
Parameters:
Parameters:
- atom1 (Atom) The first Atom connected by the bond
- atom1 (Atom) The first Atom connected by the bond
- atom2 (Atom) The second Atom connected by the bond
- atom2 (Atom) The second Atom connected by the bond
"""
"""
self
.
_bonds
.
append
((
atom1
,
atom2
))
self
.
_bonds
.
append
((
atom1
,
atom2
))
def
chains
(
self
):
def
chains
(
self
):
"""Iterate over all Chains in the Topology."""
"""Iterate over all Chains in the Topology."""
return
iter
(
self
.
_chains
)
return
iter
(
self
.
_chains
)
def
residues
(
self
):
def
residues
(
self
):
"""Iterate over all Residues in the Topology."""
"""Iterate over all Residues in the Topology."""
for
chain
in
self
.
_chains
:
for
chain
in
self
.
_chains
:
for
residue
in
chain
.
_residues
:
for
residue
in
chain
.
_residues
:
yield
residue
yield
residue
def
atoms
(
self
):
def
atoms
(
self
):
"""Iterate over all Atoms in the Topology."""
"""Iterate over all Atoms in the Topology."""
for
chain
in
self
.
_chains
:
for
chain
in
self
.
_chains
:
for
residue
in
chain
.
_residues
:
for
residue
in
chain
.
_residues
:
for
atom
in
residue
.
_atoms
:
for
atom
in
residue
.
_atoms
:
yield
atom
yield
atom
def
bonds
(
self
):
def
bonds
(
self
):
"""Iterate over all bonds (each represented as a tuple of two Atoms) in the Topology."""
"""Iterate over all bonds (each represented as a tuple of two Atoms) in the Topology."""
return
iter
(
self
.
_bonds
)
return
iter
(
self
.
_bonds
)
def
getUnitCellDimensions
(
self
):
def
getUnitCellDimensions
(
self
):
"""Get the dimensions of the crystallographic unit cell.
"""Get the dimensions of the crystallographic unit cell.
The return value may be None if this Topology does not represent a periodic structure.
The return value may be None if this Topology does not represent a periodic structure.
"""
"""
return
self
.
_unitCellDimensions
return
self
.
_unitCellDimensions
def
setUnitCellDimensions
(
self
,
dimensions
):
def
setUnitCellDimensions
(
self
,
dimensions
):
"""Set the dimensions of the crystallographic unit cell."""
"""Set the dimensions of the crystallographic unit cell."""
self
.
_unitCellDimensions
=
dimensions
self
.
_unitCellDimensions
=
dimensions
@
staticmethod
@
staticmethod
def
loadBondDefinitions
(
file
):
def
loadBondDefinitions
(
file
):
"""Load an XML file containing definitions of bonds that should be used by createStandardBonds().
"""Load an XML file containing definitions of bonds that should be used by createStandardBonds().
The built in residues.xml file containing definitions for standard amino acids and nucleotides is loaded automatically.
The built in residues.xml file containing definitions for standard amino acids and nucleotides is loaded automatically.
This method can be used to load additional definitions for other residue types. They will then be used in subsequent
This method can be used to load additional definitions for other residue types. They will then be used in subsequent
calls to createStandardBonds(). This is a static method, so it affects subsequent calls on all Topology objects.
calls to createStandardBonds(). This is a static method, so it affects subsequent calls on all Topology objects.
...
@@ -149,31 +149,31 @@ class Topology(object):
...
@@ -149,31 +149,31 @@ class Topology(object):
bonds
=
[]
bonds
=
[]
Topology
.
_standardBonds
[
residue
.
attrib
[
'name'
]]
=
bonds
Topology
.
_standardBonds
[
residue
.
attrib
[
'name'
]]
=
bonds
for
bond
in
residue
.
findall
(
'Bond'
):
for
bond
in
residue
.
findall
(
'Bond'
):
bonds
.
append
((
bond
.
attrib
[
'from'
],
bond
.
attrib
[
'to'
]))
bonds
.
append
((
bond
.
attrib
[
'from'
],
bond
.
attrib
[
'to'
]))
def
createStandardBonds
(
self
):
def
createStandardBonds
(
self
):
"""Create bonds based on the atom and residue names for all standard residue types.
"""Create bonds based on the atom and residue names for all standard residue types.
Definitions for standard amino acids and nucleotides are built in. You can call loadBondDefinitions() to load
Definitions for standard amino acids and nucleotides are built in. You can call loadBondDefinitions() to load
additional definitions for other residue types.
additional definitions for other residue types.
"""
"""
if
not
Topology
.
_hasLoadedStandardBonds
:
if
not
Topology
.
_hasLoadedStandardBonds
:
# Load the standard bond definitions.
# Load the standard bond definitions.
Topology
.
loadBondDefinitions
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'data'
,
'residues.xml'
))
Topology
.
loadBondDefinitions
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'data'
,
'residues.xml'
))
Topology
.
_hasLoadedStandardBonds
=
True
Topology
.
_hasLoadedStandardBonds
=
True
for
chain
in
self
.
_chains
:
for
chain
in
self
.
_chains
:
# First build a map of atom names to atoms.
# First build a map of atom names to atoms.
atomMaps
=
[]
atomMaps
=
[]
for
residue
in
chain
.
_residues
:
for
residue
in
chain
.
_residues
:
atomMap
=
{}
atomMap
=
{}
atomMaps
.
append
(
atomMap
)
atomMaps
.
append
(
atomMap
)
for
atom
in
residue
.
_atoms
:
for
atom
in
residue
.
_atoms
:
atomMap
[
atom
.
name
]
=
atom
atomMap
[
atom
.
name
]
=
atom
# Loop over residues and construct bonds.
# Loop over residues and construct bonds.
for
i
in
range
(
len
(
chain
.
_residues
)):
for
i
in
range
(
len
(
chain
.
_residues
)):
name
=
chain
.
_residues
[
i
].
name
name
=
chain
.
_residues
[
i
].
name
if
name
in
Topology
.
_standardBonds
:
if
name
in
Topology
.
_standardBonds
:
...
@@ -198,17 +198,17 @@ class Topology(object):
...
@@ -198,17 +198,17 @@ class Topology(object):
toAtom
=
bond
[
1
]
toAtom
=
bond
[
1
]
if
fromAtom
in
atomMaps
[
fromResidue
]
and
toAtom
in
atomMaps
[
toResidue
]:
if
fromAtom
in
atomMaps
[
fromResidue
]
and
toAtom
in
atomMaps
[
toResidue
]:
self
.
addBond
(
atomMaps
[
fromResidue
][
fromAtom
],
atomMaps
[
toResidue
][
toAtom
])
self
.
addBond
(
atomMaps
[
fromResidue
][
fromAtom
],
atomMaps
[
toResidue
][
toAtom
])
def
createDisulfideBonds
(
self
,
positions
):
def
createDisulfideBonds
(
self
,
positions
):
"""Identify disulfide bonds based on proximity and add them to the Topology.
"""Identify disulfide bonds based on proximity and add them to the Topology.
Parameters:
Parameters:
- positions (list) The list of atomic positions based on which to identify bonded atoms
- positions (list) The list of atomic positions based on which to identify bonded atoms
"""
"""
def
isCyx
(
res
):
def
isCyx
(
res
):
names
=
[
atom
.
name
for
atom
in
res
.
_atoms
]
names
=
[
atom
.
name
for
atom
in
res
.
_atoms
]
return
'SG'
in
names
and
'HG'
not
in
names
return
'SG'
in
names
and
'HG'
not
in
names
cyx
=
[
res
for
res
in
self
.
residues
()
if
res
.
name
==
'CYS'
and
isCyx
(
res
)]
cyx
=
[
res
for
res
in
self
.
residues
()
if
res
.
name
==
'CYS'
and
isCyx
(
res
)]
atomNames
=
[[
atom
.
name
for
atom
in
res
.
_atoms
]
for
res
in
cyx
]
atomNames
=
[[
atom
.
name
for
atom
in
res
.
_atoms
]
for
res
in
cyx
]
for
i
in
range
(
len
(
cyx
)):
for
i
in
range
(
len
(
cyx
)):
...
@@ -231,7 +231,7 @@ class Chain(object):
...
@@ -231,7 +231,7 @@ class Chain(object):
## The Topology this Chain belongs to
## The Topology this Chain belongs to
self
.
topology
=
topology
self
.
topology
=
topology
self
.
_residues
=
[]
self
.
_residues
=
[]
def
residues
(
self
):
def
residues
(
self
):
"""Iterate over all Residues in the Chain."""
"""Iterate over all Residues in the Chain."""
return
iter
(
self
.
_residues
)
return
iter
(
self
.
_residues
)
...
@@ -253,14 +253,14 @@ class Residue(object):
...
@@ -253,14 +253,14 @@ class Residue(object):
## The Chain this Residue belongs to
## The Chain this Residue belongs to
self
.
chain
=
chain
self
.
chain
=
chain
self
.
_atoms
=
[]
self
.
_atoms
=
[]
def
atoms
(
self
):
def
atoms
(
self
):
"""Iterate over all Atoms in the Residue."""
"""Iterate over all Atoms in the Residue."""
return
iter
(
self
.
_atoms
)
return
iter
(
self
.
_atoms
)
class
Atom
(
object
):
class
Atom
(
object
):
"""An Atom object represents a residue within a Topology."""
"""An Atom object represents a residue within a Topology."""
def
__init__
(
self
,
name
,
element
,
index
,
residue
):
def
__init__
(
self
,
name
,
element
,
index
,
residue
):
"""Construct a new Atom. You should call addAtom() on the Topology instead of calling this directly."""
"""Construct a new Atom. You should call addAtom() on the Topology instead of calling this directly."""
## The name of the Atom
## The name of the Atom
...
...
wrappers/python/simtk/openmm/vec3.py
View file @
4941cc7d
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman
Authors: Peter Eastman
Contributors:
Contributors:
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -35,43 +35,43 @@ import simtk.unit as unit
...
@@ -35,43 +35,43 @@ import simtk.unit as unit
class
Vec3
(
tuple
):
class
Vec3
(
tuple
):
"""Vec3 is a 3-element tuple that supports many math operations."""
"""Vec3 is a 3-element tuple that supports many math operations."""
def
__new__
(
cls
,
x
,
y
,
z
):
def
__new__
(
cls
,
x
,
y
,
z
):
"""Create a new Vec3."""
"""Create a new Vec3."""
return
tuple
.
__new__
(
cls
,
(
x
,
y
,
z
))
return
tuple
.
__new__
(
cls
,
(
x
,
y
,
z
))
def
__add__
(
self
,
other
):
def
__add__
(
self
,
other
):
"""Add two Vec3s."""
"""Add two Vec3s."""
return
Vec3
(
self
[
0
]
+
other
[
0
],
self
[
1
]
+
other
[
1
],
self
[
2
]
+
other
[
2
])
return
Vec3
(
self
[
0
]
+
other
[
0
],
self
[
1
]
+
other
[
1
],
self
[
2
]
+
other
[
2
])
def
__radd__
(
self
,
other
):
def
__radd__
(
self
,
other
):
"""Add two Vec3s."""
"""Add two Vec3s."""
return
Vec3
(
self
[
0
]
+
other
[
0
],
self
[
1
]
+
other
[
1
],
self
[
2
]
+
other
[
2
])
return
Vec3
(
self
[
0
]
+
other
[
0
],
self
[
1
]
+
other
[
1
],
self
[
2
]
+
other
[
2
])
def
__sub__
(
self
,
other
):
def
__sub__
(
self
,
other
):
"""Add two Vec3s."""
"""Add two Vec3s."""
return
Vec3
(
self
[
0
]
-
other
[
0
],
self
[
1
]
-
other
[
1
],
self
[
2
]
-
other
[
2
])
return
Vec3
(
self
[
0
]
-
other
[
0
],
self
[
1
]
-
other
[
1
],
self
[
2
]
-
other
[
2
])
def
__rsub__
(
self
,
other
):
def
__rsub__
(
self
,
other
):
"""Add two Vec3s."""
"""Add two Vec3s."""
return
Vec3
(
other
[
0
]
-
self
[
0
],
other
[
1
]
-
self
[
1
],
other
[
2
]
-
self
[
2
])
return
Vec3
(
other
[
0
]
-
self
[
0
],
other
[
1
]
-
self
[
1
],
other
[
2
]
-
self
[
2
])
def
__mul__
(
self
,
other
):
def
__mul__
(
self
,
other
):
"""Multiply a Vec3 by a constant."""
"""Multiply a Vec3 by a constant."""
if
unit
.
is_unit
(
other
):
if
unit
.
is_unit
(
other
):
return
unit
.
Quantity
(
self
,
other
)
return
unit
.
Quantity
(
self
,
other
)
return
Vec3
(
other
*
self
[
0
],
other
*
self
[
1
],
other
*
self
[
2
])
return
Vec3
(
other
*
self
[
0
],
other
*
self
[
1
],
other
*
self
[
2
])
def
__rmul__
(
self
,
other
):
def
__rmul__
(
self
,
other
):
"""Multiply a Vec3 by a constant."""
"""Multiply a Vec3 by a constant."""
if
unit
.
is_unit
(
other
):
if
unit
.
is_unit
(
other
):
return
unit
.
Quantity
(
self
,
other
)
return
unit
.
Quantity
(
self
,
other
)
return
Vec3
(
other
*
self
[
0
],
other
*
self
[
1
],
other
*
self
[
2
])
return
Vec3
(
other
*
self
[
0
],
other
*
self
[
1
],
other
*
self
[
2
])
def
__div__
(
self
,
other
):
def
__div__
(
self
,
other
):
"""Divide a Vec3 by a constant."""
"""Divide a Vec3 by a constant."""
return
Vec3
(
self
[
0
]
/
other
,
self
[
1
]
/
other
,
self
[
2
]
/
other
)
return
Vec3
(
self
[
0
]
/
other
,
self
[
1
]
/
other
,
self
[
2
]
/
other
)
__truediv__
=
__div__
__truediv__
=
__div__
def
__deepcopy__
(
self
,
memo
):
def
__deepcopy__
(
self
,
memo
):
return
Vec3
(
self
[
0
],
self
[
1
],
self
[
2
])
return
Vec3
(
self
[
0
],
self
[
1
],
self
[
2
])
wrappers/python/simtk/unit/basedimension.py
View file @
4941cc7d
...
@@ -16,7 +16,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
...
@@ -16,7 +16,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns
Authors: Christopher M. Bruns
Contributors: Peter Eastman
Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
the rights to use, copy, modify, merge, publish, distribute, sublicense,
...
@@ -42,7 +42,7 @@ __version__ = "0.6"
...
@@ -42,7 +42,7 @@ __version__ = "0.6"
class
BaseDimension
(
object
):
class
BaseDimension
(
object
):
'''
'''
A physical dimension such as length, mass, or temperature.
A physical dimension such as length, mass, or temperature.
It is unlikely the user will need to create new ones.
It is unlikely the user will need to create new ones.
'''
'''
# Keep deterministic order of dimensions
# Keep deterministic order of dimensions
...
@@ -57,7 +57,7 @@ class BaseDimension(object):
...
@@ -57,7 +57,7 @@ class BaseDimension(object):
'angle'
:
8
,
'angle'
:
8
,
}
}
_next_unused_index
=
9
_next_unused_index
=
9
def
__init__
(
self
,
name
):
def
__init__
(
self
,
name
):
"""Create a new BaseDimension.
"""Create a new BaseDimension.
...
@@ -70,17 +70,17 @@ class BaseDimension(object):
...
@@ -70,17 +70,17 @@ class BaseDimension(object):
BaseDimension
.
_index_by_name
[
name
]
=
BaseDimension
.
_next_unused_index
BaseDimension
.
_index_by_name
[
name
]
=
BaseDimension
.
_next_unused_index
BaseDimension
.
_next_unused_index
+=
1
BaseDimension
.
_next_unused_index
+=
1
self
.
_index
=
BaseDimension
.
_index_by_name
[
name
]
self
.
_index
=
BaseDimension
.
_index_by_name
[
name
]
def
__lt__
(
self
,
other
):
def
__lt__
(
self
,
other
):
"""
"""
The implicit order of BaseDimensions is the order in which they were created.
The implicit order of BaseDimensions is the order in which they were created.
This method is used for using BaseDimensions as hash keys, and also affects
This method is used for using BaseDimensions as hash keys, and also affects
the order in which units appear in multi-dimensional Quantities.
the order in which units appear in multi-dimensional Quantities.
Returns True if self < other, False otherwise.
Returns True if self < other, False otherwise.
"""
"""
return
self
.
_index
<
other
.
_index
return
self
.
_index
<
other
.
_index
def
__hash__
(
self
):
def
__hash__
(
self
):
"""
"""
Needed for using BaseDimensions as hash keys.
Needed for using BaseDimensions as hash keys.
...
...
Prev
1
2
Next
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