Commit 3cb25ad8 authored by Lee-Ping Wang's avatar Lee-Ping Wang
Browse files

Merge branch 'master' of github.com:leeping/openmm

parents 7bfb75c7 24608623
......@@ -114,8 +114,8 @@ extern "C" __global__ void contractForces(long long* force, long long* contracte
// Store results.
force[forceIndex] = (long long) (FORCE_SCALE*freal[indexInBlock].x);
force[forceIndex+PADDED_NUM_ATOMS] = (long long) (FORCE_SCALE*freal[indexInBlock].y);
force[forceIndex+PADDED_NUM_ATOMS*2] = (long long) (FORCE_SCALE*freal[indexInBlock].z);
force[forceIndex] += (long long) (FORCE_SCALE*freal[indexInBlock].x);
force[forceIndex+PADDED_NUM_ATOMS] += (long long) (FORCE_SCALE*freal[indexInBlock].y);
force[forceIndex+PADDED_NUM_ATOMS*2] += (long long) (FORCE_SCALE*freal[indexInBlock].z);
}
}
......@@ -391,7 +391,7 @@ void testContractions() {
map<int, int> contractions;
contractions[1] = 3;
contractions[2] = 1;
RPMDIntegrator integ(numCopies, temperature, 10.0, 0.001, contractions);
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001, contractions);
Platform& platform = Platform::getPlatformByName("CUDA");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
......
......@@ -112,7 +112,7 @@ ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${OPENCL_LIBRARIES} ${PTHREADS_LIB})
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${OPENMM_LIBRARY_NAME}OpenCL_d optimized ${OPENMM_LIBRARY_NAME}OpenCL)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_RPMD_TARGET} optimized ${SHARED_RPMD_TARGET})
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_BUILDING_SHARED_LIBRARY")
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-msse2 -DOPENMM_BUILDING_SHARED_LIBRARY")
INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins)
# Ensure that links to the main OpenCL library will be resolved.
......
......@@ -113,6 +113,6 @@ __kernel void contractForces(__global real4* force, __global real4* contracted)
// Store results.
force[index] = convert_real4(FORCE_SCALE*freal[indexInBlock]);
force[index] += convert_real4(FORCE_SCALE*freal[indexInBlock]);
}
}
......@@ -392,7 +392,7 @@ void testContractions() {
map<int, int> contractions;
contractions[1] = 3;
contractions[2] = 1;
RPMDIntegrator integ(numCopies, temperature, 10.0, 0.001, contractions);
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001, contractions);
Platform& platform = Platform::getPlatformByName("OpenCL");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
......
......@@ -336,7 +336,7 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const
q[k] = t_complex(0, 0);
fftpack_exec_1d(fft, FFTPACK_BACKWARD, &q[0], &q[0]);
for (int k = 0; k < totalCopies; k++)
forces[k][particle][component] = scale2*q[k].re;
forces[k][particle][component] += scale2*q[k].re;
}
}
}
......
......@@ -273,7 +273,7 @@ void testContractions() {
map<int, int> contractions;
contractions[1] = 3;
contractions[2] = 1;
RPMDIntegrator integ(numCopies, temperature, 10.0, 0.001, contractions);
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001, contractions);
Platform& platform = Platform::getPlatformByName("Reference");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
......
/* -------------------------------------------------------------------------- *
* 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) 2013 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/Context.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include <iostream>
#include <vector>
using namespace OpenMM;
using namespace std;
void testFindMolecules() {
const int numMolecules = 5;
const int moleculeSize[] = {1, 10, 100, 1000, 10000};
vector<int> particleMolecule;
System system;
HarmonicBondForce* bonds = new HarmonicBondForce();
system.addForce(bonds);
for (int i = 0; i < numMolecules; i++)
for (int j = 0; j < moleculeSize[i]; j++) {
int index = system.addParticle(1.0);
particleMolecule.push_back(i);
if (j > 0)
bonds->addBond(index, index-1, 1.0, 1.0);
}
VerletIntegrator integrator(1.0);
Context context(system, integrator, Platform::getPlatformByName("Reference"));
ContextImpl* contextImpl = *reinterpret_cast<ContextImpl**>(&context);
const vector<vector<int> >& molecules = contextImpl->getMolecules();
ASSERT_EQUAL(numMolecules, molecules.size());
for (int i = 0; i < numMolecules; i++) {
ASSERT_EQUAL(moleculeSize[i], molecules[i].size());
for (int j = 0; j < moleculeSize[i]; j++)
ASSERT_EQUAL(particleMolecule[molecules[i][j]], i);
}
}
int main() {
try {
testFindMolecules();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
......@@ -17,6 +17,7 @@
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
<xsl:variable name="set_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'set&lt;int')]/@id"/>
<!-- Do not generate functions for the following classes -->
<xsl:variable name="skip_classes" select="('Vec3', 'Kernel', 'Stream', 'KernelImpl', 'StreamImpl', 'KernelFactory', 'StreamFactory')"/>
......@@ -50,6 +51,7 @@ typedef struct OpenMM_ParameterArray_struct OpenMM_ParameterArray;
typedef struct OpenMM_PropertyArray_struct OpenMM_PropertyArray;
typedef struct OpenMM_DoubleArray_struct OpenMM_DoubleArray;
typedef struct OpenMM_IntArray_struct OpenMM_IntArray;
typedef struct OpenMM_IntSet_struct OpenMM_IntSet;
typedef struct {double x, y, z;} OpenMM_Vec3;
typedef enum {OpenMM_False = 0, OpenMM_True = 1} OpenMM_Boolean;
......@@ -103,6 +105,10 @@ extern OPENMM_EXPORT const char* OpenMM_PropertyArray_get(const OpenMM_PropertyA
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntArray'"/>
</xsl:call-template>
<xsl:call-template name="primitive_set">
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntSet'"/>
</xsl:call-template>
/* These methods need to be handled specially, since their C++ APIs cannot be directly translated to C.
Unlike the C++ versions, the return value is allocated on the heap, and you must delete it yourself. */
......@@ -135,6 +141,17 @@ extern OPENMM_EXPORT void <xsl:value-of select="$name"/>_set(<xsl:value-of selec
extern OPENMM_EXPORT <xsl:value-of select="concat($element_type, ' ', $name)"/>_get(const <xsl:value-of select="$name"/>* array, int index);
</xsl:template>
<!-- Print out the declarations for a (Primitive)Set type -->
<xsl:template name="primitive_set">
<xsl:param name="element_type"/>
<xsl:param name="name"/>
/* <xsl:value-of select="$name"/> */
extern OPENMM_EXPORT <xsl:value-of select="$name"/>* <xsl:value-of select="$name"/>_create();
extern OPENMM_EXPORT void <xsl:value-of select="$name"/>_destroy(<xsl:value-of select="$name"/>* set);
extern OPENMM_EXPORT int <xsl:value-of select="$name"/>_getSize(const <xsl:value-of select="$name"/>* set);
extern OPENMM_EXPORT void <xsl:value-of select="$name"/>_insert(<xsl:value-of select="$name"/>* set, <xsl:value-of select="$element_type"/> value);
</xsl:template>
<!-- Print out information for a class -->
<xsl:template name="class">
<xsl:variable name="class_name" select="@name"/>
......@@ -252,6 +269,9 @@ extern OPENMM_EXPORT <xsl:call-template name="wrap_type"><xsl:with-param name="t
<xsl:when test="$type_id=$vector_int_type_id">
<xsl:value-of select="'OpenMM_IntArray'"/>
</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">
<xsl:value-of select="'OpenMM_IntSet'"/>
</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="wrap_type">
<xsl:with-param name="type_id" select="$node/@type"/>
......
......@@ -19,6 +19,7 @@
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
<xsl:variable name="set_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'set&lt;int')]/@id"/>
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
......@@ -152,6 +153,10 @@ OPENMM_EXPORT const char* OpenMM_PropertyArray_get(const OpenMM_PropertyArray* a
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntArray'"/>
</xsl:call-template>
<xsl:call-template name="primitive_set">
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntSet'"/>
</xsl:call-template>
/* These methods need to be handled specially, since their C++ APIs cannot be directly translated to C.
Unlike the C++ versions, the return value is allocated on the heap, and you must delete it yourself. */
......@@ -200,6 +205,25 @@ OPENMM_EXPORT <xsl:value-of select="concat($element_type, ' ')"/> <xsl:value-of
}
</xsl:template>
<!-- Print out the definitions for a (Primitive)Set type -->
<xsl:template name="primitive_set">
<xsl:param name="element_type"/>
<xsl:param name="name"/>
/* <xsl:value-of select="$name"/> */
OPENMM_EXPORT <xsl:value-of select="$name"/>* <xsl:value-of select="$name"/>_create() {
return reinterpret_cast&lt;<xsl:value-of select="$name"/>*&gt;(new set&lt;<xsl:value-of select="$element_type"/>&gt;());
}
OPENMM_EXPORT void <xsl:value-of select="$name"/>_destroy(<xsl:value-of select="$name"/>* s) {
delete reinterpret_cast&lt;set&lt;<xsl:value-of select="$element_type"/>&gt;*&gt;(s);
}
OPENMM_EXPORT int <xsl:value-of select="$name"/>_getSize(const <xsl:value-of select="$name"/>* s) {
return reinterpret_cast&lt;const set&lt;<xsl:value-of select="$element_type"/>&gt;*&gt;(s)->size();
}
OPENMM_EXPORT void <xsl:value-of select="$name"/>_insert(<xsl:value-of select="$name"/>* s, <xsl:value-of select="$element_type"/> value) {
reinterpret_cast&lt;set&lt;<xsl:value-of select="$element_type"/>&gt;*&gt;(s)->insert(value);
}
</xsl:template>
<!-- Print out information for a class -->
<xsl:template name="class">
<xsl:variable name="class_name" select="@name"/>
......@@ -355,6 +379,9 @@ OPENMM_EXPORT <xsl:call-template name="wrap_type"><xsl:with-param name="type_id"
<xsl:when test="$type_id=$vector_int_type_id">
<xsl:value-of select="'OpenMM_IntArray'"/>
</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">
<xsl:value-of select="'OpenMM_IntSet'"/>
</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="wrap_type">
<xsl:with-param name="type_id" select="$node/@type"/>
......
......@@ -21,6 +21,7 @@
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
<xsl:variable name="set_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'set&lt;int')]/@id"/>
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
......@@ -514,6 +515,9 @@ END MODULE OpenMM
<xsl:when test="$type_id=$vector_int_type_id">
<xsl:value-of select="concat('type (OpenMM_IntArray) ', $value)"/>
</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">
<xsl:value-of select="concat('type (OpenMM_IntSet) ', $value)"/>
</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="declare_argument">
<xsl:with-param name="type_id" select="$node/@type"/>
......
......@@ -23,6 +23,7 @@
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
<xsl:variable name="set_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'set&lt;int')]/@id"/>
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
......@@ -243,6 +244,14 @@ OPENMM_EXPORT const char* OPENMM_PROPERTYARRAY_GET(const OpenMM_PropertyArray* c
<xsl:with-param name="element_type" select="'double'"/>
<xsl:with-param name="name" select="'OpenMM_DoubleArray'"/>
</xsl:call-template>
<xsl:call-template name="primitive_array">
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntArray'"/>
</xsl:call-template>
<xsl:call-template name="primitive_set">
<xsl:with-param name="element_type" select="'int'"/>
<xsl:with-param name="name" select="'OpenMM_IntSet'"/>
</xsl:call-template>
/* These methods need to be handled specially, since their C++ APIs cannot be directly translated to C.
Unlike the C++ versions, the return value is allocated on the heap, and you must delete it yourself. */
......@@ -320,6 +329,41 @@ OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_GET(const <xsl:value-of
}
</xsl:template>
<!-- Print out the definitions for a (Primitive)Set type -->
<xsl:template name="primitive_set">
<xsl:param name="element_type"/>
<xsl:param name="name"/>
<xsl:variable name="name_lower" select="lower-case($name)"/>
<xsl:variable name="name_upper" select="upper-case($name)"/>
/* <xsl:value-of select="$name"/> */
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_create_(<xsl:value-of select="$name"/>*&amp; result) {
result = <xsl:value-of select="$name"/>_create();
}
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_CREATE(<xsl:value-of select="$name"/>*&amp; result) {
result = <xsl:value-of select="$name"/>_create();
}
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_destroy_(<xsl:value-of select="$name"/>*&amp; array) {
<xsl:value-of select="$name"/>_destroy(array);
array = 0;
}
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_DESTROY(<xsl:value-of select="$name"/>*&amp; array) {
<xsl:value-of select="$name"/>_destroy(array);
array = 0;
}
OPENMM_EXPORT int <xsl:value-of select="$name_lower"/>_getsize_(const <xsl:value-of select="$name"/>* const&amp; array) {
return <xsl:value-of select="$name"/>_getSize(array);
}
OPENMM_EXPORT int <xsl:value-of select="$name_upper"/>_GETSIZE(const <xsl:value-of select="$name"/>* const&amp; array) {
return <xsl:value-of select="$name"/>_getSize(array);
}
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_insert_(<xsl:value-of select="$name"/>* const&amp; array, const <xsl:value-of select="$element_type"/>&amp; value) {
<xsl:value-of select="$name"/>_insert(array, value);
}
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_INSERT(<xsl:value-of select="$name"/>* const&amp; array, const <xsl:value-of select="$element_type"/>&amp; value) {
<xsl:value-of select="$name"/>_insert(array, value);
}
</xsl:template>
<!-- Print out information for a class -->
<xsl:template name="class">
<xsl:variable name="class_name" select="@name"/>
......@@ -565,6 +609,9 @@ OPENMM_EXPORT <xsl:if test="$has_return">
<xsl:when test="$type_id=$vector_int_type_id">
<xsl:value-of select="'OpenMM_IntArray'"/>
</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">
<xsl:value-of select="'OpenMM_IntSet'"/>
</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="wrap_type">
<xsl:with-param name="type_id" select="$node/@type"/>
......@@ -605,6 +652,7 @@ OPENMM_EXPORT <xsl:if test="$has_return">
<xsl:when test="$type_id=$vector_double_type_id">1</xsl:when>
<xsl:when test="$type_id=$vector_int_type_id">1</xsl:when>
<xsl:when test="$type_id=$vector_string_type_id">1</xsl:when>
<xsl:when test="$type_id=$set_int_type_id">1</xsl:when>
<xsl:when test="local-name($node)='Class' and $node/@context=$openmm_namespace_id">1</xsl:when>
<xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
<xsl:call-template name="is_handle_type">
......
......@@ -13,6 +13,7 @@ mark_as_advanced(OPENMM_PYTHON_STAGING_DIR)
file(MAKE_DIRECTORY ${OPENMM_PYTHON_STAGING_DIR}/simtk/openmm)
file(MAKE_DIRECTORY ${OPENMM_PYTHON_STAGING_DIR}/simtk/unit)
file(MAKE_DIRECTORY ${OPENMM_PYTHON_STAGING_DIR}/src/swig_doxygen/swig_lib/python)
file(MAKE_DIRECTORY ${OPENMM_PYTHON_STAGING_DIR}/tests)
##############################################################################
### Identify files that need to be copied from source area to staging area ###
......@@ -21,15 +22,32 @@ set(STAGING_OUTPUT_FILES "") # Will contain all required package files
file(GLOB STAGING_INPUT_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.in"
"${CMAKE_CURRENT_SOURCE_DIR}/README.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/*.py"
"${CMAKE_CURRENT_SOURCE_DIR}/filterPythonFiles.py"
)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py ${OPENMM_PYTHON_STAGING_DIR}/setup.py)
###########################################################
### Check the git revision of the source, and write it ###
### to a python file in the in the staging directory ###
###########################################################
execute_process(
COMMAND git rev-parse HEAD
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE rev_hash_str
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(NOT rev_hash_str)
set(rev_hash_str "Unknown")
endif()
file(WRITE "${OPENMM_PYTHON_STAGING_DIR}/simtk/openmm/version.py" "git_revision = '${rev_hash_str}'\n")
# file(GLOB_RECURSE temp RELATIVE "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/src/*.i")
# foreach(f ${temp})
# set(temp2 "${temp2}\n${f}")
# endforeach()
set(SUBDIRS src simtk)
set(SUBDIRS src simtk tests)
foreach(SUBDIR ${SUBDIRS})
file(GLOB_RECURSE STAGING_INPUT_FILES1 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*README.txt"
......@@ -38,6 +56,8 @@ foreach(SUBDIR ${SUBDIRS})
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.sh"
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.xml"
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.pdb"
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.prmtop"
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.top"
)
foreach(file ${STAGING_INPUT_FILES1})
set(STAGING_INPUT_FILES ${STAGING_INPUT_FILES} "${file}")
......
......@@ -6,15 +6,18 @@ setup.py: Used for building python wrappers for Simbios' OpenMM library.
__author__ = "Randall J. Radmer"
__version__ = "1.0"
import os, sys, platform, glob, shutil
import struct
import ast
import re
import os
import sys
import platform
from distutils.core import setup
MAJOR_VERSION_NUM='5'
MINOR_VERSION_NUM='1'
BUILD_INFO='0'
MAJOR_VERSION_NUM='@OPENMM_MAJOR_VERSION@'
MINOR_VERSION_NUM='@OPENMM_MINOR_VERSION@'
BUILD_INFO='@OPENMM_BUILD_VERSION@'
IS_RELEASED = False
def reportError(message):
sys.stdout.write("ERROR: ")
......@@ -64,6 +67,57 @@ def uninstall(verbose=True):
sys.path=save_path
def writeVersionPy(filename="simtk/openmm/version.py", major_version_num=MAJOR_VERSION_NUM,
minor_version_num=MINOR_VERSION_NUM, build_info=BUILD_INFO):
"""Write a version.py file into the python source directory before installation.
If a version.py file already exists, we assume that it contains only the git_revision
information, since from within this python session in the python staging directory, we're
not in the version controlled directory hierarchy.
When cmake is copying files into the PYTHON_STAGING_DIRECTORY, it will write the
git revision to version.py. We read that, and then overwrite it.
"""
cnt = """
# THIS FILE IS GENERATED FROM OPENMM SETUP.PY
short_version = '%(version)s'
version = '%(version)s'
full_version = '%(full_version)s'
git_revision = '%(git_revision)s'
release = %(isrelease)s
if not release:
version = full_version
"""
if os.path.exists(filename):
# git_revision is written to the file by cmake
with open(filename) as f:
text = f.read()
match = re.search(r"git_revision\s+=\s+(.*)", text, re.MULTILINE)
try:
git_revision = ast.literal_eval(match.group(1))
except:
# except anything, including no re match or
# literal_eval failing
git_revision = 'Unknown'
else:
git_revision = 'Unknown'
version = full_version = '%s.%s.%s' % (major_version_num, minor_version_num, build_info)
if not IS_RELEASED:
full_version += '.dev-' + git_revision[:7]
a = open(filename, 'w')
try:
a.write(cnt % {'version': version,
'full_version' : full_version,
'git_revision' : git_revision,
'isrelease': str(IS_RELEASED)})
finally:
a.close()
def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
minor_version_num=MINOR_VERSION_NUM,
build_info=BUILD_INFO):
......@@ -184,6 +238,7 @@ def main():
uninstall()
except:
pass
writeVersionPy()
setupKeywords=buildKeywordDictionary()
setup(**setupKeywords)
......
......@@ -12,7 +12,6 @@ It also tries to load any plugin modules it can find.
"""
__author__ = "Randall J. Radmer"
__version__ = "1.0"
import os, sys, glob
if sys.platform == "win32":
......@@ -36,3 +35,4 @@ else:
from simtk.openmm.openmm import *
from simtk.openmm.vec3 import Vec3
pluginLoadedLibNames = Platform.loadPluginsFromDirectory(Platform.getDefaultPluginsDirectory())
__version__ = Platform.getOpenMMVersion()
<ForceField>
<AtomTypes>
<Type name="swm4ndp-O" class="OW" element="O" mass="15.59943"/>
<Type name="swm4ndp-H" class="HW" element="H" mass="1.007947"/>
<Type name="swm4ndp-M" class="MW" mass="0"/>
<Type name="swm4ndp-OD" class="OWD" mass="0.4"/>
</AtomTypes>
<Residues>
<Residue name="HOH">
<Atom name="O" type="swm4ndp-O"/>
<Atom name="H1" type="swm4ndp-H"/>
<Atom name="H2" type="swm4ndp-H"/>
<Atom name="M" type="swm4ndp-M"/>
<Atom name="OD" type="swm4ndp-OD"/>
<VirtualSite type="average3" index="3" atom1="0" atom2="1" atom3="2" weight1="0.786646558" weight2="0.106676721" weight3="0.106676721"/>
<Bond from="0" to="1"/>
<Bond from="0" to="2"/>
</Residue>
</Residues>
<HarmonicBondForce>
<Bond class1="OW" class2="HW" length="0.09572" k="462750.4"/>
</HarmonicBondForce>
<HarmonicAngleForce>
<Angle class1="HW" class2="OW" class3="HW" angle="1.82421813418" k="836.8"/>
</HarmonicAngleForce>
<NonbondedForce coulomb14scale="0.833333" lj14scale="0.5">
<Atom type="swm4ndp-O" charge="1.71636" sigma="0.318395" epsilon="0.882573"/>
<Atom type="swm4ndp-H" charge="0.55733" sigma="1" epsilon="0"/>
<Atom type="swm4ndp-M" charge="-1.11466" sigma="1" epsilon="0"/>
<Atom type="swm4ndp-OD" charge="-1.71636" sigma="1" epsilon="0"/>
</NonbondedForce>
<DrudeForce>
<Particle type1="swm4ndp-OD" type2="swm4ndp-O" charge="-1.71636" polarizability="7.040850e-6" thole="1.3"/>
</DrudeForce>
</ForceField>
......@@ -323,7 +323,7 @@ class ForceField(object):
template = t
break
if matches is None:
raise ValueError('No template found for residue %d (%s). This might mean your input topology is missing some atoms or bonds, or possibly that you are using the wrong force field.' % (res.index+1, res.name))
raise ValueError('No template found for residue %d (%s). %s' % (res.index+1, res.name, _findMatchErrors(self, res)))
for atom, match in zip(res.atoms(), matches):
data.atomType[atom] = template.atoms[match].type
for site in template.virtualSites:
......@@ -461,18 +461,23 @@ class ForceField(object):
return sys
def _createResidueSignature(elements):
"""Create a signature for a residue based on the elements of the atoms it contains."""
def _countResidueAtoms(elements):
"""Count the number of atoms of each element in a residue."""
counts = {}
for element in elements:
if element is None:
pass # This residue contains "atoms" (probably virtual sites) that should match any element
elif element in counts:
if element in counts:
counts[element] += 1
else:
counts[element] = 1
return counts
def _createResidueSignature(elements):
"""Create a signature for a residue based on the elements of the atoms it contains."""
counts = _countResidueAtoms(elements)
sig = []
for c in counts:
if c is not None:
sig.append((c, counts[c]))
sig.sort(key=lambda x: -x[0].mass)
......@@ -539,6 +544,67 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
return False
def _findMatchErrors(forcefield, res):
"""Try to guess why a residue failed to match any template and return an error message."""
residueCounts = _countResidueAtoms([atom.element for atom in res.atoms()])
numResidueAtoms = sum(residueCounts.itervalues())
numResidueHeavyAtoms = sum(residueCounts[element] for element in residueCounts if element not in (None, elem.hydrogen))
# Loop over templates and see how closely each one might match.
bestMatchName = None
numBestMatchAtoms = 3*numResidueAtoms
numBestMatchHeavyAtoms = 2*numResidueHeavyAtoms
for templateName in forcefield._templates:
template = forcefield._templates[templateName]
templateCounts = _countResidueAtoms([atom.element for atom in template.atoms])
# Does the residue have any atoms that clearly aren't in the template?
if any(element not in templateCounts or templateCounts[element] < residueCounts[element] for element in residueCounts):
continue
# If there are too many missing atoms, discard this template.
numTemplateAtoms = sum(templateCounts.itervalues())
numTemplateHeavyAtoms = sum(templateCounts[element] for element in templateCounts if element not in (None, elem.hydrogen))
if numTemplateAtoms > numBestMatchAtoms:
continue
if numTemplateHeavyAtoms > numBestMatchHeavyAtoms:
continue
# If this template has the same number of missing atoms as our previous best one, look at the name
# to decide which one to use.
if numTemplateAtoms == numBestMatchAtoms:
if bestMatchName == res.name or res.name not in templateName:
continue
# Accept this as our new best match.
bestMatchName = templateName
numBestMatchAtoms = numTemplateAtoms
numBestMatchHeavyAtoms = numTemplateHeavyAtoms
numBestMatchExtraParticles = len([atom for atom in template.atoms if atom.element is None])
# Return an appropriate error message.
if numBestMatchAtoms == numResidueAtoms:
chainLength = len(list(res.chain.residues()))
if chainLength > 1 and (res.index == 0 or res.index == chainLength-1):
return 'The set of atoms matches %s, but the bonds are different. Perhaps the chain is missing a terminal group?' % bestMatchName
return 'The set of atoms matches %s, but the bonds are different.' % bestMatchName
if bestMatchName is not None:
if numBestMatchHeavyAtoms == numResidueHeavyAtoms:
numResidueExtraParticles = len([atom for atom in res.atoms() if atom.element is None])
if numResidueExtraParticles == 0 and numBestMatchExtraParticles == 0:
return 'The set of atoms is similar to %s, but it is missing %d hydrogen atoms.' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
if numBestMatchExtraParticles-numResidueExtraParticles == numBestMatchAtoms-numResidueAtoms:
return 'The set of atoms is similar to %s, but it is missing %d extra particles. You can add them with Modeller.addExtraParticles().' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
return 'The set of atoms is similar to %s, but it is missing %d atoms.' % (bestMatchName, numBestMatchAtoms-numResidueAtoms)
return 'This might mean your input topology is missing some atoms or bonds, or possibly that you are using the wrong force field.'
# The following classes are generators that know how to create Force subclasses and add them to a System that is being
# created. Each generator class must define two methods: 1) a static method that takes an etree Element and a ForceField,
# and returns the corresponding generator object; 2) a createForce() method that constructs the Force object and adds it
......
......@@ -122,7 +122,7 @@ class GromacsGroFile(object):
na = int(line.strip())
elif _is_gro_coord(line):
if frame == 0: # Create the list of residues, atom names etc. only if it's the first frame.
(thisresnum, thisresname, thisatomname, thisatomnum) = [line[i*5:i*5+5].strip() for i in range(4)]
(thisresnum, thisresname, thisatomname) = [line[i*5:i*5+5].strip() for i in range(3)]
resname.append(thisresname)
resid.append(int(thisresnum))
atomname.append(thisatomname)
......@@ -133,7 +133,10 @@ class GromacsGroFile(object):
elements.append(elem.get_by_symbol(thiselem))
except KeyError:
elements.append(None)
pos = [float(line[20+i*8:28+i*8]) for i in range(3)]
firstDecimalPos = line.index('.', 20)
secondDecimalPos = line.index('.', firstDecimalPos+1)
digits = secondDecimalPos-firstDecimalPos
pos = [float(line[20+i*digits:20+(i+1)*digits]) for i in range(3)]
xyz.append(Vec3(pos[0], pos[1], pos[2]))
elif _is_gro_box(line) and ln == na + 2:
sline = line.split()
......
......@@ -270,8 +270,19 @@ class GromacsTopFile(object):
def _processAtomType(self, line):
"""Process a line in the [ atomtypes ] category."""
fields = line.split()
if len(fields) < 7:
if len(fields) < 6:
raise ValueError('Too few fields in [ atomtypes ] line: '+line);
if len(fields[3]) == 1:
# Bonded type and atomic number are both missing.
fields.insert(1, None)
fields.insert(1, None)
elif len(fields[4]) == 1 and len(fields[5]) > 1:
if fields[1][0].isalpha():
# Atomic number is missing.
fields.insert(2, None)
else:
# Bonded type is missing.
fields.insert(1, None)
self._atomTypes[fields[0]] = fields
def _processBondType(self, line):
......@@ -463,6 +474,24 @@ class GromacsTopFile(object):
exceptions = []
fudgeQQ = float(self._defaults[4])
# Build a lookup table to let us process dihedrals more quickly.
dihedralTypeTable = {}
for key in self._dihedralTypes:
if key[1] != 'X' and key[2] != 'X':
if (key[1], key[2]) not in dihedralTypeTable:
dihedralTypeTable[(key[1], key[2])] = []
dihedralTypeTable[(key[1], key[2])].append(key)
if (key[2], key[1]) not in dihedralTypeTable:
dihedralTypeTable[(key[2], key[1])] = []
dihedralTypeTable[(key[2], key[1])].append(key)
wildcardDihedralTypes = []
for key in self._dihedralTypes:
if key[1] == 'X' or key[2] == 'X':
wildcardDihedralTypes.append(key)
for types in dihedralTypeTable.itervalues():
types.append(key)
# Loop over molecules and create the specified number of each type.
for moleculeName, moleculeCount in self._molecules:
......@@ -474,9 +503,10 @@ class GromacsTopFile(object):
baseAtomIndex = sys.getNumParticles()
atomTypes = [atom[1] for atom in moleculeType.atoms]
try:
[self._atomTypes[t][1] for t in atomTypes]
bondedTypes = [self._atomTypes[t][1] for t in atomTypes]
except KeyError as e:
raise ValueError('Unknown atom type: '+e.message)
bondedTypes = [b if b is not None else a for a, b in zip(atomTypes, bondedTypes)]
# Add atoms.
......@@ -484,7 +514,7 @@ class GromacsTopFile(object):
if len(fields) >= 8:
mass = float(fields[7])
else:
mass = float(self._atomTypes[fields[1]][2])
mass = float(self._atomTypes[fields[1]][3])
sys.addParticle(mass)
# Add bonds.
......@@ -492,7 +522,7 @@ class GromacsTopFile(object):
atomBonds = [{} for x in range(len(moleculeType.atoms))]
for fields in moleculeType.bonds:
atoms = [int(x)-1 for x in fields[:2]]
types = tuple(atomTypes[i] for i in atoms)
types = tuple(bondedTypes[i] for i in atoms)
if len(fields) >= 5:
params = fields[3:5]
elif types in self._bondTypes:
......@@ -529,7 +559,7 @@ class GromacsTopFile(object):
degToRad = math.pi/180
for fields in moleculeType.angles:
atoms = [int(x)-1 for x in fields[:3]]
types = tuple(atomTypes[i] for i in atoms)
types = tuple(bondedTypes[i] for i in atoms)
if len(fields) >= 6:
params = fields[4:]
elif types in self._angleTypes:
......@@ -575,7 +605,7 @@ class GromacsTopFile(object):
for fields in moleculeType.dihedrals:
atoms = [int(x)-1 for x in fields[:4]]
types = tuple(atomTypes[i] for i in atoms)
types = tuple(bondedTypes[i] for i in atoms)
dihedralType = fields[4]
reversedTypes = types[::-1]+(dihedralType,)
types = types+(dihedralType,)
......@@ -584,7 +614,11 @@ class GromacsTopFile(object):
else:
# Look for a matching dihedral type.
paramsList = None
for key in self._dihedralTypes:
if (types[1], types[2]) in dihedralTypeTable:
dihedralTypes = dihedralTypeTable[(types[1], types[2])]
else:
dihedralTypes = wildcardDihedralTypes
for key in dihedralTypes:
if all(a == b or a == 'X' for a, b in zip(key, types)) or all(a == b or a == 'X' for a, b in zip(key, reversedTypes)):
paramsList = self._dihedralTypes[key]
if 'X' not in key:
......@@ -623,7 +657,7 @@ class GromacsTopFile(object):
for fields in moleculeType.cmaps:
atoms = [int(x)-1 for x in fields[:5]]
types = tuple(atomTypes[i] for i in atoms)
types = tuple(bondedTypes[i] for i in atoms)
if len(fields) >= 8 and len(fields) >= 8+int(fields[6])*int(fields[7]):
params = fields
elif types in self._cmapTypes:
......@@ -655,8 +689,8 @@ class GromacsTopFile(object):
if len(fields) > 6:
q = float(fields[6])
else:
q = float(params[3])
nb.addParticle(q, float(params[5]), float(params[6]))
q = float(params[4])
nb.addParticle(q, float(params[6]), float(params[7]))
if implicitSolvent is OBC2:
if fields[1] not in self._implicitTypes:
raise ValueError('No implicit solvent parameters specified for atom type: '+fields[1])
......
......@@ -335,8 +335,8 @@ class PrmtopLoader(object):
% ((bondPointers[ii],
bondPointers[ii+1]),))
iType=int(bondPointers[ii+2])-1
returnList.append((int(bondPointers[ii])/3,
int(bondPointers[ii+1])/3,
returnList.append((int(bondPointers[ii])//3,
int(bondPointers[ii+1])//3,
float(forceConstant[iType])*forceConstConversionFactor,
float(bondEquil[iType])*lengthConversionFactor))
return returnList
......@@ -383,9 +383,9 @@ class PrmtopLoader(object):
anglePointers[ii+1],
anglePointers[ii+2]),))
iType=int(anglePointers[ii+3])-1
self._angleList.append((int(anglePointers[ii])/3,
int(anglePointers[ii+1])/3,
int(anglePointers[ii+2])/3,
self._angleList.append((int(anglePointers[ii])//3,
int(anglePointers[ii+1])//3,
int(anglePointers[ii+2])//3,
float(forceConstant[iType])*forceConstConversionFactor,
float(angleEquil[iType])))
return self._angleList
......@@ -411,10 +411,10 @@ class PrmtopLoader(object):
dihedralPointers[ii+2],
dihedralPointers[ii+3]),))
iType=int(dihedralPointers[ii+4])-1
self._dihedralList.append((int(dihedralPointers[ii])/3,
int(dihedralPointers[ii+1])/3,
abs(int(dihedralPointers[ii+2]))/3,
abs(int(dihedralPointers[ii+3]))/3,
self._dihedralList.append((int(dihedralPointers[ii])//3,
int(dihedralPointers[ii+1])//3,
abs(int(dihedralPointers[ii+2]))//3,
abs(int(dihedralPointers[ii+3]))//3,
float(forceConstant[iType])*forceConstConversionFactor,
float(phase[iType]),
int(0.5+float(periodicity[iType]))))
......@@ -429,8 +429,8 @@ class PrmtopLoader(object):
nonbondTerms = self.getNonbondTerms()
for ii in range(0,len(dihedralPointers),5):
if int(dihedralPointers[ii+2])>0 and int(dihedralPointers[ii+3])>0:
iAtom = int(dihedralPointers[ii])/3
lAtom = int(dihedralPointers[ii+3])/3
iAtom = int(dihedralPointers[ii])//3
lAtom = int(dihedralPointers[ii+3])//3
chargeProd = charges[iAtom]*charges[lAtom]
(rVdwI, epsilonI) = nonbondTerms[iAtom]
(rVdwL, epsilonL) = nonbondTerms[lAtom]
......
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