Commit 51b7f9e2 authored by Robert McGibbon's avatar Robert McGibbon
Browse files

Merge master

parents 85bfd73c be0387b6
...@@ -82,14 +82,14 @@ public: ...@@ -82,14 +82,14 @@ public:
* Get the force field parameters for a stretch-bend term. * Get the force field parameters for a stretch-bend term.
* *
* @param index the index of the stretch-bend for which to get parameters * @param index the index of the stretch-bend for which to get parameters
* @param particle1 the index of the first particle connected by the stretch-bend * @param[out] particle1 the index of the first particle connected by the stretch-bend
* @param particle2 the index of the second particle connected by the stretch-bend * @param[out] particle2 the index of the second particle connected by the stretch-bend
* @param particle3 the index of the third particle connected by the stretch-bend * @param[out] particle3 the index of the third particle connected by the stretch-bend
* @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm * @param[out] lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm
* @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm * @param[out] lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm
* @param angle the equilibrium angle in radians * @param[out] angle the equilibrium angle in radians
* @param k1 the force constant of the product of bond ab and angle a-b-c * @param[out] k1 the force constant of the product of bond ab and angle a-b-c
* @param k2 the force constant of the product of bond bc and angle a-b-c * @param[out] k2 the force constant of the product of bond bc and angle a-b-c
*/ */
void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, double& lengthAB, void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, double& lengthAB,
double& lengthCB, double& angle, double& k1, double& k2) const; double& lengthCB, double& angle, double& k1, double& k2) const;
......
...@@ -90,13 +90,13 @@ public: ...@@ -90,13 +90,13 @@ public:
* Get the force field parameters for a torsion-torsion term. * Get the force field parameters for a torsion-torsion term.
* *
* @param index the index of the torsion-torsion for which to get parameters * @param index the index of the torsion-torsion for which to get parameters
* @param particle1 the index of the first particle connected by the torsion-torsion * @param[out] particle1 the index of the first particle connected by the torsion-torsion
* @param particle2 the index of the second particle connected by the torsion-torsion * @param[out] particle2 the index of the second particle connected by the torsion-torsion
* @param particle3 the index of the third particle connected by the torsion-torsion * @param[out] particle3 the index of the third particle connected by the torsion-torsion
* @param particle4 the index of the fourth particle connected by the torsion-torsion * @param[out] particle4 the index of the fourth particle connected by the torsion-torsion
* @param particle5 the index of the fifth particle connected by the torsion-torsion * @param[out] particle5 the index of the fifth particle connected by the torsion-torsion
* @param chiralCheckAtomIndex the index of the particle connected to particle3, but not particle2 or particle4 to be used in chirality check * @param[out] chiralCheckAtomIndex the index of the particle connected to particle3, but not particle2 or particle4 to be used in chirality check
* @param gridIndex the grid index * @param[out] gridIndex the grid index
*/ */
void getTorsionTorsionParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, int& particle5, int& chiralCheckAtomIndex, int& gridIndex) const; void getTorsionTorsionParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, int& particle5, int& chiralCheckAtomIndex, int& gridIndex) const;
...@@ -117,7 +117,7 @@ public: ...@@ -117,7 +117,7 @@ public:
/** /**
* Get the torsion-torsion grid at the specified index * Get the torsion-torsion grid at the specified index
* *
* @param gridIndex the grid index * @param index the grid index
* @return grid return grid reference * @return grid return grid reference
*/ */
const std::vector<std::vector<std::vector<double> > >& getTorsionTorsionGrid(int index) const; const std::vector<std::vector<std::vector<double> > >& getTorsionTorsionGrid(int index) const;
...@@ -172,7 +172,7 @@ public: ...@@ -172,7 +172,7 @@ public:
} }
TorsionTorsionInfo(int particle1, int particle2, int particle3, int particle4, int particle5, int chiralCheckAtomIndex, int gridIndex) : TorsionTorsionInfo(int particle1, int particle2, int particle3, int particle4, int particle5, int chiralCheckAtomIndex, int gridIndex) :
particle1(particle1), particle2(particle2), particle3(particle3), particle1(particle1), particle2(particle2), particle3(particle3),
particle4(particle4), particle5(particle5), gridIndex(gridIndex), chiralCheckAtomIndex(chiralCheckAtomIndex) { particle4(particle4), particle5(particle5), chiralCheckAtomIndex(chiralCheckAtomIndex), gridIndex(gridIndex) {
} }
}; };
......
...@@ -98,10 +98,10 @@ public: ...@@ -98,10 +98,10 @@ public:
* Get the force field parameters for a vdw particle. * Get the force field parameters for a vdw particle.
* *
* @param particleIndex the particle index * @param particleIndex the particle index
* @param parentIndex the index of the parent particle * @param[out] parentIndex the index of the parent particle
* @param sigma vdw sigma * @param[out] sigma vdw sigma
* @param epsilon vdw epsilon * @param[out] epsilon vdw epsilon
* @param reductionFactor the fraction of the distance along the line from the parent particle to this particle * @param[out] reductionFactor the fraction of the distance along the line from the parent particle to this particle
* at which the interaction site should be placed * at which the interaction site should be placed
*/ */
void getParticleParameters(int particleIndex, int& parentIndex, double& sigma, double& epsilon, double& reductionFactor) const; void getParticleParameters(int particleIndex, int& parentIndex, double& sigma, double& epsilon, double& reductionFactor) const;
...@@ -179,7 +179,7 @@ public: ...@@ -179,7 +179,7 @@ public:
* Get exclusions for specified particle * Get exclusions for specified particle
* *
* @param particleIndex particle index * @param particleIndex particle index
* @param exclusions vector of exclusions * @param[out] exclusions vector of exclusions
*/ */
void getParticleExclusions(int particleIndex, std::vector<int>& exclusions) const; void getParticleExclusions(int particleIndex, std::vector<int>& exclusions) const;
...@@ -253,7 +253,7 @@ public: ...@@ -253,7 +253,7 @@ public:
epsilon = 0.0; epsilon = 0.0;
} }
VdwInfo(int parentIndex, double sigma, double epsilon, double reductionFactor) : VdwInfo(int parentIndex, double sigma, double epsilon, double reductionFactor) :
parentIndex(parentIndex), sigma(sigma), epsilon(epsilon), reductionFactor(reductionFactor) { parentIndex(parentIndex), reductionFactor(reductionFactor), sigma(sigma), epsilon(epsilon) {
} }
}; };
......
...@@ -76,8 +76,8 @@ public: ...@@ -76,8 +76,8 @@ public:
* Get the force field parameters for a WCA dispersion particle. * Get the force field parameters for a WCA dispersion particle.
* *
* @param particleIndex the particle index * @param particleIndex the particle index
* @param radius radius * @param[out] radius radius
* @param epsilon epsilon * @param[out] epsilon epsilon
*/ */
void getParticleParameters(int particleIndex, double& radius, double& epsilon) const; void getParticleParameters(int particleIndex, double& radius, double& epsilon) const;
......
...@@ -92,18 +92,18 @@ public: ...@@ -92,18 +92,18 @@ public:
* Get the parameters for a Drude particle. * Get the parameters for a Drude particle.
* *
* @param index the index of the Drude particle for which to get parameters * @param index the index of the Drude particle for which to get parameters
* @param particle the index within the System of the Drude particle * @param[out] particle the index within the System of the Drude particle
* @param particle1 the index within the System of the particle to which the Drude particle is attached * @param[out] particle1 the index within the System of the particle to which the Drude particle is attached
* @param particle2 the index within the System of the second particle used for defining anisotropic polarizability. * @param[out] particle2 the index within the System of the second particle used for defining anisotropic polarizability.
* This may be set to -1, in which case aniso12 will be ignored. * This may be set to -1, in which case aniso12 will be ignored.
* @param particle3 the index within the System of the third particle used for defining anisotropic polarizability. * @param[out] particle3 the index within the System of the third particle used for defining anisotropic polarizability.
* This may be set to -1, in which case aniso34 will be ignored. * This may be set to -1, in which case aniso34 will be ignored.
* @param particle4 the index within the System of the fourth particle used for defining anisotropic polarizability. * @param[out] particle4 the index within the System of the fourth particle used for defining anisotropic polarizability.
* This may be set to -1, in which case aniso34 will be ignored. * This may be set to -1, in which case aniso34 will be ignored.
* @param charge The charge on the Drude particle * @param[out] charge The charge on the Drude particle
* @param polarizability The isotropic polarizability * @param[out] polarizability The isotropic polarizability
* @param aniso12 The scale factor for the polarizability along the direction defined by particle1 and particle2 * @param[out] aniso12 The scale factor for the polarizability along the direction defined by particle1 and particle2
* @param aniso34 The scale factor for the polarizability along the direction defined by particle3 and particle4 * @param[out] aniso34 The scale factor for the polarizability along the direction defined by particle3 and particle4
*/ */
void getParticleParameters(int index, int& particle, int& particle1, int& particle2, int& particle3, int& particle4, double& charge, double& polarizability, double& aniso12, double& aniso34) const; void getParticleParameters(int index, int& particle, int& particle1, int& particle2, int& particle3, int& particle4, double& charge, double& polarizability, double& aniso12, double& aniso34) const;
/** /**
...@@ -137,9 +137,9 @@ public: ...@@ -137,9 +137,9 @@ public:
* Get the force field parameters for screened pair. * Get the force field parameters for screened pair.
* *
* @param index the index of the pair for which to get parameters * @param index the index of the pair for which to get parameters
* @param particle1 the index within this Force of the first particle involved in the interaction * @param[out] particle1 the index within this Force of the first particle involved in the interaction
* @param particle2 the index within this Force of the second particle involved in the interaction * @param[out] particle2 the index within this Force of the second particle involved in the interaction
* @param thole the Thole screening factor * @param[out] thole the Thole screening factor
*/ */
void getScreenedPairParameters(int index, int& particle1, int& particle2, double& thole) const; void getScreenedPairParameters(int index, int& particle1, int& particle2, double& thole) const;
/** /**
......
...@@ -128,21 +128,15 @@ State RPMDIntegrator::getState(int copy, int types, bool enforcePeriodicBox, int ...@@ -128,21 +128,15 @@ State RPMDIntegrator::getState(int copy, int types, bool enforcePeriodicBox, int
center *= 1.0/molecules[i].size(); center *= 1.0/molecules[i].size();
// Find the displacement to move it into the first periodic box. // Find the displacement to move it into the first periodic box.
Vec3 diff;
int xcell = (int) floor(center[0]/periodicBoxSize[0][0]); diff -= periodicBoxSize[0]*static_cast<int>(center[0]/periodicBoxSize[0][0]);
int ycell = (int) floor(center[1]/periodicBoxSize[1][1]); diff -= periodicBoxSize[1]*static_cast<int>(center[1]/periodicBoxSize[1][1]);
int zcell = (int) floor(center[2]/periodicBoxSize[2][2]); diff -= periodicBoxSize[2]*static_cast<int>(center[2]/periodicBoxSize[2][2]);
double dx = xcell*periodicBoxSize[0][0];
double dy = ycell*periodicBoxSize[1][1];
double dz = zcell*periodicBoxSize[2][2];
// Translate all the particles in the molecule. // Translate all the particles in the molecule.
for (int j = 0; j < (int) molecules[i].size(); j++) { for (int j = 0; j < (int) molecules[i].size(); j++) {
Vec3& pos = positions[molecules[i][j]]; Vec3& pos = positions[molecules[i][j]];
pos[0] -= dx; pos -= diff;
pos[1] -= dy;
pos[2] -= dz;
} }
} }
......
#ifndef OPENMM_COMPOUND_INTEGRATOR_PROXY_H_
#define OPENMM_COMPOUND_INTEGRATOR_PROXY_H_
#include "openmm/serialization/XmlSerializer.h"
namespace OpenMM {
class CompoundIntegratorProxy : public SerializationProxy {
public:
CompoundIntegratorProxy();
void serialize(const void* object, SerializationNode& node) const;
void* deserialize(const SerializationNode& node) const;
};
}
#endif /*OPENMM_COMPOUND_INTEGRATOR_PROXY_H_*/
\ No newline at end of file
...@@ -105,7 +105,7 @@ public: ...@@ -105,7 +105,7 @@ public:
/** /**
* Determine whether this node has a property with a particular node. * Determine whether this node has a property with a particular node.
* *
* @param the name of the property to check for * @param name the name of the property to check for
*/ */
bool hasProperty(const std::string& name) const; bool hasProperty(const std::string& name) const;
/** /**
......
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2015 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/serialization/CompoundIntegratorProxy.h"
#include <OpenMM.h>
using namespace std;
using namespace OpenMM;
CompoundIntegratorProxy::CompoundIntegratorProxy() : SerializationProxy("CompoundIntegrator") {
}
void CompoundIntegratorProxy::serialize(const void* object, SerializationNode& node) const {
node.setIntProperty("version", 1);
const CompoundIntegrator& integrator = *reinterpret_cast<const CompoundIntegrator*>(object);
node.setIntProperty("currentIntegrator", integrator.getCurrentIntegrator());
for (int i = 0; i < integrator.getNumIntegrators(); i++)
node.createChildNode("Integrator", &integrator.getIntegrator(i));
}
void* CompoundIntegratorProxy::deserialize(const SerializationNode& node) const {
if (node.getIntProperty("version") != 1)
throw OpenMMException("Unsupported version number");
CompoundIntegrator *integrator = new CompoundIntegrator();
for (int i = 0; i < node.getChildren().size(); i++)
integrator->addIntegrator(node.getChildren()[i].decodeObject<Integrator>());
integrator->setCurrentIntegrator(node.getIntProperty("currentIntegrator"));
return integrator;
}
\ No newline at end of file
...@@ -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-2014 Stanford University and the Authors. * * Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "openmm/BrownianIntegrator.h" #include "openmm/BrownianIntegrator.h"
#include "openmm/CMAPTorsionForce.h" #include "openmm/CMAPTorsionForce.h"
#include "openmm/CMMotionRemover.h" #include "openmm/CMMotionRemover.h"
#include "openmm/CompoundIntegrator.h"
#include "openmm/CustomAngleForce.h" #include "openmm/CustomAngleForce.h"
#include "openmm/CustomBondForce.h" #include "openmm/CustomBondForce.h"
#include "openmm/CustomCompoundBondForce.h" #include "openmm/CustomCompoundBondForce.h"
...@@ -65,6 +66,7 @@ ...@@ -65,6 +66,7 @@
#include "openmm/serialization/AndersenThermostatProxy.h" #include "openmm/serialization/AndersenThermostatProxy.h"
#include "openmm/serialization/CMAPTorsionForceProxy.h" #include "openmm/serialization/CMAPTorsionForceProxy.h"
#include "openmm/serialization/CMMotionRemoverProxy.h" #include "openmm/serialization/CMMotionRemoverProxy.h"
#include "openmm/serialization/CompoundIntegratorProxy.h"
#include "openmm/serialization/CustomAngleForceProxy.h" #include "openmm/serialization/CustomAngleForceProxy.h"
#include "openmm/serialization/CustomBondForceProxy.h" #include "openmm/serialization/CustomBondForceProxy.h"
#include "openmm/serialization/CustomCompoundBondForceProxy.h" #include "openmm/serialization/CustomCompoundBondForceProxy.h"
...@@ -112,6 +114,7 @@ extern "C" void registerSerializationProxies() { ...@@ -112,6 +114,7 @@ extern "C" void registerSerializationProxies() {
SerializationProxy::registerProxy(typeid(BrownianIntegrator), new BrownianIntegratorProxy()); SerializationProxy::registerProxy(typeid(BrownianIntegrator), new BrownianIntegratorProxy());
SerializationProxy::registerProxy(typeid(CMAPTorsionForce), new CMAPTorsionForceProxy()); SerializationProxy::registerProxy(typeid(CMAPTorsionForce), new CMAPTorsionForceProxy());
SerializationProxy::registerProxy(typeid(CMMotionRemover), new CMMotionRemoverProxy()); SerializationProxy::registerProxy(typeid(CMMotionRemover), new CMMotionRemoverProxy());
SerializationProxy::registerProxy(typeid(CompoundIntegrator), new CompoundIntegratorProxy());
SerializationProxy::registerProxy(typeid(Continuous1DFunction), new Continuous1DFunctionProxy()); SerializationProxy::registerProxy(typeid(Continuous1DFunction), new Continuous1DFunctionProxy());
SerializationProxy::registerProxy(typeid(Continuous2DFunction), new Continuous2DFunctionProxy()); SerializationProxy::registerProxy(typeid(Continuous2DFunction), new Continuous2DFunctionProxy());
SerializationProxy::registerProxy(typeid(Continuous3DFunction), new Continuous3DFunctionProxy()); SerializationProxy::registerProxy(typeid(Continuous3DFunction), new Continuous3DFunctionProxy());
......
...@@ -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-2015 Stanford University and the Authors. *
* Authors: Peter Eastman, Yutong Zhao * * Authors: Peter Eastman, Yutong Zhao *
* Contributors: * * Contributors: *
* * * *
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/BrownianIntegrator.h" #include "openmm/BrownianIntegrator.h"
#include "openmm/CompoundIntegrator.h"
#include "openmm/CustomIntegrator.h" #include "openmm/CustomIntegrator.h"
#include "openmm/LangevinIntegrator.h" #include "openmm/LangevinIntegrator.h"
#include "openmm/VariableLangevinIntegrator.h" #include "openmm/VariableLangevinIntegrator.h"
...@@ -185,6 +186,29 @@ void testSerializeCustomIntegrator() { ...@@ -185,6 +186,29 @@ void testSerializeCustomIntegrator() {
delete intg2; delete intg2;
} }
void testSerializeCompoundIntegrator() {
CompoundIntegrator integ;
integ.addIntegrator(new LangevinIntegrator(372.4, 1.234, 0.0018));
integ.addIntegrator(new VerletIntegrator(0.002));
integ.setCurrentIntegrator(1);
stringstream ss;
XmlSerializer::serialize<Integrator>(&integ, "CompoundIntegrator", ss);
CompoundIntegrator *integ2 = dynamic_cast<CompoundIntegrator*>(XmlSerializer::deserialize<Integrator>(ss));
ASSERT_EQUAL(integ.getCurrentIntegrator(), integ2->getCurrentIntegrator());
LangevinIntegrator& langevin1 = dynamic_cast<LangevinIntegrator&>(integ.getIntegrator(0));
LangevinIntegrator& langevin2 = dynamic_cast<LangevinIntegrator&>(integ2->getIntegrator(0));
ASSERT_EQUAL(langevin1.getConstraintTolerance(), langevin2.getConstraintTolerance());
ASSERT_EQUAL(langevin1.getStepSize(), langevin2.getStepSize());
ASSERT_EQUAL(langevin1.getTemperature(), langevin2.getTemperature());
ASSERT_EQUAL(langevin1.getFriction(), langevin2.getFriction());
ASSERT_EQUAL(langevin1.getRandomNumberSeed(), langevin2.getRandomNumberSeed());
VerletIntegrator& verlet1 = dynamic_cast<VerletIntegrator&>(integ.getIntegrator(1));
VerletIntegrator& verlet2 = dynamic_cast<VerletIntegrator&>(integ2->getIntegrator(1));
ASSERT_EQUAL(verlet1.getConstraintTolerance(), verlet2.getConstraintTolerance());
ASSERT_EQUAL(verlet1.getStepSize(), verlet2.getStepSize());
delete integ2;
}
int main() { int main() {
try { try {
testSerializeBrownianIntegrator(); testSerializeBrownianIntegrator();
...@@ -193,6 +217,7 @@ int main() { ...@@ -193,6 +217,7 @@ int main() {
testSerializeVariableLangevinIntegrator(); testSerializeVariableLangevinIntegrator();
testSerializeVariableVerletIntegrator(); testSerializeVariableVerletIntegrator();
testSerializeLangevinIntegrator(); testSerializeLangevinIntegrator();
testSerializeCompoundIntegrator();
} }
catch(const exception& e) { catch(const exception& e) {
return 1; return 1;
......
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2015 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/BrownianIntegrator.h"
#include "openmm/CompoundIntegrator.h"
#include "openmm/Context.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/LangevinIntegrator.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "SimTKOpenMMRealType.h"
#include <iostream>
#include <vector>
using namespace OpenMM;
using namespace std;
const double TOL = 1e-5;
void testChangingIntegrator() {
System system;
system.addParticle(2.0);
system.addParticle(2.0);
HarmonicBondForce* bonds = new HarmonicBondForce();
bonds->addBond(0, 1, 1.5, 1);
system.addForce(bonds);
CompoundIntegrator integrator;
integrator.addIntegrator(new VerletIntegrator(0.01));
integrator.addIntegrator(new LangevinIntegrator(300.0, 10.0, 0.011));
integrator.addIntegrator(new BrownianIntegrator(300.0, 10.0, 0.012));
Context context(system, integrator, platform);
ASSERT_EQUAL(0, integrator.getCurrentIntegrator());
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
for (int iteration = 0; iteration < 2; ++iteration) {
context.setPositions(positions);
// First integrate with the Verlet integrator and compare it to the analytical solution.
const double freq = 1.0;
State state = context.getState(State::Energy);
const double initialEnergy = state.getKineticEnergy()+state.getPotentialEnergy();
for (int i = 0; i < 100; ++i) {
state = context.getState(State::Positions | State::Velocities | State::Energy);
double time = state.getTime();
double expectedDist = 1.5+0.5*std::cos(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedDist, 0, 0), state.getPositions()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedDist, 0, 0), state.getPositions()[1], 0.02);
double expectedSpeed = -0.5*freq*std::sin(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedSpeed, 0, 0), state.getVelocities()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedSpeed, 0, 0), state.getVelocities()[1], 0.02);
double energy = state.getKineticEnergy()+state.getPotentialEnergy();
ASSERT_EQUAL_TOL(initialEnergy, energy, 0.01);
integrator.step(1);
}
ASSERT_EQUAL_TOL(100*0.01, context.getState(0).getTime(), 1e-5);
// Switch to the Langevin integrator and make sure that it heats up.
integrator.setCurrentIntegrator(1);
integrator.step(100);
double ke = 0.0;
for (int i = 0; i < 1000; ++i) {
integrator.step(10);
state = context.getState(State::Energy);
ke += state.getKineticEnergy();
}
double expectedKE = 0.5*2*3*BOLTZ*300.0;
ASSERT_USUALLY_EQUAL_TOL(expectedKE, ke/1000, 0.1);
ASSERT_EQUAL_TOL(100*0.01+10100*0.011, context.getState(0).getTime(), 1e-5);
// Now reinitialize the context and repeat all of these tests to make sure that works correctly.
context.reinitialize();
integrator.setCurrentIntegrator(0);
}
}
void testChangingParameters() {
System system;
system.addParticle(1.0);
CompoundIntegrator integrator;
integrator.addIntegrator(new VerletIntegrator(0.01));
integrator.addIntegrator(new LangevinIntegrator(300.0, 10.0, 0.02));
integrator.addIntegrator(new BrownianIntegrator(300.0, 10.0, 0.03));
// Try getting and setting the step size for different component integrators.
for (int i = 0; i < 3; i++) {
integrator.setCurrentIntegrator(i);
ASSERT_EQUAL_TOL(0.01*(i+1), integrator.getStepSize(), 1e-7);
}
for (int i = 0; i < 3; i++) {
integrator.setCurrentIntegrator(i);
integrator.setStepSize(0.02*(i+1));
ASSERT_EQUAL_TOL(0.02*(i+1), integrator.getStepSize(), 1e-7);
}
for (int i = 0; i < 3; i++) {
integrator.setCurrentIntegrator(i);
ASSERT_EQUAL_TOL(0.02*(i+1), integrator.getStepSize(), 1e-7);
}
// Try getting and setting the constraint tolerance for different component integrators.
for (int i = 0; i < 3; i++) {
integrator.setCurrentIntegrator(i);
ASSERT_EQUAL_TOL(1e-5, integrator.getConstraintTolerance(), 1e-7);
}
for (int i = 0; i < 3; i++) {
integrator.setCurrentIntegrator(i);
integrator.setConstraintTolerance(1e-4*(i+1));
ASSERT_EQUAL_TOL(1e-4*(i+1), integrator.getConstraintTolerance(), 1e-7);
}
for (int i = 0; i < 3; i++) {
integrator.setCurrentIntegrator(i);
ASSERT_EQUAL_TOL(1e-4*(i+1), integrator.getConstraintTolerance(), 1e-7);
}
}
void testDifferentStepSizes() {
System system;
system.addParticle(2.0);
system.addParticle(2.0);
HarmonicBondForce* bonds = new HarmonicBondForce();
bonds->addBond(0, 1, 1.5, 1);
system.addForce(bonds);
CompoundIntegrator integrator;
integrator.addIntegrator(new VerletIntegrator(0.005));
integrator.addIntegrator(new VerletIntegrator(0.01));
Context context(system, integrator, platform);
ASSERT_EQUAL(0, integrator.getCurrentIntegrator());
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
context.setPositions(positions);
// Integrate with the first Verlet integrator and compare it to the analytical solution.
const double freq = 1.0;
double expectedTime = 0;
for (int i = 0; i < 100; ++i) {
State state = context.getState(State::Positions);
double time = state.getTime();
ASSERT_EQUAL_TOL(expectedTime, time, 1e-5);
double expectedDist = 1.5+0.5*std::cos(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedDist, 0, 0), state.getPositions()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedDist, 0, 0), state.getPositions()[1], 0.02);
integrator.step(1);
expectedTime += 0.005;
}
// Now switch to the second Verlet integrator which has a different step size.
integrator.setCurrentIntegrator(1);
for (int i = 0; i < 100; ++i) {
State state = context.getState(State::Positions);
double time = state.getTime();
ASSERT_EQUAL_TOL(expectedTime, time, 1e-5);
double expectedDist = 1.5+0.5*std::cos(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedDist, 0, 0), state.getPositions()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedDist, 0, 0), state.getPositions()[1], 0.02);
integrator.step(1);
expectedTime += 0.01;
}
// Finally, switch back to the first one again.
integrator.setCurrentIntegrator(0);
for (int i = 0; i < 100; ++i) {
State state = context.getState(State::Positions);
double time = state.getTime();
ASSERT_EQUAL_TOL(expectedTime, time, 1e-5);
double expectedDist = 1.5+0.5*std::cos(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedDist, 0, 0), state.getPositions()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedDist, 0, 0), state.getPositions()[1], 0.02);
integrator.step(1);
expectedTime += 0.005;
}
}
void runPlatformTests();
int main(int argc, char* argv[]) {
try {
initializeTests(argc, argv);
testChangingIntegrator();
testChangingParameters();
testDifferentStepSizes();
runPlatformTests();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Robert McGibbon *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/VerletIntegrator.h"
#include "sfmt/SFMT.h"
#include <iostream>
using namespace OpenMM;
using namespace std;
void testTruncatedOctahedron() {
const int numMolecules = 5;
const int numParticles = numMolecules*2;
const float cutoff = 2.0;
Vec3 a(6.7929, 0, 0);
Vec3 b(-2.264163559406279, 6.404455775962287, 0);
Vec3 c(-2.264163559406279, -3.2019384603140684, 5.54658849047036);
System system;
system.setDefaultPeriodicBoxVectors(a, b, c);
NonbondedForce* force = new NonbondedForce();
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
vector<Vec3> positions(numParticles);
force->setCutoffDistance(cutoff);
force->setNonbondedMethod(NonbondedForce::CutoffPeriodic);
for (int i = 0; i < numMolecules; i++) {
system.addParticle(1.0);
system.addParticle(1.0);
force->addParticle(-1, 0.2, 0.2);
force->addParticle(1, 0.2, 0.2);
positions[2*i] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt);
positions[2*i+1] = positions[2*i] + Vec3(1.0, 0.0, 0.0);
system.addConstraint(2*i, 2*i+1, 1.0);
}
system.addForce(force);
VerletIntegrator integrator(0.01);
Context context(system, integrator, Platform::getPlatformByName("Reference"));
context.setPositions(positions);
State initialState = context.getState(State::Positions | State::Energy, true);
double initialEnergy = initialState.getPotentialEnergy();
context.setState(initialState);
State finalState = context.getState(State::Positions | State::Energy, true);
double finalEnergy = finalState.getPotentialEnergy();
ASSERT_EQUAL_TOL(initialEnergy, finalEnergy, 1e-4);
}
int main(int argc, char* argv[]) {
try {
testTruncatedOctahedron();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
...@@ -49,10 +49,14 @@ class AMDIntegrator(CustomIntegrator): ...@@ -49,10 +49,14 @@ class AMDIntegrator(CustomIntegrator):
def __init__(self, dt, alpha, E): def __init__(self, dt, alpha, E):
"""Create an AMDIntegrator. """Create an AMDIntegrator.
Parameters: Parameters
- dt (time) The integration time step to use ----------
- alpha (energy) The alpha parameter to use dt : time
- E (energy) The energy cutoff to use The integration time step to use
alpha : energy
The alpha parameter to use
E : energy
The energy cutoff to use
""" """
CustomIntegrator.__init__(self, dt) CustomIntegrator.__init__(self, dt)
self.addGlobalVariable("alpha", alpha) self.addGlobalVariable("alpha", alpha)
...@@ -104,11 +108,16 @@ class AMDForceGroupIntegrator(CustomIntegrator): ...@@ -104,11 +108,16 @@ class AMDForceGroupIntegrator(CustomIntegrator):
def __init__(self, dt, group, alphaGroup, EGroup): def __init__(self, dt, group, alphaGroup, EGroup):
"""Create a AMDForceGroupIntegrator. """Create a AMDForceGroupIntegrator.
Parameters: Parameters
- dt (time) The integration time step to use ----------
- group (int) The force group to apply the boost to dt : time
- alphaGroup (energy) The alpha parameter to use for the boosted force group The integration time step to use
- EGroup (energy) The energy cutoff to use for the boosted force group group : int
The force group to apply the boost to
alphaGroup : energy
The alpha parameter to use for the boosted force group
EGroup : energy
The energy cutoff to use for the boosted force group
""" """
CustomIntegrator.__init__(self, dt) CustomIntegrator.__init__(self, dt)
self.addGlobalVariable("alphaGroup", alphaGroup) self.addGlobalVariable("alphaGroup", alphaGroup)
...@@ -144,9 +153,15 @@ class AMDForceGroupIntegrator(CustomIntegrator): ...@@ -144,9 +153,15 @@ class AMDForceGroupIntegrator(CustomIntegrator):
def getEffectiveEnergy(self, groupEnergy): def getEffectiveEnergy(self, groupEnergy):
"""Given the actual group energy of the system, return the value of the effective potential. """Given the actual group energy of the system, return the value of the effective potential.
Parameters: Parameters
- groupEnergy (energy): the actual potential energy of the boosted force group ----------
Returns: the value of the effective potential groupEnergy : energy
the actual potential energy of the boosted force group
Returns
-------
energy
the value of the effective potential
""" """
alphaGroup = self.getAlphaGroup() alphaGroup = self.getAlphaGroup()
EGroup = self.getEGroup() EGroup = self.getEGroup()
...@@ -172,13 +187,20 @@ class DualAMDIntegrator(CustomIntegrator): ...@@ -172,13 +187,20 @@ class DualAMDIntegrator(CustomIntegrator):
def __init__(self, dt, group, alphaTotal, ETotal, alphaGroup, EGroup): def __init__(self, dt, group, alphaTotal, ETotal, alphaGroup, EGroup):
"""Create a DualAMDIntegrator. """Create a DualAMDIntegrator.
Parameters: Parameters
- dt (time) The integration time step to use ----------
- group (int) The force group to apply the second boost to dt : time
- alphaTotal (energy) The alpha parameter to use for the total energy The integration time step to use
- ETotal (energy) The energy cutoff to use for the total energy group : int
- alphaGroup (energy) The alpha parameter to use for the boosted force group The force group to apply the second boost to
- EGroup (energy) The energy cutoff to use for the boosted force group alphaTotal : energy
The alpha parameter to use for the total energy
ETotal : energy
The energy cutoff to use for the total energy
alphaGroup : energy
The alpha parameter to use for the boosted force group
EGroup : energy
The energy cutoff to use for the boosted force group
""" """
CustomIntegrator.__init__(self, dt) CustomIntegrator.__init__(self, dt)
self.addGlobalVariable("alphaTotal", alphaTotal) self.addGlobalVariable("alphaTotal", alphaTotal)
...@@ -237,10 +259,17 @@ class DualAMDIntegrator(CustomIntegrator): ...@@ -237,10 +259,17 @@ class DualAMDIntegrator(CustomIntegrator):
def getEffectiveEnergy(self, totalEnergy, groupEnergy): def getEffectiveEnergy(self, totalEnergy, groupEnergy):
"""Given the actual potential energy of the system, return the value of the effective potential. """Given the actual potential energy of the system, return the value of the effective potential.
Parameters: Parameters
- totalEnergy (energy): the actual potential energy of the whole system ----------
- groupEnergy (energy): the actual potential energy of the boosted force group totalEnergy : energy
Returns: the value of the effective potential the actual potential energy of the whole system
groupEnergy : energy
the actual potential energy of the boosted force group
Returns
-------
energy
the value of the effective potential
""" """
alphaTotal = self.getAlphaTotal() alphaTotal = self.getAlphaTotal()
ETotal = self.getETotal() ETotal = self.getETotal()
......
...@@ -60,12 +60,17 @@ class AmberInpcrdFile(object): ...@@ -60,12 +60,17 @@ class AmberInpcrdFile(object):
def __init__(self, file, loadVelocities=None, loadBoxVectors=None): def __init__(self, file, loadVelocities=None, loadBoxVectors=None):
"""Load an inpcrd file. """Load an inpcrd file.
An inpcrd file contains atom positions and, optionally, velocities and periodic box dimensions. An inpcrd file contains atom positions and, optionally, velocities and
periodic box dimensions.
Parameters:
- file (string) the name of the file to load Parameters
- loadVelocities (boolean=None) deprecated. Velocities are loaded automatically if present ----------
- loadBoxVectors (boolean=None) deprecated. Box vectors are loaded automatically if present file : str
The name of the file to load
loadVelocities : bool
Deprecated. Velocities are loaded automatically if present
loadBoxVectors : bool
Deprecated. Box vectors are loaded automatically if present
""" """
self.file = file self.file = file
if loadVelocities is not None or loadBoxVectors is not None: if loadVelocities is not None or loadBoxVectors is not None:
...@@ -84,8 +89,11 @@ class AmberInpcrdFile(object): ...@@ -84,8 +89,11 @@ class AmberInpcrdFile(object):
def getPositions(self, asNumpy=False): def getPositions(self, asNumpy=False):
"""Get the atomic positions. """Get the atomic positions.
Parameters: Parameters
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s ----------
asNumpy : bool=False
if true, the values are returned as a numpy array instead of a list
of Vec3s
""" """
if asNumpy: if asNumpy:
if self._numpyPositions is None: if self._numpyPositions is None:
...@@ -97,8 +105,10 @@ class AmberInpcrdFile(object): ...@@ -97,8 +105,10 @@ class AmberInpcrdFile(object):
def getVelocities(self, asNumpy=False): def getVelocities(self, asNumpy=False):
"""Get the atomic velocities. """Get the atomic velocities.
Parameters: Parameters
- asNumpy (boolean=False) if true, the vectors are returned as numpy arrays instead of Vec3s ----------
asNumpy : bool=False
if true, the vectors are returned as numpy arrays instead of Vec3s
""" """
if self.velocities is None: if self.velocities is None:
raise AttributeError('velocities not found in %s' % self.file) raise AttributeError('velocities not found in %s' % self.file)
...@@ -112,8 +122,11 @@ class AmberInpcrdFile(object): ...@@ -112,8 +122,11 @@ class AmberInpcrdFile(object):
def getBoxVectors(self, asNumpy=False): def getBoxVectors(self, asNumpy=False):
"""Get the periodic box vectors. """Get the periodic box vectors.
Parameters: Parameters
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s ----------
asNumpy : bool=False
if true, the values are returned as a numpy array instead of a list
of Vec3s
""" """
if self.boxVectors is None: if self.boxVectors is None:
raise AttributeError('Box information not found in %s' % self.file) raise AttributeError('Box information not found in %s' % self.file)
......
...@@ -151,29 +151,52 @@ class AmberPrmtopFile(object): ...@@ -151,29 +151,52 @@ class AmberPrmtopFile(object):
implicitSolventKappa=None, temperature=298.15*unit.kelvin, implicitSolventKappa=None, temperature=298.15*unit.kelvin,
soluteDielectric=1.0, solventDielectric=78.5, soluteDielectric=1.0, solventDielectric=78.5,
removeCMMotion=True, hydrogenMass=None, ewaldErrorTolerance=0.0005): removeCMMotion=True, hydrogenMass=None, ewaldErrorTolerance=0.0005):
"""Construct an OpenMM System representing the topology described by this prmtop file. """Construct an OpenMM System representing the topology described by this
prmtop file.
Parameters: Parameters
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are ----------
nonbondedMethod : object=NoCutoff
The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME. NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
- nonbondedCutoff (distance=1*nanometer) The cutoff distance to use for nonbonded interactions nonbondedCutoff : distance=1*nanometer
- constraints (object=None) Specifies which bonds angles should be implemented with constraints. The cutoff distance to use for nonbonded interactions
constraints : object=None
Specifies which bonds angles should be implemented with constraints.
Allowed values are None, HBonds, AllBonds, or HAngles. Allowed values are None, HBonds, AllBonds, or HAngles.
- rigidWater (boolean=True) If true, water molecules will be fully rigid regardless of the value passed for the constraints argument rigidWater : boolean=True
- implicitSolvent (object=None) If not None, the implicit solvent model to use. Allowed values are HCT, OBC1, OBC2, GBn, or GBn2. If true, water molecules will be fully rigid regardless of the value
- implicitSolventSaltConc (float=0.0*unit.moles/unit.liter) The salt concentration for GB passed for the constraints argument
calculations (modelled as a debye screening parameter). It is converted to the debye length (kappa) implicitSolvent : object=None
If not None, the implicit solvent model to use. Allowed values are
HCT, OBC1, OBC2, GBn, or GBn2.
implicitSolventSaltConc : float=0.0*unit.moles/unit.liter
The salt concentration for GB calculations (modelled as a debye
screening parameter). It is converted to the debye length (kappa)
using the provided temperature and solventDielectric using the provided temperature and solventDielectric
- temperature (float=300*kelvin) Temperature of the system. Only used to compute the Debye length from temperature : float=300*kelvin
implicitSolventSoltConc Temperature of the system. Only used to compute the Debye length
- implicitSolventKappa (float units of 1/length) If this value is set, implicitSolventSaltConc will be ignored. from implicitSolventSoltConc
- soluteDielectric (float=1.0) The solute dielectric constant to use in the implicit solvent model. implicitSolventKappa : float units of 1/length
- solventDielectric (float=78.5) The solvent dielectric constant to use in the implicit solvent model. If this value is set, implicitSolventSaltConc will be ignored.
- removeCMMotion (boolean=True) If true, a CMMotionRemover will be added to the System soluteDielectric : float=1.0
- hydrogenMass (mass=None) The mass to use for hydrogen atoms bound to heavy atoms. Any mass added to a hydrogen is The solute dielectric constant to use in the implicit solvent model.
subtracted from the heavy atom to keep their total mass the same. solventDielectric : float=78.5
- ewaldErrorTolerance (float=0.0005) The error tolerance to use if nonbondedMethod is Ewald or PME. The solvent dielectric constant to use in the implicit solvent
Returns: the newly created System model.
removeCMMotion : boolean=True
If true, a CMMotionRemover will be added to the System
hydrogenMass : mass=None
The mass to use for hydrogen atoms bound to heavy atoms. Any mass
added to a hydrogen is subtracted from the heavy atom to keep their
total mass the same.
ewaldErrorTolerance : float=0.0005
The error tolerance to use if nonbondedMethod is Ewald or PME.
Returns
-------
System
the newly created System
""" """
if self._prmtop.chamber: if self._prmtop.chamber:
raise ValueError("CHAMBER-style topology file detected. CHAMBER " raise ValueError("CHAMBER-style topology file detected. CHAMBER "
......
...@@ -49,12 +49,17 @@ class CharmmCrdFile(object): ...@@ -49,12 +49,17 @@ class CharmmCrdFile(object):
Reads and parses a CHARMM coordinate file (.crd) into its components, Reads and parses a CHARMM coordinate file (.crd) into its components,
namely the coordinates, CHARMM atom types, resid, resname, etc. namely the coordinates, CHARMM atom types, resid, resname, etc.
Main attributes: Attributes
- natom (int) : Number of atoms in the system ----------
- resname (list) : Names of all residues natom : int
- positions (list) : All cartesian coordinates [x1, y1, z1, x2, ...] Number of atoms in the system
resname : list
Example: Names of all residues
positions : list
All cartesian coordinates [x1, y1, z1, x2, ...]
Examples
--------
>>> chm = CharmmCrdFile('testfiles/1tnm.crd') >>> chm = CharmmCrdFile('testfiles/1tnm.crd')
>>> print '%d atoms; %d coords' % (chm.natom, len(chm.positions)) >>> print '%d atoms; %d coords' % (chm.natom, len(chm.positions))
1414 atoms; 1414 coords 1414 atoms; 1414 coords
...@@ -131,14 +136,21 @@ class CharmmRstFile(object): ...@@ -131,14 +136,21 @@ class CharmmRstFile(object):
Reads and parses data, velocities and coordinates from a CHARMM restart Reads and parses data, velocities and coordinates from a CHARMM restart
file (.rst) of file name 'fname' into class attributes file (.rst) of file name 'fname' into class attributes
Main attributes: Attributes
- natom (int) : Number of atoms in the system ----------
- resname (list) : Names of all residues natom : int
- positions (list) : All cartesian coordinates [x1, y1, z1, x2, ...] Number of atoms in the system
- positionsold (list) : Old cartesian coordinates resname : list
- velocities (list) : List of all cartesian velocities Names of all residues
positions : list
Example: All cartesian coordinates [x1, y1, z1, x2, ...]
positionsold : list
Old cartesian coordinates
velocities : list
List of all cartesian velocities
Examples
--------
>>> chm = CharmmRstFile('testfiles/sample-charmm.rst') >>> chm = CharmmRstFile('testfiles/sample-charmm.rst')
>>> print chm.header[0] >>> print chm.header[0]
REST 37 1 REST 37 1
......
...@@ -51,18 +51,19 @@ class CharmmParameterSet(object): ...@@ -51,18 +51,19 @@ class CharmmParameterSet(object):
the information found in the MASS section of the CHARMM topology file the information found in the MASS section of the CHARMM topology file
(TOP/RTF) and all of the information in the parameter files (PAR) (TOP/RTF) and all of the information in the parameter files (PAR)
Parameters: Parameters
- filenames : List of topology, parameter, and stream files to load into ----------
the parameter set. The following file type suffixes are recognized. filenames : List of topology, parameter, and stream files to load into the parameter set.
Unrecognized file types raise a TypeError The following file type suffixes are recognized. Unrecognized file types raise a TypeError
.rtf, .top -- Residue topology file * .rtf, .top -- Residue topology file
.par, .prm -- Parameter file * .par, .prm -- Parameter file
.str -- Stream file * .str -- Stream file
.inp -- If "par" is in the file name, it is a parameter file. If * .inp -- If "par" is in the file name, it is a parameter file. If
"top" is in the file name, it is a topology file. Otherwise, "top" is in the file name, it is a topology file. Otherwise,
raise TypeError raise TypeError
Attributes: Attributes
----------
All type lists are dictionaries whose keys are tuples (with however All type lists are dictionaries whose keys are tuples (with however
many elements are needed to define that type of parameter). The types many elements are needed to define that type of parameter). The types
that can be in any order are SORTED. that can be in any order are SORTED.
...@@ -85,7 +86,8 @@ class CharmmParameterSet(object): ...@@ -85,7 +86,8 @@ class CharmmParameterSet(object):
when only the integer or string is available the other dictionaries are when only the integer or string is available the other dictionaries are
helpful helpful
Example: Examples
--------
>>> params = CharmmParameterSet('charmm22.top', 'charmm22.par', 'file.str') >>> params = CharmmParameterSet('charmm22.top', 'charmm22.par', 'file.str')
""" """
...@@ -150,18 +152,25 @@ class CharmmParameterSet(object): ...@@ -150,18 +152,25 @@ class CharmmParameterSet(object):
Instantiates a CharmmParameterSet from a Topology file and a Parameter Instantiates a CharmmParameterSet from a Topology file and a Parameter
file (or just a Parameter file if it has all information) file (or just a Parameter file if it has all information)
Parameters: Parameters
- tfile (str) : Name of the Topology (RTF/TOP) file -----------
- pfile (str) : Name of the Parameter (PAR) file tfile : str
- sfiles (list of str) : List or tuple of stream (STR) file names. Name of the Topology (RTF/TOP) file
- permissive (bool) : Accept non-bonbded parameters for undefined pfile : str
atom types (default False) Name of the Parameter (PAR) file
sfiles : list of str
Returns: List or tuple of stream (STR) file names.
permissive : bool=False
Accept non-bonbded parameters for undefined atom types
Returns
-------
CharmmParameterSet
New CharmmParameterSet populated with the parameters found in the New CharmmParameterSet populated with the parameters found in the
provided files. provided files.
Notes: Notes
-----
The RTF file is read first (if provided), followed by the PAR file, The RTF file is read first (if provided), followed by the PAR file,
followed by the list of stream files (in the order they are followed by the list of stream files (in the order they are
provided). Parameters in each stream file will overwrite those that provided). Parameters in each stream file will overwrite those that
...@@ -183,21 +192,24 @@ class CharmmParameterSet(object): ...@@ -183,21 +192,24 @@ class CharmmParameterSet(object):
return inst return inst
def readParameterFile(self, pfile, permissive=False): def readParameterFile(self, pfile, permissive=False):
""" """Reads all of the parameters from a parameter file. Versions 36 and later
Reads all of the parameters from a parameter file. Versions 36 and of the CHARMM force field files have an ATOMS section defining all of
later of the CHARMM force field files have an ATOMS section defining the atom types. Older versions need to load this information from the
all of the atom types. Older versions need to load this information RTF/TOP files.
from the RTF/TOP files.
Parameters
Parameters: ----------
- pfile (str) : Name of the CHARMM PARameter file to read pfile : str
- permissive (bool) : Accept non-bonbded parameters for undefined Name of the CHARMM PARameter file to read
atom types (default False) permissive : bool
Accept non-bonbded parameters for undefined atom types (default:
Notes: The atom types must all be loaded by the end of this routine. False).
Either supply a PAR file with atom definitions in them or read in a
RTF/TOP file first. Failure to do so will result in a raised Notes
RuntimeError. -----
The atom types must all be loaded by the end of this routine. Either
supply a PAR file with atom definitions in them or read in a RTF/TOP
file first. Failure to do so will result in a raised RuntimeError.
""" """
conv = CharmmParameterSet._convert conv = CharmmParameterSet._convert
if isinstance(pfile, str): if isinstance(pfile, str):
...@@ -518,14 +530,17 @@ class CharmmParameterSet(object): ...@@ -518,14 +530,17 @@ class CharmmParameterSet(object):
if own_handle: f.close() if own_handle: f.close()
def readTopologyFile(self, tfile): def readTopologyFile(self, tfile):
""" """Reads _only_ the atom type definitions from a topology file. This is
Reads _only_ the atom type definitions from a topology file. This is
unnecessary for versions 36 and later of the CHARMM force field. unnecessary for versions 36 and later of the CHARMM force field.
Parameters: Parameters
- tfile (str) : Name of the CHARMM TOPology file to read ----------
tfile : str
: Name of the CHARMM TOPology file to read
Note: The CHARMM TOPology file is also called a Residue Topology File Notes
-----
The CHARMM TOPology file is also called a Residue Topology File
""" """
conv = CharmmParameterSet._convert conv = CharmmParameterSet._convert
if isinstance(tfile, str): if isinstance(tfile, str):
...@@ -564,12 +579,13 @@ class CharmmParameterSet(object): ...@@ -564,12 +579,13 @@ class CharmmParameterSet(object):
if own_handle: f.close() if own_handle: f.close()
def readStreamFile(self, sfile): def readStreamFile(self, sfile):
""" """Reads RTF and PAR sections from a stream file and dispatches the
Reads RTF and PAR sections from a stream file and dispatches the
sections to readTopologyFile or readParameterFile sections to readTopologyFile or readParameterFile
Parameters: Parameters
- sfile (str or CharmmStreamFile) : Stream file to parse ----------
sfile : str or CharmmStreamFile
Stream file to parse
""" """
if isinstance(sfile, CharmmStreamFile): if isinstance(sfile, CharmmStreamFile):
f = sfile f = sfile
...@@ -594,14 +610,8 @@ class CharmmParameterSet(object): ...@@ -594,14 +610,8 @@ class CharmmParameterSet(object):
bond, angle, dihedral, improper, or cmap type will pair with EVERY key bond, angle, dihedral, improper, or cmap type will pair with EVERY key
in the type mapping dictionaries that points to the equivalent type in the type mapping dictionaries that points to the equivalent type
Returns: Example
- Returns the instance that is being condensed. -------
Notes:
The return value allows you to condense the types at construction
time.
Example:
>>> params = CharmmParameterSet('charmm.prm').condense() >>> params = CharmmParameterSet('charmm.prm').condense()
""" """
# First scan through all of the bond types # First scan through all of the bond types
...@@ -631,8 +641,10 @@ class CharmmParameterSet(object): ...@@ -631,8 +641,10 @@ class CharmmParameterSet(object):
""" """
Loops through the given dict and condenses all types. Loops through the given dict and condenses all types.
Parameter: Parameters
- typedict : Type dictionary to condense ----------
typedict
Type dictionary to condense
""" """
keylist = list(typedict.keys()) keylist = list(typedict.keys())
for i in range(len(keylist) - 1): for i in range(len(keylist) - 1):
......
...@@ -116,11 +116,7 @@ def _strip_optunit(thing, unit): ...@@ -116,11 +116,7 @@ def _strip_optunit(thing, unit):
_resre = re.compile(r'(\d+)([a-zA-Z]*)') _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.
Example:
>>> cs = CharmmPsfFile("testfiles/test.psf")
This structure has numerous attributes that are lists of the elements of This structure has numerous attributes that are lists of the elements of
this structure, including atoms, bonds, torsions, etc. The attributes are this structure, including atoms, bonds, torsions, etc. The attributes are
...@@ -144,7 +140,8 @@ class CharmmPsfFile(object): ...@@ -144,7 +140,8 @@ class CharmmPsfFile(object):
The lengths of each of these lists gives the pointers (e.g., natom, nres, The lengths of each of these lists gives the pointers (e.g., natom, nres,
etc.) etc.)
Example: Examples
--------
>>> cs = CharmmPsfFile("testfiles/test.psf") >>> cs = CharmmPsfFile("testfiles/test.psf")
>>> len(cs.atom_list) >>> len(cs.atom_list)
33 33
...@@ -166,14 +163,16 @@ class CharmmPsfFile(object): ...@@ -166,14 +163,16 @@ class CharmmPsfFile(object):
@_catchindexerror @_catchindexerror
def __init__(self, psf_name): def __init__(self, psf_name):
""" """Opens and parses a PSF file, then instantiates a CharmmPsfFile
Opens and parses a PSF file, then instantiates a CharmmPsfFile
instance from the data. instance from the data.
Parameters: Parameters
psf_name (str) : Name of the PSF file (it must exist) ----------
psf_name : str
Name of the PSF file (it must exist)
Exceptions Raised: Raises
------
IOError : If file "psf_name" does not exist IOError : If file "psf_name" does not exist
CharmmPSFError: If any parsing errors are encountered CharmmPSFError: If any parsing errors are encountered
""" """
...@@ -388,14 +387,17 @@ class CharmmPsfFile(object): ...@@ -388,14 +387,17 @@ class CharmmPsfFile(object):
@staticmethod @staticmethod
def _convert(string, type, message): def _convert(string, type, message):
""" """Converts a string to a specific type, making sure to raise
Converts a string to a specific type, making sure to raise
CharmmPSFError with the given message in the event of a failure. CharmmPSFError with the given message in the event of a failure.
Parameters: Parameters
- string (str) : Input string to process ----------
- type (type) : Type of data to convert to string : str
- message (str) : Error message to put in exception if failed Input string to process
type : type
Type of data to convert to
message : str
Error message to put in exception if failed
""" """
try: try:
return type(string) return type(string)
...@@ -405,23 +407,24 @@ class CharmmPsfFile(object): ...@@ -405,23 +407,24 @@ class CharmmPsfFile(object):
@staticmethod @staticmethod
def _parse_psf_section(psf): def _parse_psf_section(psf):
""" """This method parses a section of the PSF file
This method parses a section of the PSF file
Parameters
Parameters: ----------
- psf (CharmmFile) : Open file that is pointing to the first line psf : CharmmFile
of the section that is to be parsed Open file that is pointing to the first line of the section
that is to be parsed
Returns:
(title, pointers, data) Returns
--------
- title (str) : The label of the PSF section we are parsing str
- pointers (int/tuple of ints) : If one pointer is set, pointers is The label of the PSF section we are parsing
simply the integer that is value of that pointer. Otherwise int/tuple of ints
it is a tuple with every pointer value defined in the first If one pointer is set, pointers is simply the integer that is
line value of that pointer. Otherwise it is a tuple with every pointer
- data (list) : A list of all data in the parsed section converted value defined in the first line
to `dtype' list
A list of all data in the parsed section converted to `dtype'
""" """
conv = CharmmPsfFile._convert conv = CharmmPsfFile._convert
line = psf.readline() line = psf.readline()
...@@ -462,22 +465,22 @@ class CharmmPsfFile(object): ...@@ -462,22 +465,22 @@ class CharmmPsfFile(object):
return title, pointers, data return title, pointers, data
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,
PAR, and STR files. PAR, and STR files.
Parameters: Parameters
- parmset (CharmmParameterSet) : List of all parameters ----------
parmset : CharmmParameterSet
List of all parameters
Notes: Notes
-----
- If any parameters that are necessary cannot be found, a - If any parameters that are necessary cannot be found, a
MissingParameter exception is raised. MissingParameter exception is raised.
- If any dihedral or improper parameters cannot be found, I will try - If any dihedral or improper parameters cannot be found, I will try
inserting wildcards (at either end for dihedrals and as the two inserting wildcards (at either end for dihedrals and as the two
central atoms in impropers) and see if that matches. Wild-cards central atoms in impropers) and see if that matches. Wild-cards
will apply ONLY if specific parameters cannot be found. will apply ONLY if specific parameters cannot be found.
- This method will expand the dihedral_parameter_list attribute by - This method will expand the dihedral_parameter_list attribute by
adding a separate Dihedral object for each term for types that adding a separate Dihedral object for each term for types that
have a multi-term expansion have a multi-term expansion
...@@ -588,13 +591,22 @@ class CharmmPsfFile(object): ...@@ -588,13 +591,22 @@ class CharmmPsfFile(object):
def setBox(self, a, b, c, alpha=90.0*u.degrees, beta=90.0*u.degrees, def setBox(self, a, b, c, alpha=90.0*u.degrees, beta=90.0*u.degrees,
gamma=90.0*u.degrees): gamma=90.0*u.degrees):
""" """Sets the periodic box boundary conditions.
Sets the periodic box boundary conditions.
Parameters
Parameters: ----------
- a, b, c (floats) : Lengths of the periodic cell a : length
- alpha, beta, gamma (floats, optional) : Angles between the Lengths of the periodic cell
periodic cell vectors. b : length
Lengths of the periodic cell
c : length
Lengths of the periodic cell
alpha : floats, optional
Angles between the periodic cell vectors.
beta : floats, optional
Angles between the periodic cell vectors.
gamma : floats, optional
Angles between the periodic cell vectors.
""" """
try: try:
# Since we are setting the box, delete the cached box lengths if we # Since we are setting the box, delete the cached box lengths if we
...@@ -752,52 +764,60 @@ class CharmmPsfFile(object): ...@@ -752,52 +764,60 @@ class CharmmPsfFile(object):
ewaldErrorTolerance=0.0005, ewaldErrorTolerance=0.0005,
flexibleConstraints=True, flexibleConstraints=True,
verbose=False): verbose=False):
""" """Construct an OpenMM System representing the topology described by the
Construct an OpenMM System representing the topology described by the
prmtop file. You MUST have loaded a parameter set into this PSF before prmtop file. You MUST have loaded a parameter set into this PSF before
calling createSystem. If not, AttributeError will be raised. ValueError calling createSystem. If not, AttributeError will be raised. ValueError
is raised for illegal input. is raised for illegal input.
Parameters: Parameters
- params (CharmmParameterSet) The parameter set to use to parametrize ----------
this molecule params : CharmmParameterSet
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded The parameter set to use to parametrize this molecule
interactions. Allowed values are NoCutoff, CutoffNonPeriodic, nonbondedMethod : object=NoCutoff
CutoffPeriodic, Ewald, or PME. The method to use for nonbonded interactions. Allowed values are
- nonbondedCutoff (distance=1*nanometer) The cutoff distance to use NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
for nonbonded interactions. nonbondedCutoff : distance=1*nanometer
- switchDistance (distance=0*nanometer) The distance at which the The cutoff distance to use for nonbonded interactions.
switching function is active for nonbonded interactions. If the switchDistance : distance=0*nanometer
switchDistance evaluates to boolean False (if it is 0), no The distance at which the switching function is active for nonbonded
switching function will be used. Illegal values will raise a interactions. If the switchDistance evaluates to boolean False (if
ValueError it is 0), no switching function will be used. Illegal values will
- constraints (object=None) Specifies which bonds or angles should be raise a ValueError
implemented with constraints. Allowed values are None, HBonds, constraints : object=None
AllBonds, or HAngles. Specifies which bonds or angles should be implemented with
- rigidWater (boolean=True) If true, water molecules will be fully constraints. Allowed values are None, HBonds, AllBonds, or HAngles.
rigid regardless of the value passed for the constraints argument rigidWater : boolean=True
- implicitSolvent (object=None) If not None, the implicit solvent If true, water molecules will be fully rigid regardless of the value
model to use. Allowed values are HCT, OBC1, OBC2, or GBn passed for the constraints argument
- implicitSolventKappa (float=None): Debye screening parameter to implicitSolvent : object=None
model salt concentrations in GB solvent. If not None, the implicit solvent model to use. Allowed values are
- implicitSolventSaltConc (float=0.0*u.moles/u.liter): Salt HCT, OBC1, OBC2, or GBn
concentration for GB simulations. Converted to Debye length implicitSolventKappa : float=None
Debye screening parameter to model salt concentrations in GB
solvent.
implicitSolventSaltConc : float=0.0*u.moles/u.liter
Salt concentration for GB simulations. Converted to Debye length
`kappa' `kappa'
- temperature (float=298.15*u.kelvin): Temperature used in the salt temperature : float=298.15*u.kelvin
concentration-to-kappa conversion for GB salt concentration term Temperature used in the salt concentration-to-kappa conversion for
- soluteDielectric (float=1.0) The solute dielectric constant to use GB salt concentration term
in the implicit solvent model. soluteDielectric : float=1.0
- solventDielectric (float=78.5) The solvent dielectric constant to The solute dielectric constant to use in the implicit solvent model.
use in the implicit solvent model. solventDielectric : float=78.5
- removeCMMotion (boolean=True) If true, a CMMotionRemover will be The solvent dielectric constant to use in the implicit solvent
added to the System. model.
- hydrogenMass (mass=None) The mass to use for hydrogen atoms bound to removeCMMotion : boolean=True
heavy atoms. Any mass added to a hydrogen is subtracted from the If true, a CMMotionRemover will be added to the System.
heavy atom to keep their total mass the same. hydrogenMass : mass=None
- ewaldErrorTolerance (float=0.0005) The error tolerance to use if the The mass to use for hydrogen atoms bound to heavy atoms. Any mass
nonbonded method is Ewald or PME. added to a hydrogen is subtracted from the heavy atom to keep their
- flexibleConstraints (bool=True) Are our constraints flexible or not? total mass the same.
- verbose (bool=False) Optionally prints out a running progress report ewaldErrorTolerance : float=0.0005
The error tolerance to use if the nonbonded method is Ewald or PME.
flexibleConstraints : bool=True
Are our constraints flexible or not?
verbose : bool=False
Optionally prints out a running progress report
""" """
# Load the parameter set # Load the parameter set
self.loadParameters(params.condense()) self.loadParameters(params.condense())
......
...@@ -71,10 +71,12 @@ class CheckpointReporter(object): ...@@ -71,10 +71,12 @@ class CheckpointReporter(object):
def __init__(self, file, reportInterval): def __init__(self, file, reportInterval):
"""Create a CheckpointReporter. """Create a CheckpointReporter.
Parameters: Parameters
- file (string or open file object) The file to write to. Any current ----------
contents will be overwritten. file : string or open file object
- reportInterval (int) The interval (in time steps) at which to write checkpoints The file to write to. Any current contents will be overwritten.
reportInterval : int
The interval (in time steps) at which to write checkpoints.
""" """
self._reportInterval = reportInterval self._reportInterval = reportInterval
...@@ -88,12 +90,18 @@ class CheckpointReporter(object): ...@@ -88,12 +90,18 @@ class CheckpointReporter(object):
def describeNextReport(self, simulation): def describeNextReport(self, simulation):
"""Get information about the next report this object will generate. """Get information about the next report this object will generate.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
simulation : Simulation
Returns: A five element tuple. The first element is the number of steps until the The Simulation to generate a report for
next report. The remaining elements specify whether that report will require
positions, velocities, forces, and energies respectively. Returns
-------
tuple
A five element tuple. The first element is the number of steps
until the next report. The remaining elements specify whether
that report will require positions, velocities, forces, and
energies respectively.
""" """
steps = self._reportInterval - simulation.currentStep%self._reportInterval steps = self._reportInterval - simulation.currentStep%self._reportInterval
return (steps, False, False, False, False) return (steps, False, False, False, False)
...@@ -101,9 +109,12 @@ class CheckpointReporter(object): ...@@ -101,9 +109,12 @@ class CheckpointReporter(object):
def report(self, simulation, state): def report(self, simulation, state):
"""Generate a report. """Generate a report.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
- state (State) The current state of the simulation simulation : Simulation
The Simulation to generate a report for
state : State
The current state of the simulation
""" """
self._out.seek(0) self._out.seek(0)
chk = simulation.context.createCheckpoint() chk = simulation.context.createCheckpoint()
......
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