Header installation does not yet work.
Conflicts:
src/gromacs/CMakeLists.txt
src/gromacs/options/tests/CMakeLists.txt
src/gromacs/selection/CMakeLists.txt
src/gromacs/selection/params.cpp
src/gromacs/selection/regenerate_parser.sh
src/gromacs/selection/selcollection.h
src/gromacs/selection/selection.cpp
src/gromacs/selection/selhelp.cpp
src/gromacs/selection/sm_keywords.cpp
src/gromacs/trajana/trajana.cpp
src/gromacs/trajana/trajana.h
src/tools/CMakeLists.txt
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmakein ${CMAKE_CURRENT_BINARY_DIR}/config.h)
-add_subdirectory(gmxlib)
-add_subdirectory(mdlib)
add_subdirectory(gromacs)
add_subdirectory(kernel)
+ add_subdirectory(programs)
if(NOT GMX_FAHCORE)
add_subdirectory(tools)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+set(LIBGROMACS_SOURCES)
+add_subdirectory(legacyheaders)
+add_subdirectory(gmxlib)
+add_subdirectory(mdlib)
++add_subdirectory(analysisdata)
+add_subdirectory(errorreporting)
+add_subdirectory(fatalerror)
add_subdirectory(options)
add_subdirectory(selection)
- list(APPEND LIBGROMACS_SOURCES trajana/trajana.cpp)
+ add_subdirectory(trajectoryanalysis)
-file(GLOB GMXLIB_SOURCES */*.cpp */*/*.cpp)
-file(GLOB_RECURSE NOT_GMXLIB_SOURCES */tests/*.cpp)
-list(REMOVE_ITEM GMXLIB_SOURCES ${NOT_GMXLIB_SOURCES})
+file(GLOB LIBGROMACS_HEADERS *.h)
+install(FILES ${LIBGROMACS_HEADERS} DESTINATION ${INCL_INSTALL_DIR}/gromacs
+ COMPONENT development)
-add_library(gromacs ${GMXLIB_SOURCES})
-target_link_libraries(gromacs gmx ${GMX_EXTRA_LIBRARIES} ${THREAD_LIB})
-set_target_properties(gromacs PROPERTIES OUTPUT_NAME "gromacs${GMX_LIBS_SUFFIX}" SOVERSION ${SOVERSION} INSTALL_NAME_DIR "${LIB_INSTALL_DIR}")
+# only fiddle with assembly kernels if we're not doing OpenMM build
+if(NOT GMX_OPENMM)
+if(GMX_ASM_USEASM-NASM)
+ enable_language(ASM-NASM)
+ # if NASM is used, we need a special build command for windows...
+ FOREACH(SRC ${GMX_SSEKERNEL_ASM_SRC})
+ GET_FILENAME_COMPONENT(FILE_BASE ${SRC} NAME_WE)
+ SET(OBJ ${CMAKE_CURRENT_BINARY_DIR}/${FILE_BASE}${CMAKE_C_OUTPUT_EXTENSION})
-install(TARGETS gromacs DESTINATION ${LIB_INSTALL_DIR})
+ ADD_CUSTOM_COMMAND(OUTPUT ${OBJ}
+ MAIN_DEPENDENCY ${SRC}
+ COMMAND ${CMAKE_ASM-NASM_COMPILER} -f ${CMAKE_ASM-NASM_OBJECT_FORMAT} -o ${OBJ} ${SRC})
+
+ SET(ALL_ASM_OBJS ${ALL_ASM_OBJS} ${OBJ})
+ ENDFOREACH(SRC ${GMX_SSEKERNEL_ASM_SRC})
+ set(GMX_SSEKERNEL_ASM_SRC ${ALL_ASM_OBJS})
+else(GMX_ASM_USEASM-NASM)
+ enable_language(ASM-ATT)
+ SET(CMAKE_ASM-ATT_COMPILER ${CMAKE_C_COMPILER})
+ if(GMX_IA32_ASM)
+ set_source_files_properties(${GMX_SSEKERNEL_ASM_SRC} PROPERTIES COMPILE_FLAGS "-c -m32")
+ else()
+ set_source_files_properties(${GMX_SSEKERNEL_ASM_SRC} PROPERTIES COMPILE_FLAGS "-c -m64")
+ endif()
+endif(GMX_ASM_USEASM-NASM)
+endif(NOT GMX_OPENMM)
+
+list(APPEND LIBGROMACS_SOURCES ${GMXLIB_SOURCES} ${GMX_SSEKERNEL_ASM_SRC} ${MDLIB_SOURCES})
+
+# add target that generates version.c every time a make is run
+# only do this if we generate the version
+if (USE_VERSION_H)
+ add_custom_target(gmx_version ALL
+ COMMAND ${CMAKE_COMMAND}
+ -D Git_EXECUTABLE="${Git_EXECUTABLE}"
+ -D Git_VERSION="${Git_VERSION}"
+ -D PROJECT_VERSION="${PROJECT_VERSION}"
+ -D PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}"
+ -D VERSION_C_CMAKEIN="${CMAKE_CURRENT_SOURCE_DIR}/version.c.cmakein"
+ -D VERSION_C_OUT="${CMAKE_CURRENT_BINARY_DIR}/version.c"
+ -P ${CMAKE_SOURCE_DIR}/cmake/gmxGenerateVersionInfo.cmake
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/gmxlib
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/version.c.cmakein
+ COMMENT "Generating version information")
+ list(APPEND LIBGROMACS_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/version.c) # auto-generated
+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/version.c
+ PROPERTIES GENERATED true)
+endif (USE_VERSION_H)
+
+add_library(libgromacs ${LIBGROMACS_SOURCES})
+if (USE_VERSION_H)
+ add_dependencies(libgromacs gmx_version)
+endif (USE_VERSION_H)
+target_link_libraries(libgromacs
+ ${GMX_EXTRA_LIBRARIES} ${FFT_LIBRARIES} ${XML_LIBRARIES}
+ ${THREAD_LIB})
+set_target_properties(libgromacs PROPERTIES
+ OUTPUT_NAME "gromacs${GMX_LIBS_SUFFIX}"
+ SOVERSION ${SOVERSION}
+ INSTALL_NAME_DIR "${LIB_INSTALL_DIR}")
+
+install(TARGETS libgromacs DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libgromacs.pc.cmakein
+ ${CMAKE_CURRENT_BINARY_DIR}/libgromacs.pc @ONLY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgromacs.pc
+ DESTINATION ${LIB_INSTALL_DIR}/pkgconfig
+ RENAME "libgromacs${GMX_LIBS_SUFFIX}.pc"
+ COMPONENT development)
--- /dev/null
--- /dev/null
++file(GLOB ANALYSISDATA_SOURCES *.cpp modules/*.cpp)
++set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${ANALYSISDATA_SOURCES} PARENT_SCOPE)
IF (GTEST_FOUND)
- include_directories(${GTEST_INCLUDE_DIR})
- add_executable(options-test
- cmdlineparser.cpp option.cpp optionsassigner.cpp
- test_main.cpp)
+ include_directories(${GTEST_INCLUDE_DIRS})
+ set(UNITTEST_SOURCES cmdlineparser.cpp option.cpp optionsassigner.cpp)
+ IF (GMOCK_FOUND)
+ include_directories(${GMOCK_INCLUDE_DIRS})
+ list(APPEND UNITTEST_SOURCES
+ abstractoptionstorage.cpp test_gmock_main.cpp)
+ ELSE (GMOCK_FOUND)
+ list(APPEND UNITTEST_SOURCES test_main.cpp)
+ ENDIF (GMOCK_FOUND)
+ add_executable(options-test ${UNITTEST_SOURCES})
- target_link_libraries(options-test gromacs gmx ${GTEST_LIBRARIES})
+ target_link_libraries(options-test libgromacs ${GTEST_LIBRARIES})
+ IF (GMOCK_FOUND)
+ target_link_libraries(options-test ${GMOCK_LIBRARIES})
+ ENDIF (GMOCK_FOUND)
add_test(OptionsUnitTests options-test)
ENDIF (GTEST_FOUND)
+file(GLOB SELECTION_SOURCES *.cpp)
+set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${SELECTION_SOURCES} PARENT_SCOPE)
+
+set(SELECTION_PUBLIC_HEADERS
+ centerofmass.h
+ indexutil.h
+ nbsearch.h
+ poscalc.h
+ position.h
+ selection.h
+ selparam.h
+ selmethod.h
+ selvalue.h)
+install(FILES ${SELECTION_PUBLIC_HEADERS}
+ DESTINATION ${INCL_INSTALL_DIR}/gromacs/selection
+ COMPONENT development)
++
+ if (BUILD_TESTING)
+ add_subdirectory(tests)
+ endif (BUILD_TESTING)
#include <string2.h>
#include <vec.h>
-
-#include "position.h"
-#include "selmethod.h"
-#include "selparam.h"
+ #include "gromacs/errorreporting/errorcontext.h"
+ #include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/selection/position.h"
+#include "gromacs/selection/selmethod.h"
+#include "gromacs/selection/selparam.h"
#include "parsetree.h"
#include "position.h"
#include <futil.h>
#include <smalloc.h>
#include <string2.h>
- #include <gmx_fatal.h>
+
+ #include "gromacs/errorreporting/abstracterrorreporter.h"
+ #include "gromacs/errorreporting/errorcontext.h"
+ #include "gromacs/fatalerror/fatalerror.h"
-#include "poscalc.h"
-#include "selection.h"
-#include "selmethod.h"
+#include "gromacs/selection/poscalc.h"
+#include "gromacs/selection/selection.h"
+#include "gromacs/selection/selmethod.h"
#include "keywords.h"
#include "parsetree.h"
* need. Instead, one should write an analysis tool such that it gets all
* positions through selections.
*
- * \internal
- *
* The API is documented in more detail on a separate page:
* \ref poscalcengine.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_selection
*/
-#ifndef POSCALC_H
-#define POSCALC_H
+#ifndef GMX_SELECTION_POSCALC_H
+#define GMX_SELECTION_POSCALC_H
-#include "typedefs.h"
+#include "../legacyheaders/typedefs.h"
#ifdef __cplusplus
extern "C" {
*/
/*! \file
* \brief API for handling positions.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_selection
*/
-#ifndef POSITION_H
-#define POSITION_H
+#ifndef GMX_SELECTION_POSITION_H
+#define GMX_SELECTION_POSITION_H
-#include "typedefs.h"
+#include "../legacyheaders/types/simple.h"
#include "indexutil.h"
#include <string.h>
#include "string2.h"
- #include "gmx_fatal.h"
+
+ #include "gromacs/fatalerror/fatalerror.h"
-#include "selmethod.h"
+#include "gromacs/selection/selmethod.h"
#include "parsetree.h"
- #include "selcollection.h"
+ #include "selectioncollection-impl.h"
#include "selelem.h"
#include "symrec.h"
#include <statutil.h>
#include <string2.h>
#include <xvgr.h>
- #include <gmx_fatal.h>
- #include "gromacs/selection/poscalc.h"
++#include "gromacs/selection/position.h"
#include "gromacs/selection/selection.h"
- #include "gromacs/selection/selmethod.h"
-#include "position.h"
++#include "gromacs/selection/selvalue.h"
+
- #include "mempool.h"
- #include "selcollection.h"
#include "selelem.h"
- #include "symrec.h"
-#include "selvalue.h"
- /*!
- * \param[out] scp Pointer to a newly allocated empty selection collection.
- * \param[in] pcc Position calculation data structure to use for selection
- * position evaluation.
- * \returns 0 on success.
- */
- int
- gmx_ana_selcollection_create(gmx_ana_selcollection_t **scp,
- gmx_ana_poscalc_coll_t *pcc)
+ namespace gmx
{
- gmx_ana_selcollection_t *sc;
-
- snew(sc, 1);
- sc->rpost = NULL;
- sc->spost = NULL;
- sc->bMaskOnly = FALSE;
- sc->bVelocities = FALSE;
- sc->bForces = FALSE;
- sc->bDebugCompile = FALSE;
- sc->root = NULL;
- sc->nr = 0;
- sc->sel = NULL;
- sc->nvars = 0;
- sc->varstrs = NULL;
- sc->top = NULL;
- gmx_ana_index_clear(&sc->gall);
- sc->pcc = pcc;
- sc->mempool = NULL;
- _gmx_sel_symtab_create(&sc->symtab);
- *scp = sc;
- return 0;
- }
- /*!
- * \param[in,out] sc Selection collection to free.
- *
- * The pointer \p sc is invalid after the call.
- */
- void
- gmx_ana_selcollection_free(gmx_ana_selcollection_t *sc)
+ Selection::Selection(t_selelem *elem, const char *selstr)
{
- int i;
-
- _gmx_selelem_free_chain(sc->root);
- if (sc->sel)
- {
- for (i = 0; i < sc->nr; ++i)
- {
- gmx_ana_selection_free(sc->sel[i]);
- }
- }
- sfree(sc->sel);
- for (i = 0; i < sc->nvars; ++i)
- {
- sfree(sc->varstrs[i]);
- }
- sfree(sc->varstrs);
- gmx_ana_index_deinit(&sc->gall);
- if (sc->mempool)
- {
- _gmx_sel_mempool_destroy(sc->mempool);
- }
- _gmx_selcollection_clear_symtab(sc);
- sfree(sc);
- }
+ _sel.name = strdup(elem->name);
+ _sel.selstr = strdup(selstr);
+ gmx_ana_pos_clear(&_sel.p);
- /*!
- * \param[in,out] sc Selection collection.
- */
- void
- _gmx_selcollection_clear_symtab(gmx_ana_selcollection_t *sc)
- {
- if (sc->symtab)
+ if (elem->child->type == SEL_CONST)
{
- _gmx_sel_symtab_free(sc->symtab);
- sc->symtab = NULL;
+ gmx_ana_pos_copy(&_sel.p, elem->child->v.u.p, TRUE);
+ _sel.bDynamic = FALSE;
}
- }
-
- /*!
- * \param[in,out] sc Selection collection to modify.
- * \param[in] type Default selection reference position type
- * (one of the strings acceptable for gmx_ana_poscalc_type_from_enum()).
- *
- * Should be called before calling gmx_ana_selcollection_requires_top() or
- * gmx_ana_selcollection_parse_*().
- */
- void
- gmx_ana_selcollection_set_refpostype(gmx_ana_selcollection_t *sc,
- const char *type)
- {
- sc->rpost = type;
- }
-
- /*!
- * \param[in,out] sc Selection collection to modify.
- * \param[in] type Default selection output position type
- * (one of the strings acceptable for gmx_ana_poslcalc_type_from_enum()).
- * \param[in] bMaskOnly If TRUE, the output positions are initialized
- * using \ref POS_MASKONLY.
- *
- * If \p type is NULL, the default type is not modified.
- * Should be called before calling gmx_ana_selcollection_requires_top() or
- * gmx_ana_selcollection_parse_*().
- */
- void
- gmx_ana_selcollection_set_outpostype(gmx_ana_selcollection_t *sc,
- const char *type, gmx_bool bMaskOnly)
- {
- if (type)
+ else
{
- sc->spost = type;
- }
- sc->bMaskOnly = bMaskOnly;
- }
-
- /*!
- * \param[in,out] sc Selection collection to modify.
- * \param[in] bVelOut If TRUE, selections will also evaluate
- * velocities.
- */
- void
- gmx_ana_selcollection_set_veloutput(gmx_ana_selcollection_t *sc,
- gmx_bool bVelOut)
- {
- sc->bVelocities = bVelOut;
- }
-
- /*!
- * \param[in,out] sc Selection collection to modify.
- * \param[in] bForceOut If TRUE, selections will also evaluate
- * forces.
- */
- void
- gmx_ana_selcollection_set_forceoutput(gmx_ana_selcollection_t *sc,
- gmx_bool bForceOut)
- {
- sc->bForces = bForceOut;
- }
+ t_selelem *child;
- /*!
- * \param[in,out] sc Selection collection to set the topology for.
- * \param[in] top Topology data.
- * \param[in] natoms Number of atoms. If <=0, the number of atoms in the
- * topology is used.
- * \returns 0 on success, EINVAL if \p top is NULL and \p natoms <= 0.
- *
- * The topology is also set for the position calculation collection
- * associated with \p sc.
- *
- * \p natoms determines the largest atom index that can be selected by the
- * selection: even if the topology contains more atoms, they will not be
- * selected.
- */
- int
- gmx_ana_selcollection_set_topology(gmx_ana_selcollection_t *sc, t_topology *top,
- int natoms)
- {
- gmx_ana_poscalc_coll_set_topology(sc->pcc, top);
- sc->top = top;
-
- /* Get the number of atoms from the topology if it is not given */
- if (natoms <= 0)
- {
- if (!sc->top)
+ child = elem->child;
+ child->flags &= ~SEL_ALLOCVAL;
+ _gmx_selvalue_setstore(&child->v, &_sel.p);
+ /* We should also skip any modifiers to determine the dynamic
+ * status. */
+ while (child->type == SEL_MODIFIER)
{
- gmx_incons("selections need either the topology or the number of atoms");
- return EINVAL;
+ child = child->child;
+ if (child->type == SEL_SUBEXPRREF)
+ {
+ child = child->child;
+ /* Because most subexpression elements are created
+ * during compilation, we need to check for them
+ * explicitly here.
+ */
+ if (child->type == SEL_SUBEXPR)
+ {
+ child = child->child;
+ }
+ }
}
- natoms = sc->top->atoms.nr;
- }
- gmx_ana_index_init_simple(&sc->gall, natoms, NULL);
- return 0;
- }
-
- /*!
- * \param[in] sc Selection collection to query.
- * \returns Number of selections in \p sc.
- *
- * If gmx_ana_selcollection_parse_*() has not been called, returns 0.
- *
- * \see gmx_ana_selcollection_get_selection()
- */
- int
- gmx_ana_selcollection_get_count(gmx_ana_selcollection_t *sc)
- {
- return sc->nr;
- }
-
- /*!
- * \param[in] sc Selection collection to query.
- * \param[in] i Number of the selection.
- * \returns Pointer to the \p i'th selection in \p sc,
- * or NULL if there is no such selection.
- *
- * \p i should be between 0 and the value returned by
- * gmx_ana_selcollection_get_count().
- * The returned pointer should not be freed.
- * If gmx_ana_selcollection_compile() has not been called, the returned
- * selection is not completely initialized (but the returned pointer will be
- * valid even after compilation, and will point to the initialized selection).
- *
- * \see gmx_ana_selcollection_get_count()
- */
- gmx_ana_selection_t *
- gmx_ana_selcollection_get_selection(gmx_ana_selcollection_t *sc, int i)
- {
- if (i < 0 || i >= sc->nr || !sc->sel)
- return NULL;
- return sc->sel[i];
- }
-
- /*!
- * \param[in] sc Selection collection to query.
- * \returns TRUE if any selection in \p sc requires topology information,
- * FALSE otherwise.
- *
- * Before gmx_ana_selcollection_parse_*(), the return value is based just on
- * the position types set.
- * After gmx_ana_selcollection_parse_*(), the return value also takes into account the
- * selection keywords used.
- */
- gmx_bool
- gmx_ana_selcollection_requires_top(gmx_ana_selcollection_t *sc)
- {
- t_selelem *sel;
- e_poscalc_t type;
- int flags;
- int rc;
-
- if (sc->rpost)
- {
- flags = 0;
- rc = gmx_ana_poscalc_type_from_enum(sc->rpost, &type, &flags);
- if (rc == 0 && type != POS_ATOM)
- {
- return TRUE;
- }
- }
- if (sc->spost)
- {
- flags = 0;
- rc = gmx_ana_poscalc_type_from_enum(sc->spost, &type, &flags);
- if (rc == 0 && type != POS_ATOM)
+ /* For variable references, we should skip the
+ * SEL_SUBEXPRREF and SEL_SUBEXPR elements. */
+ if (child->type == SEL_SUBEXPRREF)
{
- return TRUE;
+ child = child->child->child;
}
+ _sel.bDynamic = (child->child->flags & SEL_DYNAMIC);
}
-
- sel = sc->root;
- while (sel)
- {
- if (_gmx_selelem_requires_top(sel))
- {
- return TRUE;
- }
- sel = sel->next;
- }
- return FALSE;
+ /* The group will be set after compilation */
+ _sel.m = NULL;
+ _sel.q = NULL;
+ _sel.g = NULL;
+ _sel.orgm = NULL;
+ _sel.orgq = NULL;
+ _sel.selelem = elem;
+ initCoveredFraction(CFRAC_NONE);
}
- /*!
- * \param[in] fp File handle to receive the output.
- * \param[in] sc Selection collection to print.
- * \param[in] bValues If TRUE, the evaluated values of selection elements
- * are printed as well.
- */
- void
- gmx_ana_selcollection_print_tree(FILE *fp, gmx_ana_selcollection_t *sc, gmx_bool bValues)
- {
- t_selelem *sel;
- sel = sc->root;
- while (sel)
- {
- _gmx_selelem_print_tree(fp, sel, bValues, 0);
- sel = sel->next;
- }
- }
-
- /*!
- * \param[in] sel Selection to free.
- *
- * After the call, the pointer \p sel is invalid.
- */
- void
- gmx_ana_selection_free(gmx_ana_selection_t *sel)
+ Selection::~Selection()
{
- sfree(sel->name);
- sfree(sel->selstr);
- gmx_ana_pos_deinit(&sel->p);
- if (sel->m != sel->orgm)
+ sfree(_sel.name);
+ sfree(_sel.selstr);
+ gmx_ana_pos_deinit(&_sel.p);
+ if (_sel.m != _sel.orgm)
{
- sfree(sel->m);
+ sfree(_sel.m);
}
- if (sel->q != sel->orgq)
+ if (_sel.q != _sel.orgq)
{
- sfree(sel->q);
+ sfree(_sel.q);
}
- sfree(sel->orgm);
- sfree(sel->orgq);
- sfree(sel);
+ sfree(_sel.orgm);
+ sfree(_sel.orgq);
}
- /*!
- * \param[in] sel Selection whose name is needed.
- * \returns Pointer to the name of the selection.
- *
- * The return value should not be freed by the caller.
- */
- char *
- gmx_ana_selection_name(gmx_ana_selection_t *sel)
- {
- return sel->name;
- }
- /*!
- * \param[in] sel Selection for which information should be printed.
- */
void
- gmx_ana_selection_print_info(gmx_ana_selection_t *sel)
+ Selection::printInfo() const
{
- fprintf(stderr, "\"%s\" (%d position%s, %d atom%s%s)", sel->name,
- sel->p.nr, sel->p.nr == 1 ? "" : "s",
- sel->g->isize, sel->g->isize == 1 ? "" : "s",
- sel->bDynamic ? ", dynamic" : "");
+ fprintf(stderr, "\"%s\" (%d position%s, %d atom%s%s)", _sel.name,
+ _sel.p.nr, _sel.p.nr == 1 ? "" : "s",
+ _sel.g->isize, _sel.g->isize == 1 ? "" : "s",
+ _sel.bDynamic ? ", dynamic" : "");
fprintf(stderr, "\n");
}
#include <string2.h>
#include <wman.h>
-#include "selmethod.h"
+#include "gromacs/selection/selmethod.h"
+
- #include "selcollection.h"
#include "selhelp.h"
#include "symrec.h"
#include <macros.h>
#include <string2.h>
-#include "selmethod.h"
+#include "gromacs/selection/selmethod.h"
- #include "selcollection.h"
#include "symrec.h"
/*
* method.
*
* More details can be found on the page discussing
- * \ref selmethods "custom selection methods".
+ * \ref page_module_selection_custom "custom selection methods".
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_selection
*/
-#ifndef SELPARAM_H
-#define SELPARAM_H
-
-#include "typedefs.h"
+#ifndef GMX_SELECTION_SELPARAM_H
+#define GMX_SELECTION_SELPARAM_H
#include "indexutil.h"
#include "selvalue.h"
*
* There should be no need to use the data structures in this file directly
* unless implementing a custom selection routine.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_selection
*/
-#ifndef SELVALUE_H
-#define SELVALUE_H
+#ifndef GMX_SELECTION_SELVALUE_H
+#define GMX_SELECTION_SELVALUE_H
-#include "types/simple.h"
+#include "../legacyheaders/types/simple.h"
#ifdef __cplusplus
extern "C"
#include <smalloc.h>
#include <string2.h>
-
-#include "selmethod.h"
+ #include "gromacs/errorreporting/errorcontext.h"
+ #include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/selection/selmethod.h"
#include "keywords.h"
#include "parsetree.h"
--- /dev/null
- target_link_libraries(selection-test gromacs gmx ${GTEST_LIBRARIES})
+ IF (GTEST_FOUND)
+ include_directories(${GTEST_INCLUDE_DIRS})
+ add_executable(selection-test
+ selectioncollection.cpp selectionoption.cpp
+ test_main.cpp)
++ target_link_libraries(selection-test libgromacs ${GTEST_LIBRARIES})
+ add_test(SelectionUnitTests selection-test)
+ ENDIF (GTEST_FOUND)
--- /dev/null
++file(GLOB TRAJECTORYANALYSIS_SOURCES *.cpp modules/*.cpp)
++set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TRAJECTORYANALYSIS_SOURCES} PARENT_SCOPE)
++
+ if (BUILD_TESTING)
+ add_subdirectory(tests)
+ endif (BUILD_TESTING)
--- /dev/null
- SelectionCollection *_selections;
+ /*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * If you want to redistribute modifications, 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 www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+ /*! \internal \file
+ * \brief
+ * Declares private implementation classes for gmx::TrajectoryAnalysisModule
+ * and gmx::TrajectoryAnalysisModuleData.
+ *
+ * \ingroup module_trajectoryanalysis
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ */
+ #ifndef GMX_TRAJECTORYANALYSIS_ANALYSISMODULE_IMPL_H
+ #define GMX_TRAJECTORYANALYSIS_ANALYSISMODULE_IMPL_H
+
+ #include <map>
+ #include <string>
+ #include <vector>
+
+ #include "analysismodule.h"
+
+ namespace gmx
+ {
+
+ class AbstractAnalysisData;
+ class AnalysisData;
+ class AnalysisDataHandle;
+
+ class TrajectoryAnalysisModuleData::Impl
+ {
+ public:
+ typedef std::map<std::string, AnalysisDataHandle *> HandleContainer;
+
+ Impl() : _selections(NULL) {}
+ ~Impl();
+
+ int finishHandles();
+
+ HandleContainer _handles;
++ const SelectionCollection *_selections;
+ };
+
+ class TrajectoryAnalysisModule::Impl
+ {
+ public:
+ typedef std::map<std::string, AbstractAnalysisData *> DatasetContainer;
+ typedef std::map<std::string, AnalysisData *> AnalysisDatasetContainer;
+
+ std::vector<std::string> _datasetNames;
+ DatasetContainer _datasets;
+ AnalysisDatasetContainer _analysisDatasets;
+ };
+
+ /*! \internal \brief
+ * Basic thread-local trajectory analysis data storage class.
+ *
+ * Most simple tools should only require data handles and selections to be
+ * thread-local, so this class implements just that.
+ */
+ class TrajectoryAnalysisModuleDataBasic : public TrajectoryAnalysisModuleData
+ {
+ public:
+ virtual int finish();
+ };
+
+ } // namespace gmx
+
+ #endif
--- /dev/null
+ /*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * If you want to redistribute modifications, 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 www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+ /*! \internal \file
+ * \brief
+ * Implements gmx::TrajectoryAnalysisRunnerCommon.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ */
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+
+ #include <cassert>
++#include <string.h>
+
+ #include <rmpbc.h>
+ #include <smalloc.h>
+ #include <statutil.h>
+ #include <tpxio.h>
+ #include <vec.h>
+
+ #include "gromacs/fatalerror/fatalerror.h"
+ #include "gromacs/options/basicoptions.h"
+ #include "gromacs/options/globalproperties.h"
+ #include "gromacs/options/options.h"
+ #include "gromacs/selection/indexutil.h"
+ #include "gromacs/selection/selectioncollection.h"
+ #include "gromacs/trajectoryanalysis/analysissettings.h"
+ #include "gromacs/trajectoryanalysis/runnercommon.h"
+
+ #include "analysissettings-impl.h"
+
+ namespace gmx
+ {
+
+ class TrajectoryAnalysisRunnerCommon::Impl
+ {
+ public:
+ Impl(TrajectoryAnalysisSettings *settings);
+ ~Impl();
+
+ void finishTrajectory();
+
+ TrajectoryAnalysisSettings &_settings;
+ Options _options;
+ TopologyInformation _topInfo;
+
+ bool _bHelp;
+ bool _bShowHidden;
+ bool _bQuiet;
+ //! Name of the trajectory file (empty if not provided).
+ std::string _trjfile;
+ //! Name of the topology file (empty if no topology provided).
+ std::string _topfile;
+ //! Name of the index file (empty if no index file provided).
+ std::string _ndxfile;
+ double _startTime;
+ double _endTime;
+ double _deltaTime;
+
+ gmx_ana_indexgrps_t *_grps;
+ bool _bTrajOpen;
+ //! The current frame, or \p NULL if no frame loaded yet.
+ t_trxframe *fr;
+ gmx_rmpbc_t _gpbc;
+ //! Used to store the status variable from read_first_frame().
+ t_trxstatus *_status;
+ output_env_t _oenv;
+ };
+
+
+ TrajectoryAnalysisRunnerCommon::Impl::Impl(TrajectoryAnalysisSettings *settings)
+ : _settings(*settings), _options("common", "Common analysis control"),
+ _bHelp(false), _bShowHidden(false), _bQuiet(false),
+ _startTime(0.0), _endTime(0.0), _deltaTime(0.0),
+ _grps(NULL),
+ _bTrajOpen(false), fr(NULL), _gpbc(NULL), _status(NULL), _oenv(NULL)
+ {
+ }
+
+
+ TrajectoryAnalysisRunnerCommon::Impl::~Impl()
+ {
+ if (_grps != NULL)
+ {
+ gmx_ana_indexgrps_free(_grps);
+ }
+ finishTrajectory();
+ if (fr)
+ {
+ // There doesn't seem to be a function for freeing frame data
+ sfree(fr->x);
+ sfree(fr->v);
+ sfree(fr->f);
+ sfree(fr);
+ }
+ }
+
+
+ void
+ TrajectoryAnalysisRunnerCommon::Impl::finishTrajectory()
+ {
+ if (_bTrajOpen)
+ {
+ close_trx(_status);
+ _bTrajOpen = false;
+ }
+ if (_gpbc != NULL)
+ {
+ gmx_rmpbc_done(_gpbc);
+ _gpbc = NULL;
+ }
+ }
+
+ /*********************************************************************
+ * TrajectoryAnalysisRunnerCommon
+ */
+
+ TrajectoryAnalysisRunnerCommon::TrajectoryAnalysisRunnerCommon(
+ TrajectoryAnalysisSettings *settings)
+ : _impl(new Impl(settings))
+ {
+ }
+
+
+ TrajectoryAnalysisRunnerCommon::~TrajectoryAnalysisRunnerCommon()
+ {
+ delete _impl;
+ }
+
+
+ Options *
+ TrajectoryAnalysisRunnerCommon::initOptions()
+ {
+ TrajectoryAnalysisSettings &settings = _impl->_settings;
+ Options &options = _impl->_options;
+
+ // Add options for help.
+ options.addOption(BooleanOption("h").store(&_impl->_bHelp)
+ .description("Print help and quit"));
+ options.addOption(BooleanOption("hidden").store(&_impl->_bShowHidden)
+ .hidden()
+ .description("Show hidden options"));
+ options.addOption(BooleanOption("quiet").store(&_impl->_bQuiet)
+ .hidden()
+ .description("Hide options in normal run"));
+
+ // Add common file name arguments.
+ options.addOption(FileNameOption("f")
+ .filetype(eftTrajectory).readOnly()
+ .store(&_impl->_trjfile)
+ .description("Input trajectory"));
+ options.addOption(FileNameOption("s")
+ .filetype(eftTopology).readOnly()
+ .store(&_impl->_topfile)
+ .description("Input topology"));
+ options.addOption(FileNameOption("n")
+ .filetype(eftIndex).readOnly()
+ .store(&_impl->_ndxfile)
+ .description("Extra index groups"));
+
+ // Add options for trajectory time control.
+ options.addOption(DoubleOption("b").store(&_impl->_startTime).timeValue()
+ .description("First frame (%t) to read from trajectory"));
+ options.addOption(DoubleOption("e").store(&_impl->_endTime).timeValue()
+ .description("Last frame (%t) to read from trajectory"));
+ options.addOption(DoubleOption("dt").store(&_impl->_deltaTime).timeValue()
+ .description("Only use frame if t MOD dt == first time (%t)"));
+
+ // Add common options for trajectory processing.
+ if (!settings.hasFlag(TrajectoryAnalysisSettings::efNoUserRmPBC))
+ {
+ options.addOption(BooleanOption("rmpbc").store(&settings._impl->bRmPBC)
+ .description("Make molecules whole for each frame"));
+ }
+ if (!settings.hasFlag(TrajectoryAnalysisSettings::efNoUserPBC))
+ {
+ options.addOption(BooleanOption("pbc").store(&settings._impl->bPBC)
+ .description("Use periodic boundary conditions for distance calculation"));
+ }
+
+ return &_impl->_options;
+ }
+
+
+ int
+ TrajectoryAnalysisRunnerCommon::initOptionsDone()
+ {
+ if (_impl->_bHelp)
+ {
+ // TODO: Proper error code for graceful exit
+ return -1;
+ }
+
+ if (_impl->_trjfile.empty() && _impl->_topfile.empty())
+ {
+ GMX_ERROR(eeInconsistentInput,
+ "No trajectory or topology provided, nothing to do!");
+ }
+
+ if (_impl->_options.isSet("b"))
+ setTimeValue(TBEGIN, _impl->_startTime);
+ if (_impl->_options.isSet("e"))
+ setTimeValue(TEND, _impl->_endTime);
+ if (_impl->_options.isSet("dt"))
+ setTimeValue(TDELTA, _impl->_deltaTime);
+
+ return 0;
+ }
+
+
+ int
+ TrajectoryAnalysisRunnerCommon::initIndexGroups(SelectionCollection *selections)
+ {
+ int rc = 0;
+
+ if (_impl->_ndxfile.empty())
+ {
+ // TODO: Initialize default selections
+ selections->setIndexGroups(NULL);
+ }
+ else
+ {
+ gmx_ana_indexgrps_init(&_impl->_grps, NULL, _impl->_ndxfile.c_str());
+ rc = selections->setIndexGroups(_impl->_grps);
+ }
+ return rc;
+ }
+
+
+ void
+ TrajectoryAnalysisRunnerCommon::doneIndexGroups(SelectionCollection *selections)
+ {
+ if (_impl->_grps != NULL)
+ {
+ selections->setIndexGroups(NULL);
+ gmx_ana_indexgrps_free(_impl->_grps);
+ _impl->_grps = NULL;
+ }
+ }
+
+
+ int
+ TrajectoryAnalysisRunnerCommon::initTopology(SelectionCollection *selections)
+ {
+ const TrajectoryAnalysisSettings &settings = _impl->_settings;
+ bool bRequireTop
+ = settings.hasFlag(TrajectoryAnalysisSettings::efRequireTop)
+ || selections->requiresTopology();
+ if (bRequireTop && _impl->_topfile.empty())
+ {
+ GMX_ERROR(eeInconsistentInput,
+ "No topology provided, but one is required for analysis");
+ }
+
+ // Load the topology if requested.
+ if (!_impl->_topfile.empty())
+ {
+ char title[STRLEN];
+
+ snew(_impl->_topInfo._top, 1);
+ _impl->_topInfo._bTop = read_tps_conf(_impl->_topfile.c_str(), title,
+ _impl->_topInfo._top, &_impl->_topInfo._ePBC,
+ &_impl->_topInfo._xtop, NULL, _impl->_topInfo._boxtop, TRUE);
+ if (hasTrajectory()
+ && !settings.hasFlag(TrajectoryAnalysisSettings::efUseTopX))
+ {
+ sfree(_impl->_topInfo._xtop);
+ _impl->_topInfo._xtop = NULL;
+ }
+ }
+
+ // Read the first frame if we don't know the maximum number of atoms
+ // otherwise.
+ int natoms = -1;
+ if (!_impl->_topInfo.hasTopology())
+ {
+ int rc = initFirstFrame();
+ if (rc != 0)
+ {
+ return rc;
+ }
+ natoms = _impl->fr->natoms;
+ }
+ int rc = selections->setTopology(_impl->_topInfo.topology(), natoms);
+ if (rc != 0)
+ {
+ return rc;
+ }
+
+ /*
+ if (_impl->bSelDump)
+ {
+ gmx_ana_poscalc_coll_print_tree(stderr, _impl->pcc);
+ fprintf(stderr, "\n");
+ }
+ */
+
+ return 0;
+ }
+
+
+ int
+ TrajectoryAnalysisRunnerCommon::initFirstFrame()
+ {
+ // Return if we have already initialized the trajectory.
+ if (_impl->fr)
+ {
+ return 0;
+ }
+ _impl->_oenv = _impl->_options.globalProperties().output_env();
+
+ int frflags = _impl->_settings.frflags();
+ frflags |= TRX_NEED_X;
+
+ snew(_impl->fr, 1);
+
+ const TopologyInformation &top = _impl->_topInfo;
+ if (hasTrajectory())
+ {
+ if (!read_first_frame(_impl->_oenv, &_impl->_status,
+ _impl->_trjfile.c_str(), _impl->fr, frflags))
+ {
+ GMX_ERROR(eeFileNotFound,
+ "Could not read coordinates from trajectory");
+ }
+ _impl->_bTrajOpen = true;
+
+ if (top.hasTopology() && _impl->fr->natoms > top.topology()->atoms.nr)
+ {
+ fatalErrorFormatted(eeInconsistentInput, GMX_ERRORLOC,
+ "Trajectory (%d atoms) does not match topology (%d atoms)",
+ _impl->fr->natoms, top.topology()->atoms.nr);
+ return eeInconsistentInput;
+ }
+ // Check index groups if they have been initialized based on the topology.
+ /*
+ if (top)
+ {
+ for (int i = 0; i < _impl->sel->nr(); ++i)
+ {
+ gmx_ana_index_check(_impl->sel->sel(i)->indexGroup(),
+ _impl->fr->natoms);
+ }
+ }
+ */
+ }
+ else
+ {
+ // Prepare a frame from topology information.
+ // TODO: Initialize more of the fields.
+ if (frflags & (TRX_NEED_V))
+ {
+ GMX_ERROR(eeNotImplemented,
+ "Velocity reading from a topology not implemented");
+ }
+ if (frflags & (TRX_NEED_F))
+ {
+ GMX_ERROR(eeInvalidInput,
+ "Forces cannot be read from a topology");
+ }
+ _impl->fr->flags = frflags;
+ _impl->fr->natoms = top.topology()->atoms.nr;
+ _impl->fr->bX = TRUE;
+ snew(_impl->fr->x, _impl->fr->natoms);
+ memcpy(_impl->fr->x, top._xtop,
+ sizeof(*_impl->fr->x) * _impl->fr->natoms);
+ _impl->fr->bBox = TRUE;
+ copy_mat(const_cast<rvec *>(top._boxtop), _impl->fr->box);
+ }
+
+ set_trxframe_ePBC(_impl->fr, top.ePBC());
+ if (top.hasTopology() && _impl->_settings.hasRmPBC())
+ {
+ _impl->_gpbc = gmx_rmpbc_init(&top.topology()->idef, top.ePBC(),
+ _impl->fr->natoms, _impl->fr->box);
+ }
+
+ return 0;
+ }
+
+
+ bool
+ TrajectoryAnalysisRunnerCommon::readNextFrame()
+ {
+ bool bContinue = FALSE;
+ if (hasTrajectory())
+ {
+ bContinue = read_next_frame(_impl->_oenv, _impl->_status, _impl->fr);
+ }
+ if (!bContinue)
+ {
+ _impl->finishTrajectory();
+ }
+ return bContinue;
+ }
+
+
+ int
+ TrajectoryAnalysisRunnerCommon::initFrame()
+ {
+ if (_impl->_gpbc != NULL)
+ {
+ gmx_rmpbc_trxfr(_impl->_gpbc, _impl->fr);
+ }
+ return 0;
+ }
+
+
+ TrajectoryAnalysisRunnerCommon::HelpFlags
+ TrajectoryAnalysisRunnerCommon::helpFlags() const
+ {
+ HelpFlags flags = 0;
+
+ if (!_impl->_bQuiet)
+ {
+ flags |= efHelpShowOptions;
+ if (_impl->_bHelp)
+ {
+ flags |= efHelpShowDescriptions;
+ }
+ if (_impl->_bShowHidden)
+ {
+ flags |= efHelpShowHidden;
+ }
+ }
+ return flags;
+ }
+
+ bool
+ TrajectoryAnalysisRunnerCommon::hasTrajectory() const
+ {
+ return !_impl->_trjfile.empty();
+ }
+
+
+ const TopologyInformation &
+ TrajectoryAnalysisRunnerCommon::topologyInformation() const
+ {
+ return _impl->_topInfo;
+ }
+
+
+ t_trxframe &
+ TrajectoryAnalysisRunnerCommon::frame() const
+ {
+ assert(_impl->fr != NULL);
+ return *_impl->fr;
+ }
+
+ } // namespace gmx
--- /dev/null
-target_link_libraries(test_selection gromacs gmx)
+ add_executable(test_selection test_selection.cpp)
++target_link_libraries(test_selection libgromacs)
--- /dev/null
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
-
+ add_subdirectory(g_ana)
--- /dev/null
-target_link_libraries(g_ana gromacs)
+ add_executable(g_ana g_ana.cpp)
++target_link_libraries(g_ana libgromacs)
+ set_target_properties(g_ana PROPERTIES OUTPUT_NAME "g_ana${GMX_BINARY_SUFFIX}")
+
+ install(TARGETS g_ana
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR})
g_helixorient g_principal g_dipoles g_disre g_dist
g_dyndom g_enemat g_energy g_lie g_filter g_gyrate
g_h2order g_hbond g_helix g_mindist g_msd g_morph g_nmeig
- g_nmens g_order g_polystat g_potential g_rama g_rdf g_rms
+ g_nmens g_order g_kinetics g_polystat g_potential g_rama g_rdf g_rms
- g_rmsf g_rotacf g_saltbr g_sas g_select g_sgangle g_sham g_sorient
+ g_rmsf g_rotacf g_saltbr g_sas g_sgangle g_sham g_sorient
g_spol g_spatial g_tcaf g_traj g_tune_pme g_vanhove
g_velacc g_clustsize g_mdmat g_wham g_sigeps g_bar
g_pme_error g_rmsdist g_rotmat)