--- /dev/null
+
+project(pygromacs)
+
+cmake_minimum_required(VERSION 2.6)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_SOURCE_DIR}/../../share/template/cmake)
+add_compile_options(-std=c++11)
+
+find_package(PythonLibrary REQUIRED)
+find_package(SIP REQUIRED)
+include(SIPMacros)
+include(PythonMacros)
+
+find_package(GROMACS REQUIRED)
+
+include_directories(
+ ${PYTHON_INCLUDE_PATH}
+ ${SIP_INCLUDE_DIR}
+ ${GROMACS_INCLUDE_DIRS}
+ ${CMAKE_SOURCE_DIR}/include
+)
+
+set(SIP_INCLUDES ${CMAKE_BINARY_DIR} sip)
+set(SIP_EXTRA_OPTIONS ${SIP_EXTRA_OPTIONS} -e -o)
+
+file(GLOB common_files_sip sip/*.sip)
+
+file(GLOB options_files_sip sip/options/*.sip)
+set(SIP_EXTRA_FILES_DEPEND ${options_files_sip} ${common_files_sip})
+add_sip_python_module(gromacs.Options sip/options/Options.sip ${GROMACS_LIBRARIES})
+
+file(GLOB trajectoryanalysis_files_sip sip/trajectoryanalysis/*.sip)
+set(SIP_EXTRA_FILES_DEPEND ${trajectoryanalysis_files_sip} ${common_files_sip})
+add_sip_python_module(gromacs.TrajectoryAnalysis sip/trajectoryanalysis/TrajectoryAnalysis.sip ${GROMACS_LIBRARIES})
+
+python_install(__init__.py ${PYTHON_SITE_PACKAGES_INSTALL_DIR}/gromacs)
--- /dev/null
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2014, by the GROMACS development team, led by
+# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+# and including many others, as listed in the AUTHORS file in the
+# top-level source directory and at http://www.gromacs.org.
+#
+# GROMACS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1
+# of the License, or (at your option) any later version.
+#
+# GROMACS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GROMACS; if not, see
+# http://www.gnu.org/licenses, or write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# If you want to redistribute modifications to GROMACS, please
+# consider that scientific software is very special. Version
+# control is crucial - bugs must be traceable. We will be happy to
+# consider code for inclusion in the official distribution, but
+# derived work must not be called official GROMACS. Details are found
+# in the README & COPYING files - if they are missing, get the
+# official version at http://www.gromacs.org.
+#
+# To help us fund GROMACS development, we humbly ask that you cite
+# the research papers on the package. Check out http://www.gromacs.org.
+
+# This file should remain version-agnostic, with all things specific to a
+# particular GROMACS version remaining in the package configuration files.
+# This find module only provides some convenience functionality to manage the
+# suffixes etc.
+# That should allow using the same FindGROMACS.cmake file with multiple
+# different GROMACS installations on the same machine.
+
+# Propagate all flags passed to parent find_package() to the config call below.
+set(_gmx_find_args "")
+if (GROMACS_FIND_VERSION)
+ if (GROMACS_FIND_VERSION VERSION_LESS "5.1")
+ message(FATAL_ERROR
+ "This version of FindGROMACS.cmake requires GROMACS-provided "
+ "package configuration files, and only works to find "
+ "GROMACS 5.1 or later.")
+ endif()
+ list(APPEND _gmx_find_args ${GROMACS_FIND_VERSION})
+ if (GROMACS_FIND_VERSION_EXACT)
+ list(APPEND _gmx_find_args EXACT)
+ endif()
+endif()
+if (GROMACS_FIND_REQUIRED)
+ list(APPEND _gmx_find_args REQUIRED)
+endif()
+if (GROMACS_FIND_QUIETLY)
+ list(APPEND _gmx_find_args QUIET)
+endif()
+
+# Determine the actual name of the package configuration files.
+set(_gmx_pkg_name gromacs)
+if (DEFINED GROMACS_SUFFIX)
+ set(_gmx_pkg_name gromacs${GROMACS_SUFFIX})
+endif()
+# Delegate all the actual work to the package configuration files.
+# The CONFIGS option is not really necessary, but provides a bit better error
+# messages, since we actually know what the config file should be called.
+find_package(GROMACS ${_gmx_find_args} CONFIG
+ NAMES ${_gmx_pkg_name}
+ CONFIGS ${_gmx_pkg_name}-config.cmake)
+unset(_gmx_find_args)
+unset(_gmx_pkg_name)
--- /dev/null
+# Find Python
+# ~~~~~~~~~~~
+# Find the Python interpreter and related Python directories.
+#
+# This file defines the following variables:
+#
+# PYTHON_EXECUTABLE - The path and filename of the Python interpreter.
+#
+# PYTHON_SHORT_VERSION - The version of the Python interpreter found,
+# excluding the patch version number. (e.g. 2.5 and not 2.5.1))
+#
+# PYTHON_LONG_VERSION - The version of the Python interpreter found as a human
+# readable string.
+#
+# PYTHON_SITE_PACKAGES_INSTALL_DIR - this cache variable can be used for installing
+# own python modules. You may want to adjust this to be the
+# same as ${PYTHON_SITE_PACKAGES_DIR}, but then admin
+# privileges may be required for installation.
+#
+# PYTHON_SITE_PACKAGES_DIR - Location of the Python site-packages directory.
+#
+# PYTHON_INCLUDE_PATH - Directory holding the python.h include file.
+#
+# PYTHON_LIBRARY, PYTHON_LIBRARIES- Location of the Python library.
+
+# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
+# Copyright (c) 2012, Luca Beltrame <lbeltrame@kde.org>
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+include(FindPackageHandleStandardArgs)
+
+find_package(PythonInterp)
+
+if (PYTHONINTERP_FOUND)
+
+ option(INSTALL_PYTHON_FILES_IN_PYTHON_PREFIX "Install the Python files in the Python packages dir" FALSE)
+
+ # Set the Python libraries to what we actually found for interpreters
+ set(Python_ADDITIONAL_VERSIONS "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
+ # These are kept for compatibility
+ set(PYTHON_SHORT_VERSION "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
+ set(PYTHON_LONG_VERSION ${PYTHON_VERSION_STRING})
+
+ find_package(PythonLibs QUIET)
+
+ if(PYTHONLIBS_FOUND)
+ set(PYTHON_LIBRARY ${PYTHON_LIBRARIES})
+ endif(PYTHONLIBS_FOUND)
+
+ # Auto detect Python site-packages directory
+ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True))"
+ OUTPUT_VARIABLE PYTHON_SITE_PACKAGES_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ message(STATUS "Python system site-packages directory: ${PYTHON_SITE_PACKAGES_DIR}")
+ if(INSTALL_PYTHON_FILES_IN_PYTHON_PREFIX)
+ set(PYTHON_SITE_PACKAGES_INSTALL_DIR ${PYTHON_SITE_PACKAGES_DIR})
+ else()
+ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True, prefix='${CMAKE_INSTALL_PREFIX}'))"
+ OUTPUT_VARIABLE PYTHON_SITE_PACKAGES_INSTALL_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ endif()
+
+ if(NOT PYTHON_SITE_PACKAGES_INSTALL_DIR STREQUAL PYTHON_SITE_PACKAGES_DIR)
+ message(STATUS "The Python files will be installed to ${PYTHON_SITE_PACKAGES_INSTALL_DIR}. Make sure to add them to the Python search path (e.g. by setting PYTHONPATH)")
+ endif()
+
+endif(PYTHONINTERP_FOUND)
+
+find_package_handle_standard_args(PythonLibrary DEFAULT_MSG PYTHON_LIBRARY)
+
--- /dev/null
+# Find SIP
+# ~~~~~~~~
+#
+# SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
+#
+# Find the installed version of SIP. FindSIP should be called after Python
+# has been found.
+#
+# This file defines the following variables:
+#
+# SIP_VERSION - The version of SIP found expressed as a 6 digit hex number
+# suitable for comparison as a string.
+#
+# SIP_VERSION_STR - The version of SIP found as a human readable string.
+#
+# SIP_EXECUTABLE - Path and filename of the SIP command line executable.
+#
+# SIP_INCLUDE_DIR - Directory holding the SIP C++ header file.
+#
+# SIP_DEFAULT_SIP_DIR - Default directory where .sip files should be installed
+# into.
+
+# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+
+IF(SIP_VERSION)
+ # Already in cache, be silent
+ SET(SIP_FOUND TRUE)
+ELSE(SIP_VERSION)
+
+ FIND_FILE(_find_sip_py FindSIP.py PATHS ${CMAKE_MODULE_PATH})
+
+ EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_sip_py} OUTPUT_VARIABLE sip_config)
+ IF(sip_config)
+ STRING(REGEX REPLACE "^sip_version:([^\n]+).*$" "\\1" SIP_VERSION ${sip_config})
+ STRING(REGEX REPLACE ".*\nsip_version_str:([^\n]+).*$" "\\1" SIP_VERSION_STR ${sip_config})
+ STRING(REGEX REPLACE ".*\nsip_bin:([^\n]+).*$" "\\1" SIP_EXECUTABLE ${sip_config})
+ IF(NOT SIP_DEFAULT_SIP_DIR)
+ STRING(REGEX REPLACE ".*\ndefault_sip_dir:([^\n]+).*$" "\\1" SIP_DEFAULT_SIP_DIR ${sip_config})
+ ENDIF(NOT SIP_DEFAULT_SIP_DIR)
+ STRING(REGEX REPLACE ".*\nsip_inc_dir:([^\n]+).*$" "\\1" SIP_INCLUDE_DIR ${sip_config})
+ FILE(TO_CMAKE_PATH ${SIP_DEFAULT_SIP_DIR} SIP_DEFAULT_SIP_DIR)
+ FILE(TO_CMAKE_PATH ${SIP_INCLUDE_DIR} SIP_INCLUDE_DIR)
+ IF(EXISTS ${SIP_EXECUTABLE})
+ SET(SIP_FOUND TRUE)
+ ELSE()
+ MESSAGE(STATUS "Found SIP configuration but the sip executable could not be found.")
+ ENDIF()
+ ENDIF(sip_config)
+
+ IF(SIP_FOUND)
+ IF(NOT SIP_FIND_QUIETLY)
+ MESSAGE(STATUS "Found SIP version: ${SIP_VERSION_STR}")
+ ENDIF(NOT SIP_FIND_QUIETLY)
+ ELSE(SIP_FOUND)
+ IF(SIP_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find SIP")
+ ENDIF(SIP_FIND_REQUIRED)
+ ENDIF(SIP_FOUND)
+
+ENDIF(SIP_VERSION)
+
--- /dev/null
+# FindSIP.py
+#
+# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+import sys
+import sipconfig
+
+sipcfg = sipconfig.Configuration()
+print("sip_version:%06.0x" % sipcfg.sip_version)
+print("sip_version_str:%s" % sipcfg.sip_version_str)
+print("sip_bin:%s" % sipcfg.sip_bin)
+print("default_sip_dir:%s" % sipcfg.default_sip_dir)
+print("sip_inc_dir:%s" % sipcfg.sip_inc_dir)
+
--- /dev/null
+# By Simon Edwards <simon@simonzone.com>
+# This file is in the public domain.
+import py_compile, sys
+sys.exit(py_compile.main())
+
--- /dev/null
+# Python macros
+# ~~~~~~~~~~~~~
+# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
+# Copyright (c) 2012, Luca Beltrame <lbeltrame@kde.org>
+# Copyright (c) 2012, Rolf Eike Beer <eike@sf-mail.de>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+# This file defines the following macros:
+#
+# PYTHON_INSTALL (SOURCE_FILE DESTINATION_DIR)
+# Install the SOURCE_FILE, which is a Python .py file, into the
+# destination directory during install. The file will be byte compiled
+# and both the .py file and .pyc file will be installed.
+
+set(PYTHON_MACROS_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+macro(PYTHON_INSTALL SOURCE_FILE DESTINATION_DIR)
+
+ find_file(_python_compile_py PythonCompile.py PATHS ${CMAKE_MODULE_PATH})
+
+ # Install the source file.
+ install(FILES ${SOURCE_FILE} DESTINATION ${DESTINATION_DIR})
+
+ # Byte compile and install the .pyc file, unless explicitly prevented by env..
+ if("$ENV{PYTHONDONTWRITEBYTECODE}" STREQUAL "")
+ get_filename_component(_absfilename ${SOURCE_FILE} ABSOLUTE)
+ get_filename_component(_filename ${SOURCE_FILE} NAME)
+ get_filename_component(_filenamebase ${SOURCE_FILE} NAME_WE)
+ get_filename_component(_basepath ${SOURCE_FILE} PATH)
+
+ if(WIN32)
+ # remove drive letter
+ string(REGEX REPLACE "^[a-zA-Z]:/" "/" _basepath "${_basepath}")
+ endif(WIN32)
+
+ set(_bin_py ${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filename})
+
+ # Python 3.2 changed the pyc file location
+ if(PYTHON_VERSION_STRING VERSION_GREATER 3.1)
+ # To get the right version for suffix
+ set(_bin_pyc "${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/__pycache__/${_filenamebase}.cpython-${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}.pyc")
+ set(_py_install_dir "${DESTINATION_DIR}/__pycache__/")
+ else()
+ set(_bin_pyc "${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filenamebase}.pyc")
+ set(_py_install_dir "${DESTINATION_DIR}")
+ endif()
+
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_basepath})
+
+ # Setting because it will be displayed later, in compile_python_files
+ set(_message "Byte-compiling ${_bin_py} to ${_bin_pyc}")
+
+ string(REPLACE "/" "_" _rule_name "${_basepath}/${_bin_pyc}")
+ add_custom_target("${_rule_name}" ALL)
+
+ get_filename_component(_abs_bin_py ${_bin_py} ABSOLUTE)
+ if(_abs_bin_py STREQUAL _absfilename) # Don't copy the file onto itself.
+ add_custom_command(
+ TARGET "${_rule_name}"
+ COMMAND "${CMAKE_COMMAND}" -E echo "${_message}"
+ COMMAND "${PYTHON_EXECUTABLE}" "${_python_compile_py}" "${_bin_py}"
+ DEPENDS "${_absfilename}"
+ )
+ else()
+ add_custom_command(
+ TARGET "${_rule_name}"
+ COMMAND "${CMAKE_COMMAND}" -E echo "${_message}"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${_absfilename}" "${_bin_py}"
+ COMMAND "${PYTHON_EXECUTABLE}" "${_python_compile_py}" "${_bin_py}"
+ DEPENDS "${_absfilename}"
+ )
+ endif()
+
+ install(FILES ${_bin_pyc} DESTINATION "${_py_install_dir}")
+ unset(_py_install_dir)
+ unset(_message)
+
+ endif("$ENV{PYTHONDONTWRITEBYTECODE}" STREQUAL "")
+
+endmacro(PYTHON_INSTALL)
+
--- /dev/null
+# Macros for SIP
+# ~~~~~~~~~~~~~~
+# Copyright (c) 2007, Simon Edwards <simon@simonzone.com>
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+# SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
+#
+# This file defines the following macros:
+#
+# ADD_SIP_PYTHON_MODULE (MODULE_NAME MODULE_SIP [library1, libaray2, ...])
+# Specifies a SIP file to be built into a Python module and installed.
+# MODULE_NAME is the name of Python module including any path name. (e.g.
+# os.sys, Foo.bar etc). MODULE_SIP the path and filename of the .sip file
+# to process and compile. libraryN are libraries that the Python module,
+# which is typically a shared library, should be linked to. The built
+# module will also be install into Python's site-packages directory.
+#
+# The behaviour of the ADD_SIP_PYTHON_MODULE macro can be controlled by a
+# number of variables:
+#
+# SIP_INCLUDES - List of directories which SIP will scan through when looking
+# for included .sip files. (Corresponds to the -I option for SIP.)
+#
+# SIP_TAGS - List of tags to define when running SIP. (Corresponds to the -t
+# option for SIP.)
+#
+# SIP_CONCAT_PARTS - An integer which defines the number of parts the C++ code
+# of each module should be split into. Defaults to 8. (Corresponds to the
+# -j option for SIP.)
+#
+# SIP_DISABLE_FEATURES - List of feature names which should be disabled
+# running SIP. (Corresponds to the -x option for SIP.)
+#
+# SIP_EXTRA_OPTIONS - Extra command line options which should be passed on to
+# SIP.
+
+SET(SIP_INCLUDES)
+SET(SIP_TAGS)
+SET(SIP_CONCAT_PARTS 8)
+SET(SIP_DISABLE_FEATURES)
+SET(SIP_EXTRA_OPTIONS)
+
+MACRO(ADD_SIP_PYTHON_MODULE MODULE_NAME MODULE_SIP)
+
+ SET(EXTRA_LINK_LIBRARIES ${ARGN})
+
+ STRING(REPLACE "." "/" _x ${MODULE_NAME})
+ GET_FILENAME_COMPONENT(_parent_module_path ${_x} PATH)
+ GET_FILENAME_COMPONENT(_child_module_name ${_x} NAME)
+
+ GET_FILENAME_COMPONENT(_module_path ${MODULE_SIP} PATH)
+
+ if(_module_path STREQUAL "")
+ set(CMAKE_CURRENT_SIP_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ else(_module_path STREQUAL "")
+ set(CMAKE_CURRENT_SIP_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_module_path}")
+ endif(_module_path STREQUAL "")
+
+ GET_FILENAME_COMPONENT(_abs_module_sip ${MODULE_SIP} ABSOLUTE)
+
+ # We give this target a long logical target name.
+ # (This is to avoid having the library name clash with any already
+ # install library names. If that happens then cmake dependancy
+ # tracking get confused.)
+ STRING(REPLACE "." "_" _logical_name ${MODULE_NAME})
+ SET(_logical_name "python_module_${_logical_name}")
+
+ FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_SIP_OUTPUT_DIR}) # Output goes in this dir.
+
+ SET(_sip_includes)
+ FOREACH (_inc ${SIP_INCLUDES})
+ GET_FILENAME_COMPONENT(_abs_inc ${_inc} ABSOLUTE)
+ LIST(APPEND _sip_includes -I ${_abs_inc})
+ ENDFOREACH (_inc )
+
+ SET(_sip_tags)
+ FOREACH (_tag ${SIP_TAGS})
+ LIST(APPEND _sip_tags -t ${_tag})
+ ENDFOREACH (_tag)
+
+ SET(_sip_x)
+ FOREACH (_x ${SIP_DISABLE_FEATURES})
+ LIST(APPEND _sip_x -x ${_x})
+ ENDFOREACH (_x ${SIP_DISABLE_FEATURES})
+
+ SET(_message "-DMESSAGE=Generating CPP code for module ${MODULE_NAME}")
+ SET(_sip_output_files)
+ FOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
+ IF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
+ SET(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_SIP_OUTPUT_DIR}/sip${_child_module_name}part${CONCAT_NUM}.cpp )
+ ENDIF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
+ ENDFOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
+
+ IF(NOT WIN32)
+ SET(TOUCH_COMMAND touch)
+ ELSE(NOT WIN32)
+ SET(TOUCH_COMMAND echo)
+ # instead of a touch command, give out the name and append to the files
+ # this is basically what the touch command does.
+ FOREACH(filename ${_sip_output_files})
+ FILE(APPEND filename "")
+ ENDFOREACH(filename ${_sip_output_files})
+ ENDIF(NOT WIN32)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_sip_output_files}
+ COMMAND ${CMAKE_COMMAND} -E echo ${message}
+ COMMAND ${TOUCH_COMMAND} ${_sip_output_files}
+ COMMAND ${SIP_EXECUTABLE} ${_sip_tags} ${_sip_x} ${SIP_EXTRA_OPTIONS} -j ${SIP_CONCAT_PARTS} -c ${CMAKE_CURRENT_SIP_OUTPUT_DIR} ${_sip_includes} ${_abs_module_sip}
+ DEPENDS ${_abs_module_sip} ${SIP_EXTRA_FILES_DEPEND}
+ )
+ # not sure if type MODULE could be uses anywhere, limit to cygwin for now
+ IF (CYGWIN)
+ ADD_LIBRARY(${_logical_name} MODULE ${_sip_output_files} )
+ ELSE (CYGWIN)
+ ADD_LIBRARY(${_logical_name} SHARED ${_sip_output_files} )
+ ENDIF (CYGWIN)
+ TARGET_LINK_LIBRARIES(${_logical_name} ${PYTHON_LIBRARY})
+ TARGET_LINK_LIBRARIES(${_logical_name} ${EXTRA_LINK_LIBRARIES})
+ SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES PREFIX "" OUTPUT_NAME ${_child_module_name})
+
+ INSTALL(TARGETS ${_logical_name} DESTINATION "${PYTHON_SITE_PACKAGES_INSTALL_DIR}/${_parent_module_path}")
+
+ENDMACRO(ADD_SIP_PYTHON_MODULE)
+
--- /dev/null
+#ifndef VEC_H
+#define VEC_H
+
+#include <cstdlib>
+#include <stdexcept>
+#include <gromacs/math/vectypes.h>
+
+template<typename T> class RealVector {
+public:
+ T x, y, z;
+ RealVector(T v[3]) : x(v[0]), y(v[1]), z(v[2]) {};
+ T operator[] (size_t i) {
+ switch (i) {
+ case 0:
+ return x;
+ case 1:
+ return y;
+ case 2:
+ return z;
+ default:
+ throw std::out_of_range("Inexistent component requested");
+ };
+ };
+};
+
+template<typename T, typename Adaptor, typename Inner> class Array {
+private:
+ Inner *data;
+ size_t length;
+public:
+ Array(Inner *data, size_t length) : data(data), length(length) {};
+ Adaptor operator[] (size_t i) {
+ if (i >= length)
+ throw std::out_of_range("Array index out of range");
+
+ return Adaptor(data[i]);
+ };
+ size_t len() { return length; };
+};
+
+class Matrix {
+private:
+ real data[3][3];
+public:
+ Matrix(real data[3][3]) {
+ std::copy((real*) data, ((real*) data) + 9, (real*) this->data);
+ };
+ real get(size_t i, size_t j) {
+ if (i > 2 || j > 2)
+ throw std::out_of_range("Matrix index out of range");
+ return data[i][j];
+ }
+ RealVector<real> get(size_t i) {
+ if (i > 2)
+ throw std::out_of_range("Matrix index out of range");
+ return RealVector<real>(data[i]);
+ }
+};
+
+typedef RealVector<real> py_rvec;
+typedef Array<real, py_rvec, rvec> rvecs;
+#endif
--- /dev/null
+
+%Exception std::out_of_range(SIP_IndexError) {
+
+%TypeHeaderCode
+#include <stdexcept>
+%End
+
+%RaiseCode
+ SIP_BLOCK_THREADS
+ PyErr_SetString(PyExc_IndexError, sipExceptionRef.what());
+ SIP_UNBLOCK_THREADS
+%End
+};
+
+template<T> class RealVector /NoDefaultCtors/ {
+%TypeHeaderCode
+#include "vec.h"
+%End
+
+public:
+ T x;
+ T y;
+ T z;
+ T operator[] (unsigned int i) throw (std::out_of_range);
+ PyObject* __str__();
+ %MethodCode
+ size_t size = PyOS_snprintf(NULL, 0, "Vector [%f, %f, %f]", sipCpp->x, sipCpp->y, sipCpp->z);
+ char str[size + 1];
+ PyOS_snprintf(str, size + 1, "Vector [%f, %f, %f]", sipCpp->x, sipCpp->y, sipCpp->z);
+
+ return PyUnicode_FromString(str);
+ %End
+};
+
+template<T, Adaptor, Inner> class Array /NoDefaultCtors/ {
+%TypeHeaderCode
+#include "vec.h"
+%End
+
+public:
+ Adaptor operator[] (unsigned int i) throw (std::out_of_range);
+ SIP_SSIZE_T __len__();
+ %MethodCode
+ sipRes = sipCpp->len();
+ %End
+};
+
+class Matrix /NoDefaultCtors/ {
+%TypeHeaderCode
+#include "vec.h"
+%End
+
+public:
+ py_rvec __getitem__(int) throw (std::out_of_range);
+ %MethodCode
+ try {
+ sipRes = new py_rvec(sipCpp->get(a0));
+ } catch (const std::out_of_range &e) {
+ sipIsErr = 1;
+ SIP_BLOCK_THREADS
+ PyErr_SetString(PyExc_IndexError, e.what());
+ SIP_UNBLOCK_THREADS
+ }
+ %End
+ double __getitem__(SIP_PYTUPLE) throw (std::out_of_range);
+ %MethodCode
+ size_t i, j;
+ if (PyArg_ParseTuple(a0, "nn", &i, &j))
+ try {
+ sipRes = sipCpp->get(i, j);
+ } catch (const std::out_of_range &e) {
+ sipIsErr = 1;
+ SIP_BLOCK_THREADS
+ PyErr_SetString(PyExc_IndexError, e.what());
+ SIP_UNBLOCK_THREADS
+ }
+ else
+ sipIsErr = 1;
+ %End
+};
+
+typedef double* rvec;
+typedef double* dvec;
+typedef double** matrix;
+typedef double** tensor;
+typedef int* ivec;
+typedef int** imatrix;
+
+typedef RealVector<double> py_rvec;
+typedef Array<double, py_rvec, rvec> rvecs;
--- /dev/null
+%Module gromacs.Options
+
+%Include string.sip
+
+%Include options.sip
--- /dev/null
+
+class OptionManagerInterface /NoDefaultCtors/ {
+%TypeHeaderCode
+#include <string>
+
+#include <gromacs/options/options.h>
+using gmx::OptionManagerInterface;
+%End
+
+protected:
+ virtual ~OptionManagerInterface();
+};
+
+class Options {
+%TypeHeaderCode
+#include <string>
+
+#include <gromacs/options/options.h>
+using gmx::Options;
+%End
+
+public:
+ Options(const char *name, const char *title);
+ const std::string &name() const;
+ const std::string &title() const;
+ const std::string &description() const;
+ void setDescription (const std::string &desc);
+ void addManager (OptionManagerInterface *manager);
+ void addSubSection (Options *section);
+
+ bool isSet(const char *name) const;
+ void finish();
+private:
+ Options(const Options &other);
+};
--- /dev/null
+%MappedType std::string
+{
+%TypeHeaderCode
+#include <string>
+%End
+
+%ConvertToTypeCode
+if (sipIsErr == NULL)
+ return PyBytes_Check(sipPy);
+
+ *sipCppPtr = new std::string(PyBytes_AsString(sipPy), PyBytes_Size(sipPy));
+
+ return sipGetState(sipTransferObj);
+%End
+
+%ConvertFromTypeCode
+return PyBytes_FromStringAndSize(sipCpp->data(),sipCpp->length());
+%End
+
+};
--- /dev/null
+%Module gromacs.TrajectoryAnalysis
+
+%Import options/Options.sip
+
+%Include definitions.sip
+
+%Include analysissettings.sip
+%Include analysismodule.sip
--- /dev/null
+
+struct t_trxframe {
+
+%TypeHeaderCode
+#include <gromacs/fileio/trx.h>
+#include "vec.h"
+%End
+
+ int flags;
+ int not_ok;
+ bool bDouble;
+ int natoms;
+ double t0;
+ double tf;
+ double tpf;
+ double tppf;
+ bool bTitle;
+ const char *title;
+ bool bStep;
+ int step;
+ bool bTime;
+ double time;
+ bool bLambda;
+ bool bFepState;
+ double lambda;
+ int fep_state;
+ bool bAtoms;
+ // TODO
+ /*void *atoms;*/
+ bool bPrec;
+ double prec;
+ bool bX;
+ rvec *x {
+ %GetCode
+ rvecs *arr = new rvecs(sipCpp->x, sipCpp->natoms);
+ sipPy = sipConvertFromNewType(arr, sipType_rvecs, NULL);
+ %End
+ %SetCode
+
+ %End
+ };
+ bool bV;
+ rvec *v {
+ %GetCode
+ rvecs *arr = new rvecs(sipCpp->v, sipCpp->natoms);
+ sipPy = sipConvertFromNewType(arr, sipType_rvecs, NULL);
+ %End
+ %SetCode
+
+ %End
+ };
+ bool bF;
+ rvec *f {
+ %GetCode
+ rvecs *arr = new rvecs(sipCpp->f, sipCpp->natoms);
+ sipPy = sipConvertFromNewType(arr, sipType_rvecs, NULL);
+ %End
+ %SetCode
+
+ %End
+ };
+ bool bBox;
+ matrix box {
+ %GetCode
+ Matrix *mat = new Matrix(sipCpp->box);
+ sipPy = sipConvertFromNewType(mat, sipType_Matrix, NULL);
+ %End
+ %SetCode
+
+ %End
+ };
+ bool bPBC;
+ int ePBC;
+ // TODO
+ /*t_gmxvmdplugin* *vmdplugin; */
+};
+
+struct t_pbc {
+
+%TypeHeaderCode
+#include <gromacs/pbcutil/pbc.h>
+#include "vec.h"
+%End
+ int ePBC;
+ int ndim_ePBC;
+ int ePBCDX;
+ int dim;
+ matrix box {
+ %GetCode
+ Matrix *mat = new Matrix(sipCpp->box);
+ sipPy = sipConvertFromNewType(mat, sipType_Matrix, NULL);
+ %End
+ %SetCode
+
+ %End
+ };
+ rvec fbox_diag {
+ %GetCode
+ py_rvec *vec = new py_rvec(sipCpp->fbox_diag);
+ sipPy = sipConvertFromNewType(vec, sipType_py_rvec, NULL);
+ %End
+ %SetCode
+
+ %End
+ };
+ rvec hbox_diag {
+ %GetCode
+ py_rvec *vec = new py_rvec(sipCpp->fbox_diag);
+ sipPy = sipConvertFromNewType(vec, sipType_py_rvec, NULL);
+ %End
+ %SetCode
+
+ %End
+ };
+ rvec mhbox_diag {
+ %GetCode
+ py_rvec *vec = new py_rvec(sipCpp->mhbox_diag);
+ sipPy = sipConvertFromNewType(vec, sipType_py_rvec, NULL);
+ %End
+ %SetCode
+
+ %End
+ };
+ double max_cutoff2;
+ bool bLimitDistance;
+ double limit_distance2;
+ int ntric_vec;
+ /*ivec tric_shift[MAX_NTRICVEC];*/
+ /*rvec tric_vec[MAX_NTRICVEC];*/
+};
+
+class TrajectoryAnalysisModuleData /NoDefaultCtors/ {
+
+%TypeHeaderCode
+#include <gromacs/trajectoryanalysis/analysismodule.h>
+using namespace gmx;
+%End
+
+public:
+ virtual void finish() = 0;
+};
+
+class TrajectoryAnalysisModule {
+
+%TypeHeaderCode
+#include <gromacs/trajectoryanalysis/analysismodule.h>
+using namespace gmx;
+%End
+public:
+ virtual void initOptions(Options *options, TrajectoryAnalysisSettings *settings) = 0;
+ virtual void optionsFinished(Options *options, TrajectoryAnalysisSettings *settings);
+ virtual void initAnalysis(const TrajectoryAnalysisSettings &settings, const TopologyInformation &top) = 0;
+ virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings &settings, const t_trxframe &fr);
+// virtual TrajectoryAnalysisModuleDataPointer startFrames (const AnalysisDataParallelOptions &opt, const SelectionCollection &selections);
+ virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, TrajectoryAnalysisModuleData *pdata ) = 0;
+ virtual void finishFrames(TrajectoryAnalysisModuleData *pdata);
+ virtual void finishAnalysis(int nframes) = 0;
+ virtual void writeOutput() = 0;
+ const char* name() const;
+ const char* description() const;
+ int datasetCount() const;
+protected:
+ TrajectoryAnalysisModule(const char *name, const char *description);
+private:
+ TrajectoryAnalysisModule(const TrajectoryAnalysisModule &other);
+};
+
+%Exception gmx::InconsistentInputError(SIP_Exception) {
+
+%TypeHeaderCode
+#include <gromacs/utility/exceptions.h>
+using namespace std;
+%End
+
+%RaiseCode
+ printf("lALLA\n");
+ const char *detail = sipExceptionRef.what();
+
+ SIP_BLOCK_THREADS
+ PyErr_SetString(sipException_gmx_InconsistentInputError, detail);
+ SIP_UNBLOCK_THREADS
+%End
+};
+
+class TrajectoryAnalysisCommandLineRunner {
+%TypeHeaderCode
+#include <gromacs/trajectoryanalysis/cmdlinerunner.h>
+%End
+
+public:
+ TrajectoryAnalysisCommandLineRunner(TrajectoryAnalysisModule *module);
+ int run(SIP_PYLIST) throw (gmx::InconsistentInputError);
+ %MethodCode
+ int argc = PyList_GET_SIZE(a0);
+
+ char **argv = new char *[argc + 1];
+
+ // Convert the list.
+ for (int a = 0; a < argc; ++a)
+ {
+ PyObject *arg_obj = PyList_GET_ITEM(a0, a);
+ const char *arg = sipString_AsLatin1String(&arg_obj);
+
+ if (arg)
+ {
+ arg = strdup(arg);
+ Py_DECREF(arg_obj);
+ }
+ else
+ {
+ arg = "unknown";
+ }
+
+ argv[a] = const_cast<char *>(arg);
+ }
+
+ argv[argc] = NULL;
+
+ try {
+ sipCpp->run(argc, argv);
+ } catch (gmx::InconsistentInputError &e) {
+ sipIsErr = 1;
+ PyErr_SetString(sipException_gmx_InconsistentInputError, e.what());
+ }
+ %End
+private:
+ TrajectoryAnalysisCommandLineRunner(const TrajectoryAnalysisCommandLineRunner &other);
+};
+
--- /dev/null
+
+class TrajectoryAnalysisSettings {
+%TypeHeaderCode
+#include <gromacs/trajectoryanalysis/analysissettings.h>
+using namespace gmx;
+%End
+
+public:
+ enum {
+ efRequireTop = 1,
+ efUseTopX = 2,
+ efNoUserPBC = 16,
+ efNoUserRmPBC = 32
+ };
+
+ TrajectoryAnalysisSettings();
+ /*
+ const TimeUnitManager& timeUnitManager() const;
+ TimeUnit timeUnit();
+ const AnalysisDataPlotSettings& plotSettings() const;
+ */
+ unsigned long flags() const;
+ bool hasFlag(unsigned long flag) const;
+ bool hasPBC() const;
+ bool hasRmPBC() const;
+ int frflags() const;
+ void setFlags(unsigned long flags);
+ void setFlag(unsigned long flag, bool bSet = true);
+ void setPBC(bool bPBC);
+ void setRmPBC(bool bRmPBC);
+ void setFrameFlags(int frflags);
+private:
+ TrajectoryAnalysisSettings(const TrajectoryAnalysisSettings &other);
+};
+
+class TopologyInformation {
+%TypeHeaderCode
+#include <gromacs/trajectoryanalysis/analysissettings.h>
+using namespace gmx;
+%End
+
+private:
+ TopologyInformation(const TopologyInformation &other);
+ ~TopologyInformation();
+};
--- /dev/null
+import sys
+from gromacs import TrajectoryAnalysis
+
+class M(TrajectoryAnalysis.TrajectoryAnalysisModule):
+ def __init__(self):
+ super(M, self).__init__(b"a", b"a")
+
+ def initOptions(self, options, settings):
+ print('python: initOptions')
+ options.setDescription(b'A stupid test module')
+ #settings.setFlag(TrajectoryAnalysis.TrajectoryAnalysisSettings.efRequireTop)
+ print('python: inited')
+
+ def initAnalysis(self, settings, top):
+ print('python: initAnalysis')
+
+ def analyzeFrame(self, frnr, frame, pbc, data):
+ print('python: Analyzing frame {}, {} atoms'.format(frnr, frame.natoms))
+ #print(frame.box[0,0], frame.box[0,1], frame.box[0,2])
+ print(pbc.box[0], pbc.box[1], pbc.box[2])
+
+ def finishAnalysis(self, nframes):
+ print('python: Analyzed {} frames'.format(nframes))
+
+ def writeOutput(self):
+ print('python: writeOutput')
+
+m = M()
+
+runner = TrajectoryAnalysis.TrajectoryAnalysisCommandLineRunner(m)
+print(runner.run(sys.argv))