Commit 39120086 authored by John Chodera (MSKCC)'s avatar John Chodera (MSKCC)
Browse files

Merge remote-tracking branch 'upstream/master' into forcefield

parents 87b95319 2acba7ad
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -45,6 +45,7 @@ void testSerialization() { ...@@ -45,6 +45,7 @@ void testSerialization() {
// Create a Force. // Create a Force.
AmoebaBondForce force1; AmoebaBondForce force1;
force1.setForceGroup(3);
force1.setAmoebaGlobalBondCubic(12.3); force1.setAmoebaGlobalBondCubic(12.3);
force1.setAmoebaGlobalBondQuartic(98.7); force1.setAmoebaGlobalBondQuartic(98.7);
force1.addBond(0, 1, 1.0, 2.0); force1.addBond(0, 1, 1.0, 2.0);
...@@ -60,6 +61,7 @@ void testSerialization() { ...@@ -60,6 +61,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaBondForce& force2 = *copy; AmoebaBondForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getAmoebaGlobalBondCubic(), force2.getAmoebaGlobalBondCubic()); ASSERT_EQUAL(force1.getAmoebaGlobalBondCubic(), force2.getAmoebaGlobalBondCubic());
ASSERT_EQUAL(force1.getAmoebaGlobalBondQuartic(), force2.getAmoebaGlobalBondQuartic()); ASSERT_EQUAL(force1.getAmoebaGlobalBondQuartic(), force2.getAmoebaGlobalBondQuartic());
ASSERT_EQUAL(force1.getNumBonds(), force2.getNumBonds()); ASSERT_EQUAL(force1.getNumBonds(), force2.getNumBonds());
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -45,6 +45,7 @@ void testSerialization() { ...@@ -45,6 +45,7 @@ void testSerialization() {
// Create a Force. // Create a Force.
AmoebaGeneralizedKirkwoodForce force1; AmoebaGeneralizedKirkwoodForce force1;
force1.setForceGroup(3);
force1.setSolventDielectric( 80.0); force1.setSolventDielectric( 80.0);
force1.setSoluteDielectric( 1.0); force1.setSoluteDielectric( 1.0);
//force1.setDielectricOffset( 0.09); //force1.setDielectricOffset( 0.09);
...@@ -64,6 +65,7 @@ void testSerialization() { ...@@ -64,6 +65,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaGeneralizedKirkwoodForce& force2 = *copy; AmoebaGeneralizedKirkwoodForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getSolventDielectric(), force2.getSolventDielectric()); ASSERT_EQUAL(force1.getSolventDielectric(), force2.getSolventDielectric());
ASSERT_EQUAL(force1.getSoluteDielectric(), force2.getSoluteDielectric()); ASSERT_EQUAL(force1.getSoluteDielectric(), force2.getSoluteDielectric());
//ASSERT_EQUAL(force1.getDielectricOffset(), force2.getDielectricOffset()); //ASSERT_EQUAL(force1.getDielectricOffset(), force2.getDielectricOffset());
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -46,6 +46,7 @@ void testSerialization() { ...@@ -46,6 +46,7 @@ void testSerialization() {
AmoebaInPlaneAngleForce force1; AmoebaInPlaneAngleForce force1;
force1.setForceGroup(3);
force1.setAmoebaGlobalInPlaneAngleCubic(12.3); force1.setAmoebaGlobalInPlaneAngleCubic(12.3);
force1.setAmoebaGlobalInPlaneAngleQuartic(98.7); force1.setAmoebaGlobalInPlaneAngleQuartic(98.7);
force1.setAmoebaGlobalInPlaneAnglePentic(91.7); force1.setAmoebaGlobalInPlaneAnglePentic(91.7);
...@@ -65,6 +66,7 @@ void testSerialization() { ...@@ -65,6 +66,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaInPlaneAngleForce& force2 = *copy; AmoebaInPlaneAngleForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getAmoebaGlobalInPlaneAngleCubic(), force2.getAmoebaGlobalInPlaneAngleCubic()); ASSERT_EQUAL(force1.getAmoebaGlobalInPlaneAngleCubic(), force2.getAmoebaGlobalInPlaneAngleCubic());
ASSERT_EQUAL(force1.getAmoebaGlobalInPlaneAngleQuartic(), force2.getAmoebaGlobalInPlaneAngleQuartic()); ASSERT_EQUAL(force1.getAmoebaGlobalInPlaneAngleQuartic(), force2.getAmoebaGlobalInPlaneAngleQuartic());
ASSERT_EQUAL(force1.getAmoebaGlobalInPlaneAnglePentic(), force2.getAmoebaGlobalInPlaneAnglePentic()); ASSERT_EQUAL(force1.getAmoebaGlobalInPlaneAnglePentic(), force2.getAmoebaGlobalInPlaneAnglePentic());
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -59,6 +59,7 @@ void testSerialization() { ...@@ -59,6 +59,7 @@ void testSerialization() {
// Create a Force. // Create a Force.
AmoebaMultipoleForce force1; AmoebaMultipoleForce force1;
force1.setForceGroup(3);
force1.setNonbondedMethod(AmoebaMultipoleForce::NoCutoff); force1.setNonbondedMethod(AmoebaMultipoleForce::NoCutoff);
force1.setCutoffDistance(0.9); force1.setCutoffDistance(0.9);
force1.setAEwald(0.544); force1.setAEwald(0.544);
...@@ -74,6 +75,12 @@ void testSerialization() { ...@@ -74,6 +75,12 @@ void testSerialization() {
force1.setMutualInducedTargetEpsilon(1.0e-05); force1.setMutualInducedTargetEpsilon(1.0e-05);
//force1.setElectricConstant(138.93); //force1.setElectricConstant(138.93);
force1.setEwaldErrorTolerance(1.0e-05); force1.setEwaldErrorTolerance(1.0e-05);
vector<double> coeff;
coeff.push_back(0.0);
coeff.push_back(-0.1);
coeff.push_back(1.1);
force1.setExtrapolationCoefficients(coeff);
std::vector<std::string> covalentTypes; std::vector<std::string> covalentTypes;
getCovalentTypes(covalentTypes); getCovalentTypes(covalentTypes);
...@@ -105,6 +112,7 @@ void testSerialization() { ...@@ -105,6 +112,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaMultipoleForce& force2 = *copy; AmoebaMultipoleForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getCutoffDistance(), force2.getCutoffDistance()); ASSERT_EQUAL(force1.getCutoffDistance(), force2.getCutoffDistance());
ASSERT_EQUAL(force1.getNonbondedMethod(), force2.getNonbondedMethod()); ASSERT_EQUAL(force1.getNonbondedMethod(), force2.getNonbondedMethod());
ASSERT_EQUAL(force1.getAEwald(), force2.getAEwald()); ASSERT_EQUAL(force1.getAEwald(), force2.getAEwald());
...@@ -125,6 +133,8 @@ void testSerialization() { ...@@ -125,6 +133,8 @@ void testSerialization() {
ASSERT_EQUAL(gridDimension1[jj], gridDimension2[jj]); ASSERT_EQUAL(gridDimension1[jj], gridDimension2[jj]);
} }
ASSERT_EQUAL_CONTAINERS(force1.getExtrapolationCoefficients(), force2.getExtrapolationCoefficients());
ASSERT_EQUAL(force1.getNumMultipoles(), force2.getNumMultipoles()); ASSERT_EQUAL(force1.getNumMultipoles(), force2.getNumMultipoles());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumMultipoles()); ii++) { for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumMultipoles()); ii++) {
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -46,6 +46,7 @@ void testSerialization() { ...@@ -46,6 +46,7 @@ void testSerialization() {
AmoebaOutOfPlaneBendForce force1; AmoebaOutOfPlaneBendForce force1;
force1.setForceGroup(3);
force1.setAmoebaGlobalOutOfPlaneBendCubic(12.3); force1.setAmoebaGlobalOutOfPlaneBendCubic(12.3);
force1.setAmoebaGlobalOutOfPlaneBendQuartic(98.7); force1.setAmoebaGlobalOutOfPlaneBendQuartic(98.7);
force1.setAmoebaGlobalOutOfPlaneBendPentic(91.7); force1.setAmoebaGlobalOutOfPlaneBendPentic(91.7);
...@@ -65,6 +66,7 @@ void testSerialization() { ...@@ -65,6 +66,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaOutOfPlaneBendForce& force2 = *copy; AmoebaOutOfPlaneBendForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendCubic(), force2.getAmoebaGlobalOutOfPlaneBendCubic()); ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendCubic(), force2.getAmoebaGlobalOutOfPlaneBendCubic());
ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendQuartic(), force2.getAmoebaGlobalOutOfPlaneBendQuartic()); ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendQuartic(), force2.getAmoebaGlobalOutOfPlaneBendQuartic());
ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendPentic(), force2.getAmoebaGlobalOutOfPlaneBendPentic()); ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendPentic(), force2.getAmoebaGlobalOutOfPlaneBendPentic());
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -45,6 +45,7 @@ void testSerialization() { ...@@ -45,6 +45,7 @@ void testSerialization() {
// Create a Force. // Create a Force.
AmoebaPiTorsionForce force1; AmoebaPiTorsionForce force1;
force1.setForceGroup(3);
force1.addPiTorsion(0, 1, 3, 4, 5, 6, 2.0); force1.addPiTorsion(0, 1, 3, 4, 5, 6, 2.0);
force1.addPiTorsion(0, 2, 3, 5, 12, 13, 2.1); force1.addPiTorsion(0, 2, 3, 5, 12, 13, 2.1);
force1.addPiTorsion(2, 3, 5, 6, 81, 91, 2.2); force1.addPiTorsion(2, 3, 5, 6, 81, 91, 2.2);
...@@ -58,6 +59,7 @@ void testSerialization() { ...@@ -58,6 +59,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaPiTorsionForce& force2 = *copy; AmoebaPiTorsionForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getNumPiTorsions(), force2.getNumPiTorsions()); ASSERT_EQUAL(force1.getNumPiTorsions(), force2.getNumPiTorsions());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumPiTorsions()); ii++) { for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumPiTorsions()); ii++) {
int a1, a2, a3, a4, a5, a6, b1, b2, b3, b4, b5, b6; int a1, a2, a3, a4, a5, a6, b1, b2, b3, b4, b5, b6;
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -45,6 +45,7 @@ void testSerialization() { ...@@ -45,6 +45,7 @@ void testSerialization() {
// Create a Force. // Create a Force.
AmoebaStretchBendForce force1; AmoebaStretchBendForce force1;
force1.setForceGroup(3);
force1.addStretchBend(0, 1, 3, 1.0, 1.2, 150.1, 83.2, 100.); force1.addStretchBend(0, 1, 3, 1.0, 1.2, 150.1, 83.2, 100.);
force1.addStretchBend(2, 4, 4, 1.1, 2.2, 180.1, 89.2, 100.); force1.addStretchBend(2, 4, 4, 1.1, 2.2, 180.1, 89.2, 100.);
force1.addStretchBend(5, 0, 1, 3.1, 8.2, 140.1, 98.2, 100.); force1.addStretchBend(5, 0, 1, 3.1, 8.2, 140.1, 98.2, 100.);
...@@ -57,6 +58,7 @@ void testSerialization() { ...@@ -57,6 +58,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaStretchBendForce& force2 = *copy; AmoebaStretchBendForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getNumStretchBends(), force2.getNumStretchBends()); ASSERT_EQUAL(force1.getNumStretchBends(), force2.getNumStretchBends());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumStretchBends()); ii++) { for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumStretchBends()); ii++) {
int p11, p12, p13; int p11, p12, p13;
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -81,6 +81,7 @@ void testSerialization() { ...@@ -81,6 +81,7 @@ void testSerialization() {
AmoebaTorsionTorsionForce force1; AmoebaTorsionTorsionForce force1;
force1.setForceGroup(3);
for (unsigned int ii = 0; ii < 5; ii++) { for (unsigned int ii = 0; ii < 5; ii++) {
std::vector< std::vector< std::vector<double> > > gridVector; std::vector< std::vector< std::vector<double> > > gridVector;
loadTorsionTorsionGrid(gridVector); loadTorsionTorsionGrid(gridVector);
...@@ -99,6 +100,7 @@ void testSerialization() { ...@@ -99,6 +100,7 @@ void testSerialization() {
// Compare the two force1s to see if they are identical. // Compare the two force1s to see if they are identical.
AmoebaTorsionTorsionForce & force2 = *copy; AmoebaTorsionTorsionForce & force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getNumTorsionTorsions(), force2.getNumTorsionTorsions()); ASSERT_EQUAL(force1.getNumTorsionTorsions(), force2.getNumTorsionTorsions());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumTorsionTorsions()); ii++) { for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumTorsionTorsions()); ii++) {
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -45,6 +45,7 @@ void testSerialization() { ...@@ -45,6 +45,7 @@ void testSerialization() {
// Create a Force. // Create a Force.
AmoebaVdwForce force1; AmoebaVdwForce force1;
force1.setForceGroup(3);
force1.setSigmaCombiningRule("GEOMETRIC"); force1.setSigmaCombiningRule("GEOMETRIC");
force1.setEpsilonCombiningRule("GEOMETRIC"); force1.setEpsilonCombiningRule("GEOMETRIC");
force1.setCutoff(0.9); force1.setCutoff(0.9);
...@@ -70,6 +71,7 @@ void testSerialization() { ...@@ -70,6 +71,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaVdwForce& force2 = *copy; AmoebaVdwForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getSigmaCombiningRule(), force2.getSigmaCombiningRule()); ASSERT_EQUAL(force1.getSigmaCombiningRule(), force2.getSigmaCombiningRule());
ASSERT_EQUAL(force1.getEpsilonCombiningRule(), force2.getEpsilonCombiningRule()); ASSERT_EQUAL(force1.getEpsilonCombiningRule(), force2.getEpsilonCombiningRule());
ASSERT_EQUAL(force1.getCutoff(), force2.getCutoff()); ASSERT_EQUAL(force1.getCutoff(), force2.getCutoff());
......
...@@ -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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -45,6 +45,7 @@ void testSerialization() { ...@@ -45,6 +45,7 @@ void testSerialization() {
// Create a Force. // Create a Force.
AmoebaWcaDispersionForce force1; AmoebaWcaDispersionForce force1;
force1.setForceGroup(3);
force1.setEpso( 1.0); force1.setEpso( 1.0);
force1.setEpsh( 1.1); force1.setEpsh( 1.1);
force1.setRmino( 1.2); force1.setRmino( 1.2);
...@@ -68,6 +69,7 @@ void testSerialization() { ...@@ -68,6 +69,7 @@ void testSerialization() {
AmoebaWcaDispersionForce& force2 = *copy; AmoebaWcaDispersionForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getEpso(), force2.getEpso()); ASSERT_EQUAL(force1.getEpso(), force2.getEpso());
ASSERT_EQUAL(force1.getEpsh(), force2.getEpsh()); ASSERT_EQUAL(force1.getEpsh(), force2.getEpsh());
ASSERT_EQUAL(force1.getRmino(), force2.getRmino()); ASSERT_EQUAL(force1.getRmino(), force2.getRmino());
......
...@@ -64,7 +64,8 @@ void CustomCentroidBondForceProxy::serialize(const void* object, SerializationNo ...@@ -64,7 +64,8 @@ void CustomCentroidBondForceProxy::serialize(const void* object, SerializationNo
for (int j = 0; j < (int) particles.size(); j++) { for (int j = 0; j < (int) particles.size(); j++) {
SerializationNode& node = group.createChildNode("Particle"); SerializationNode& node = group.createChildNode("Particle");
node.setIntProperty("p", particles[j]); node.setIntProperty("p", particles[j]);
node.setDoubleProperty("weight", weights[j]); if (j < weights.size())
node.setDoubleProperty("weight", weights[j]);
} }
} }
SerializationNode& bonds = node.createChildNode("Bonds"); SerializationNode& bonds = node.createChildNode("Bonds");
...@@ -115,7 +116,8 @@ void* CustomCentroidBondForceProxy::deserialize(const SerializationNode& node) c ...@@ -115,7 +116,8 @@ void* CustomCentroidBondForceProxy::deserialize(const SerializationNode& node) c
vector<double> weights; vector<double> weights;
for (int j = 0; j < (int) group.getChildren().size(); j++) { for (int j = 0; j < (int) group.getChildren().size(); j++) {
particles.push_back(group.getChildren()[j].getIntProperty("p")); particles.push_back(group.getChildren()[j].getIntProperty("p"));
weights.push_back(group.getChildren()[j].getDoubleProperty("weight")); if (group.getChildren()[j].hasProperty("weight"))
weights.push_back(group.getChildren()[j].getDoubleProperty("weight"));
} }
force->addGroup(particles, weights); force->addGroup(particles, weights);
} }
......
...@@ -51,7 +51,8 @@ void testSerialization() { ...@@ -51,7 +51,8 @@ void testSerialization() {
vector<double> weights; vector<double> weights;
for (int j = 0; j < i+1; j++) { for (int j = 0; j < i+1; j++) {
particles.push_back(i+j); particles.push_back(i+j);
weights.push_back(1.0/(i+1)); if (i < 2)
weights.push_back(1.0/(i+1));
} }
force.addGroup(particles, weights); force.addGroup(particles, weights);
} }
......
...@@ -220,6 +220,7 @@ ...@@ -220,6 +220,7 @@
<Variant name="HID"/> <Variant name="HID"/>
<Variant name="HIE"/> <Variant name="HIE"/>
<Variant name="HIP"/> <Variant name="HIP"/>
<Variant name="HIN"/>
<H name="H" parent="N"/> <H name="H" parent="N"/>
<H name="H2" parent="N" terminal="N"/> <H name="H2" parent="N" terminal="N"/>
<H name="H3" parent="N" terminal="N"/> <H name="H3" parent="N" terminal="N"/>
......
...@@ -3760,6 +3760,8 @@ class AmoebaMultipoleGenerator: ...@@ -3760,6 +3760,8 @@ class AmoebaMultipoleGenerator:
polarizationType = args['polarization'] polarizationType = args['polarization']
if (polarizationType.lower() == 'direct'): if (polarizationType.lower() == 'direct'):
force.setPolarizationType(mm.AmoebaMultipoleForce.Direct) force.setPolarizationType(mm.AmoebaMultipoleForce.Direct)
elif (polarizationType.lower() == 'extrapolated'):
force.setPolarizationType(mm.AmoebaMultipoleForce.Extrapolated)
else: else:
force.setPolarizationType(mm.AmoebaMultipoleForce.Mutual) force.setPolarizationType(mm.AmoebaMultipoleForce.Mutual)
......
...@@ -123,7 +123,7 @@ class PdbStructure(object): ...@@ -123,7 +123,7 @@ class PdbStructure(object):
""" """
def __init__(self, input_stream, load_all_models=False): def __init__(self, input_stream, load_all_models=False, extraParticleIdentifier='EP'):
"""Create a PDB model from a PDB file stream. """Create a PDB model from a PDB file stream.
Parameters Parameters
...@@ -135,9 +135,12 @@ class PdbStructure(object): ...@@ -135,9 +135,12 @@ class PdbStructure(object):
load_all_models : bool load_all_models : bool
Whether to load every model of an NMR structure or trajectory, or Whether to load every model of an NMR structure or trajectory, or
just load the first model, to save memory. just load the first model, to save memory.
extraParticleIdentifier : string='EP'
if this value appears in the element column for an ATOM record, the Atom's element will be set to 'EP' to mark it as an extra particle
""" """
# initialize models # initialize models
self.load_all_models = load_all_models self.load_all_models = load_all_models
self.extraParticleIdentifier = extraParticleIdentifier
self.models = [] self.models = []
self._current_model = None self._current_model = None
self.default_model = None self.default_model = None
...@@ -157,7 +160,7 @@ class PdbStructure(object): ...@@ -157,7 +160,7 @@ class PdbStructure(object):
pdb_line = pdb_line.decode('utf-8') pdb_line = pdb_line.decode('utf-8')
# Look for atoms # Look for atoms
if (pdb_line.find("ATOM ") == 0) or (pdb_line.find("HETATM") == 0): if (pdb_line.find("ATOM ") == 0) or (pdb_line.find("HETATM") == 0):
self._add_atom(Atom(pdb_line, self)) self._add_atom(Atom(pdb_line, self, self.extraParticleIdentifier))
# Notice MODEL punctuation, for the next level of detail # Notice MODEL punctuation, for the next level of detail
# in the structure->model->chain->residue->atom->position hierarchy # in the structure->model->chain->residue->atom->position hierarchy
elif (pdb_line.find("MODEL") == 0): elif (pdb_line.find("MODEL") == 0):
...@@ -682,7 +685,7 @@ class Residue(object): ...@@ -682,7 +685,7 @@ class Residue(object):
class Atom(object): class Atom(object):
"""Atom represents one atom in a PDB structure. """Atom represents one atom in a PDB structure.
""" """
def __init__(self, pdb_line, pdbstructure=None): def __init__(self, pdb_line, pdbstructure=None, extraParticleIdentifier='EP'):
"""Create a new pdb.Atom from an ATOM or HETATM line. """Create a new pdb.Atom from an ATOM or HETATM line.
Example line: Example line:
...@@ -795,11 +798,14 @@ class Atom(object): ...@@ -795,11 +798,14 @@ class Atom(object):
try: self.formal_charge = int(pdb_line[78:80]) try: self.formal_charge = int(pdb_line[78:80])
except ValueError: self.formal_charge = None except ValueError: self.formal_charge = None
# figure out atom element # figure out atom element
try: if self.element_symbol == extraParticleIdentifier:
# Try to find a sensible element symbol from columns 76-77 self.element = 'EP'
self.element = element.get_by_symbol(self.element_symbol) else:
except KeyError: try:
self.element = None # Try to find a sensible element symbol from columns 76-77
self.element = element.get_by_symbol(self.element_symbol)
except KeyError:
self.element = None
if pdbstructure is not None: if pdbstructure is not None:
pdbstructure._next_atom_number = self.serial_number+1 pdbstructure._next_atom_number = self.serial_number+1
pdbstructure._next_residue_number = self.residue_number+1 pdbstructure._next_residue_number = self.residue_number+1
......
...@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of ...@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of
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) 2012-2015 Stanford University and the Authors. Portions copyright (c) 2012-2016 Stanford University and the Authors.
Authors: Peter Eastman Authors: Peter Eastman
Contributors: Contributors:
...@@ -614,6 +614,7 @@ class Modeller(object): ...@@ -614,6 +614,7 @@ class Modeller(object):
HID: Neutral form with a hydrogen on the ND1 atom HID: Neutral form with a hydrogen on the ND1 atom
HIE: Neutral form with a hydrogen on the NE2 atom HIE: Neutral form with a hydrogen on the NE2 atom
HIP: Positively charged form with hydrogens on both ND1 and NE2 HIP: Positively charged form with hydrogens on both ND1 and NE2
HIN: Negatively charged form without a hydrogen on either ND1 or NE2
Lysine: Lysine:
LYN: Neutral form with two hydrogens on the zeta nitrogen LYN: Neutral form with two hydrogens on the zeta nitrogen
...@@ -625,9 +626,14 @@ class Modeller(object): ...@@ -625,9 +626,14 @@ class Modeller(object):
2. Any Cysteine that participates in a disulfide bond uses the CYX variant regardless of pH. 2. Any Cysteine that participates in a disulfide bond uses the CYX variant regardless of pH.
3. For a neutral Histidine residue, the HID or HIE variant is selected based on which one forms a better hydrogen bond. 3. For a neutral Histidine residue, the HID or HIE variant is selected based on which one forms a better hydrogen bond.
You can override these rules by explicitly specifying a variant for any residue. Also keep in mind that this You can override these rules by explicitly specifying a variant for any residue. To do that, provide a list for the
function will only add hydrogens. It will never remove ones that are already present in the model, regardless 'variants' parameter, and set the corresponding element to the name of the variant to use.
of the specified pH.
A special case is when the model already contains a hydrogen that should not be present in the desired variant.
If you explicitly specify a variant using the 'variants' parameter, the residue will be modified to match the
desired variant, removing hydrogens if necessary. On the other hand, for residues whose variant is selected
automatically, this function will only add hydrogens. It will never remove ones that are already present in the
model, regardless of the specified pH.
Definitions for standard amino acids and nucleotides are built in. You can call loadHydrogenDefinitions() to load Definitions for standard amino acids and nucleotides are built in. You can call loadHydrogenDefinitions() to load
additional definitions for other residue types. additional definitions for other residue types.
...@@ -771,6 +777,7 @@ class Modeller(object): ...@@ -771,6 +777,7 @@ class Modeller(object):
if variant is not None and variant not in spec.variants: if variant is not None and variant not in spec.variants:
raise ValueError('Illegal variant for %s residue: %s' % (residue.name, variant)) raise ValueError('Illegal variant for %s residue: %s' % (residue.name, variant))
actualVariants[residue.index] = variant actualVariants[residue.index] = variant
removeExtraHydrogens = (variants[residue.index] is not None)
# Make a list of hydrogens that should be present in the residue. # Make a list of hydrogens that should be present in the residue.
...@@ -783,6 +790,11 @@ class Modeller(object): ...@@ -783,6 +790,11 @@ class Modeller(object):
# Loop over atoms in the residue, adding them to the new topology along with required hydrogens. # Loop over atoms in the residue, adding them to the new topology along with required hydrogens.
for parent in residue.atoms(): for parent in residue.atoms():
# Check whether this is a hydrogen that should be removed.
if removeExtraHydrogens and parent.element == elem.hydrogen and not any(parent.name == h.name for h in hydrogens):
continue
# Add the atom. # Add the atom.
newAtom = newTopology.addAtom(parent.name, parent.element, newResidue) newAtom = newTopology.addAtom(parent.name, parent.element, newResidue)
......
...@@ -59,7 +59,7 @@ class PDBFile(object): ...@@ -59,7 +59,7 @@ class PDBFile(object):
_residueNameReplacements = {} _residueNameReplacements = {}
_atomNameReplacements = {} _atomNameReplacements = {}
def __init__(self, file): def __init__(self, file, extraParticleIdentifier='EP'):
"""Load a PDB file. """Load a PDB file.
The atom positions and Topology can be retrieved by calling getPositions() and getTopology(). The atom positions and Topology can be retrieved by calling getPositions() and getTopology().
...@@ -68,6 +68,8 @@ class PDBFile(object): ...@@ -68,6 +68,8 @@ class PDBFile(object):
---------- ----------
file : string file : string
the name of the file to load the name of the file to load
extraParticleIdentifier : string='EP'
if this value appears in the element column for an ATOM record, the Atom's element will be set to None to mark it as an extra particle
""" """
metalElements = ['Al','As','Ba','Ca','Cd','Ce','Co','Cs','Cu','Dy','Fe','Gd','Hg','Ho','In','Ir','K','Li','Mg', metalElements = ['Al','As','Ba','Ca','Cd','Ce','Co','Cs','Cu','Dy','Fe','Gd','Hg','Ho','In','Ir','K','Li','Mg',
...@@ -91,7 +93,7 @@ class PDBFile(object): ...@@ -91,7 +93,7 @@ class PDBFile(object):
if isinstance(file, str): if isinstance(file, str):
inputfile = open(file) inputfile = open(file)
own_handle = True own_handle = True
pdb = PdbStructure(inputfile, load_all_models=True) pdb = PdbStructure(inputfile, load_all_models=True, extraParticleIdentifier=extraParticleIdentifier)
if own_handle: if own_handle:
inputfile.close() inputfile.close()
PDBFile._loadNameReplacementTables() PDBFile._loadNameReplacementTables()
...@@ -116,7 +118,9 @@ class PDBFile(object): ...@@ -116,7 +118,9 @@ class PDBFile(object):
atomName = atomReplacements[atomName] atomName = atomReplacements[atomName]
atomName = atomName.strip() atomName = atomName.strip()
element = atom.element element = atom.element
if element is None: if element == 'EP':
element = None
elif element is None:
# Try to guess the element. # Try to guess the element.
upper = atomName.upper() upper = atomName.upper()
...@@ -253,7 +257,7 @@ class PDBFile(object): ...@@ -253,7 +257,7 @@ class PDBFile(object):
map[atom.attrib[id]] = name map[atom.attrib[id]] = name
@staticmethod @staticmethod
def writeFile(topology, positions, file=sys.stdout, keepIds=False): def writeFile(topology, positions, file=sys.stdout, keepIds=False, extraParticleIdentifier=' '):
"""Write a PDB file containing a single model. """Write a PDB file containing a single model.
Parameters Parameters
...@@ -269,9 +273,11 @@ class PDBFile(object): ...@@ -269,9 +273,11 @@ class PDBFile(object):
rather than generating new ones. Warning: It is up to the caller to rather than generating new ones. Warning: It is up to the caller to
make sure these are valid IDs that satisfy the requirements of the make sure these are valid IDs that satisfy the requirements of the
PDB format. Otherwise, the output file will be invalid. PDB format. Otherwise, the output file will be invalid.
extraParticleIdentifier : string=' '
String to write in the element column of the ATOM records for atoms whose element is None (extra particles)
""" """
PDBFile.writeHeader(topology, file) PDBFile.writeHeader(topology, file)
PDBFile.writeModel(topology, positions, file, keepIds=keepIds) PDBFile.writeModel(topology, positions, file, keepIds=keepIds, extraParticleIdentifier=extraParticleIdentifier)
PDBFile.writeFooter(topology, file) PDBFile.writeFooter(topology, file)
@staticmethod @staticmethod
...@@ -294,7 +300,7 @@ class PDBFile(object): ...@@ -294,7 +300,7 @@ class PDBFile(object):
a*10, b*10, c*10, alpha*RAD_TO_DEG, beta*RAD_TO_DEG, gamma*RAD_TO_DEG), file=file) a*10, b*10, c*10, alpha*RAD_TO_DEG, beta*RAD_TO_DEG, gamma*RAD_TO_DEG), file=file)
@staticmethod @staticmethod
def writeModel(topology, positions, file=sys.stdout, modelIndex=None, keepIds=False): def writeModel(topology, positions, file=sys.stdout, modelIndex=None, keepIds=False, extraParticleIdentifier=' '):
"""Write out a model to a PDB file. """Write out a model to a PDB file.
Parameters Parameters
...@@ -313,6 +319,8 @@ class PDBFile(object): ...@@ -313,6 +319,8 @@ class PDBFile(object):
rather than generating new ones. Warning: It is up to the caller to rather than generating new ones. Warning: It is up to the caller to
make sure these are valid IDs that satisfy the requirements of the make sure these are valid IDs that satisfy the requirements of the
PDB format. Otherwise, the output file will be invalid. PDB format. Otherwise, the output file will be invalid.
extraParticleIdentifier : string=' '
String to write in the element column of the ATOM records for atoms whose element is None (extra particles)
""" """
if len(list(topology.atoms())) != len(positions): if len(list(topology.atoms())) != len(positions):
...@@ -343,17 +351,17 @@ class PDBFile(object): ...@@ -343,17 +351,17 @@ class PDBFile(object):
else: else:
resId = "%4d" % ((resIndex+1)%10000) resId = "%4d" % ((resIndex+1)%10000)
for atom in res.atoms(): for atom in res.atoms():
if len(atom.name) < 4 and atom.name[:1].isalpha() and (atom.element is None or len(atom.element.symbol) < 2): if atom.element is not None:
symbol = atom.element.symbol
else:
symbol = extraParticleIdentifier
if len(atom.name) < 4 and atom.name[:1].isalpha() and len(symbol) < 2:
atomName = ' '+atom.name atomName = ' '+atom.name
elif len(atom.name) > 4: elif len(atom.name) > 4:
atomName = atom.name[:4] atomName = atom.name[:4]
else: else:
atomName = atom.name atomName = atom.name
coords = positions[posIndex] coords = positions[posIndex]
if atom.element is not None:
symbol = atom.element.symbol
else:
symbol = ' '
line = "ATOM %5d %-4s %3s %s%4s %s%s%s 1.00 0.00 %2s " % ( line = "ATOM %5d %-4s %3s %s%4s %s%s%s 1.00 0.00 %2s " % (
atomIndex%100000, atomName, resName, chainName, resId, _format_83(coords[0]), atomIndex%100000, atomName, resName, chainName, resId, _format_83(coords[0]),
_format_83(coords[1]), _format_83(coords[2]), symbol) _format_83(coords[1]), _format_83(coords[2]), symbol)
......
...@@ -247,6 +247,7 @@ UNITS = { ...@@ -247,6 +247,7 @@ UNITS = {
("AmoebaMultipoleForce", "getPmeBSplineOrder") : ( None,()), ("AmoebaMultipoleForce", "getPmeBSplineOrder") : ( None,()),
("AmoebaMultipoleForce", "getMutualInducedMaxIterations") : ( None, ()), ("AmoebaMultipoleForce", "getMutualInducedMaxIterations") : ( None, ()),
("AmoebaMultipoleForce", "getMutualInducedTargetEpsilon") : ( None, ()), ("AmoebaMultipoleForce", "getMutualInducedTargetEpsilon") : ( None, ()),
("AmoebaMultipoleForce", "getExtrapolationCoefficients") : ( None, ()),
("AmoebaMultipoleForce", "getEwaldErrorTolerance") : ( None, ()), ("AmoebaMultipoleForce", "getEwaldErrorTolerance") : ( None, ()),
("AmoebaMultipoleForce", "getPmeGridDimensions") : ( None,()), ("AmoebaMultipoleForce", "getPmeGridDimensions") : ( None,()),
......
...@@ -903,6 +903,29 @@ class TestModeller(unittest.TestCase): ...@@ -903,6 +903,29 @@ class TestModeller(unittest.TestCase):
validate_equivalence(self, topology_LYN, topology_after) validate_equivalence(self, topology_LYN, topology_after)
def test_removeExtraHydrogens(self):
"""Test that addHydrogens() can remove hydrogens that shouldn't be there. """
topology_start = self.topology_start3
positions = self.positions3
modeller = Modeller(topology_start, positions)
# Add hydrogens, forcing residue 1 to be ASH.
variants = [None]*25
variants[1] = 'ASH'
modeller.addHydrogens(self.forcefield, variants=variants)
residue = list(modeller.topology.residues())[1]
self.assertTrue(any(a.name == 'HD2' for a in residue.atoms()))
# Now force it to be ASP and see if HD2 gets removed.
variants[1] = 'ASP'
modeller.addHydrogens(self.forcefield, variants=variants)
residue = list(modeller.topology.residues())[1]
self.assertFalse(any(a.name == 'HD2' for a in residue.atoms()))
def test_addExtraParticles(self): def test_addExtraParticles(self):
"""Test addExtraParticles().""" """Test addExtraParticles()."""
......
...@@ -70,6 +70,20 @@ class TestPdbFile(unittest.TestCase): ...@@ -70,6 +70,20 @@ class TestPdbFile(unittest.TestCase):
pdb = PDBFile(open('systems/triclinic.pdb', 'rb')) pdb = PDBFile(open('systems/triclinic.pdb', 'rb'))
self.assertEqual(len(pdb.positions), 8) self.assertEqual(len(pdb.positions), 8)
def test_ExtraParticles(self):
"""Test reading, and writing and re-reading of a file containing extra particle atoms."""
pdb = PDBFile('systems/tip5p.pdb')
for atom in pdb.topology.atoms():
if atom.index > 2:
self.assertEqual(None, atom.element)
output = StringIO()
PDBFile.writeFile(pdb.topology, pdb.positions, output)
input = StringIO(output.getvalue())
pdb = PDBFile(input, extraParticleIdentifier = '')
for atom in pdb.topology.atoms():
if atom.index > 2:
self.assertEqual(None, atom.element)
def assertVecAlmostEqual(self, p1, p2, tol=1e-7): def assertVecAlmostEqual(self, p1, p2, tol=1e-7):
unit = p1.unit unit = p1.unit
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment