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
c7aa1d00
Commit
c7aa1d00
authored
Jul 21, 2014
by
kyleabeauchamp
Browse files
Merge remote-tracking branch 'upstream/master' into vagrant
parents
aea4e454
f7127d33
Changes
52
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
11806 additions
and
230 deletions
+11806
-230
plugins/drude/platforms/cuda/tests/TestCudaDrudeForce.cpp
plugins/drude/platforms/cuda/tests/TestCudaDrudeForce.cpp
+11
-11
plugins/drude/platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
.../platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
+3
-3
plugins/drude/platforms/cuda/tests/TestCudaDrudeSCFIntegrator.cpp
...drude/platforms/cuda/tests/TestCudaDrudeSCFIntegrator.cpp
+1
-1
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
+6
-6
plugins/drude/platforms/opencl/src/kernels/drudePairForce.cl
plugins/drude/platforms/opencl/src/kernels/drudePairForce.cl
+4
-4
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeForce.cpp
...ins/drude/platforms/opencl/tests/TestOpenCLDrudeForce.cpp
+11
-11
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
...tforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
+3
-3
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeSCFIntegrator.cpp
...e/platforms/opencl/tests/TestOpenCLDrudeSCFIntegrator.cpp
+1
-1
plugins/drude/platforms/reference/src/ReferenceDrudeKernels.cpp
...s/drude/platforms/reference/src/ReferenceDrudeKernels.cpp
+8
-7
plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp
...ude/platforms/reference/tests/TestReferenceDrudeForce.cpp
+11
-11
plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
.../reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
+3
-3
plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp
...forms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp
+1
-1
wrappers/python/CMakeLists.txt
wrappers/python/CMakeLists.txt
+4
-0
wrappers/python/simtk/openmm/app/__init__.py
wrappers/python/simtk/openmm/app/__init__.py
+1
-1
wrappers/python/simtk/openmm/app/charmmparameterset.py
wrappers/python/simtk/openmm/app/charmmparameterset.py
+23
-3
wrappers/python/simtk/openmm/app/charmmpsffile.py
wrappers/python/simtk/openmm/app/charmmpsffile.py
+101
-4
wrappers/python/simtk/openmm/app/data/charmm_polar_2013.xml
wrappers/python/simtk/openmm/app/data/charmm_polar_2013.xml
+11396
-0
wrappers/python/simtk/openmm/app/data/swm4ndp.xml
wrappers/python/simtk/openmm/app/data/swm4ndp.xml
+1
-1
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+124
-99
wrappers/python/simtk/openmm/app/internal/amber_file_parser.py
...ers/python/simtk/openmm/app/internal/amber_file_parser.py
+93
-60
No files found.
plugins/drude/platforms/cuda/tests/TestCudaDrudeForce.cpp
View file @
c7aa1d00
...
...
@@ -61,7 +61,7 @@ void validateForce(System& system, vector<Vec3>& positions, double expectedEnerg
// Try moving each particle along each axis, and see if the energy changes by the correct amount.
double
offset
=
1e-
3
;
double
offset
=
1e-
2
;
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
vector
<
Vec3
>
offsetPos
=
positions
;
...
...
@@ -76,9 +76,9 @@ void validateForce(System& system, vector<Vec3>& positions, double expectedEnerg
}
void
testSingleParticle
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
...
@@ -92,9 +92,9 @@ void testSingleParticle() {
}
void
testAnisotropicParticle
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
a1
=
0.8
;
const
double
a2
=
1.1
;
const
double
k1
=
k
/
a1
;
...
...
@@ -124,9 +124,9 @@ double computeScreening(double r, double thole, double alpha1, double alpha2) {
}
void
testThole
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
thole
=
2.5
;
System
system
;
system
.
addParticle
(
1.0
);
...
...
@@ -157,9 +157,9 @@ void testThole() {
}
void
testChangingParameters
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
Platform
&
platform
=
Platform
::
getPlatformByName
(
"CUDA"
);
// Create the system.
...
...
@@ -184,9 +184,9 @@ void testChangingParameters() {
// Modify the parameters.
const
double
k2
=
2.2
;
const
double
k2
=
ONE_4PI_EPS0
*
2.2
;
const
double
charge2
=
0.3
;
const
double
alpha2
=
charge2
*
charge2
/
k2
;
const
double
alpha2
=
ONE_4PI_EPS0
*
charge2
*
charge2
/
k2
;
drude
->
setParticleParameters
(
0
,
1
,
0
,
-
1
,
-
1
,
-
1
,
charge2
,
alpha2
,
1
,
1
);
drude
->
updateParametersInContext
(
context
);
state
=
context
.
getState
(
State
::
Energy
);
...
...
plugins/drude/platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp
View file @
c7aa1d00
...
...
@@ -53,9 +53,9 @@ extern "C" OPENMM_EXPORT void registerDrudeCudaKernelFactories();
void
testSinglePair
()
{
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
mass1
=
1.0
;
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
...
...
@@ -132,7 +132,7 @@ void testWater() {
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
...
...
plugins/drude/platforms/cuda/tests/TestCudaDrudeSCFIntegrator.cpp
View file @
c7aa1d00
...
...
@@ -85,7 +85,7 @@ void testWater() {
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
...
...
plugins/drude/platforms/opencl/src/OpenCLDrudeKernels.cpp
View file @
c7aa1d00
...
...
@@ -131,9 +131,9 @@ void OpenCLCalcDrudeForceKernel::initialize(const System& system, const DrudeFor
double
a1
=
(
atoms
[
i
][
2
]
==
-
1
?
1
:
aniso12
);
double
a2
=
(
atoms
[
i
][
3
]
==
-
1
||
atoms
[
i
][
4
]
==
-
1
?
1
:
aniso34
);
double
a3
=
3
-
a1
-
a2
;
double
k3
=
charge
*
charge
/
(
polarizability
*
a3
);
double
k1
=
charge
*
charge
/
(
polarizability
*
a1
)
-
k3
;
double
k2
=
charge
*
charge
/
(
polarizability
*
a2
)
-
k3
;
double
k3
=
ONE_4PI_EPS0
*
charge
*
charge
/
(
polarizability
*
a3
);
double
k1
=
ONE_4PI_EPS0
*
charge
*
charge
/
(
polarizability
*
a1
)
-
k3
;
double
k2
=
ONE_4PI_EPS0
*
charge
*
charge
/
(
polarizability
*
a2
)
-
k3
;
if
(
atoms
[
i
][
2
]
==
-
1
)
{
atoms
[
i
][
2
]
=
0
;
k1
=
0
;
...
...
@@ -202,9 +202,9 @@ void OpenCLCalcDrudeForceKernel::copyParametersToContext(ContextImpl& context, c
double
a1
=
(
p2
==
-
1
?
1
:
aniso12
);
double
a2
=
(
p3
==
-
1
||
p4
==
-
1
?
1
:
aniso34
);
double
a3
=
3
-
a1
-
a2
;
double
k3
=
charge
*
charge
/
(
polarizability
*
a3
);
double
k1
=
charge
*
charge
/
(
polarizability
*
a1
)
-
k3
;
double
k2
=
charge
*
charge
/
(
polarizability
*
a2
)
-
k3
;
double
k3
=
ONE_4PI_EPS0
*
charge
*
charge
/
(
polarizability
*
a3
);
double
k1
=
ONE_4PI_EPS0
*
charge
*
charge
/
(
polarizability
*
a1
)
-
k3
;
double
k2
=
ONE_4PI_EPS0
*
charge
*
charge
/
(
polarizability
*
a2
)
-
k3
;
if
(
p2
==
-
1
)
k1
=
0
;
if
(
p3
==
-
1
||
p4
==
-
1
)
...
...
plugins/drude/platforms/opencl/src/kernels/drudePairForce.cl
View file @
c7aa1d00
...
...
@@ -13,7 +13,7 @@ real u = drudeParams.x*r;
real
screening
=
1-
(
1+0.5f*u
)
*EXP
(
-u
)
;
real
pairEnergy
=
drudeParams.y*screening*rInv
;
energy
+=
pairEnergy
;
real4
f
=
delta*
(
pairEnergy*rInv*rInv
)
;
real4
f
=
delta*
(
drudeParams.y*rInv*rInv
)
*
(
screening*rInv-0.5f*
(
1+u
)
*EXP
(
-u
)
*drudeParams.x
)
;
force1
+=
f
;
force3
-=
f
;
...
...
@@ -26,7 +26,7 @@ u = drudeParams.x*r;
screening
=
1-
(
1+0.5f*u
)
*EXP
(
-u
)
;
pairEnergy
=
-drudeParams.y*screening*rInv
;
energy
+=
pairEnergy
;
f
=
delta*
(
pairEnergy*rInv*rInv
)
;
f
=
delta*
(
-drudeParams.y*rInv*rInv
)
*
(
screening*rInv-0.5f*
(
1+u
)
*EXP
(
-u
)
*drudeParams.x
)
;
force1
+=
f
;
force4
-=
f
;
...
...
@@ -39,7 +39,7 @@ u = drudeParams.x*r;
screening
=
1-
(
1+0.5f*u
)
*EXP
(
-u
)
;
pairEnergy
=
-drudeParams.y*screening*rInv
;
energy
+=
pairEnergy
;
f
=
delta*
(
pairEnergy*rInv*rInv
)
;
f
=
delta*
(
-drudeParams.y*rInv*rInv
)
*
(
screening*rInv-0.5f*
(
1+u
)
*EXP
(
-u
)
*drudeParams.x
)
;
force2
+=
f
;
force3
-=
f
;
...
...
@@ -52,6 +52,6 @@ u = drudeParams.x*r;
screening
=
1-
(
1+0.5f*u
)
*EXP
(
-u
)
;
pairEnergy
=
drudeParams.y*screening*rInv
;
energy
+=
pairEnergy
;
f
=
delta*
(
pairEnergy*rInv*rInv
)
;
f
=
delta*
(
drudeParams.y*rInv*rInv
)
*
(
screening*rInv-0.5f*
(
1+u
)
*EXP
(
-u
)
*drudeParams.x
)
;
force2
+=
f
;
force4
-=
f
;
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeForce.cpp
View file @
c7aa1d00
...
...
@@ -61,7 +61,7 @@ void validateForce(System& system, vector<Vec3>& positions, double expectedEnerg
// Try moving each particle along each axis, and see if the energy changes by the correct amount.
double
offset
=
1e-
3
;
double
offset
=
1e-
2
;
for
(
int
i
=
0
;
i
<
system
.
getNumParticles
();
i
++
)
for
(
int
j
=
0
;
j
<
3
;
j
++
)
{
vector
<
Vec3
>
offsetPos
=
positions
;
...
...
@@ -76,9 +76,9 @@ void validateForce(System& system, vector<Vec3>& positions, double expectedEnerg
}
void
testSingleParticle
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
...
@@ -92,9 +92,9 @@ void testSingleParticle() {
}
void
testAnisotropicParticle
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
a1
=
0.8
;
const
double
a2
=
1.1
;
const
double
k1
=
k
/
a1
;
...
...
@@ -124,9 +124,9 @@ double computeScreening(double r, double thole, double alpha1, double alpha2) {
}
void
testThole
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
thole
=
2.5
;
System
system
;
system
.
addParticle
(
1.0
);
...
...
@@ -157,9 +157,9 @@ void testThole() {
}
void
testChangingParameters
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
Platform
&
platform
=
Platform
::
getPlatformByName
(
"OpenCL"
);
// Create the system.
...
...
@@ -184,9 +184,9 @@ void testChangingParameters() {
// Modify the parameters.
const
double
k2
=
2.2
;
const
double
k2
=
ONE_4PI_EPS0
*
2.2
;
const
double
charge2
=
0.3
;
const
double
alpha2
=
charge2
*
charge2
/
k2
;
const
double
alpha2
=
ONE_4PI_EPS0
*
charge2
*
charge2
/
k2
;
drude
->
setParticleParameters
(
0
,
1
,
0
,
-
1
,
-
1
,
-
1
,
charge2
,
alpha2
,
1
,
1
);
drude
->
updateParametersInContext
(
context
);
state
=
context
.
getState
(
State
::
Energy
);
...
...
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp
View file @
c7aa1d00
...
...
@@ -53,9 +53,9 @@ extern "C" OPENMM_EXPORT void registerDrudeOpenCLKernelFactories();
void
testSinglePair
()
{
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
mass1
=
1.0
;
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
...
...
@@ -132,7 +132,7 @@ void testWater() {
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
...
...
plugins/drude/platforms/opencl/tests/TestOpenCLDrudeSCFIntegrator.cpp
View file @
c7aa1d00
...
...
@@ -85,7 +85,7 @@ void testWater() {
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
...
...
plugins/drude/platforms/reference/src/ReferenceDrudeKernels.cpp
View file @
c7aa1d00
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2011-201
3
Stanford University and the Authors. *
* Portions copyright (c) 2011-201
4
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -136,9 +136,9 @@ double ReferenceCalcDrudeForceKernel::execute(ContextImpl& context, bool include
RealOpenMM
a1
=
(
p2
==
-
1
?
1
:
aniso12
[
i
]);
RealOpenMM
a2
=
(
p3
==
-
1
||
p4
==
-
1
?
1
:
aniso34
[
i
]);
RealOpenMM
a3
=
3
-
a1
-
a2
;
RealOpenMM
k3
=
charge
[
i
]
*
charge
[
i
]
/
(
polarizability
[
i
]
*
a3
);
RealOpenMM
k1
=
charge
[
i
]
*
charge
[
i
]
/
(
polarizability
[
i
]
*
a1
)
-
k3
;
RealOpenMM
k2
=
charge
[
i
]
*
charge
[
i
]
/
(
polarizability
[
i
]
*
a2
)
-
k3
;
RealOpenMM
k3
=
ONE_4PI_EPS0
*
charge
[
i
]
*
charge
[
i
]
/
(
polarizability
[
i
]
*
a3
);
RealOpenMM
k1
=
ONE_4PI_EPS0
*
charge
[
i
]
*
charge
[
i
]
/
(
polarizability
[
i
]
*
a1
)
-
k3
;
RealOpenMM
k2
=
ONE_4PI_EPS0
*
charge
[
i
]
*
charge
[
i
]
/
(
polarizability
[
i
]
*
a2
)
-
k3
;
// Compute the isotropic force.
...
...
@@ -188,6 +188,7 @@ double ReferenceCalcDrudeForceKernel::execute(ContextImpl& context, bool include
int
dipole2
=
pair2
[
i
];
int
dipole1Particles
[]
=
{
particle
[
dipole1
],
particle1
[
dipole1
]};
int
dipole2Particles
[]
=
{
particle
[
dipole2
],
particle1
[
dipole2
]};
RealOpenMM
uscale
=
pairThole
[
i
]
/
pow
(
polarizability
[
dipole1
]
*
polarizability
[
dipole2
],
1.0
/
6.0
);
for
(
int
j
=
0
;
j
<
2
;
j
++
)
for
(
int
k
=
0
;
k
<
2
;
k
++
)
{
int
p1
=
dipole1Particles
[
j
];
...
...
@@ -195,10 +196,10 @@ double ReferenceCalcDrudeForceKernel::execute(ContextImpl& context, bool include
RealOpenMM
chargeProduct
=
charge
[
dipole1
]
*
charge
[
dipole2
]
*
(
j
==
k
?
1
:
-
1
);
RealVec
delta
=
pos
[
p1
]
-
pos
[
p2
];
RealOpenMM
r
=
sqrt
(
delta
.
dot
(
delta
));
RealOpenMM
u
=
r
*
pairThole
[
i
]
/
pow
(
polarizability
[
dipole1
]
*
polarizability
[
dipole2
],
1.0
/
6.0
)
;
RealOpenMM
u
=
r
*
uscale
;
RealOpenMM
screening
=
1.0
-
(
1.0
+
0.5
*
u
)
*
exp
(
-
u
);
energy
+=
ONE_4PI_EPS0
*
chargeProduct
*
screening
/
r
;
RealVec
f
=
delta
*
(
ONE_4PI_EPS0
*
chargeProduct
*
screening
/
(
r
*
r
*
r
)
);
RealVec
f
=
delta
*
(
ONE_4PI_EPS0
*
chargeProduct
/
(
r
*
r
))
*
(
screening
/
r
-
0.5
*
(
1
+
u
)
*
exp
(
-
u
)
*
uscale
);
force
[
p1
]
+=
f
;
force
[
p2
]
-=
f
;
}
...
...
@@ -461,4 +462,4 @@ void ReferenceIntegrateDrudeSCFStepKernel::minimize(ContextImpl& context, double
lbfgsfloatval_t
fx
;
MinimizerData
data
(
context
,
drudeParticles
);
lbfgs
(
numDrudeParticles
*
3
,
minimizerPos
,
&
fx
,
evaluate
,
NULL
,
&
data
,
&
minimizerParams
);
}
\ No newline at end of file
}
plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp
View file @
c7aa1d00
...
...
@@ -71,14 +71,14 @@ void validateForce(System& system, vector<Vec3>& positions, double expectedEnerg
offsetPos
[
i
][
j
]
=
positions
[
i
][
j
]
+
offset
;
context
.
setPositions
(
offsetPos
);
double
e2
=
context
.
getState
(
State
::
Energy
|
State
::
Forces
).
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
state
.
getForces
()[
i
][
j
],
(
e1
-
e2
)
/
(
2
*
offset
),
1e-
3
);
ASSERT_EQUAL_TOL
(
state
.
getForces
()[
i
][
j
],
(
e1
-
e2
)
/
(
2
*
offset
),
1e-
5
);
}
}
void
testSingleParticle
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
...
@@ -92,9 +92,9 @@ void testSingleParticle() {
}
void
testAnisotropicParticle
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
a1
=
0.8
;
const
double
a2
=
1.1
;
const
double
k1
=
k
/
a1
;
...
...
@@ -124,9 +124,9 @@ double computeScreening(double r, double thole, double alpha1, double alpha2) {
}
void
testThole
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
thole
=
2.5
;
System
system
;
system
.
addParticle
(
1.0
);
...
...
@@ -157,9 +157,9 @@ void testThole() {
}
void
testChangingParameters
()
{
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
Platform
&
platform
=
Platform
::
getPlatformByName
(
"Reference"
);
// Create the system.
...
...
@@ -184,9 +184,9 @@ void testChangingParameters() {
// Modify the parameters.
const
double
k2
=
2.2
;
const
double
k2
=
ONE_4PI_EPS0
*
2.2
;
const
double
charge2
=
0.3
;
const
double
alpha2
=
charge2
*
charge2
/
k2
;
const
double
alpha2
=
ONE_4PI_EPS0
*
charge2
*
charge2
/
k2
;
drude
->
setParticleParameters
(
0
,
1
,
0
,
-
1
,
-
1
,
-
1
,
charge2
,
alpha2
,
1
,
1
);
drude
->
updateParametersInContext
(
context
);
state
=
context
.
getState
(
State
::
Energy
);
...
...
plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp
View file @
c7aa1d00
...
...
@@ -53,9 +53,9 @@ extern "C" OPENMM_EXPORT void registerDrudeReferenceKernelFactories();
void
testSinglePair
()
{
const
double
temperature
=
300.0
;
const
double
temperatureDrude
=
10.0
;
const
double
k
=
1.5
;
const
double
k
=
ONE_4PI_EPS0
*
1.5
;
const
double
charge
=
0.1
;
const
double
alpha
=
charge
*
charge
/
k
;
const
double
alpha
=
ONE_4PI_EPS0
*
charge
*
charge
/
k
;
const
double
mass1
=
1.0
;
const
double
mass2
=
0.1
;
const
double
totalMass
=
mass1
+
mass2
;
...
...
@@ -132,7 +132,7 @@ void testWater() {
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
...
...
plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp
View file @
c7aa1d00
...
...
@@ -85,7 +85,7 @@ void testWater() {
system
.
addConstraint
(
startIndex
,
startIndex
+
3
,
0.09572
);
system
.
addConstraint
(
startIndex
+
2
,
startIndex
+
3
,
0.15139
);
system
.
setVirtualSite
(
startIndex
+
4
,
new
ThreeParticleAverageSite
(
startIndex
,
startIndex
+
2
,
startIndex
+
3
,
0.786646558
,
0.106676721
,
0.106676721
));
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
drude
->
addParticle
(
startIndex
+
1
,
startIndex
,
-
1
,
-
1
,
-
1
,
-
1.71636
,
ONE_4PI_EPS0
*
1.71636
*
1.71636
/
(
100000
*
4.184
),
1
,
1
);
}
vector
<
Vec3
>
positions
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
...
...
wrappers/python/CMakeLists.txt
View file @
c7aa1d00
...
...
@@ -55,12 +55,16 @@ foreach(SUBDIR ${SUBDIRS})
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.xml"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.pdb"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.prmtop"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.prm"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.inpcrd"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.crd"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.parm7"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.rst7"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.ncrst"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.dms"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.top"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.par"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*.str"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/*psf"
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/
${
SUBDIR
}
/charmm22.*"
)
...
...
wrappers/python/simtk/openmm/app/__init__.py
View file @
c7aa1d00
...
...
@@ -28,7 +28,7 @@ from desmonddmsfile import DesmondDMSFile
from
checkpointreporter
import
CheckpointReporter
from
charmmcrdfiles
import
CharmmCrdFile
,
CharmmRstFile
from
charmmparameterset
import
CharmmParameterSet
from
charmmpsffile
import
CharmmPsfFile
from
charmmpsffile
import
CharmmPsfFile
,
CharmmPSFWarning
# Enumerated values
...
...
wrappers/python/simtk/openmm/app/charmmparameterset.py
View file @
c7aa1d00
...
...
@@ -13,7 +13,7 @@ Copyright (c) 2014 the Authors
Author: Jason M. Swails
Contributors:
Date:
April
1
8
, 2014
Date:
July
1
7
, 2014
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
...
...
@@ -123,6 +123,8 @@ class CharmmParameterSet(object):
elif
arg
.
endswith
(
'.str'
):
strs
.
append
(
arg
)
elif
arg
.
endswith
(
'.inp'
):
# Only consider the file name (since the directory is likely
# "toppar" and will screw up file type detection)
fname
=
os
.
path
.
split
(
arg
)[
1
]
if
'par'
in
fname
:
pars
.
append
(
arg
)
...
...
@@ -436,11 +438,29 @@ class CharmmParameterSet(object):
try
:
at1
=
words
[
0
]
at2
=
words
[
1
]
emin
=
conv
(
words
[
2
],
float
,
'NBFIX Emin'
)
emin
=
abs
(
conv
(
words
[
2
],
float
,
'NBFIX Emin'
)
)
rmin
=
conv
(
words
[
3
],
float
,
'NBFIX Rmin'
)
try
:
emin14
=
abs
(
conv
(
words
[
4
],
float
,
'NBFIX Emin 1-4'
))
rmin14
=
conv
(
words
[
5
],
float
,
'NBFIX Rmin 1-4'
)
except
IndexError
:
emin14
=
rmin14
=
None
try
:
self
.
atom_types_str
[
at1
].
add_nbfix
(
at2
,
rmin
,
emin
,
rmin14
,
emin14
)
self
.
atom_types_str
[
at2
].
add_nbfix
(
at1
,
rmin
,
emin
,
rmin14
,
emin14
)
except
KeyError
:
# Some stream files define NBFIX terms with an atom that
# is defined in another toppar file that does not
# necessarily have to be loaded. As a result, not every
# NBFIX found here will necessarily need to be applied.
# If we can't find a particular atom type, don't bother
# adding that nbfix and press on
pass
except
IndexError
:
raise
CharmmFileError
(
'Could not parse NBFIX terms.'
)
self
.
nbfix_types
[(
min
(
at1
,
at2
),
max
(
at1
,
at2
))]
=
(
e
min
,
r
min
)
self
.
nbfix_types
[(
min
(
at1
,
at2
),
max
(
at1
,
at2
))]
=
(
r
min
,
e
min
)
# Now we're done. Load the nonbonded types into the relevant AtomType
# instances. In order for this to work, all keys in nonbonded_types
# must be in the self.atom_types_str dict. Raise a RuntimeError if this
...
...
wrappers/python/simtk/openmm/app/charmmpsffile.py
View file @
c7aa1d00
...
...
@@ -995,11 +995,25 @@ class CharmmPsfFile(object):
u
.
kilojoule_per_mole
)
ene_conv
=
dihe_frc_conv
# Create the system
# Create the system and determine if any of our atoms have NBFIX (and
# therefore requires a CustomNonbondedForce instead)
typenames
=
set
()
system
=
mm
.
System
()
if
verbose
:
print
(
'Adding particles...'
)
for
atom
in
self
.
atom_list
:
typenames
.
add
(
atom
.
type
.
name
)
system
.
addParticle
(
atom
.
mass
)
has_nbfix_terms
=
False
typenames
=
list
(
typenames
)
try
:
for
i
,
typename
in
enumerate
(
typenames
):
typ
=
params
.
atom_types_str
[
typename
]
for
j
in
range
(
i
,
len
(
typenames
)):
if
typenames
[
j
]
in
typ
.
nbfix
:
has_nbfix_terms
=
True
raise
StopIteration
except
StopIteration
:
pass
# Set up the constraints
if
verbose
and
(
constraints
is
not
None
and
not
rigidWater
):
print
(
'Adding constraints...'
)
...
...
@@ -1240,9 +1254,85 @@ class CharmmPsfFile(object):
# Add per-particle nonbonded parameters (LJ params)
sigma_scale
=
2
**
(
-
1
/
6
)
*
2
for
i
,
atm
in
enumerate
(
self
.
atom_list
):
force
.
addParticle
(
atm
.
charge
,
sigma_scale
*
atm
.
type
.
rmin
*
length_conv
,
abs
(
atm
.
type
.
epsilon
*
ene_conv
))
if
not
has_nbfix_terms
:
for
atm
in
self
.
atom_list
:
force
.
addParticle
(
atm
.
charge
,
sigma_scale
*
atm
.
type
.
rmin
*
length_conv
,
abs
(
atm
.
type
.
epsilon
*
ene_conv
))
else
:
for
atm
in
self
.
atom_list
:
force
.
addParticle
(
atm
.
charge
,
1.0
,
0.0
)
# Now add the custom nonbonded force that implements NBFIX. First
# thing we need to do is condense our number of types
lj_idx_list
=
[
0
for
atom
in
self
.
atom_list
]
lj_radii
,
lj_depths
=
[],
[]
num_lj_types
=
0
lj_type_list
=
[]
for
i
,
atom
in
enumerate
(
self
.
atom_list
):
atom
=
atom
.
type
if
lj_idx_list
[
i
]:
continue
# already assigned
num_lj_types
+=
1
lj_idx_list
[
i
]
=
num_lj_types
ljtype
=
(
atom
.
rmin
,
atom
.
epsilon
)
lj_type_list
.
append
(
atom
)
lj_radii
.
append
(
atom
.
rmin
)
lj_depths
.
append
(
atom
.
epsilon
)
for
j
in
range
(
i
+
1
,
len
(
self
.
atom_list
)):
atom2
=
self
.
atom_list
[
j
].
type
if
lj_idx_list
[
j
]
>
0
:
continue
# already assigned
if
atom2
is
atom
:
lj_idx_list
[
j
]
=
num_lj_types
elif
not
atom
.
nbfix
:
# Only non-NBFIXed atom types can be compressed
ljtype2
=
(
atom2
.
rmin
,
atom2
.
epsilon
)
if
ljtype
==
ljtype2
:
lj_idx_list
[
j
]
=
num_lj_types
# Now everything is assigned. Create the A-coefficient and
# B-coefficient arrays
acoef
=
[
0
for
i
in
range
(
num_lj_types
*
num_lj_types
)]
bcoef
=
acoef
[:]
for
i
in
range
(
num_lj_types
):
for
j
in
range
(
num_lj_types
):
namej
=
lj_type_list
[
j
].
name
try
:
rij
,
wdij
,
rij14
,
wdij14
=
lj_type_list
[
i
].
nbfix
[
namej
]
except
KeyError
:
rij
=
(
lj_radii
[
i
]
+
lj_radii
[
j
])
*
length_conv
wdij
=
sqrt
(
lj_depths
[
i
]
*
lj_depths
[
j
])
*
ene_conv
else
:
rij
*=
length_conv
wdij
*=
ene_conv
acoef
[
i
+
num_lj_types
*
j
]
=
sqrt
(
wdij
)
*
rij
**
6
bcoef
[
i
+
num_lj_types
*
j
]
=
2
*
wdij
*
rij
**
6
cforce
=
mm
.
CustomNonbondedForce
(
'(a/r6)^2-b/r6; r6=r^6;'
'a=acoef(type1, type2);'
'b=bcoef(type1, type2)'
)
cforce
.
addTabulatedFunction
(
'acoef'
,
mm
.
Discrete2DFunction
(
num_lj_types
,
num_lj_types
,
acoef
))
cforce
.
addTabulatedFunction
(
'bcoef'
,
mm
.
Discrete2DFunction
(
num_lj_types
,
num_lj_types
,
bcoef
))
cforce
.
addPerParticleParameter
(
'type'
)
cforce
.
setForceGroup
(
self
.
NONBONDED_FORCE_GROUP
)
if
(
nonbondedMethod
is
ff
.
PME
or
nonbondedMethod
is
ff
.
Ewald
or
nonbondedMethod
is
ff
.
CutoffPeriodic
):
cforce
.
setNonbondedMethod
(
cforce
.
CutoffPeriodic
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
cforce
.
setUseLongRangeCorrection
(
True
)
elif
nonbondedMethod
is
ff
.
NoCutoff
:
cforce
.
setNonbondedMethod
(
cforce
.
NoCutoff
)
elif
nonbondedMethod
is
ff
.
CutoffNonPeriodic
:
cforce
.
setNonbondedMethod
(
cforce
.
CutoffNonPeriodic
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
else
:
raise
ValueError
(
'Unrecognized nonbonded method'
)
if
switchDistance
and
nonbondedMethod
is
not
ff
.
NoCutoff
:
# make sure it's legal
if
switchDistance
>=
nonbondedCutoff
:
raise
ValueError
(
'switchDistance is too large compared '
'to the cutoff!'
)
cforce
.
setUseSwitchingFunction
(
True
)
cforce
.
setSwitchingDistance
(
switchDistance
)
for
i
in
lj_idx_list
:
cforce
.
addParticle
((
i
-
1
,))
# adjust for indexing from 0
# Add 1-4 interactions
excluded_atom_pairs
=
set
()
# save these pairs so we don't zero them out
...
...
@@ -1283,6 +1373,13 @@ class CharmmPsfFile(object):
continue
force
.
addException
(
atom
.
idx
,
atom2
.
idx
,
0.0
,
0.1
,
0.0
)
system
.
addForce
(
force
)
# If we needed a CustomNonbondedForce, map all of the exceptions from
# the NonbondedForce to the CustomNonbondedForce
if
has_nbfix_terms
:
for
i
in
range
(
force
.
getNumExceptions
()):
ii
,
jj
,
q
,
eps
,
sig
=
force
.
getExceptionParameters
(
i
)
cforce
.
addExclusion
(
ii
,
jj
)
system
.
addForce
(
cforce
)
# Add GB model if we're doing one
if
implicitSolvent
is
not
None
:
...
...
wrappers/python/simtk/openmm/app/data/charmm_polar_2013.xml
0 → 100644
View file @
c7aa1d00
This source diff could not be displayed because it is too large. You can
view the blob
instead.
wrappers/python/simtk/openmm/app/data/swm4ndp.xml
View file @
c7aa1d00
...
...
@@ -30,7 +30,7 @@
<Atom
type=
"swm4ndp-OD"
charge=
"-1.71636"
sigma=
"1"
epsilon=
"0"
/>
</NonbondedForce>
<DrudeForce>
<Particle
type1=
"swm4ndp-OD"
type2=
"swm4ndp-O"
charge=
"-1.71636"
polarizability=
"
7
.0
40850e-6
"
thole=
"1.3"
/>
<Particle
type1=
"swm4ndp-OD"
type2=
"swm4ndp-O"
charge=
"-1.71636"
polarizability=
"
0
.0
00978253
"
thole=
"1.3"
/>
</DrudeForce>
</ForceField>
wrappers/python/simtk/openmm/app/forcefield.py
View file @
c7aa1d00
...
...
@@ -100,7 +100,7 @@ class ForceField(object):
"""Load one or more XML files and create a ForceField object based on them.
Parameters:
- files A list of XML files defining the force field. Each entry may
- files
(list)
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, a path relative to this module's data subdirectory
(for built in force fields), or an open file-like object with a
...
...
@@ -113,47 +113,59 @@ class ForceField(object):
self
.
_forces
=
[]
self
.
_scripts
=
[]
for
file
in
files
:
try
:
# this handles either filenames or open file-like objects
tree
=
etree
.
parse
(
file
)
except
IOError
:
tree
=
etree
.
parse
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'data'
,
file
))
root
=
tree
.
getroot
()
# Load the atom types.
if
tree
.
getroot
().
find
(
'AtomTypes'
)
is
not
None
:
for
type
in
tree
.
getroot
().
find
(
'AtomTypes'
).
findall
(
'Type'
):
self
.
registerAtomType
(
type
.
attrib
)
# Load the residue templates.
if
tree
.
getroot
().
find
(
'Residues'
)
is
not
None
:
for
residue
in
root
.
find
(
'Residues'
).
findall
(
'Residue'
):
resName
=
residue
.
attrib
[
'name'
]
template
=
ForceField
.
_TemplateData
(
resName
)
for
atom
in
residue
.
findall
(
'Atom'
):
template
.
atoms
.
append
(
ForceField
.
_TemplateAtomData
(
atom
.
attrib
[
'name'
],
atom
.
attrib
[
'type'
],
self
.
_atomTypes
[
atom
.
attrib
[
'type'
]][
2
]))
for
site
in
residue
.
findall
(
'VirtualSite'
):
template
.
virtualSites
.
append
(
ForceField
.
_VirtualSiteData
(
site
))
for
bond
in
residue
.
findall
(
'Bond'
):
template
.
addBond
(
int
(
bond
.
attrib
[
'from'
]),
int
(
bond
.
attrib
[
'to'
]))
for
bond
in
residue
.
findall
(
'ExternalBond'
):
b
=
int
(
bond
.
attrib
[
'from'
])
template
.
externalBonds
.
append
(
b
)
template
.
atoms
[
b
].
externalBonds
+=
1
self
.
registerResidueTemplate
(
template
)
# Load force definitions
for
child
in
root
:
if
child
.
tag
in
parsers
:
parsers
[
child
.
tag
](
child
,
self
)
# Load scripts
for
node
in
tree
.
getroot
().
findall
(
'Script'
):
self
.
registerScript
(
node
.
text
)
self
.
loadFile
(
file
)
def
loadFile
(
self
,
file
):
"""Load an XML file and add the definitions from it to this FieldField.
Parameters:
- file (string or file) An XML file containing force field definitions. It may
be either an absolute file path, a path relative to the current working
directory, a path relative to this module's data subdirectory
(for built in force fields), or an open file-like object with a
read() method from which the forcefield XML data can be loaded.
"""
try
:
# this handles either filenames or open file-like objects
tree
=
etree
.
parse
(
file
)
except
IOError
:
tree
=
etree
.
parse
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'data'
,
file
))
root
=
tree
.
getroot
()
# Load the atom types.
if
tree
.
getroot
().
find
(
'AtomTypes'
)
is
not
None
:
for
type
in
tree
.
getroot
().
find
(
'AtomTypes'
).
findall
(
'Type'
):
self
.
registerAtomType
(
type
.
attrib
)
# Load the residue templates.
if
tree
.
getroot
().
find
(
'Residues'
)
is
not
None
:
for
residue
in
root
.
find
(
'Residues'
).
findall
(
'Residue'
):
resName
=
residue
.
attrib
[
'name'
]
template
=
ForceField
.
_TemplateData
(
resName
)
for
atom
in
residue
.
findall
(
'Atom'
):
template
.
atoms
.
append
(
ForceField
.
_TemplateAtomData
(
atom
.
attrib
[
'name'
],
atom
.
attrib
[
'type'
],
self
.
_atomTypes
[
atom
.
attrib
[
'type'
]][
2
]))
for
site
in
residue
.
findall
(
'VirtualSite'
):
template
.
virtualSites
.
append
(
ForceField
.
_VirtualSiteData
(
site
))
for
bond
in
residue
.
findall
(
'Bond'
):
template
.
addBond
(
int
(
bond
.
attrib
[
'from'
]),
int
(
bond
.
attrib
[
'to'
]))
for
bond
in
residue
.
findall
(
'ExternalBond'
):
b
=
int
(
bond
.
attrib
[
'from'
])
template
.
externalBonds
.
append
(
b
)
template
.
atoms
[
b
].
externalBonds
+=
1
self
.
registerResidueTemplate
(
template
)
# Load force definitions
for
child
in
root
:
if
child
.
tag
in
parsers
:
parsers
[
child
.
tag
](
child
,
self
)
# Load scripts
for
node
in
tree
.
getroot
().
findall
(
'Script'
):
self
.
registerScript
(
node
.
text
)
def
getGenerators
(
self
):
"""Get the list of all registered generators."""
...
...
@@ -240,6 +252,7 @@ class ForceField(object):
def
__init__
(
self
):
self
.
atomType
=
{}
self
.
atoms
=
[]
self
.
excludeAtomWith
=
[]
self
.
virtualSites
=
{}
self
.
bonds
=
[]
self
.
angles
=
[]
...
...
@@ -302,6 +315,10 @@ class ForceField(object):
self
.
localPos
=
[
float
(
attrib
[
'p1'
]),
float
(
attrib
[
'p2'
]),
float
(
attrib
[
'p3'
])]
else
:
raise
ValueError
(
'Unknown virtual site type: %s'
%
self
.
type
)
if
'excludeWith'
in
attrib
:
self
.
excludeWith
=
int
(
attrib
[
'excludeWith'
])
else
:
self
.
excludeWith
=
self
.
atoms
[
0
]
def
createSystem
(
self
,
topology
,
nonbondedMethod
=
NoCutoff
,
nonbondedCutoff
=
1.0
*
unit
.
nanometer
,
constraints
=
None
,
rigidWater
=
True
,
removeCMMotion
=
True
,
hydrogenMass
=
None
,
**
args
):
...
...
@@ -324,6 +341,8 @@ class ForceField(object):
"""
data
=
ForceField
.
_SystemData
()
data
.
atoms
=
list
(
topology
.
atoms
())
for
atom
in
data
.
atoms
:
data
.
excludeAtomWith
.
append
([])
# Make a list of all bonds
...
...
@@ -363,7 +382,7 @@ class ForceField(object):
data
.
atomType
[
atom
]
=
template
.
atoms
[
match
].
type
for
site
in
template
.
virtualSites
:
if
match
==
site
.
index
:
data
.
virtualSites
[
atom
]
=
(
site
,
[
matchAtoms
[
i
].
index
for
i
in
site
.
atoms
])
data
.
virtualSites
[
atom
]
=
(
site
,
[
matchAtoms
[
i
].
index
for
i
in
site
.
atoms
]
,
matchAtoms
[
site
.
excludeWith
].
index
)
# Create the System and add atoms
...
...
@@ -478,8 +497,9 @@ class ForceField(object):
# Add virtual sites
for
atom
in
data
.
virtualSites
:
(
site
,
atoms
)
=
data
.
virtualSites
[
atom
]
(
site
,
atoms
,
excludeWith
)
=
data
.
virtualSites
[
atom
]
index
=
atom
.
index
data
.
excludeAtomWith
[
excludeWith
].
append
(
index
)
if
site
.
type
==
'average2'
:
sys
.
setVirtualSite
(
index
,
mm
.
TwoParticleAverageSite
(
atoms
[
0
],
atoms
[
1
],
site
.
weights
[
0
],
site
.
weights
[
1
]))
elif
site
.
type
==
'average3'
:
...
...
@@ -895,7 +915,7 @@ class PeriodicTorsionGenerator:
for
(
t2
,
t3
,
t4
)
in
itertools
.
permutations
(((
type2
,
1
),
(
type3
,
2
),
(
type4
,
3
))):
if
t2
[
0
]
in
types2
and
t3
[
0
]
in
types3
and
t4
[
0
]
in
types4
:
# Workaround to be more consistent with AMBER. It uses wildcards to define most of its
# impropers, which leaves the ordering ambigous. It then follows some bizarre rules
# impropers, which leaves the ordering ambig
u
ous. It then follows some bizarre rules
# to pick the order.
a1
=
torsion
[
t2
[
1
]]
a2
=
torsion
[
t3
[
1
]]
...
...
@@ -991,18 +1011,22 @@ class RBTorsionGenerator:
if
type1
in
types1
:
for
(
t2
,
t3
,
t4
)
in
itertools
.
permutations
(((
type2
,
1
),
(
type3
,
2
),
(
type4
,
3
))):
if
t2
[
0
]
in
types2
and
t3
[
0
]
in
types3
and
t4
[
0
]
in
types4
:
# Workaround to be more consistent with AMBER. It uses wildcards to define most of its
# impropers, which leaves the ordering ambigous. It then follows some bizarre rules
# to pick the order.
a1
=
torsion
[
t2
[
1
]]
a2
=
torsion
[
t3
[
1
]]
e1
=
data
.
atoms
[
a1
].
element
e2
=
data
.
atoms
[
a2
].
element
if
e1
==
e2
and
a1
>
a2
:
(
a1
,
a2
)
=
(
a2
,
a1
)
elif
e1
!=
elem
.
carbon
and
(
e2
==
elem
.
carbon
or
e1
.
mass
<
e2
.
mass
):
(
a1
,
a2
)
=
(
a2
,
a1
)
force
.
addTorsion
(
a1
,
a2
,
torsion
[
0
],
torsion
[
t4
[
1
]],
tordef
.
c
[
0
],
tordef
.
c
[
1
],
tordef
.
c
[
2
],
tordef
.
c
[
3
],
tordef
.
c
[
4
],
tordef
.
c
[
5
])
if
wildcard
in
(
types1
,
types2
,
types3
,
types4
):
# Workaround to be more consistent with AMBER. It uses wildcards to define most of its
# impropers, which leaves the ordering ambiguous. It then follows some bizarre rules
# to pick the order.
a1
=
torsion
[
t2
[
1
]]
a2
=
torsion
[
t3
[
1
]]
e1
=
data
.
atoms
[
a1
].
element
e2
=
data
.
atoms
[
a2
].
element
if
e1
==
e2
and
a1
>
a2
:
(
a1
,
a2
)
=
(
a2
,
a1
)
elif
e1
!=
elem
.
carbon
and
(
e2
==
elem
.
carbon
or
e1
.
mass
<
e2
.
mass
):
(
a1
,
a2
)
=
(
a2
,
a1
)
force
.
addTorsion
(
a1
,
a2
,
torsion
[
0
],
torsion
[
t4
[
1
]],
tordef
.
c
[
0
],
tordef
.
c
[
1
],
tordef
.
c
[
2
],
tordef
.
c
[
3
],
tordef
.
c
[
4
],
tordef
.
c
[
5
])
else
:
# There are no wildcards, so the order is unambiguous.
force
.
addTorsion
(
torsion
[
0
],
torsion
[
t2
[
1
]],
torsion
[
t3
[
1
]],
torsion
[
t4
[
1
]],
tordef
.
c
[
0
],
tordef
.
c
[
1
],
tordef
.
c
[
2
],
tordef
.
c
[
3
],
tordef
.
c
[
4
],
tordef
.
c
[
5
])
done
=
True
break
...
...
@@ -1157,33 +1181,33 @@ class NonbondedGenerator:
sys
.
addForce
(
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# Create exceptions based on bonds, virtual sites, and Drude particles.
# Create exceptions based on bonds.
bondIndices
=
[]
for
bond
in
data
.
bonds
:
bondIndices
.
append
((
bond
.
atom1
,
bond
.
atom2
))
# If a virtual site does *not* share exclusions with another atom, add a bond between it and its first parent atom.
for
i
in
range
(
sys
.
getNumParticles
()):
if
sys
.
isVirtualSite
(
i
):
site
=
sys
.
getVirtualSite
(
i
)
for
j
in
range
(
site
.
getNumParticles
()):
bondIndices
.
append
((
i
,
site
.
getParticle
(
j
)))
drude
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
DrudeForce
)]
if
len
(
drude
)
>
0
:
drude
=
drude
[
0
]
# For purposes of creating exceptions, a Drude particle is "bonded" to anything
# its parent atom is bonded to.
drudeMap
=
{}
for
i
in
range
(
drude
.
getNumParticles
()):
params
=
drude
.
getParticleParameters
(
i
)
drudeMap
[
params
[
1
]]
=
params
[
0
]
for
atom1
,
atom2
in
bondIndices
:
drude1
=
drudeMap
[
atom1
]
if
atom1
in
drudeMap
else
None
drude2
=
drudeMap
[
atom2
]
if
atom2
in
drudeMap
else
None
if
drude1
is
not
None
:
bondIndices
.
append
((
drude1
,
atom2
))
if
drude2
is
not
None
:
bondIndices
.
append
((
drude1
,
drude2
))
if
drude2
is
not
None
:
bondIndices
.
append
((
atom1
,
drude2
))
(
site
,
atoms
,
excludeWith
)
=
data
.
virtualSites
[
data
.
atoms
[
i
]]
if
excludeWith
is
None
:
bondIndices
.
append
((
i
,
site
.
getParticle
(
0
)))
# Certain particles, such as lone pairs and Drude particles, share exclusions with a parent atom.
# If the parent atom does not interact with an atom, the child particle does not either.
for
atom1
,
atom2
in
bondIndices
:
for
child1
in
data
.
excludeAtomWith
[
atom1
]:
bondIndices
.
append
((
child1
,
atom2
))
for
child2
in
data
.
excludeAtomWith
[
atom2
]:
bondIndices
.
append
((
child1
,
child2
))
for
child2
in
data
.
excludeAtomWith
[
atom2
]:
bondIndices
.
append
((
atom1
,
child2
))
# Create the exceptions.
nonbonded
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
NonbondedForce
)][
0
]
nonbonded
.
createExceptionsFromBonds
(
bondIndices
,
self
.
coulomb14scale
,
self
.
lj14scale
)
...
...
@@ -1519,18 +1543,22 @@ class CustomTorsionGenerator:
if
type1
in
types1
:
for
(
t2
,
t3
,
t4
)
in
itertools
.
permutations
(((
type2
,
1
),
(
type3
,
2
),
(
type4
,
3
))):
if
t2
[
0
]
in
types2
and
t3
[
0
]
in
types3
and
t4
[
0
]
in
types4
:
# Workaround to be more consistent with AMBER. It uses wildcards to define most of its
# impropers, which leaves the ordering ambigous. It then follows some bizarre rules
# to pick the order.
a1
=
torsion
[
t2
[
1
]]
a2
=
torsion
[
t3
[
1
]]
e1
=
data
.
atoms
[
a1
].
element
e2
=
data
.
atoms
[
a2
].
element
if
e1
==
e2
and
a1
>
a2
:
(
a1
,
a2
)
=
(
a2
,
a1
)
elif
e1
!=
elem
.
carbon
and
(
e2
==
elem
.
carbon
or
e1
.
mass
<
e2
.
mass
):
(
a1
,
a2
)
=
(
a2
,
a1
)
force
.
addTorsion
(
a1
,
a2
,
torsion
[
0
],
torsion
[
t4
[
1
]],
tordef
.
paramValues
)
if
wildcard
in
(
types1
,
types2
,
types3
,
types4
):
# Workaround to be more consistent with AMBER. It uses wildcards to define most of its
# impropers, which leaves the ordering ambiguous. It then follows some bizarre rules
# to pick the order.
a1
=
torsion
[
t2
[
1
]]
a2
=
torsion
[
t3
[
1
]]
e1
=
data
.
atoms
[
a1
].
element
e2
=
data
.
atoms
[
a2
].
element
if
e1
==
e2
and
a1
>
a2
:
(
a1
,
a2
)
=
(
a2
,
a1
)
elif
e1
!=
elem
.
carbon
and
(
e2
==
elem
.
carbon
or
e1
.
mass
<
e2
.
mass
):
(
a1
,
a2
)
=
(
a2
,
a1
)
force
.
addTorsion
(
a1
,
a2
,
torsion
[
0
],
torsion
[
t4
[
1
]],
tordef
.
paramValues
)
else
:
# There are no wildcards, so the order is unambiguous.
force
.
addTorsion
(
torsion
[
0
],
torsion
[
t2
[
1
]],
torsion
[
t3
[
1
]],
torsion
[
t4
[
1
]],
tordef
.
paramValues
)
done
=
True
break
...
...
@@ -4290,8 +4318,6 @@ class DrudeGenerator:
# Add Drude particles.
drudeMap
=
{}
parentMap
=
{}
for
atom
in
data
.
atoms
:
t
=
data
.
atomType
[
atom
]
if
t
in
self
.
typeMap
:
...
...
@@ -4308,9 +4334,8 @@ class DrudeGenerator:
p
[
2
]
=
atom2
.
index
elif
values
[
3
]
is
not
None
and
type2
in
values
[
3
]:
p
[
3
]
=
atom2
.
index
drudeIndex
=
force
.
addParticle
(
atom
.
index
,
p
[
0
],
p
[
1
],
p
[
2
],
p
[
3
],
values
[
4
],
values
[
5
],
values
[
6
],
values
[
7
])
drudeMap
[
atom
.
index
]
=
p
[
0
]
parentMap
[
p
[
0
]]
=
(
atom
.
index
,
drudeIndex
)
force
.
addParticle
(
atom
.
index
,
p
[
0
],
p
[
1
],
p
[
2
],
p
[
3
],
values
[
4
],
values
[
5
],
values
[
6
],
values
[
7
])
data
.
excludeAtomWith
[
p
[
0
]].
append
(
atom
.
index
)
sys
.
addForce
(
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
...
...
@@ -4323,14 +4348,14 @@ class DrudeGenerator:
particleMap
[
drude
.
getParticleParameters
(
i
)[
0
]]
=
i
for
i
in
range
(
nonbonded
.
getNumExceptions
()):
(
particle1
,
particle2
,
charge
,
sigma
,
epsilon
)
=
nonbonded
.
getExceptionParameters
(
i
)
if
charge
==
0
and
epsilon
==
0
:
if
charge
.
_value
==
0
and
epsilon
.
_value
==
0
:
# This is an exclusion.
if
particle1
in
particleMap
and
particle2
in
particleMap
:
# It connects two Drude particles, so add a screened pair.
drude1
=
particleMap
[
particle1
]
drude2
=
particleMap
[
particle2
]
type1
=
data
.
atomType
[
data
.
atoms
[
drud
e1
]]
type2
=
data
.
atomType
[
data
.
atoms
[
drud
e2
]]
type1
=
data
.
atomType
[
data
.
atoms
[
particl
e1
]]
type2
=
data
.
atomType
[
data
.
atoms
[
particl
e2
]]
thole1
=
self
.
typeMap
[
type1
][
8
]
thole2
=
self
.
typeMap
[
type2
][
8
]
drude
.
addScreenedPair
(
drude1
,
drude2
,
thole1
+
thole2
)
...
...
wrappers/python/simtk/openmm/app/internal/amber_file_parser.py
View file @
c7aa1d00
...
...
@@ -52,6 +52,7 @@ except:
import
simtk.unit
as
units
import
simtk.openmm
from
simtk.openmm.app
import
element
as
elem
from
simtk.openmm.vec3
import
Vec3
import
customgbforces
as
customgb
#=============================================================================================
...
...
@@ -116,6 +117,7 @@ class PrmtopLoader(object):
self
.
_flags
=
[]
self
.
_raw_format
=
{}
self
.
_raw_data
=
{}
self
.
_has_nbfix_terms
=
False
fIn
=
open
(
inFilename
)
for
line
in
fIn
:
...
...
@@ -218,28 +220,16 @@ class PrmtopLoader(object):
try
:
return
self
.
_massList
except
AttributeError
:
pass
self
.
_massList
=
[]
raw_masses
=
self
.
_raw_data
[
'MASS'
]
for
ii
in
range
(
self
.
getNumAtoms
()):
self
.
_massList
.
append
(
float
(
raw_masses
[
ii
]))
self
.
_massList
=
self
.
_massList
return
self
.
_massList
self
.
_massList
=
[
float
(
x
)
for
x
in
self
.
_raw_data
[
'MASS'
]]
return
self
.
_massList
def
getCharges
(
self
):
"""Return a list of atomic charges in the system"""
try
:
return
self
.
_chargeList
except
AttributeError
:
pass
self
.
_chargeList
=
[]
raw_charges
=
self
.
_raw_data
[
'CHARGE'
]
for
ii
in
range
(
self
.
getNumAtoms
()):
self
.
_chargeList
.
append
(
float
(
raw_charges
[
ii
])
/
18.2223
)
self
.
_chargeList
=
self
.
_chargeList
return
self
.
_chargeList
self
.
_chargeList
=
[
float
(
x
)
/
18.2223
for
x
in
self
.
_raw_data
[
'CHARGE'
]]
return
self
.
_chargeList
def
getAtomName
(
self
,
iAtom
):
"""Return the atom name for iAtom"""
...
...
@@ -254,11 +244,8 @@ class PrmtopLoader(object):
try
:
return
self
.
_atomTypeIndexes
except
AttributeError
:
pass
self
.
_atomTypeIndexes
=
[]
for
atomTypeIndex
in
self
.
_raw_data
[
'ATOM_TYPE_INDEX'
]:
self
.
_atomTypeIndexes
.
append
(
int
(
atomTypeIndex
))
return
self
.
_atomTypeIndexes
self
.
_atomTypeIndexes
=
[
int
(
x
)
for
x
in
self
.
_raw_data
[
'ATOM_TYPE_INDEX'
]]
return
self
.
_atomTypeIndexes
def
getAtomType
(
self
,
iAtom
):
"""Return the AMBER atom type for iAtom"""
...
...
@@ -275,11 +262,11 @@ class PrmtopLoader(object):
def
getResidueLabel
(
self
,
iAtom
=
None
,
iRes
=
None
):
"""Return residue label for iAtom OR iRes"""
if
iRes
==
None
and
iAtom
==
None
:
if
iRes
is
None
and
iAtom
is
None
:
raise
Exception
(
"only specify iRes or iAtom, not both"
)
if
iRes
!=
None
and
iAtom
!=
None
:
if
iRes
is
not
None
and
iAtom
is
not
None
:
raise
Exception
(
"iRes or iAtom must be set"
)
if
iRes
!=
None
:
if
iRes
is
not
None
:
return
self
.
_raw_data
[
'RESIDUE_LABEL'
][
iRes
]
else
:
return
self
.
getResidueLabel
(
iRes
=
self
.
_getResiduePointer
(
iAtom
))
...
...
@@ -306,6 +293,9 @@ class PrmtopLoader(object):
elements of the Lennard-Jones A and B coefficient matrices are found,
NbfixPresent exception is raised
"""
if
self
.
_has_nbfix_terms
:
raise
NbfixPresent
(
'Off-diagonal Lennard-Jones elements found. '
'Cannot determine LJ parameters for individual atoms.'
)
try
:
return
self
.
_nonbondTerms
except
AttributeError
:
...
...
@@ -344,13 +334,13 @@ class PrmtopLoader(object):
b
=
float
(
self
.
_raw_data
[
'LENNARD_JONES_BCOEF'
][
index
])
if
a
==
0
or
b
==
0
:
if
a
!=
0
or
b
!=
0
or
(
wdij
!=
0
and
rij
!=
0
):
del
self
.
_
nonbondTerms
self
.
_
has_nbfix_terms
=
True
raise
NbfixPresent
(
'Off-diagonal Lennard-Jones elements'
' found. Cannot determine LJ '
'parameters for individual atoms.'
)
elif
(
abs
((
a
-
(
wdij
*
rij
**
12
))
/
a
)
>
1e-6
or
abs
((
b
-
(
2
*
wdij
*
rij
**
6
))
/
b
)
>
1e-6
):
del
self
.
_
nonbondTerms
self
.
_
has_nbfix_terms
=
True
raise
NbfixPresent
(
'Off-diagonal Lennard-Jones elements '
'found. Cannot determine LJ parameters '
'for individual atoms.'
)
...
...
@@ -712,6 +702,10 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
warnings
.
warn
(
"1-4 scaling parameters in topology file are being ignored. "
"This is not recommended unless you know what you are doing."
)
has_1264
=
'LENNARD_JONES_CCOEF'
in
prmtop
.
_raw_data
.
keys
()
if
has_1264
:
parm_ccoef
=
[
float
(
x
)
for
x
in
prmtop
.
_raw_data
[
'LENNARD_JONES_CCOEF'
]]
# Use pyopenmm implementation of OpenMM by default.
if
mm
is
None
:
mm
=
simtk
.
openmm
...
...
@@ -875,31 +869,52 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
acoef
[
i
+
numTypes
*
j
]
=
sqrt
(
parm_acoef
[
idx
])
*
afac
bcoef
[
i
+
numTypes
*
j
]
=
parm_bcoef
[
idx
]
*
bfac
cforce
=
mm
.
CustomNonbondedForce
(
'(a/r6)^2-b/r6; r6=r^6;'
'a=acoef(type1, type2);'
'b=bcoef(type1, type2);'
)
if
has_1264
:
cfac
=
ene_conv
*
length_conv
**
4
ccoef
=
[
0
for
i
in
range
(
numTypes
*
numTypes
)]
for
i
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
ccoef
[
i
+
numTypes
*
j
]
=
parm_ccoef
[
idx
]
*
cfac
cforce
=
mm
.
CustomNonbondedForce
(
'(a/r6)^2-b/r6-c/r^4; r6=r^6;'
'a=acoef(type1, type2);'
'b=bcoef(type1, type2);'
'c=ccoef(type1, type2);'
)
else
:
cforce
=
mm
.
CustomNonbondedForce
(
'(a/r6)^2-b/r6; r6=r^6;'
'a=acoef(type1, type2);'
'b=bcoef(type1, type2);'
)
cforce
.
addTabulatedFunction
(
'acoef'
,
mm
.
Discrete2DFunction
(
numTypes
,
numTypes
,
acoef
))
cforce
.
addTabulatedFunction
(
'bcoef'
,
mm
.
Discrete2DFunction
(
numTypes
,
numTypes
,
bcoef
))
if
has_1264
:
cforce
.
addTabulatedFunction
(
'ccoef'
,
mm
.
Discrete2DFunction
(
numTypes
,
numTypes
,
ccoef
))
cforce
.
addPerParticleParameter
(
'type'
)
for
atom
in
prmtop
.
_getAtomTypeIndexes
():
cforce
.
addParticle
((
atom
-
1
,))
# Now set the various properties based on the NonbondedForce object
if
nonbondedMethod
in
(
'PME'
,
'Ewald'
,
'CutoffPeriodic'
):
cforce
.
setNonbondedMethod
(
cforce
.
CutoffPeriodic
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
elif
nonbondedMethod
==
'CutoffNonPeriodic'
:
cforce
.
setNonbondedMethod
(
cforce
.
CutoffNonPeriodic
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
elif
nonbondedMethod
==
'NoCutoff'
:
cforce
.
setNonbondedMethod
(
cforce
.
NoCutoff
)
else
:
raise
ValueError
(
'Unrecognized cutoff option %s'
%
nonbondedMethod
)
else
:
for
(
charge
,
(
rVdw
,
epsilon
))
in
zip
(
prmtop
.
getCharges
(),
nonbondTerms
):
sigma
=
rVdw
*
sigmaScale
force
.
addParticle
(
charge
,
sigma
,
epsilon
)
if
has_1264
:
numTypes
=
prmtop
.
getNumTypes
()
nbidx
=
[
int
(
x
)
for
x
in
prmtop
.
_raw_data
[
'NONBONDED_PARM_INDEX'
]]
ccoef
=
[
0
for
i
in
range
(
numTypes
*
numTypes
)]
ene_conv
=
units
.
kilocalories_per_mole
.
conversion_factor_to
(
units
.
kilojoules_per_mole
)
length_conv
=
units
.
angstroms
.
conversion_factor_to
(
units
.
nanometers
)
cfac
=
ene_conv
*
length_conv
**
4
for
i
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
ccoef
[
i
+
numTypes
*
j
]
=
parm_ccoef
[
idx
]
*
cfac
cforce
=
mm
.
CustomNonbondedForce
(
'-c/r^4; c=ccoef(type1, type2)'
)
cforce
.
addTabulatedFunction
(
'ccoef'
,
mm
.
Discrete2DFunction
(
numTypes
,
numTypes
,
ccoef
))
cforce
.
addPerParticleParameter
(
'type'
)
for
atom
in
prmtop
.
_getAtomTypeIndexes
():
cforce
.
addParticle
((
atom
-
1
,))
# Add 1-4 Interactions
...
...
@@ -925,10 +940,23 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
# Copy the exceptions as exclusions to the CustomNonbondedForce if we have
# NBFIX terms
if
nbfix
:
if
nbfix
or
has_1264
:
for
i
in
range
(
force
.
getNumExceptions
()):
ii
,
jj
,
chg
,
sig
,
eps
=
force
.
getExceptionParameters
(
i
)
cforce
.
addExclusion
(
ii
,
jj
)
# Now set the various properties based on the NonbondedForce object
if
nonbondedMethod
in
(
'PME'
,
'Ewald'
,
'CutoffPeriodic'
):
cforce
.
setNonbondedMethod
(
cforce
.
CutoffPeriodic
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
cforce
.
setUseLongRangeCorrection
(
True
)
elif
nonbondedMethod
==
'CutoffNonPeriodic'
:
cforce
.
setNonbondedMethod
(
cforce
.
CutoffNonPeriodic
)
cforce
.
setCutoffDistance
(
nonbondedCutoff
)
elif
nonbondedMethod
==
'NoCutoff'
:
cforce
.
setNonbondedMethod
(
cforce
.
NoCutoff
)
else
:
raise
ValueError
(
'Unrecognized cutoff option %s'
%
nonbondedMethod
)
# Add this force to the system
system
.
addForce
(
cforce
)
system
.
addForce
(
force
)
...
...
@@ -1190,9 +1218,9 @@ class AmberAsciiRestart(object):
if
hasbox
:
boxVectors
=
np
.
zeros
((
3
,
3
),
np
.
float32
)
else
:
coordinates
=
[
[
0.0
,
0.0
,
0.0
]
for
i
in
range
(
self
.
natom
)]
coordinates
=
[
Vec3
(
0.0
,
0.0
,
0.0
)
for
i
in
range
(
self
.
natom
)]
if
hasvels
:
velocities
=
[
[
0.0
,
0.0
,
0.0
]
for
i
in
range
(
self
.
natom
)]
velocities
=
[
Vec3
(
0.0
,
0.0
,
0.0
)
for
i
in
range
(
self
.
natom
)]
if
hasbox
:
boxVectors
=
[[
0.0
,
0.0
,
0.0
]
for
i
in
range
(
3
)]
...
...
@@ -1202,14 +1230,16 @@ class AmberAsciiRestart(object):
idx
=
0
for
i
in
range
(
startline
,
endline
):
line
=
lines
[
i
]
coordinates
[
idx
][
0
]
=
float
(
line
[
0
:
12
])
coordinates
[
idx
][
1
]
=
float
(
line
[
12
:
24
])
coordinates
[
idx
][
2
]
=
float
(
line
[
24
:
36
])
x
=
float
(
line
[
0
:
12
])
y
=
float
(
line
[
12
:
24
])
z
=
float
(
line
[
24
:
36
])
coordinates
[
idx
]
=
Vec3
(
x
,
y
,
z
)
idx
+=
1
if
idx
<
self
.
natom
:
coordinates
[
idx
][
0
]
=
float
(
line
[
36
:
48
])
coordinates
[
idx
][
1
]
=
float
(
line
[
48
:
60
])
coordinates
[
idx
][
2
]
=
float
(
line
[
60
:
72
])
x
=
float
(
line
[
36
:
48
])
y
=
float
(
line
[
48
:
60
])
z
=
float
(
line
[
60
:
72
])
coordinates
[
idx
]
=
Vec3
(
x
,
y
,
z
)
idx
+=
1
self
.
coordinates
=
units
.
Quantity
(
coordinates
,
units
.
angstroms
)
startline
=
endline
...
...
@@ -1219,14 +1249,16 @@ class AmberAsciiRestart(object):
idx
=
0
for
i
in
range
(
startline
,
endline
):
line
=
lines
[
i
]
velocities
[
idx
][
0
]
=
float
(
line
[
0
:
12
])
*
VELSCALE
velocities
[
idx
][
1
]
=
float
(
line
[
12
:
24
])
*
VELSCALE
velocities
[
idx
][
2
]
=
float
(
line
[
24
:
36
])
*
VELSCALE
x
=
float
(
line
[
0
:
12
])
*
VELSCALE
y
=
float
(
line
[
12
:
24
])
*
VELSCALE
z
=
float
(
line
[
24
:
36
])
*
VELSCALE
velocities
[
idx
]
=
Vec3
(
x
,
y
,
z
)
idx
+=
1
if
idx
<
self
.
natom
:
velocities
[
idx
][
0
]
=
float
(
line
[
36
:
48
])
*
VELSCALE
velocities
[
idx
][
1
]
=
float
(
line
[
48
:
60
])
*
VELSCALE
velocities
[
idx
][
2
]
=
float
(
line
[
60
:
72
])
*
VELSCALE
x
=
float
(
line
[
36
:
48
])
*
VELSCALE
y
=
float
(
line
[
48
:
60
])
*
VELSCALE
z
=
float
(
line
[
60
:
72
])
*
VELSCALE
velocities
[
idx
]
=
Vec3
(
x
,
y
,
z
)
idx
+=
1
startline
=
endline
self
.
velocities
=
units
.
Quantity
(
velocities
,
...
...
@@ -1241,7 +1273,7 @@ class AmberAsciiRestart(object):
lengths
=
tmp
[:
3
]
angles
=
tmp
[
3
:]
_box_vectors_from_lengths_angles
(
lengths
,
angles
,
boxVectors
)
self
.
boxVectors
=
units
.
Quantity
(
boxVectors
,
units
.
angstrom
s
)
self
.
boxVectors
=
[
units
.
Quantity
(
Vec3
(
*
x
)
,
units
.
angstrom
)
for
x
in
boxVectors
]
class
AmberNetcdfRestart
(
object
):
"""
...
...
@@ -1324,11 +1356,11 @@ class AmberNetcdfRestart(object):
# They are already numpy -- convert to list if we don't want numpy
if
not
asNumpy
:
self
.
coordinates
=
self
.
coordinates
.
tolist
()
self
.
coordinates
=
[
Vec3
(
*
x
)
for
x
in
self
.
coordinates
]
if
self
.
velocities
is
not
None
:
self
.
velocities
=
self
.
velocities
.
tolist
()
self
.
velocities
=
[
Vec3
(
*
x
)
for
x
in
self
.
velocities
]
if
self
.
boxVectors
is
not
None
:
self
.
boxVectors
=
self
.
boxVectors
.
tolist
()
self
.
boxVectors
=
[
Vec3
(
*
x
)
for
x
in
self
.
boxVectors
]
# Now add the units
self
.
coordinates
=
units
.
Quantity
(
self
.
coordinates
,
units
.
angstroms
)
...
...
@@ -1336,7 +1368,7 @@ class AmberNetcdfRestart(object):
self
.
velocities
=
units
.
Quantity
(
self
.
velocities
,
units
.
angstroms
/
units
.
picoseconds
)
if
self
.
boxVectors
is
not
None
:
self
.
boxVectors
=
units
.
Quantity
(
self
.
boxVectors
,
units
.
angstroms
)
self
.
boxVectors
=
[
units
.
Quantity
(
x
,
units
.
angstroms
)
for
x
in
self
.
boxVectors
]
self
.
time
=
units
.
Quantity
(
self
.
time
,
units
.
picosecond
)
def
_box_vectors_from_lengths_angles
(
lengths
,
angles
,
boxVectors
):
...
...
@@ -1426,6 +1458,7 @@ def readAmberCoordinates(filename, asNumpy=False):
try
:
crdfile
=
AmberAsciiRestart
(
filename
)
except
TypeError
:
raise
raise
TypeError
(
'Problem parsing %s as an ASCII Amber restart file'
%
filename
)
except
(
IndexError
,
ValueError
):
...
...
Prev
1
2
3
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