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
71d33617
Commit
71d33617
authored
Apr 24, 2015
by
John Chodera (MSKCC)
Browse files
Merge remote-tracking branch 'upstream/master'
parents
eb232608
9da36463
Changes
127
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
130 additions
and
258 deletions
+130
-258
platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp
...reference/tests/TestReferenceVariableVerletIntegrator.cpp
+2
-5
platforms/reference/tests/TestReferenceVerletIntegrator.cpp
platforms/reference/tests/TestReferenceVerletIntegrator.cpp
+2
-4
platforms/reference/tests/TestReferenceVirtualSites.cpp
platforms/reference/tests/TestReferenceVirtualSites.cpp
+2
-6
plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h
plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h
plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h
...openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h
...amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h
...ns/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h
...oeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h
...ns/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h
.../amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h
plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h
+1
-1
plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h
...moeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h
+1
-1
tests/TestVectorize.cpp
tests/TestVectorize.cpp
+2
-1
wrappers/python/simtk/openmm/app/amberprmtopfile.py
wrappers/python/simtk/openmm/app/amberprmtopfile.py
+2
-3
wrappers/python/simtk/openmm/app/charmmpsffile.py
wrappers/python/simtk/openmm/app/charmmpsffile.py
+14
-178
wrappers/python/simtk/openmm/app/dcdfile.py
wrappers/python/simtk/openmm/app/dcdfile.py
+7
-5
wrappers/python/simtk/openmm/app/element.py
wrappers/python/simtk/openmm/app/element.py
+39
-7
wrappers/python/simtk/openmm/app/internal/amber_file_parser.py
...ers/python/simtk/openmm/app/internal/amber_file_parser.py
+37
-24
wrappers/python/simtk/openmm/app/internal/charmm/topologyobjects.py
...ython/simtk/openmm/app/internal/charmm/topologyobjects.py
+13
-15
No files found.
platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp
View file @
71d33617
...
@@ -48,10 +48,11 @@
...
@@ -48,10 +48,11 @@
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
ReferencePlatform
platform
;
const
double
TOL
=
1e-5
;
const
double
TOL
=
1e-5
;
void
testSingleBond
()
{
void
testSingleBond
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
...
@@ -89,7 +90,6 @@ void testSingleBond() {
...
@@ -89,7 +90,6 @@ void testSingleBond() {
void
testConstraints
()
{
void
testConstraints
()
{
const
int
numParticles
=
8
;
const
int
numParticles
=
8
;
const
double
temp
=
500.0
;
const
double
temp
=
500.0
;
ReferencePlatform
platform
;
System
system
;
System
system
;
VariableVerletIntegrator
integrator
(
1e-5
);
VariableVerletIntegrator
integrator
(
1e-5
);
integrator
.
setConstraintTolerance
(
1e-5
);
integrator
.
setConstraintTolerance
(
1e-5
);
...
@@ -148,7 +148,6 @@ void testConstraints() {
...
@@ -148,7 +148,6 @@ void testConstraints() {
void
testConstrainedClusters
()
{
void
testConstrainedClusters
()
{
const
int
numParticles
=
7
;
const
int
numParticles
=
7
;
const
double
temp
=
500.0
;
const
double
temp
=
500.0
;
ReferencePlatform
platform
;
System
system
;
System
system
;
VariableVerletIntegrator
integrator
(
1e-5
);
VariableVerletIntegrator
integrator
(
1e-5
);
integrator
.
setConstraintTolerance
(
1e-5
);
integrator
.
setConstraintTolerance
(
1e-5
);
...
@@ -211,7 +210,6 @@ void testConstrainedClusters() {
...
@@ -211,7 +210,6 @@ void testConstrainedClusters() {
}
}
void
testConstrainedMasslessParticles
()
{
void
testConstrainedMasslessParticles
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
0.0
);
system
.
addParticle
(
0.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
@@ -255,7 +253,6 @@ void testArgonBox() {
...
@@ -255,7 +253,6 @@ void testArgonBox() {
// Create a box of argon atoms.
// Create a box of argon atoms.
ReferencePlatform
platform
;
System
system
;
System
system
;
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
NonbondedForce
*
nonbonded
=
new
NonbondedForce
();
vector
<
Vec3
>
positions
;
vector
<
Vec3
>
positions
;
...
...
platforms/reference/tests/TestReferenceVerletIntegrator.cpp
View file @
71d33617
...
@@ -48,10 +48,11 @@
...
@@ -48,10 +48,11 @@
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
ReferencePlatform
platform
;
const
double
TOL
=
1e-5
;
const
double
TOL
=
1e-5
;
void
testSingleBond
()
{
void
testSingleBond
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
...
@@ -88,7 +89,6 @@ void testSingleBond() {
...
@@ -88,7 +89,6 @@ void testSingleBond() {
void
testConstraints
()
{
void
testConstraints
()
{
const
int
numParticles
=
8
;
const
int
numParticles
=
8
;
const
double
temp
=
500.0
;
const
double
temp
=
500.0
;
ReferencePlatform
platform
;
System
system
;
System
system
;
VerletIntegrator
integrator
(
0.002
);
VerletIntegrator
integrator
(
0.002
);
integrator
.
setConstraintTolerance
(
1e-5
);
integrator
.
setConstraintTolerance
(
1e-5
);
...
@@ -139,7 +139,6 @@ void testConstraints() {
...
@@ -139,7 +139,6 @@ void testConstraints() {
void
testConstrainedClusters
()
{
void
testConstrainedClusters
()
{
const
int
numParticles
=
7
;
const
int
numParticles
=
7
;
const
double
temp
=
500.0
;
const
double
temp
=
500.0
;
ReferencePlatform
platform
;
System
system
;
System
system
;
VerletIntegrator
integrator
(
0.001
);
VerletIntegrator
integrator
(
0.001
);
integrator
.
setConstraintTolerance
(
1e-5
);
integrator
.
setConstraintTolerance
(
1e-5
);
...
@@ -201,7 +200,6 @@ void testConstrainedClusters() {
...
@@ -201,7 +200,6 @@ void testConstrainedClusters() {
}
}
void
testConstrainedMasslessParticles
()
{
void
testConstrainedMasslessParticles
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
0.0
);
system
.
addParticle
(
0.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
...
platforms/reference/tests/TestReferenceVirtualSites.cpp
View file @
71d33617
...
@@ -50,11 +50,12 @@
...
@@ -50,11 +50,12 @@
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
ReferencePlatform
platform
;
/**
/**
* Check that massless particles are handled correctly.
* Check that massless particles are handled correctly.
*/
*/
void
testMasslessParticle
()
{
void
testMasslessParticle
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
0.0
);
system
.
addParticle
(
0.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
@@ -91,7 +92,6 @@ void testMasslessParticle() {
...
@@ -91,7 +92,6 @@ void testMasslessParticle() {
* Test a TwoParticleAverageSite virtual site.
* Test a TwoParticleAverageSite virtual site.
*/
*/
void
testTwoParticleAverage
()
{
void
testTwoParticleAverage
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
@@ -128,7 +128,6 @@ void testTwoParticleAverage() {
...
@@ -128,7 +128,6 @@ void testTwoParticleAverage() {
* Test a ThreeParticleAverageSite virtual site.
* Test a ThreeParticleAverageSite virtual site.
*/
*/
void
testThreeParticleAverage
()
{
void
testThreeParticleAverage
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
@@ -170,7 +169,6 @@ void testThreeParticleAverage() {
...
@@ -170,7 +169,6 @@ void testThreeParticleAverage() {
* Test an OutOfPlaneSite virtual site.
* Test an OutOfPlaneSite virtual site.
*/
*/
void
testOutOfPlane
()
{
void
testOutOfPlane
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
@@ -223,7 +221,6 @@ void testLocalCoordinates() {
...
@@ -223,7 +221,6 @@ void testLocalCoordinates() {
const
Vec3
xWeights
(
-
1.0
,
0.5
,
0.5
);
const
Vec3
xWeights
(
-
1.0
,
0.5
,
0.5
);
const
Vec3
yWeights
(
0.0
,
-
1.0
,
1.0
);
const
Vec3
yWeights
(
0.0
,
-
1.0
,
1.0
);
const
Vec3
localPosition
(
0.4
,
0.3
,
0.2
);
const
Vec3
localPosition
(
0.4
,
0.3
,
0.2
);
ReferencePlatform
platform
;
System
system
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
...
@@ -299,7 +296,6 @@ void testLocalCoordinates() {
...
@@ -299,7 +296,6 @@ void testLocalCoordinates() {
* when using virtual sites.
* when using virtual sites.
*/
*/
void
testConservationLaws
()
{
void
testConservationLaws
()
{
ReferencePlatform
platform
;
System
system
;
System
system
;
NonbondedForce
*
forceField
=
new
NonbondedForce
();
NonbondedForce
*
forceField
=
new
NonbondedForce
();
system
.
addForce
(
forceField
);
system
.
addForce
(
forceField
);
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h
View file @
71d33617
...
@@ -159,7 +159,7 @@ public:
...
@@ -159,7 +159,7 @@ public:
/**
/**
* Update the per-angle parameters in a Context to match those stored in this Force object. This method provides
* Update the per-angle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setAngleParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setAngleParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-angle parameters. The set of particles involved
* The only information this method updates is the values of per-angle parameters. The set of particles involved
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h
View file @
71d33617
...
@@ -131,7 +131,7 @@ public:
...
@@ -131,7 +131,7 @@ public:
/**
/**
* Update the per-bond parameters in a Context to match those stored in this Force object. This method provides
* Update the per-bond parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setBondParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setBondParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-bond parameters. The set of particles involved
* The only information this method updates is the values of per-bond parameters. The set of particles involved
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h
View file @
71d33617
...
@@ -156,7 +156,7 @@ public:
...
@@ -156,7 +156,7 @@ public:
/**
/**
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setParticleParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setParticleParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-particle parameters. All other aspects of the Force
* The only information this method updates is the values of per-particle parameters. All other aspects of the Force
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h
View file @
71d33617
...
@@ -164,7 +164,7 @@ public:
...
@@ -164,7 +164,7 @@ public:
/**
/**
* Update the per-angle parameters in a Context to match those stored in this Force object. This method provides
* Update the per-angle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setAngleParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setAngleParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-angle parameters. The set of particles involved
* The only information this method updates is the values of per-angle parameters. The set of particles involved
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h
View file @
71d33617
...
@@ -340,7 +340,7 @@ public:
...
@@ -340,7 +340,7 @@ public:
/**
/**
* Update the multipole parameters in a Context to match those stored in this Force object. This method
* Update the multipole parameters in a Context to match those stored in this Force object. This method
* provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setMultipoleParameters() to modify this object's parameters, then call updateParametersIn
State
() to
* Simply call setMultipoleParameters() to modify this object's parameters, then call updateParametersIn
Context
() to
* copy them over to the Context.
* copy them over to the Context.
*
*
* This method has several limitations. The only information it updates is the parameters of multipoles.
* This method has several limitations. The only information it updates is the parameters of multipoles.
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h
View file @
71d33617
...
@@ -156,7 +156,7 @@ public:
...
@@ -156,7 +156,7 @@ public:
/**
/**
* Update the per-bend term parameters in a Context to match those stored in this Force object. This method provides
* Update the per-bend term parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setOutOfPlaneBendParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setOutOfPlaneBendParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-bend term parameters. The set of particles involved
* The only information this method updates is the values of per-bend term parameters. The set of particles involved
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h
View file @
71d33617
...
@@ -106,7 +106,7 @@ public:
...
@@ -106,7 +106,7 @@ public:
/**
/**
* Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides
* Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setPiTorsionParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setPiTorsionParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-torsion parameters. The set of particles involved
* The only information this method updates is the values of per-torsion parameters. The set of particles involved
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h
View file @
71d33617
...
@@ -112,7 +112,7 @@ public:
...
@@ -112,7 +112,7 @@ public:
/**
/**
* Update the per-stretch-bend term parameters in a Context to match those stored in this Force object. This method provides
* Update the per-stretch-bend term parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setStretchBendParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setStretchBendParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-stretch-bend term parameters. The set of particles involved
* The only information this method updates is the values of per-stretch-bend term parameters. The set of particles involved
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h
View file @
71d33617
...
@@ -205,7 +205,7 @@ public:
...
@@ -205,7 +205,7 @@ public:
/**
/**
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setParticleParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setParticleParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-particle parameters. All other aspects of the Force
* The only information this method updates is the values of per-particle parameters. All other aspects of the Force
...
...
plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h
View file @
71d33617
...
@@ -92,7 +92,7 @@ public:
...
@@ -92,7 +92,7 @@ public:
/**
/**
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setParticleParameters() to modify this object's parameters, then call updateParametersIn
State
()
* Simply call setParticleParameters() to modify this object's parameters, then call updateParametersIn
Context
()
* to copy them over to the Context.
* to copy them over to the Context.
*
*
* The only information this method updates is the values of per-particle parameters. All other aspects of the Force
* The only information this method updates is the values of per-particle parameters. All other aspects of the Force
...
...
tests/TestVectorize.cpp
View file @
71d33617
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2014 Stanford University and the Authors.
*
* Portions copyright (c) 2014
-2015
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -148,6 +148,7 @@ void testMathFunctions() {
...
@@ -148,6 +148,7 @@ void testMathFunctions() {
ASSERT_VEC4_EQUAL
(
min
(
f1
,
f2
),
0.4
,
1.2
,
-
1.2
,
-
5.0
);
ASSERT_VEC4_EQUAL
(
min
(
f1
,
f2
),
0.4
,
1.2
,
-
1.2
,
-
5.0
);
ASSERT_VEC4_EQUAL
(
max
(
f1
,
f2
),
1.1
,
1.9
,
1.3
,
-
3.8
);
ASSERT_VEC4_EQUAL
(
max
(
f1
,
f2
),
1.1
,
1.9
,
1.3
,
-
3.8
);
ASSERT_VEC4_EQUAL
(
sqrt
(
fvec4
(
1.5
,
3.1
,
4.0
,
15.0
)),
sqrt
(
1.5
),
sqrt
(
3.1
),
sqrt
(
4.0
),
sqrt
(
15.0
));
ASSERT_VEC4_EQUAL
(
sqrt
(
fvec4
(
1.5
,
3.1
,
4.0
,
15.0
)),
sqrt
(
1.5
),
sqrt
(
3.1
),
sqrt
(
4.0
),
sqrt
(
15.0
));
ASSERT_VEC4_EQUAL
(
rsqrt
(
fvec4
(
1.5
,
3.1
,
4.0
,
15.0
)),
1.0
/
sqrt
(
1.5
),
1.0
/
sqrt
(
3.1
),
1.0
/
sqrt
(
4.0
),
1.0
/
sqrt
(
15.0
));
ASSERT_EQUAL_TOL
(
f1
[
0
]
*
f2
[
0
]
+
f1
[
1
]
*
f2
[
1
]
+
f1
[
2
]
*
f2
[
2
],
dot3
(
f1
,
f2
),
1e-6
);
ASSERT_EQUAL_TOL
(
f1
[
0
]
*
f2
[
0
]
+
f1
[
1
]
*
f2
[
1
]
+
f1
[
2
]
*
f2
[
2
],
dot3
(
f1
,
f2
),
1e-6
);
ASSERT_EQUAL_TOL
(
f1
[
0
]
*
f2
[
0
]
+
f1
[
1
]
*
f2
[
1
]
+
f1
[
2
]
*
f2
[
2
]
+
f1
[
3
]
*
f2
[
3
],
dot4
(
f1
,
f2
),
1e-6
);
ASSERT_EQUAL_TOL
(
f1
[
0
]
*
f2
[
0
]
+
f1
[
1
]
*
f2
[
1
]
+
f1
[
2
]
*
f2
[
2
]
+
f1
[
3
]
*
f2
[
3
],
dot4
(
f1
,
f2
),
1e-6
);
ASSERT
(
any
(
f1
>
0.5
));
ASSERT
(
any
(
f1
>
0.5
));
...
...
wrappers/python/simtk/openmm/app/amberprmtopfile.py
View file @
71d33617
...
@@ -73,9 +73,8 @@ class AmberPrmtopFile(object):
...
@@ -73,9 +73,8 @@ class AmberPrmtopFile(object):
def
__init__
(
self
,
file
):
def
__init__
(
self
,
file
):
"""Load a prmtop file."""
"""Load a prmtop file."""
top
=
Topology
()
## The Topology read from the prmtop file
## The Topology read from the prmtop file
self
.
topology
=
top
self
.
topology
=
top
=
Topology
()
self
.
elements
=
[]
self
.
elements
=
[]
# Load the prmtop file
# Load the prmtop file
...
@@ -229,7 +228,7 @@ class AmberPrmtopFile(object):
...
@@ -229,7 +228,7 @@ class AmberPrmtopFile(object):
elif
implicitSolvent
is
None
:
elif
implicitSolvent
is
None
:
implicitSolventKappa
=
0.0
implicitSolventKappa
=
0.0
sys
=
amber_file_parser
.
readAmberSystem
(
prmtop_loader
=
self
.
_prmtop
,
shake
=
constraintString
,
sys
=
amber_file_parser
.
readAmberSystem
(
self
.
topology
,
prmtop_loader
=
self
.
_prmtop
,
shake
=
constraintString
,
nonbondedCutoff
=
nonbondedCutoff
,
nonbondedMethod
=
methodMap
[
nonbondedMethod
],
nonbondedCutoff
=
nonbondedCutoff
,
nonbondedMethod
=
methodMap
[
nonbondedMethod
],
flexibleConstraints
=
False
,
gbmodel
=
implicitString
,
soluteDielectric
=
soluteDielectric
,
flexibleConstraints
=
False
,
gbmodel
=
implicitString
,
soluteDielectric
=
soluteDielectric
,
solventDielectric
=
solventDielectric
,
implicitSolventKappa
=
implicitSolventKappa
,
solventDielectric
=
solventDielectric
,
implicitSolventKappa
=
implicitSolventKappa
,
...
...
wrappers/python/simtk/openmm/app/charmmpsffile.py
View file @
71d33617
...
@@ -37,6 +37,7 @@ from __future__ import division
...
@@ -37,6 +37,7 @@ from __future__ import division
from
functools
import
wraps
from
functools
import
wraps
from
math
import
pi
,
cos
,
sin
,
sqrt
from
math
import
pi
,
cos
,
sin
,
sqrt
import
os
import
os
import
re
import
simtk.openmm
as
mm
import
simtk.openmm
as
mm
from
simtk.openmm.vec3
import
Vec3
from
simtk.openmm.vec3
import
Vec3
import
simtk.unit
as
u
import
simtk.unit
as
u
...
@@ -99,6 +100,8 @@ class _ZeroDict(dict):
...
@@ -99,6 +100,8 @@ class _ZeroDict(dict):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
_resre
=
re
.
compile
(
r
'(\d+)([a-zA-Z]*)'
)
class
CharmmPsfFile
(
object
):
class
CharmmPsfFile
(
object
):
"""
"""
A chemical structure instantiated from CHARMM files.
A chemical structure instantiated from CHARMM files.
...
@@ -192,11 +195,13 @@ class CharmmPsfFile(object):
...
@@ -192,11 +195,13 @@ class CharmmPsfFile(object):
atom_list
=
AtomList
()
atom_list
=
AtomList
()
for
i
in
xrange
(
natom
):
for
i
in
xrange
(
natom
):
words
=
psfsections
[
'NATOM'
][
1
][
i
].
split
()
words
=
psfsections
[
'NATOM'
][
1
][
i
].
split
()
atid
=
int
(
words
[
0
])
if
atid
!=
i
+
1
:
raise
CharmmPSFError
(
'Nonsequential atoms detected!'
)
system
=
words
[
1
]
system
=
words
[
1
]
resid
=
conv
(
words
[
2
],
int
,
'residue number'
)
rematch
=
_resre
.
match
(
words
[
2
])
if
not
rematch
:
raise
RuntimeError
(
'Could not parse residue number %s'
%
words
[
2
])
resid
,
inscode
=
rematch
.
groups
()
resid
=
int
(
resid
)
resname
=
words
[
3
]
resname
=
words
[
3
]
name
=
words
[
4
]
name
=
words
[
4
]
attype
=
words
[
5
]
attype
=
words
[
5
]
...
@@ -209,7 +214,7 @@ class CharmmPsfFile(object):
...
@@ -209,7 +214,7 @@ class CharmmPsfFile(object):
mass
=
conv
(
words
[
7
],
float
,
'atomic mass'
)
mass
=
conv
(
words
[
7
],
float
,
'atomic mass'
)
props
=
words
[
8
:]
props
=
words
[
8
:]
atom
=
residue_list
.
add_atom
(
system
,
resid
,
resname
,
name
,
atom
=
residue_list
.
add_atom
(
system
,
resid
,
resname
,
name
,
attype
,
charge
,
mass
,
props
)
attype
,
charge
,
mass
,
inscode
,
props
)
atom_list
.
append
(
atom
)
atom_list
.
append
(
atom
)
atom_list
.
assign_indexes
()
atom_list
.
assign_indexes
()
atom_list
.
changed
=
False
atom_list
.
changed
=
False
...
@@ -443,175 +448,6 @@ class CharmmPsfFile(object):
...
@@ -443,175 +448,6 @@ class CharmmPsfFile(object):
line
=
psf
.
readline
().
strip
()
line
=
psf
.
readline
().
strip
()
return
title
,
pointers
,
data
return
title
,
pointers
,
data
def
writePsf
(
self
,
dest
,
vmd
=
False
):
"""
Writes a PSF file from the stored molecule
Parameters:
- dest (str or file-like) : The place to write the output PSF file.
If it has a "write" attribute, it will be used to print the
PSF file. Otherwise, it will be treated like a string and a
file will be opened, printed, then closed
- vmd (bool) : If True, it will write out a PSF in the format that
VMD prints it in (i.e., no NUMLP/NUMLPH or MOLNT sections)
Example:
>>> cs = CharmmPsfFile('testfiles/test.psf')
>>> cs.writePsf('testfiles/test2.psf')
"""
# See if this is an extended format
ext
=
'EXT'
in
self
.
flags
own_handle
=
False
# Index the atoms and residues
self
.
residue_list
.
assign_indexes
()
self
.
atom_list
.
assign_indexes
()
if
not
hasattr
(
dest
,
'write'
):
own_handle
=
True
dest
=
open
(
dest
,
'w'
)
# Assign the formats we need to write with
if
ext
:
atmfmt1
=
(
'%10d %-8s %-8i %-8s %-8s %4d %10.6f %13.4f'
+
11
*
' '
)
atmfmt2
=
(
'%10d %-8s %-8i %-8s %-8s %-4s %10.6f %13.4f'
+
11
*
' '
)
intfmt
=
'%10d'
# For pointers
else
:
atmfmt1
=
(
'%8d %-4s %-4i %-4s %-4s %4d %10.6f %13.4f'
+
11
*
' '
)
atmfmt2
=
(
'%8d %-4s %-4i %-4s %-4s %-4s %10.6f %13.4f'
+
11
*
' '
)
intfmt
=
'%8d'
# For pointers
# Now print the header then the title
dest
.
write
(
'PSF '
+
' '
.
join
(
self
.
flags
)
+
'
\n
'
)
dest
.
write
(
'
\n
'
)
dest
.
write
(
intfmt
%
len
(
self
.
title
)
+
' !NTITLE
\n
'
)
dest
.
write
(
'
\n
'
.
join
(
self
.
title
)
+
'
\n\n
'
)
# Now time for the atoms
dest
.
write
(
intfmt
%
len
(
self
.
atom_list
)
+
' !NATOM
\n
'
)
# atmfmt1 is for CHARMM format (i.e., atom types are integers)
# atmfmt is for XPLOR format (i.e., atom types are strings)
for
i
,
atom
in
enumerate
(
self
.
atom_list
):
if
isinstance
(
atom
.
attype
,
str
):
fmt
=
atmfmt2
else
:
fmt
=
atmfmt1
atmstr
=
fmt
%
(
i
+
1
,
atom
.
system
,
atom
.
residue
.
resnum
,
atom
.
residue
.
resname
,
atom
.
name
,
atom
.
attype
,
atom
.
charge
,
atom
.
mass
)
dest
.
write
(
atmstr
+
' '
.
join
(
atom
.
props
)
+
'
\n
'
)
dest
.
write
(
'
\n
'
)
# Bonds
dest
.
write
(
intfmt
%
len
(
self
.
bond_list
)
+
' !NBOND: bonds
\n
'
)
for
i
,
bond
in
enumerate
(
self
.
bond_list
):
dest
.
write
((
intfmt
*
2
)
%
(
bond
.
atom1
.
idx
+
1
,
bond
.
atom2
.
idx
+
1
))
if
i
%
4
==
3
:
# Write 4 bonds per line
dest
.
write
(
'
\n
'
)
# See if we need to terminate
if
len
(
self
.
bond_list
)
%
4
!=
0
or
len
(
self
.
bond_list
)
==
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# Angles
dest
.
write
(
intfmt
%
len
(
self
.
angle_list
)
+
' !NTHETA: angles
\n
'
)
for
i
,
angle
in
enumerate
(
self
.
angle_list
):
dest
.
write
((
intfmt
*
3
)
%
(
angle
.
atom1
.
idx
+
1
,
angle
.
atom2
.
idx
+
1
,
angle
.
atom3
.
idx
+
1
)
)
if
i
%
3
==
2
:
# Write 3 angles per line
dest
.
write
(
'
\n
'
)
# See if we need to terminate
if
len
(
self
.
angle_list
)
%
3
!=
0
or
len
(
self
.
angle_list
)
==
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# Dihedrals
dest
.
write
(
intfmt
%
len
(
self
.
dihedral_list
)
+
' !NPHI: dihedrals
\n
'
)
for
i
,
dih
in
enumerate
(
self
.
dihedral_list
):
dest
.
write
((
intfmt
*
4
)
%
(
dih
.
atom1
.
idx
+
1
,
dih
.
atom2
.
idx
+
1
,
dih
.
atom3
.
idx
+
1
,
dih
.
atom4
.
idx
+
1
)
)
if
i
%
2
==
1
:
# Write 2 dihedrals per line
dest
.
write
(
'
\n
'
)
# See if we need to terminate
if
len
(
self
.
dihedral_list
)
%
2
!=
0
or
len
(
self
.
dihedral_list
)
==
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# Impropers
dest
.
write
(
intfmt
%
len
(
self
.
improper_list
)
+
' !NIMPHI: impropers
\n
'
)
for
i
,
imp
in
enumerate
(
self
.
improper_list
):
dest
.
write
((
intfmt
*
4
)
%
(
imp
.
atom1
.
idx
+
1
,
imp
.
atom2
.
idx
+
1
,
imp
.
atom3
.
idx
+
1
,
imp
.
atom4
.
idx
+
1
)
)
if
i
%
2
==
1
:
# Write 2 dihedrals per line
dest
.
write
(
'
\n
'
)
# See if we need to terminate
if
len
(
self
.
improper_list
)
%
2
!=
0
or
len
(
self
.
improper_list
)
==
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# Donor section
dest
.
write
(
intfmt
%
len
(
self
.
donor_list
)
+
' !NDON: donors
\n
'
)
for
i
,
don
in
enumerate
(
self
.
donor_list
):
dest
.
write
((
intfmt
*
2
)
%
(
don
.
atom1
.
idx
+
1
,
don
.
atom2
.
idx
+
1
))
if
i
%
4
==
3
:
# 4 donors per line
dest
.
write
(
'
\n
'
)
if
len
(
self
.
donor_list
)
%
4
!=
0
or
len
(
self
.
donor_list
)
==
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# Acceptor section
dest
.
write
(
intfmt
%
len
(
self
.
acceptor_list
)
+
' !NACC: acceptors
\n
'
)
for
i
,
acc
in
enumerate
(
self
.
acceptor_list
):
dest
.
write
((
intfmt
*
2
)
%
(
acc
.
atom1
.
idx
+
1
,
acc
.
atom2
.
idx
+
1
))
if
i
%
4
==
3
:
# 4 donors per line
dest
.
write
(
'
\n
'
)
if
len
(
self
.
acceptor_list
)
%
4
!=
0
or
len
(
self
.
acceptor_list
)
==
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# NNB section ??
dest
.
write
(
intfmt
%
0
+
' !NNB
\n\n
'
)
for
i
in
range
(
len
(
self
.
atom_list
)):
dest
.
write
(
intfmt
%
0
)
if
i
%
8
==
7
:
# Write 8 0's per line
dest
.
write
(
'
\n
'
)
if
len
(
self
.
atom_list
)
%
8
!=
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# Group section
dest
.
write
((
intfmt
*
2
)
%
(
len
(
self
.
group_list
),
self
.
group_list
.
nst2
))
dest
.
write
(
' !NGRP NST2
\n
'
)
for
i
,
gp
in
enumerate
(
self
.
group_list
):
dest
.
write
((
intfmt
*
3
)
%
(
gp
.
bs
,
gp
.
type
,
gp
.
move
))
if
i
%
3
==
2
:
dest
.
write
(
'
\n
'
)
if
len
(
self
.
group_list
)
%
3
!=
0
or
len
(
self
.
group_list
)
==
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# The next two sections are never found in VMD prmtops...
if
not
vmd
:
# Molecule section; first set molecularity
set_molecules
(
self
.
atom_list
)
mollist
=
[
a
.
marked
for
a
in
self
.
atom_list
]
dest
.
write
(
intfmt
%
max
(
mollist
)
+
' !MOLNT
\n
'
)
for
i
,
atom
in
enumerate
(
self
.
atom_list
):
dest
.
write
(
intfmt
%
atom
.
marked
)
if
i
%
8
==
7
:
dest
.
write
(
'
\n
'
)
if
len
(
self
.
atom_list
)
%
8
!=
0
:
dest
.
write
(
'
\n
'
)
dest
.
write
(
'
\n
'
)
# NUMLP/NUMLPH section
dest
.
write
((
intfmt
*
2
)
%
(
0
,
0
)
+
' !NUMLP NUMLPH
\n
'
)
dest
.
write
(
'
\n
'
)
# CMAP section
dest
.
write
(
intfmt
%
len
(
self
.
cmap_list
)
+
' !NCRTERM: cross-terms
\n
'
)
for
i
,
cmap
in
enumerate
(
self
.
cmap_list
):
dest
.
write
((
intfmt
*
4
)
%
(
cmap
.
atom1
.
idx
+
1
,
cmap
.
atom2
.
idx
+
1
,
cmap
.
atom3
.
idx
+
1
,
cmap
.
atom4
.
idx
+
1
)
)
if
cmap
.
consecutive
:
dest
.
write
((
intfmt
*
4
)
%
(
cmap
.
atom2
.
idx
+
1
,
cmap
.
atom3
.
idx
+
1
,
cmap
.
atom4
.
idx
+
1
,
cmap
.
atom5
.
idx
+
1
)
)
else
:
dest
.
write
((
intfmt
*
4
)
%
(
cmap
.
atom5
.
idx
+
1
,
cmap
.
atom6
.
idx
+
1
,
cmap
.
atom7
.
idx
+
1
,
cmap
.
atom8
.
idx
+
1
)
)
dest
.
write
(
'
\n
'
)
# Done!
# If we opened our own handle, close it
if
own_handle
:
dest
.
close
()
def
loadParameters
(
self
,
parmset
):
def
loadParameters
(
self
,
parmset
):
"""
"""
Loads parameters from a parameter set that was loaded via CHARMM RTF,
Loads parameters from a parameter set that was loaded via CHARMM RTF,
...
@@ -776,13 +612,13 @@ class CharmmPsfFile(object):
...
@@ -776,13 +612,13 @@ class CharmmPsfFile(object):
last_residue
=
None
last_residue
=
None
# Add each chain (separate 'system's) and residue
# Add each chain (separate 'system's) and residue
for
atom
in
self
.
atom_list
:
for
atom
in
self
.
atom_list
:
resid
=
'%d%s'
%
(
atom
.
residue
.
idx
,
atom
.
residue
.
inscode
)
if
atom
.
system
!=
last_chain
:
if
atom
.
system
!=
last_chain
:
chain
=
topology
.
addChain
(
atom
.
system
)
chain
=
topology
.
addChain
(
atom
.
system
)
last_chain
=
atom
.
system
last_chain
=
atom
.
system
if
atom
.
residue
.
idx
!=
last_residue
:
if
resid
!=
last_residue
:
last_residue
=
atom
.
residue
.
idx
last_residue
=
resid
residue
=
topology
.
addResidue
(
atom
.
residue
.
resname
,
chain
,
residue
=
topology
.
addResidue
(
atom
.
residue
.
resname
,
chain
,
resid
)
str
(
atom
.
residue
.
idx
))
if
atom
.
type
is
not
None
:
if
atom
.
type
is
not
None
:
# This is the most reliable way of determining the element
# This is the most reliable way of determining the element
atomic_num
=
atom
.
type
.
atomic_number
atomic_num
=
atom
.
type
.
atomic_number
...
...
wrappers/python/simtk/openmm/app/dcdfile.py
View file @
71d33617
...
@@ -37,6 +37,8 @@ import time
...
@@ -37,6 +37,8 @@ import time
import
struct
import
struct
import
math
import
math
from
simtk.unit
import
picoseconds
,
nanometers
,
angstroms
,
is_quantity
,
norm
from
simtk.unit
import
picoseconds
,
nanometers
,
angstroms
,
is_quantity
,
norm
from
simtk.openmm
import
Vec3
from
simtk.openmm.app.internal.unitcell
import
computeLengthsAndAngles
class
DCDFile
(
object
):
class
DCDFile
(
object
):
"""DCDFile provides methods for creating DCD files.
"""DCDFile provides methods for creating DCD files.
...
@@ -112,16 +114,16 @@ class DCDFile(object):
...
@@ -112,16 +114,16 @@ class DCDFile(object):
file
.
seek
(
0
,
os
.
SEEK_END
)
file
.
seek
(
0
,
os
.
SEEK_END
)
boxVectors
=
self
.
_topology
.
getPeriodicBoxVectors
()
boxVectors
=
self
.
_topology
.
getPeriodicBoxVectors
()
if
boxVectors
is
not
None
:
if
boxVectors
is
not
None
:
if
getP
eriodicBoxVectors
is
not
None
:
if
p
eriodicBoxVectors
is
not
None
:
boxVectors
=
getP
eriodicBoxVectors
boxVectors
=
p
eriodicBoxVectors
elif
unitCellDimensions
is
not
None
:
elif
unitCellDimensions
is
not
None
:
if
is_quantity
(
unitCellDimensions
):
if
is_quantity
(
unitCellDimensions
):
unitCellDimensions
=
unitCellDimensions
.
value_in_unit
(
nanometers
)
unitCellDimensions
=
unitCellDimensions
.
value_in_unit
(
nanometers
)
boxVectors
=
(
Vec3
(
unitCellDimensions
[
0
],
0
,
0
),
Vec3
(
0
,
unitCellDimensions
[
1
],
0
),
Vec3
(
0
,
0
,
unitCellDimensions
[
2
]))
*
nanometers
boxVectors
=
(
Vec3
(
unitCellDimensions
[
0
],
0
,
0
),
Vec3
(
0
,
unitCellDimensions
[
1
],
0
),
Vec3
(
0
,
0
,
unitCellDimensions
[
2
]))
*
nanometers
(
a_length
,
b_length
,
c_length
,
alpha
,
beta
,
gamma
)
=
computeLengthsAndAngles
(
boxVectors
)
(
a_length
,
b_length
,
c_length
,
alpha
,
beta
,
gamma
)
=
computeLengthsAndAngles
(
boxVectors
)
a_length
=
a_length
.
value_in_unit
(
angstroms
)
a_length
=
a_length
*
10.
# computeLengthsAndAngles returns unitless nanometers, but need
angstroms
here.
b_length
=
b_length
.
value_in_unit
(
angstroms
)
b_length
=
b_length
*
10.
# computeLengthsAndAngles returns unitless nanometers, but need
angstroms
here.
c_length
=
c_length
.
value_in_unit
(
angstroms
)
c_length
=
c_length
*
10.
# computeLengthsAndAngles returns unitless nanometers, but need
angstroms
here.
angle1
=
math
.
sin
(
math
.
pi
/
2
-
gamma
)
angle1
=
math
.
sin
(
math
.
pi
/
2
-
gamma
)
angle2
=
math
.
sin
(
math
.
pi
/
2
-
beta
)
angle2
=
math
.
sin
(
math
.
pi
/
2
-
beta
)
angle3
=
math
.
sin
(
math
.
pi
/
2
-
alpha
)
angle3
=
math
.
sin
(
math
.
pi
/
2
-
alpha
)
...
...
wrappers/python/simtk/openmm/app/element.py
View file @
71d33617
...
@@ -31,7 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
...
@@ -31,7 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
__author__
=
"Christopher M. Bruns"
__author__
=
"Christopher M. Bruns"
__version__
=
"1.0"
__version__
=
"1.0"
from
collections
import
OrderedDict
from
simtk.unit
import
daltons
,
is_quantity
from
simtk.unit
import
daltons
,
is_quantity
import
copy_reg
import
copy_reg
...
@@ -47,6 +47,7 @@ class Element(object):
...
@@ -47,6 +47,7 @@ class Element(object):
_elements_by_symbol
=
{}
_elements_by_symbol
=
{}
_elements_by_atomic_number
=
{}
_elements_by_atomic_number
=
{}
_elements_by_mass
=
None
def
__init__
(
self
,
number
,
name
,
symbol
,
mass
):
def
__init__
(
self
,
number
,
name
,
symbol
,
mass
):
"""Create a new element
"""Create a new element
...
@@ -67,8 +68,11 @@ class Element(object):
...
@@ -67,8 +68,11 @@ class Element(object):
self
.
_mass
=
mass
self
.
_mass
=
mass
# Index this element in a global table
# Index this element in a global table
s
=
symbol
.
strip
().
upper
()
s
=
symbol
.
strip
().
upper
()
## If we add a new element, we need to re-hash elements by mass
Element
.
_elements_by_mass
=
None
assert
s
not
in
Element
.
_elements_by_symbol
if
s
in
Element
.
_elements_by_symbol
:
raise
ValueError
(
'Duplicate element symbol %s'
%
s
)
Element
.
_elements_by_symbol
[
s
]
=
self
Element
.
_elements_by_symbol
[
s
]
=
self
if
number
in
Element
.
_elements_by_atomic_number
:
if
number
in
Element
.
_elements_by_atomic_number
:
other_element
=
Element
.
_elements_by_atomic_number
[
number
]
other_element
=
Element
.
_elements_by_atomic_number
[
number
]
...
@@ -96,20 +100,45 @@ class Element(object):
...
@@ -96,20 +100,45 @@ class Element(object):
"""
"""
Get the element whose mass is CLOSEST to the requested mass. This method
Get the element whose mass is CLOSEST to the requested mass. This method
should not be used for repartitioned masses
should not be used for repartitioned masses
Parameters
----------
mass : float or Quantity
Mass of the atom to find the element for. Units assumed to be
daltons if not specified
Returns
-------
element : Element
The element whose atomic mass is closest to the input mass
"""
"""
# Assume masses are in daltons if they are not units
# Assume masses are in daltons if they are not units
if
not
is_quantity
(
mass
):
if
is_quantity
(
mass
):
mass
=
mass
*
daltons
mass
=
mass
.
value_in_unit
(
daltons
)
if
mass
<
0
:
raise
ValueError
(
'Invalid Higgs field'
)
# If this is our first time calling getByMass (or we added an element
# since the last call), re-generate the ordered by-mass dict cache
if
Element
.
_elements_by_mass
is
None
:
Element
.
_elements_by_mass
=
OrderedDict
()
for
elem
in
sorted
(
Element
.
_elements_by_symbol
.
values
(),
key
=
lambda
x
:
x
.
mass
):
Element
.
_elements_by_mass
[
elem
.
mass
]
=
elem
diff
=
mass
diff
=
mass
best_guess
=
None
best_guess
=
None
for
key
in
Element
.
_elements_by_atomic_number
:
for
elemmass
,
element
in
Element
.
_elements_by_mass
.
iteritems
():
element
=
Element
.
_elements_by_atomic_number
[
key
]
massdiff
=
abs
(
elemmass
.
_value
-
mass
)
massdiff
=
abs
(
element
.
mass
-
mass
)
if
massdiff
<
diff
:
if
massdiff
<
diff
:
best_guess
=
element
best_guess
=
element
diff
=
massdiff
diff
=
massdiff
if
elemmass
.
_value
>
mass
:
# Elements are only getting heavier, so bail out early
return
best_guess
# This really should only happen if we wanted ununoctium or something
# bigger... won't really happen but still make sure we return an Element
return
best_guess
return
best_guess
@
property
@
property
...
@@ -145,6 +174,9 @@ def _pickle_element(element):
...
@@ -145,6 +174,9 @@ def _pickle_element(element):
copy_reg
.
pickle
(
Element
,
_pickle_element
)
copy_reg
.
pickle
(
Element
,
_pickle_element
)
# NOTE: getElementByMass assumes all masses are Quantity instances with unit
# "daltons". All elements need to obey this assumption, or that method will
# fail. No checking is done in getElementByMass for performance reasons
hydrogen
=
Element
(
1
,
"hydrogen"
,
"H"
,
1.007947
*
daltons
)
hydrogen
=
Element
(
1
,
"hydrogen"
,
"H"
,
1.007947
*
daltons
)
deuterium
=
Element
(
1
,
"deuterium"
,
"D"
,
2.01355321270
*
daltons
)
deuterium
=
Element
(
1
,
"deuterium"
,
"D"
,
2.01355321270
*
daltons
)
helium
=
Element
(
2
,
"helium"
,
"He"
,
4.003
*
daltons
)
helium
=
Element
(
2
,
"helium"
,
"He"
,
4.003
*
daltons
)
...
...
wrappers/python/simtk/openmm/app/internal/amber_file_parser.py
View file @
71d33617
...
@@ -122,21 +122,22 @@ class PrmtopLoader(object):
...
@@ -122,21 +122,22 @@ class PrmtopLoader(object):
with
open
(
inFilename
,
'r'
)
as
fIn
:
with
open
(
inFilename
,
'r'
)
as
fIn
:
for
line
in
fIn
:
for
line
in
fIn
:
if
line
.
startswith
(
'%VERSION'
):
if
line
[
0
]
==
'%'
:
tag
,
self
.
_prmtopVersion
=
line
.
rstrip
().
split
(
None
,
1
)
if
line
.
startswith
(
'%VERSION'
):
elif
line
.
startswith
(
'%FLAG'
):
tag
,
self
.
_prmtopVersion
=
line
.
rstrip
().
split
(
None
,
1
)
tag
,
flag
=
line
.
rstrip
().
split
(
None
,
1
)
elif
line
.
startswith
(
'%FLAG'
):
self
.
_flags
.
append
(
flag
)
tag
,
flag
=
line
.
rstrip
().
split
(
None
,
1
)
self
.
_raw_data
[
flag
]
=
[]
self
.
_flags
.
append
(
flag
)
elif
line
.
startswith
(
'%FORMAT'
):
self
.
_raw_data
[
flag
]
=
[]
format
=
line
.
rstrip
()
elif
line
.
startswith
(
'%FORMAT'
):
index0
=
format
.
index
(
'('
)
format
=
line
.
rstrip
()
index1
=
format
.
index
(
')'
)
index0
=
format
.
index
(
'('
)
format
=
format
[
index0
+
1
:
index1
]
index1
=
format
.
index
(
')'
)
m
=
FORMAT_RE_PATTERN
.
search
(
format
)
format
=
format
[
index0
+
1
:
index1
]
self
.
_raw_format
[
self
.
_flags
[
-
1
]]
=
(
format
,
m
.
group
(
1
),
m
.
group
(
2
),
m
.
group
(
3
),
m
.
group
(
4
))
m
=
FORMAT_RE_PATTERN
.
search
(
format
)
elif
line
.
startswith
(
'%COMMENT'
):
self
.
_raw_format
[
self
.
_flags
[
-
1
]]
=
(
format
,
m
.
group
(
1
),
m
.
group
(
2
),
int
(
m
.
group
(
3
)),
m
.
group
(
4
))
continue
elif
line
.
startswith
(
'%COMMENT'
):
continue
elif
self
.
_flags
\
elif
self
.
_flags
\
and
'TITLE'
==
self
.
_flags
[
-
1
]
\
and
'TITLE'
==
self
.
_flags
[
-
1
]
\
and
not
self
.
_raw_data
[
'TITLE'
]:
and
not
self
.
_raw_data
[
'TITLE'
]:
...
@@ -144,8 +145,7 @@ class PrmtopLoader(object):
...
@@ -144,8 +145,7 @@ class PrmtopLoader(object):
else
:
else
:
flag
=
self
.
_flags
[
-
1
]
flag
=
self
.
_flags
[
-
1
]
(
format
,
numItems
,
itemType
,
(
format
,
numItems
,
itemType
,
itemLength
,
itemPrecision
)
=
self
.
_getFormat
(
flag
)
iLength
,
itemPrecision
)
=
self
.
_getFormat
(
flag
)
iLength
=
int
(
itemLength
)
line
=
line
.
rstrip
()
line
=
line
.
rstrip
()
for
index
in
range
(
0
,
len
(
line
),
iLength
):
for
index
in
range
(
0
,
len
(
line
),
iLength
):
item
=
line
[
index
:
index
+
iLength
]
item
=
line
[
index
:
index
+
iLength
]
...
@@ -305,6 +305,10 @@ class PrmtopLoader(object):
...
@@ -305,6 +305,10 @@ class PrmtopLoader(object):
return
self
.
_nonbondTerms
return
self
.
_nonbondTerms
except
AttributeError
:
except
AttributeError
:
pass
pass
# Check if there are any non-zero HBOND terms
for
x
,
y
in
zip
(
self
.
_raw_data
[
'HBOND_ACOEF'
],
self
.
_raw_data
[
'HBOND_BCOEF'
]):
if
float
(
x
)
or
float
(
y
):
raise
Exception
(
'10-12 interactions are not supported'
)
self
.
_nonbondTerms
=
[]
self
.
_nonbondTerms
=
[]
lengthConversionFactor
=
units
.
angstrom
.
conversion_factor_to
(
units
.
nanometer
)
lengthConversionFactor
=
units
.
angstrom
.
conversion_factor_to
(
units
.
nanometer
)
energyConversionFactor
=
units
.
kilocalorie_per_mole
.
conversion_factor_to
(
units
.
kilojoule_per_mole
)
energyConversionFactor
=
units
.
kilocalorie_per_mole
.
conversion_factor_to
(
units
.
kilojoule_per_mole
)
...
@@ -333,6 +337,7 @@ class PrmtopLoader(object):
...
@@ -333,6 +337,7 @@ class PrmtopLoader(object):
for
i
in
range
(
numTypes
):
for
i
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
index
=
int
(
self
.
_raw_data
[
'NONBONDED_PARM_INDEX'
][
numTypes
*
i
+
j
])
-
1
index
=
int
(
self
.
_raw_data
[
'NONBONDED_PARM_INDEX'
][
numTypes
*
i
+
j
])
-
1
if
index
<
0
:
continue
rij
=
type_parameters
[
i
][
0
]
+
type_parameters
[
j
][
0
]
rij
=
type_parameters
[
i
][
0
]
+
type_parameters
[
j
][
0
]
wdij
=
sqrt
(
type_parameters
[
i
][
1
]
*
type_parameters
[
j
][
1
])
wdij
=
sqrt
(
type_parameters
[
i
][
1
]
*
type_parameters
[
j
][
1
])
a
=
float
(
self
.
_raw_data
[
'LENNARD_JONES_ACOEF'
][
index
])
a
=
float
(
self
.
_raw_data
[
'LENNARD_JONES_ACOEF'
][
index
])
...
@@ -477,6 +482,7 @@ class PrmtopLoader(object):
...
@@ -477,6 +482,7 @@ class PrmtopLoader(object):
typ1
=
atomTypeIndexes
[
iAtom
]
-
1
typ1
=
atomTypeIndexes
[
iAtom
]
-
1
typ2
=
atomTypeIndexes
[
lAtom
]
-
1
typ2
=
atomTypeIndexes
[
lAtom
]
-
1
idx
=
nbidx
[
numTypes
*
typ1
+
typ2
]
-
1
idx
=
nbidx
[
numTypes
*
typ1
+
typ2
]
-
1
if
idx
<
0
:
continue
a
=
parm_acoef
[
idx
]
a
=
parm_acoef
[
idx
]
b
=
parm_bcoef
[
idx
]
b
=
parm_bcoef
[
idx
]
try
:
try
:
...
@@ -645,7 +651,7 @@ class PrmtopLoader(object):
...
@@ -645,7 +651,7 @@ class PrmtopLoader(object):
# AMBER System builder (based on, but not identical to, systemManager from 'zander')
# AMBER System builder (based on, but not identical to, systemManager from 'zander')
#=============================================================================================
#=============================================================================================
def
readAmberSystem
(
prmtop_filename
=
None
,
prmtop_loader
=
None
,
shake
=
None
,
gbmodel
=
None
,
def
readAmberSystem
(
topology
,
prmtop_filename
=
None
,
prmtop_loader
=
None
,
shake
=
None
,
gbmodel
=
None
,
soluteDielectric
=
1.0
,
solventDielectric
=
78.5
,
soluteDielectric
=
1.0
,
solventDielectric
=
78.5
,
implicitSolventKappa
=
0.0
*
(
1
/
units
.
nanometer
),
nonbondedCutoff
=
None
,
implicitSolventKappa
=
0.0
*
(
1
/
units
.
nanometer
),
nonbondedCutoff
=
None
,
nonbondedMethod
=
'NoCutoff'
,
scee
=
None
,
scnb
=
None
,
mm
=
None
,
verbose
=
False
,
nonbondedMethod
=
'NoCutoff'
,
scee
=
None
,
scnb
=
None
,
mm
=
None
,
verbose
=
False
,
...
@@ -653,6 +659,9 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -653,6 +659,9 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
"""
"""
Create an OpenMM System from an Amber prmtop file.
Create an OpenMM System from an Amber prmtop file.
REQUIRED ARGUMENT
topology (forcefield.Topology) The topology for the system that is about
to be created
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
...
@@ -733,7 +742,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -733,7 +742,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
system
.
addParticle
(
mass
)
system
.
addParticle
(
mass
)
# Add constraints.
# Add constraints.
isWater
=
[
prmtop
.
getResidueLabel
(
i
)
in
(
'WAT'
,
'TP4'
,
'TP5'
,
'T4E'
)
for
i
in
range
(
prmtop
.
getNumAtoms
())]
isWater
=
[
prmtop
.
getResidueLabel
(
i
)
in
(
'WAT'
,
'HOH'
,
'TP4'
,
'TP5'
,
'T4E'
)
for
i
in
range
(
prmtop
.
getNumAtoms
())]
if
shake
in
(
'h-bonds'
,
'all-bonds'
,
'h-angles'
):
if
shake
in
(
'h-bonds'
,
'all-bonds'
,
'h-angles'
):
for
(
iAtom
,
jAtom
,
k
,
rMin
)
in
prmtop
.
getBondsWithH
():
for
(
iAtom
,
jAtom
,
k
,
rMin
)
in
prmtop
.
getBondsWithH
():
system
.
addConstraint
(
iAtom
,
jAtom
,
rMin
)
system
.
addConstraint
(
iAtom
,
jAtom
,
rMin
)
...
@@ -768,13 +777,14 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -768,13 +777,14 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
distance
=
c
[
2
].
value_in_unit
(
units
.
nanometer
)
distance
=
c
[
2
].
value_in_unit
(
units
.
nanometer
)
atomConstraints
[
c
[
0
]].
append
((
c
[
1
],
distance
))
atomConstraints
[
c
[
0
]].
append
((
c
[
1
],
distance
))
atomConstraints
[
c
[
1
]].
append
((
c
[
0
],
distance
))
atomConstraints
[
c
[
1
]].
append
((
c
[
0
],
distance
))
topatoms
=
list
(
topology
.
atoms
())
for
(
iAtom
,
jAtom
,
kAtom
,
k
,
aMin
)
in
prmtop
.
getAngles
():
for
(
iAtom
,
jAtom
,
kAtom
,
k
,
aMin
)
in
prmtop
.
getAngles
():
if
shake
==
'h-angles'
:
if
shake
==
'h-angles'
:
type1
=
prmtop
.
getAtomType
(
iAtom
)
atomI
=
topatoms
[
iAtom
]
type2
=
prmtop
.
getAtomType
(
jAtom
)
atomJ
=
topatoms
[
jAtom
]
type3
=
prmtop
.
getAtomType
(
kAtom
)
atomK
=
topatoms
[
kAtom
]
numH
=
len
([
type
for
type
in
(
type1
,
type3
)
if
type
.
startswith
(
'H'
)]
)
numH
=
((
atomI
.
element
.
atomic_number
==
1
)
+
(
atomK
.
element
.
atomic_number
==
1
)
)
constrained
=
(
numH
==
2
or
(
numH
==
1
and
type2
.
startswith
(
'O'
)
))
constrained
=
(
numH
==
2
or
(
numH
==
1
and
atomJ
.
element
is
elem
.
oxygen
))
else
:
else
:
constrained
=
False
constrained
=
False
if
constrained
:
if
constrained
:
...
@@ -870,6 +880,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -870,6 +880,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
for
i
in
range
(
numTypes
):
for
i
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
if
idx
<
0
:
continue
acoef
[
i
+
numTypes
*
j
]
=
sqrt
(
parm_acoef
[
idx
])
*
afac
acoef
[
i
+
numTypes
*
j
]
=
sqrt
(
parm_acoef
[
idx
])
*
afac
bcoef
[
i
+
numTypes
*
j
]
=
parm_bcoef
[
idx
]
*
bfac
bcoef
[
i
+
numTypes
*
j
]
=
parm_bcoef
[
idx
]
*
bfac
if
has_1264
:
if
has_1264
:
...
@@ -878,6 +889,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -878,6 +889,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
for
i
in
range
(
numTypes
):
for
i
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
if
idx
<
0
:
continue
ccoef
[
i
+
numTypes
*
j
]
=
parm_ccoef
[
idx
]
*
cfac
ccoef
[
i
+
numTypes
*
j
]
=
parm_ccoef
[
idx
]
*
cfac
cforce
=
mm
.
CustomNonbondedForce
(
'(a/r6)^2-b/r6-c/r^4; r6=r^6;'
cforce
=
mm
.
CustomNonbondedForce
(
'(a/r6)^2-b/r6-c/r^4; r6=r^6;'
'a=acoef(type1, type2);'
'a=acoef(type1, type2);'
...
@@ -911,6 +923,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
...
@@ -911,6 +923,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode
for
i
in
range
(
numTypes
):
for
i
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
for
j
in
range
(
numTypes
):
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
idx
=
nbidx
[
numTypes
*
i
+
j
]
-
1
if
idx
<
0
:
continue
ccoef
[
i
+
numTypes
*
j
]
=
parm_ccoef
[
idx
]
*
cfac
ccoef
[
i
+
numTypes
*
j
]
=
parm_ccoef
[
idx
]
*
cfac
cforce
=
mm
.
CustomNonbondedForce
(
'-c/r^4; c=ccoef(type1, type2)'
)
cforce
=
mm
.
CustomNonbondedForce
(
'-c/r^4; c=ccoef(type1, type2)'
)
cforce
.
addTabulatedFunction
(
'ccoef'
,
cforce
.
addTabulatedFunction
(
'ccoef'
,
...
...
wrappers/python/simtk/openmm/app/internal/charmm/topologyobjects.py
View file @
71d33617
...
@@ -375,12 +375,13 @@ class AtomList(TrackedList):
...
@@ -375,12 +375,13 @@ class AtomList(TrackedList):
class
Residue
(
object
):
class
Residue
(
object
):
""" Residue class """
""" Residue class """
def
__init__
(
self
,
resname
,
idx
):
def
__init__
(
self
,
resname
,
idx
,
inscode
=
''
):
self
.
resname
=
resname
self
.
resname
=
resname
self
.
idx
=
idx
self
.
idx
=
idx
self
.
atoms
=
[]
self
.
atoms
=
[]
self
.
resnum
=
None
# Numbered based on SYSTEM name
self
.
resnum
=
None
# Numbered based on SYSTEM name
self
.
system
=
None
self
.
system
=
None
self
.
inscode
=
inscode
def
add_atom
(
self
,
atom
):
def
add_atom
(
self
,
atom
):
if
self
.
system
is
None
:
if
self
.
system
is
None
:
...
@@ -416,7 +417,7 @@ class Residue(object):
...
@@ -416,7 +417,7 @@ class Residue(object):
return
self
.
resname
==
thing
.
resname
and
self
.
idx
==
thing
.
idx
return
self
.
resname
==
thing
.
resname
and
self
.
idx
==
thing
.
idx
if
isinstance
(
thing
,
tuple
)
or
isinstance
(
thing
,
list
):
if
isinstance
(
thing
,
tuple
)
or
isinstance
(
thing
,
list
):
# Must be resnum, resname
# Must be resnum, resname
return
thing
==
(
self
.
resname
,
self
.
idx
)
return
thing
==
(
self
.
resname
,
self
.
idx
,
self
.
inscode
)
return
False
# No other type can be equal.
return
False
# No other type can be equal.
def
__ne__
(
self
,
thing
):
def
__ne__
(
self
,
thing
):
...
@@ -447,7 +448,7 @@ class ResidueList(list):
...
@@ -447,7 +448,7 @@ class ResidueList(list):
resnum
+=
1
resnum
+=
1
def
add_atom
(
self
,
system
,
resnum
,
resname
,
name
,
def
add_atom
(
self
,
system
,
resnum
,
resname
,
name
,
attype
,
charge
,
mass
,
props
=
None
):
attype
,
charge
,
mass
,
inscode
,
props
=
None
):
"""
"""
Adds an atom to the list of residues. If the residue is not the same as
Adds an atom to the list of residues. If the residue is not the same as
the last residue that was created, a new Residue is created and added
the last residue that was created, a new Residue is created and added
...
@@ -461,25 +462,22 @@ class ResidueList(list):
...
@@ -461,25 +462,22 @@ class ResidueList(list):
- attype (int or str) : Type of the atom
- attype (int or str) : Type of the atom
- charge (float) : Partial atomic charge of the atom
- charge (float) : Partial atomic charge of the atom
- mass (float) : Mass (amu) of the atom
- mass (float) : Mass (amu) of the atom
- inscode (str) : Insertion code, if it is specified
Returns:
Returns:
The Atom instance created and added to the list of residues
The Atom instance created and added to the list of residues
"""
"""
if
self
.
_last_residue
is
None
:
lr
=
self
.
_last_residue
res
=
self
.
_last_residue
=
Residue
(
resname
,
resnum
)
if
lr
is
None
:
res
=
self
.
_last_residue
=
Residue
(
resname
,
resnum
,
inscode
)
list
.
append
(
self
,
res
)
list
.
append
(
self
,
res
)
elif
(
self
.
_last_residue
!=
(
resname
,
resnum
)
or
elif
(
lr
.
resname
!=
resname
or
lr
.
idx
!=
resname
or
system
!=
self
.
_last_residue
.
system
):
lr
.
inscode
!=
inscode
or
system
!=
lr
.
system
):
if
(
self
.
_last_residue
.
idx
==
resnum
and
res
=
self
.
_last_residue
=
Residue
(
resname
,
resnum
,
inscode
)
self
.
_last_residue
.
system
==
system
):
res
.
system
=
system
lresname
=
self
.
_last_residue
.
resname
warnings
.
warn
(
'Residue %d split into separate residues %s '
'and %s'
%
(
resnum
,
lresname
,
resname
),
SplitResidueWarning
)
res
=
self
.
_last_residue
=
Residue
(
resname
,
resnum
)
list
.
append
(
self
,
res
)
list
.
append
(
self
,
res
)
else
:
else
:
res
=
self
.
_last_residue
res
=
lr
atom
=
Atom
(
system
,
name
,
attype
,
float
(
charge
),
float
(
mass
),
props
)
atom
=
Atom
(
system
,
name
,
attype
,
float
(
charge
),
float
(
mass
),
props
)
res
.
add_atom
(
atom
)
res
.
add_atom
(
atom
)
return
atom
return
atom
...
...
Prev
1
2
3
4
5
6
7
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