Commit a57facb4 authored by Peter Eastman's avatar Peter Eastman
Browse files

Generate Python wrapper for RPMDIntegrator

parent 90007de2
...@@ -453,6 +453,9 @@ IF(OPENMM_BUILD_PYTHON_WRAPPERS) ...@@ -453,6 +453,9 @@ IF(OPENMM_BUILD_PYTHON_WRAPPERS)
IF(NOT OPENMM_BUILD_AMOEBA_PLUGIN) IF(NOT OPENMM_BUILD_AMOEBA_PLUGIN)
MESSAGE(SEND_ERROR "The Python wrappers require that the AMOEBA plugin be built.") MESSAGE(SEND_ERROR "The Python wrappers require that the AMOEBA plugin be built.")
ENDIF(NOT OPENMM_BUILD_AMOEBA_PLUGIN) ENDIF(NOT OPENMM_BUILD_AMOEBA_PLUGIN)
IF(NOT OPENMM_BUILD_RPMD_PLUGIN)
MESSAGE(SEND_ERROR "The Python wrappers require that the RPMD plugin be built.")
ENDIF(NOT OPENMM_BUILD_RPMD_PLUGIN)
ADD_SUBDIRECTORY(wrappers/python) ADD_SUBDIRECTORY(wrappers/python)
ENDIF(OPENMM_BUILD_PYTHON_WRAPPERS) ENDIF(OPENMM_BUILD_PYTHON_WRAPPERS)
......
...@@ -199,7 +199,7 @@ set (STAGING_OUTPUT_FILES ${STAGING_OUTPUT_FILES} ...@@ -199,7 +199,7 @@ set (STAGING_OUTPUT_FILES ${STAGING_OUTPUT_FILES}
### Make a list of all folders containing include files the wrappers must be compiled against. ### ### Make a list of all folders containing include files the wrappers must be compiled against. ###
################################################################################################## ##################################################################################################
SET(WRAPPER_BASE_SUBDIRS . openmmapi olla serialization plugins/amoeba/openmmapi plugins/freeEnergy/openmmapi) SET(WRAPPER_BASE_SUBDIRS . openmmapi olla serialization plugins/amoeba/openmmapi plugins/freeEnergy/openmmapi plugins/rpmd/openmmapi)
SET(WRAPPER_INCLUDE_DIRS) # start empty SET(WRAPPER_INCLUDE_DIRS) # start empty
FOREACH(subdir ${WRAPPER_BASE_SUBDIRS}) FOREACH(subdir ${WRAPPER_BASE_SUBDIRS})
# append # append
......
...@@ -113,6 +113,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM, ...@@ -113,6 +113,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
'OpenMMSerialization', 'OpenMMSerialization',
'OpenMMFreeEnergy', 'OpenMMFreeEnergy',
'OpenMMAmoeba', 'OpenMMAmoeba',
'OpenMMRpmd',
] ]
if 'OPENMM_USE_DEBUG_LIBS' in os.environ: if 'OPENMM_USE_DEBUG_LIBS' in os.environ:
if platform.system() == "Windows": if platform.system() == "Windows":
......
...@@ -43,6 +43,7 @@ namespace std { ...@@ -43,6 +43,7 @@ namespace std {
#include "OpenMM.h" #include "OpenMM.h"
#include "OpenMMFreeEnergy.h" #include "OpenMMFreeEnergy.h"
#include "OpenMMAmoeba.h" #include "OpenMMAmoeba.h"
#include "openmm/RPMDIntegrator.h"
#include "openmm/serialization/SerializationNode.h" #include "openmm/serialization/SerializationNode.h"
#include "openmm/serialization/SerializationProxy.h" #include "openmm/serialization/SerializationProxy.h"
#include "openmm/serialization/XmlSerializer.h" #include "openmm/serialization/XmlSerializer.h"
......
...@@ -570,6 +570,7 @@ INPUT = "@CMAKE_SOURCE_DIR@/openmmapi" \ ...@@ -570,6 +570,7 @@ INPUT = "@CMAKE_SOURCE_DIR@/openmmapi" \
"@CMAKE_SOURCE_DIR@/serialization/include/openmm/serialization/SerializationProxy.h" \ "@CMAKE_SOURCE_DIR@/serialization/include/openmm/serialization/SerializationProxy.h" \
"@CMAKE_SOURCE_DIR@/serialization/include/openmm/serialization/XmlSerializer.h" \ "@CMAKE_SOURCE_DIR@/serialization/include/openmm/serialization/XmlSerializer.h" \
"@CMAKE_SOURCE_DIR@/plugins/amoeba/openmmapi" \ "@CMAKE_SOURCE_DIR@/plugins/amoeba/openmmapi" \
"@CMAKE_SOURCE_DIR@/plugins/rpmd/openmmapi" \
"@CMAKE_SOURCE_DIR@/plugins/freeEnergy/openmmapi" "@CMAKE_SOURCE_DIR@/plugins/freeEnergy/openmmapi"
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
......
...@@ -146,6 +146,8 @@ SKIP_METHODS = [('State',), ...@@ -146,6 +146,8 @@ SKIP_METHODS = [('State',),
('Platform', 'contextDestroyed'), ('Platform', 'contextDestroyed'),
('Platform', 'createKernel'), ('Platform', 'createKernel'),
('Platform', 'registerKernelFactory'), ('Platform', 'registerKernelFactory'),
('IntegrateRPMDStepKernel',),
('RPMDIntegrator', 'getState'),
] ]
# The build script assumes method args that are non-const references are # The build script assumes method args that are non-const references are
......
...@@ -6,85 +6,14 @@ ...@@ -6,85 +6,14 @@
int getParameters, int getParameters,
int enforcePeriodic, int enforcePeriodic,
int groups) { int groups) {
int types; int types = 0;
double simTime;
PyObject *pPeriodicBoxVectorsList;
PyObject *pEnergy;
PyObject *pPositions;
PyObject *pVelocities;
PyObject *pForces;
PyObject *pyTuple;
PyObject *pParameters;
types = 0;
if (getPositions) types |= State::Positions; if (getPositions) types |= State::Positions;
if (getVelocities) types |= State::Velocities; if (getVelocities) types |= State::Velocities;
if (getForces) types |= State::Forces; if (getForces) types |= State::Forces;
if (getEnergy) types |= State::Energy; if (getEnergy) types |= State::Energy;
if (getParameters) types |= State::Parameters; if (getParameters) types |= State::Parameters;
State state = self->getState(types, enforcePeriodic, groups); State state = self->getState(types, enforcePeriodic, groups);
return _convertStateToLists(state);
simTime=state.getTime();
OpenMM::Vec3 myVecA;
OpenMM::Vec3 myVecB;
OpenMM::Vec3 myVecC;
state.getPeriodicBoxVectors(myVecA, myVecB, myVecC);
PyObject* mm = PyImport_AddModule("simtk.openmm");
PyObject* vec3 = PyObject_GetAttrString(mm, "Vec3");
PyObject* args1 = Py_BuildValue("(d,d,d)", myVecA[0], myVecA[1], myVecA[2]);
PyObject* args2 = Py_BuildValue("(d,d,d)", myVecB[0], myVecB[1], myVecB[2]);
PyObject* args3 = Py_BuildValue("(d,d,d)", myVecC[0], myVecC[1], myVecC[2]);
PyObject* pyVec1 = PyObject_CallObject(vec3, args1);
PyObject* pyVec2 = PyObject_CallObject(vec3, args2);
PyObject* pyVec3 = PyObject_CallObject(vec3, args3);
Py_DECREF(args1);
Py_DECREF(args2);
Py_DECREF(args3);
pPeriodicBoxVectorsList = Py_BuildValue("N,N,N", pyVec1, pyVec2, pyVec3);
if (getPositions) {
pPositions = copyVVec3ToList(state.getPositions());
} else {
pPositions = Py_None;
Py_INCREF(Py_None);
}
if (getVelocities) {
pVelocities = copyVVec3ToList(state.getVelocities());
} else {
pVelocities = Py_None;
Py_INCREF(Py_None);
}
if (getForces) {
pForces = copyVVec3ToList(state.getForces());
} else {
pForces = Py_None;
Py_INCREF(Py_None);
}
if (getEnergy) {
pEnergy = Py_BuildValue("(d,d)",
state.getKineticEnergy(),
state.getPotentialEnergy());
} else {
pEnergy = Py_None;
Py_INCREF(Py_None);
}
if (getParameters) {
pParameters = PyDict_New();
const std::map<std::string, double>& params = state.getParameters();
for (std::map<std::string, double>::const_iterator iter = params.begin(); iter != params.end(); ++iter)
PyDict_SetItemString(pParameters, iter->first.c_str(), Py_BuildValue("d", iter->second));
} else {
pParameters = Py_None;
Py_INCREF(Py_None);
}
pyTuple=Py_BuildValue("(d,N,N,N,N,N,N)",
simTime, pPeriodicBoxVectorsList, pEnergy,
pPositions, pVelocities,
pForces, pParameters);
return pyTuple;
} }
...@@ -146,6 +75,87 @@ ...@@ -146,6 +75,87 @@
} }
%extend OpenMM::RPMDIntegrator {
PyObject *_getStateAsLists(int copy,
int getPositions,
int getVelocities,
int getForces,
int getEnergy,
int getParameters,
int enforcePeriodic,
int groups) {
int types = 0;
if (getPositions) types |= State::Positions;
if (getVelocities) types |= State::Velocities;
if (getForces) types |= State::Forces;
if (getEnergy) types |= State::Energy;
if (getParameters) types |= State::Parameters;
State state = self->getState(copy, types, enforcePeriodic, groups);
return _convertStateToLists(state);
}
%pythoncode {
def getState(self,
copy,
getPositions=False,
getVelocities=False,
getForces=False,
getEnergy=False,
getParameters=False,
enforcePeriodicBox=False,
groups=-1):
"""
getState(self,
copy,
getPositions = False,
getVelocities = False,
getForces = False,
getEnergy = False,
getParameters = False,
enforcePeriodicBox = False,
groups = -1)
-> State
Get a State object recording the current state information about one copy of the system.
copy -- the index of the copy for which to retrieve state information
getPositions -- whether to store particle positions in the State
getVelocities -- whether to store particle velocities in the State
getForces -- whether to store the forces acting on particles in the State
getEnergy -- whether to store potential and kinetic energy in the State
getParameter -- whether to store context parameters in the State
enforcePeriodicBox -- if false, the position of each particle will be whatever position is stored in the Context, regardless of periodic boundary conditions. If true, particle positions will be translated so the center of every molecule lies in the same periodic box.
groups -- a set of bit flags for which force groups to include when computing forces and energies. Group i will be included if (groups&(1<<i)) != 0. The default value includes all groups.
"""
if getPositions: getP=1
else: getP=0
if getVelocities: getV=1
else: getV=0
if getForces: getF=1
else: getF=0
if getEnergy: getE=1
else: getE=0
if getParameters: getPa=1
else: getPa=0
if enforcePeriodicBox: enforcePeriodic=1
else: enforcePeriodic=0
(simTime, periodicBoxVectorsList, energy, coordList, velList,
forceList, paramMap) = \
self._getStateAsLists(copy, getP, getV, getF, getE, getPa, enforcePeriodic, groups)
state = State(simTime=simTime,
energy=energy,
coordList=coordList,
velList=velList,
forceList=forceList,
periodicBoxVectorsList=periodicBoxVectorsList,
paramMap=paramMap)
return state
}
}
%extend OpenMM::NonbondedForce { %extend OpenMM::NonbondedForce {
%pythoncode { %pythoncode {
......
...@@ -20,6 +20,82 @@ PyObject *copyVVec3ToList(std::vector<Vec3> vVec3) { ...@@ -20,6 +20,82 @@ PyObject *copyVVec3ToList(std::vector<Vec3> vVec3) {
return pyList; return pyList;
} }
PyObject *_convertStateToLists(const State& state) {
double simTime;
PyObject *pPeriodicBoxVectorsList;
PyObject *pEnergy;
PyObject *pPositions;
PyObject *pVelocities;
PyObject *pForces;
PyObject *pyTuple;
PyObject *pParameters;
simTime=state.getTime();
OpenMM::Vec3 myVecA;
OpenMM::Vec3 myVecB;
OpenMM::Vec3 myVecC;
state.getPeriodicBoxVectors(myVecA, myVecB, myVecC);
PyObject* mm = PyImport_AddModule("simtk.openmm");
PyObject* vec3 = PyObject_GetAttrString(mm, "Vec3");
PyObject* args1 = Py_BuildValue("(d,d,d)", myVecA[0], myVecA[1], myVecA[2]);
PyObject* args2 = Py_BuildValue("(d,d,d)", myVecB[0], myVecB[1], myVecB[2]);
PyObject* args3 = Py_BuildValue("(d,d,d)", myVecC[0], myVecC[1], myVecC[2]);
PyObject* pyVec1 = PyObject_CallObject(vec3, args1);
PyObject* pyVec2 = PyObject_CallObject(vec3, args2);
PyObject* pyVec3 = PyObject_CallObject(vec3, args3);
Py_DECREF(args1);
Py_DECREF(args2);
Py_DECREF(args3);
pPeriodicBoxVectorsList = Py_BuildValue("N,N,N", pyVec1, pyVec2, pyVec3);
try {
pPositions = copyVVec3ToList(state.getPositions());
}
catch (std::exception& ex) {
pPositions = Py_None;
Py_INCREF(Py_None);
}
try {
pVelocities = copyVVec3ToList(state.getVelocities());
}
catch (std::exception& ex) {
pVelocities = Py_None;
Py_INCREF(Py_None);
}
try {
pForces = copyVVec3ToList(state.getForces());
}
catch (std::exception& ex) {
pForces = Py_None;
Py_INCREF(Py_None);
}
try {
pEnergy = Py_BuildValue("(d,d)",
state.getKineticEnergy(),
state.getPotentialEnergy());
}
catch (std::exception& ex) {
pEnergy = Py_None;
Py_INCREF(Py_None);
}
try {
pParameters = PyDict_New();
const std::map<std::string, double>& params = state.getParameters();
for (std::map<std::string, double>::const_iterator iter = params.begin(); iter != params.end(); ++iter)
PyDict_SetItemString(pParameters, iter->first.c_str(), Py_BuildValue("d", iter->second));
}
catch (std::exception& ex) {
pParameters = Py_None;
Py_INCREF(Py_None);
}
pyTuple=Py_BuildValue("(d,N,N,N,N,N,N)",
simTime, pPeriodicBoxVectorsList, pEnergy,
pPositions, pVelocities,
pForces, pParameters);
return pyTuple;
}
} // namespace OpenMM } // namespace OpenMM
%} %}
......
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