+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2012,2013, by the GROMACS development team, led by
+# David van der Spoel, Berk Hess, 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.
+
find_package(Doxygen)
+if (DOXYGEN_FOUND)
+ # This logic closely follows that found in FindDoxygen.cmake for dot,
+ # except that the PATH variable is not cached.
+ FIND_PROGRAM(DOXYGEN_MSCGEN_EXECUTABLE
+ NAMES mscgen
+ DOC "Message sequence chart renderer tool (http://www.mcternan.me.uk/mscgen/)")
+ if (DOXYGEN_MSCGEN_EXECUTABLE)
+ set(DOXYGEN_MSCGEN_FOUND TRUE)
+ get_filename_component(DOXYGEN_MSCGEN_PATH "${DOXYGEN_MSCGEN_EXECUTABLE}" PATH)
+ endif (DOXYGEN_MSCGEN_EXECUTABLE)
+ mark_as_advanced(DOXYGEN_MSCGEN_EXECUTABLE)
+endif (DOXYGEN_FOUND)
########################################################################
# Doxygen configuration
SET(NB_KERNEL_DIRS_TO_IGNORE_IN_DOXYGEN
"${NB_KERNEL_DIRS_TO_IGNORE_IN_DOXYGEN} \\\n ${NB_KERNEL_DIR}")
ENDFOREACH(NB_KERNEL_DIR)
+ set(DOXYGEN_SECTIONS "")
CONFIGURE_FILE(Doxyfile-common.cmakein Doxyfile-common)
CONFIGURE_FILE(Doxyfile-full.cmakein Doxyfile-full)
CONFIGURE_FILE(Doxyfile-lib.cmakein Doxyfile-lib)
CONFIGURE_FILE(Doxyfile-user.cmakein Doxyfile-user)
+
FILE(COPY index.html DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+ configure_file(RunDoxygen.cmake.cmakein RunDoxygen.cmake @ONLY)
add_custom_target(doc-full
- ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile-full
+ ${CMAKE_COMMAND} -DDOCTYPE=full -P RunDoxygen.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating full documentation with Doxygen" VERBATIM)
add_custom_target(doc-lib
- ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile-lib
+ ${CMAKE_COMMAND} -DDOCTYPE=lib -P RunDoxygen.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating library documentation with Doxygen" VERBATIM)
add_custom_target(doc-user
- ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile-user
+ ${CMAKE_COMMAND} -DDOCTYPE=user -P RunDoxygen.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating user documentation with Doxygen" VERBATIM)
add_custom_target(doc-all)
@CMAKE_SOURCE_DIR@/src/gromacs/legacyheaders
HAVE_DOT = @DOXYGEN_DOT_FOUND@
DOT_PATH = @DOXYGEN_DOT_PATH@
+MSCGEN_PATH = @DOXYGEN_MSCGEN_PATH@
+
+ENABLED_SECTIONS = @DOXYGEN_SECTIONS@
# This is for thread_mpi to #ifdef some code out that should not be documented.
PREDEFINED = DOXYGEN
EXPAND_ONLY_PREDEF = YES
PREDEFINED += F77_FUNC(name,NAME)=name
-ENABLED_SECTIONS = libapi internal
+ENABLED_SECTIONS += libapi internal
INTERNAL_DOCS = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
@INCLUDE = Doxyfile-common
-ENABLED_SECTIONS = libapi
+ENABLED_SECTIONS += libapi
INTERNAL_DOCS = NO
HIDE_UNDOC_CLASSES = YES
WARN_LOGFILE = doxygen-lib.log
@INCLUDE = Doxyfile-common
-ENABLED_SECTIONS =
INTERNAL_DOCS = NO
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = YES
--- /dev/null
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2013, by the GROMACS development team, led by
+# David van der Spoel, Berk Hess, 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.
+
+set(DOXYGEN_EXECUTABLE @DOXYGEN_EXECUTABLE@)
+set(DOXYGEN_MSCGEN_FOUND @DOXYGEN_MSCGEN_FOUND@)
+
+message("Running Doxygen...")
+# The standard output shows a lot of progress information, but obscures errors
+# that may appear. CMake-introduced buffering also makes it appear sluggish,
+# so disable it.
+execute_process(COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile-${DOCTYPE}
+ OUTPUT_QUIET)
+file(READ doxygen-${DOCTYPE}.log DOXYGEN_WARNINGS)
+string(STRIP "${DOXYGEN_WARNINGS}" DOXYGEN_WARNINGS)
+if (DOXYGEN_WARNINGS)
+ message("The following warnings were produced by Doxygen:")
+ message(${DOXYGEN_WARNINGS})
+endif ()
+if (NOT DOXYGEN_MSCGEN_FOUND)
+ message("NOTE: mscgen was not available. "
+ "Please install it to produce graphs in the documentation.")
+endif ()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2012, by the GROMACS development team, led by
+ * Copyright (c) 2010,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and 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.
*/
-/*! \defgroup module_analysisdata Parallelizable Handling of Output Data
+/*! \defgroup module_analysisdata Parallelizable Handling of Output Data (analysisdata)
* \ingroup group_analysismodules
* \brief
* Provides functionality for handling and processing output data from
* frames is collected and output in the correct order.
*
* This module consists of two main parts. The first is formed by the
- * AbstractAnalysisData class and classes that derive from it:
- * AnalysisData and AnalysisArrayData. These classes are used to process and
- * store raw data as produced by the analysis tool. They also provide an
- * interface to attach data modules that implement AnalysisDataModuleInterface.
+ * gmx::AbstractAnalysisData class and classes that derive from it:
+ * gmx::AnalysisData and gmx::AnalysisArrayData. These classes are used to
+ * process and store raw data as produced by the analysis tool. They also
+ * provide an interface to attach data modules that implement
+ * gmx::AnalysisDataModuleInterface.
* Modules that implement this interface form the second part of the module,
* and they provide functionality to do processing operations on the data.
- * These modules can also derive from AbstractAnalysisData, allowing other
+ * These modules can also derive from gmx::AbstractAnalysisData, allowing other
* modules to be attached to them to form a processing chain that best suits
* the analysis tool. Typically, such a processing chain ends in a plotting
* module that writes the data into a file, but the final module can also
* provide direct access to the processed data, allowing the analysis tool to
* do custom postprocessing outside the module framework.
*
+ * The sequence chart below shows an overview of how analysis data objects
+ * and modules interact (currently, multipoint data is an exception to this
+ * diagram).
+ * \msc
+ * caller,
+ * data [ label="AnalysisData", URL="\ref gmx::AnalysisData" ],
+ * module1 [ label="data module", URL="\ref gmx::AnalysisDataModuleInterface" ];
+ *
+ * caller box module1 [ label="caller creates and initializes all objects" ];
+ * caller => data [ label="addModule(module1)",
+ * URL="\ref gmx::AbstractAnalysisData::addModule() " ];
+ * caller => data [ label="startData()",
+ * URL="\ref gmx::AnalysisData::startData()" ];
+ * data => module1 [ label="dataStarted()",
+ * URL="\ref gmx::AnalysisDataModuleInterface::dataStarted()" ];
+ * caller << data [ label="handle",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * caller => data [ label="handle->startFrame(0)",
+ * URL="\ref gmx::AnalysisDataHandle::startFrame()" ];
+ * caller => data [ label="add data for frame 0",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * caller => data [ label="handle->finishFrame() (frame 0)",
+ * URL="\ref gmx::AnalysisDataHandle::finishFrame()" ];
+ * data => module1 [ label="frameStarted(0)",
+ * URL="\ref gmx::AnalysisDataModuleInterface::frameStarted()" ];
+ * data => module1 [ label="pointsAdded()",
+ * URL="\ref gmx::AnalysisDataModuleInterface::pointsAdded()" ];
+ * data => module1 [ label="frameFinished(0)",
+ * URL="\ref gmx::AnalysisDataModuleInterface::frameFinished()" ];
+ * caller => data [ label="handle->startFrame(1)",
+ * URL="\ref gmx::AnalysisDataHandle::startFrame()" ];
+ * caller => data [ label="add data for frame 1",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * caller => data [ label="handle2->finishFrame() (frame 1)",
+ * URL="\ref gmx::AnalysisDataHandle::finishFrame()" ];
+ * data => module1 [ label="process frame 1" ];
+ * ... [ label="add more frames" ];
+ * caller => data [ label="handle->finishData()",
+ * URL="\ref gmx::AnalysisDataHandle::finishData()" ];
+ * data => module1 [ label="dataFinished()",
+ * URL="\ref gmx::AnalysisDataModuleInterface::dataFinished()" ];
+ * \endmsc
+ *
+ * The second sequence chart below shows the interaction in the case of two
+ * gmx::AnalysisDataHandle objects, which can be used to insert data
+ * concurrently for multiple frames. The gmx::AnalysisData object and the
+ * handles take care to notify the module such that it always receives the
+ * frames in the correct order.
+ * \msc
+ * caller,
+ * handle1 [ label="handle1", URL="\ref gmx::AnalysisDataHandle" ],
+ * handle2 [ label="handle2", URL="\ref gmx::AnalysisDataHandle" ],
+ * module1 [ label="data module", URL="\ref gmx::AnalysisDataModuleInterface" ];
+ *
+ * caller box handle2 [ label="caller has created both handles using startData()" ];
+ * caller => handle1 [ label="startFrame(0)",
+ * URL="\ref gmx::AnalysisDataHandle::startFrame()" ];
+ * caller => handle2 [ label="startFrame(1)",
+ * URL="\ref gmx::AnalysisDataHandle::startFrame()" ];
+ * caller => handle1 [ label="add data for frame 0",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * caller => handle2 [ label="add data for frame 1",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * caller => handle2 [ label="finishFrame() (frame 1)",
+ * URL="\ref gmx::AnalysisDataHandle::finishFrame()" ];
+ * caller => handle2 [ label="startFrame(2)",
+ * URL="\ref gmx::AnalysisDataHandle::startFrame()" ];
+ * caller => handle1 [ label="finishFrame() (frame 0)",
+ * URL="\ref gmx::AnalysisDataHandle::finishFrame()" ];
+ * handle1 => module1 [ label="process frame 0" ];
+ * handle1 => module1 [ label="process frame 1" ];
+ * caller => handle2 [ label="add data for frame 2",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * caller => handle2 [ label="finishFrame() (frame 2)",
+ * URL="\ref gmx::AnalysisDataHandle::finishFrame()" ];
+ * handle2 => module1 [ label="process frame 2" ];
+ * ...;
+ * caller => handle1 [ label="finishData()",
+ * URL="\ref gmx::AnalysisDataHandle::finishData()" ];
+ * caller => handle2 [ label="finishData()",
+ * URL="\ref gmx::AnalysisDataHandle::finishData()" ];
+ * handle2 => module1 [ label="dataFinished()",
+ * URL="\ref gmx::AnalysisDataModuleInterface::dataFinished()" ];
+ * \endmsc
+ *
* <H3>Using Data Objects and Modules</H3>
*
* To use the functionality in this module, you typically declare one or more
* AnalysisData objects and set its properties. You then create some module
* objects and set their properties (see the list of classes that implement
- * AnalysisDataModuleInterface) and attach them to the data objects or to one
- * another using AbstractAnalysisData::addModule(). Then you add the actual
- * data values to the AnalysisData object, which automatically passes it on to
- * the modules. After all data is added, you may optionally access some
+ * gmx::AnalysisDataModuleInterface) and attach them to the data objects or to
+ * one another using gmx::AbstractAnalysisData::addModule(). Then you add the
+ * actual data values to the gmx::AnalysisData object, which automatically
+ * passes it on to the modules.
+ * After all data is added, you may optionally access some
* results directly from the module objects. However, in many cases it is
* sufficient to initially add a plotting module to the processing chain, which
* will then automatically write the results into a file.
*
* For simple processing needs with a small amount of data, an
- * AnalysisArrayData class is also provided, which keeps all the data in an
+ * gmx::AnalysisArrayData class is also provided, which keeps all the data in an
* in-memory array and allows you to manipulate the data as you wish before you
* pass the data to the attached modules.
*
*
* New data modules can be implemented to perform custom operations that are
* not supported by the modules provided in this module. This is done by
- * creating a new class that implements AnalysisDataModuleInterface.
+ * creating a new class that implements gmx::AnalysisDataModuleInterface.
* If the new module computes values that can be used as input for other
- * modules, the new class should also derive from AbstractAnalysisData, and
- * preferably use AnalysisDataStorage internally to implement storage of
+ * modules, the new class should also derive from gmx::AbstractAnalysisData, and
+ * preferably use gmx::AnalysisDataStorage internally to implement storage of
* values. See the documentation of the mentioned classes for more details on
* how to implement custom modules.
* When implementing a new module, it should be considered whether it can be of
* more general use, and if so, it should be added to this module.
*
* It is also possible to implement new data source objects by deriving a class
- * from AbstractAnalysisData. This should not normally be necessary, since
+ * from gmx::AbstractAnalysisData. This should not normally be necessary, since
* this module provides general data source objects for most typical uses.
* If the classes in this module are not suitable for some specific use, it
* should be considered whether a new generic class could be added (or an
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and 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.
*/
-/*! \defgroup module_options Extensible Handling of Options
+/*! \defgroup module_options Extensible Handling of Options (options)
* \ingroup group_utilitymodules
* \brief
* Provides functionality for handling options.
* descriptions for individual options as well as for the whole set of options.
* These can then be used to write out help text.
*
+ * The sequence charts below provides an overview of how the options work from
+ * usage perspective. They include two fictional modules, A and B, that provide
+ * options, and a main routine that manages these. The first chart shows a
+ * typical initialization sequence, where the main routine creates an options
+ * object, and calls an initOptions() method in each module that can provide
+ * options (the modules may also request their submodules to add their own
+ * options). Each module uses gmx::Options::addOption() to add the options
+ * they require, and specify output variables into which the options values are
+ * stored.
+ * \msc
+ * main,
+ * options [ label="Options", URL="\ref gmx::Options" ],
+ * A [ label="module A" ],
+ * B [ label="module B" ];
+ *
+ * main box B [ label="main owns all objects" ];
+ * main => options [ label="create", URL="\ref gmx::Options::Options()" ];
+ * main => A [ label="initOptions()" ];
+ * A => options [ label="addOption()", URL="\ref gmx::Options::addOption()" ];
+ * ...;
+ * main << A;
+ * main => B [ label="initOptions()" ];
+ * B => options [ label="addOption()", URL="\ref gmx::Options::addOption()" ];
+ * ...;
+ * main << B;
+ * \endmsc
+ *
+ * After all options have been specified, they can be parsed. A parser splits
+ * the input into option-value pairs (one option may have multiple values), and
+ * passes these into the gmx::Options object, which is responsible for
+ * converting them into the appropriate types and storing the values into the
+ * variables provided in the calls to gmx::Options::addOption().
+ * \msc
+ * main,
+ * parser [ label="parser" ],
+ * options [ label="Options", URL="\ref gmx::Options" ],
+ * A [ label="module A" ],
+ * B [ label="module B" ];
+ *
+ * main => parser [ label="parse()" ];
+ * parser => options [ label="assign(string)" ];
+ * options -> A [ label="set variable" ];
+ * parser => options [ label="assign(string)" ];
+ * options -> B [ label="set variable" ];
+ * ...;
+ * \endmsc
+ *
+ * After all options have been parsed (possibly using multiple different
+ * parsers), gmx::Options::finish() is called. This performs final
+ * validation of the options and may further adjust the values stored in the
+ * output variables (see documentation on individual option types on when this
+ * may happen).
+ * \msc
+ * main,
+ * options [ label="Options", URL="\ref gmx::Options" ],
+ * A [ label="module A" ],
+ * B [ label="module B" ];
+ *
+ * main => options [ label="finish()", URL="\ref gmx::Options::finish()" ];
+ * options -> A [ label="set variable" ];
+ * options -> B [ label="set variable" ];
+ * ...;
+ * \endmsc
+ *
* Module \ref module_commandline implements classes that assign option values
* from command line and produce help for programs that use the command line
* parser.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and 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.
*/
-/*! \defgroup module_trajectoryanalysis Framework for Trajectory Analysis
+/*! \defgroup module_trajectoryanalysis Framework for Trajectory Analysis (trajectoryanalysis)
* \ingroup group_analysismodules
* \brief
* Provides functionality for implementing trajectory analysis modules.
* be used in advanced scenarios where the tool requires custom thread-local
* data for parallel analysis.
*
+ * The sequence charts below provides an overview of how the trajectory
+ * analysis modules typically interact with other components.
+ * The first chart provides an overview of the call sequence of the most
+ * important methods in gmx::TrajectoryAnalysisModule.
+ * There is a runner, which is responsible for doing the work that is shared
+ * between all trajectory analysis (such as reading the trajectory and
+ * processing selections). The runner then calls different methods in the
+ * analysis module at appropriate points to perform the module-specific tasks.
+ * The analysis module is responsible for creating and managing
+ * gmx::AnalysisData objects, and the chart shows the most important
+ * interactions with this module as well. Interactions with options (for
+ * command-line option processing) and selections is not shown for brevity: see
+ * \ref module_options for an overview of how options work, and the second
+ * chart for a more detailed view of how selections are accessed from an
+ * analysis module.
+ * \msc
+ * runner,
+ * module [ URL="\ref gmx::TrajectoryAnalysisModule" ],
+ * data [ label="analysis data", URL="\ref module_analysisdata" ];
+ *
+ * runner box module [ label="caller owns runner and module objects" ];
+ * module => data [ label="create (in constructor)" ];
+ * runner => module [ label="initOptions()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::initOptions()" ];
+ * runner => runner [ label="parse user input" ];
+ * runner => module [ label="optionsFinished()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::optionsFinished()" ];
+ * runner => runner [ label="initialize topology\nand selections" ];
+ * runner => module [ label="initAnalysis()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::initAnalysis()" ];
+ * module => data [ label="initialize" ];
+ * runner => runner [ label="read frame 0" ];
+ * runner => module [ label="initAfterFirstFrame()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::initAfterFirstFrame()" ];
+ * --- [ label="loop over frames starts" ];
+ * runner => runner [ label="initialize frame 0" ];
+ * runner => module [ label="analyzeFrame(0)",
+ * URL="\ref gmx::TrajectoryAnalysisModule::analyzeFrame()" ];
+ * module => data [ label="add data",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * module => data [ label="finishFrame()",
+ * URL="\ref gmx::AnalysisDataHandle::finishFrame()" ];
+ * data => data [ label="process frame 0" ];
+ * runner => runner [ label="read and initialize frame 1" ];
+ * runner => module [ label="analyzeFrame(1)",
+ * URL="\ref gmx::TrajectoryAnalysisModule::analyzeFrame()" ];
+ * ...;
+ * --- [ label="loop over frames ends" ];
+ * runner => module [ label="finishAnalysis()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::finishAnalysis()" ];
+ * module => data [ label="post-process data" ];
+ * runner => module [ label="writeOutput()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::writeOutput()" ];
+ * \endmsc
+ *
+ * The second chart below shows the interaction with selections and options
+ * with focus on selection options. The gmx::TrajectoryAnalysisModule object
+ * creates one or more gmx::Selection variables, and uses gmx::SelectionOption
+ * to indicate them as the destination for selections. This happens in
+ * gmx::TrajectoryAnalysisModule::initOptions(). After the options have been
+ * parsed (includes parsing any options present on the command-line or read
+ * from files, but not those provided interactively),
+ * gmx::TrajectoryAnalysisModule::optionsFinished() can adjust the selections
+ * using gmx::SelectionOptionInfo. This is done like this to allow the
+ * analysis module to influence the interactive prompt of selections based on
+ * what command-line options were given. After optionsFinished() returns, the
+ * interactive selection prompt is presented if necessary. After this point,
+ * all access to selections from the analysis module is through the
+ * gmx::Selection variables: the runner is responsible for calling methods in
+ * the selection library, and these methods update the content referenced by
+ * the gmx::Selection variables. See documentation of
+ * gmx::TrajectoryAnalysisModule for details of what the selections contain at
+ * each point.
+ * \msc
+ * runner,
+ * options [ label="Options", URL="\ref module_options" ],
+ * selection [ label="selections", URL="\ref module_selection" ],
+ * module [ label="module", URL="\ref gmx::TrajectoryAnalysisModule" ];
+ *
+ * runner box selection [ label="all these objects are owned by the framework" ];
+ * runner => module [ label="initOptions()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::initOptions()" ];
+ * module => options [ label="addOption(SelectionOption)",
+ * URL="\ref gmx::SelectionOption" ];
+ * module => options [ label="addOption() (other options)",
+ * URL="\ref gmx::Options::addOption()" ];
+ * ...;
+ * runner << module;
+ * runner => options [ label="parse command-line parameters" ];
+ * options => selection [ label="parse selections" ];
+ * selection -> module [ label="initialize Selection variables",
+ * URL="\ref gmx::Selection" ];
+ * runner << options;
+ * runner => module [ label="optionsFinished()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::optionsFinished()" ];
+ * module => selection [ label="adjust SelectionOptions",
+ * URL="\ref gmx::SelectionOptionInfo" ];
+ * runner << module;
+ * runner => selection [ label="prompt missing selections" ];
+ * selection -> module [ label="initialize Selection variables",
+ * URL="\ref gmx::Selection" ];
+ * runner => selection [ label="compile selections" ];
+ * selection -> module [ label="change content referenced\nby Selection variables" ];
+ * runner => module [ label="initAnalysis()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::initAnalysis()" ];
+ * ...;
+ * --- [ label="loop over frames starts" ];
+ * runner => runner [ label="read and initialize frame 0" ];
+ * runner => selection [ label="evaluate selections for frame 0" ];
+ * selection -> module [ label="change content referenced\nby Selection variables" ];
+ * ...;
+ * \endmsc
+ *
+ * The final chart shows the flow within the frame loop in the case of parallel
+ * (threaded) execution and the interaction with the \ref module_analysisdata
+ * module in this case. Although parallelization has not yet been implemented,
+ * it has influenced the design and needs to be understood if one wants to
+ * write modules that can take advantage of the parallelization once it gets
+ * implemented. The parallelization takes part over frames: analyzing a single
+ * frame is one unit of work. When the frame loop is started,
+ * gmx::TrajectoryAnalysisModule::startFrames() is called for each thread, and
+ * initializes an object that contains thread-local data needed during the
+ * analysis. This includes selection information, gmx::AnalysisDataHandle
+ * objects, and possibly other module-specific variables. Then, the runner
+ * reads the frames in sequence and passes the work into the different threads,
+ * together with the appropriate thread-local data object.
+ * The gmx::TrajectoryAnalysisModule::analyzeFrame() calls are only allowed to modify
+ * the thread-local data object; everything else is read-only. For any output,
+ * they pass the information to gmx::AnalysisData, which takes care of ordering
+ * the data from different frames such that it gets processed in the right
+ * order.
+ * When all frames are analyzed, gmx::TrajectoryAnalysisModule::finishFrames()
+ * is called for each thread-local data object to destroy them and to
+ * accumulate possible results from them into the main
+ * gmx::TrajectoryAnalysisModule object.
+ * Note that in the diagram, some part of the work attributed for the runner
+ * (e.g., evaluating selections) will actually be carried out in the analysis
+ * threads before gmx::TrajectoryAnalysisModule::analyzeFrame() gets called.
+ * \msc
+ * runner,
+ * module [ label="module object" ],
+ * thread1 [ label="analysis\nthread 1" ],
+ * thread2 [ label="analysis\nthread 2" ],
+ * data [ label="analysis data", URL="\ref module_analysisdata" ];
+ *
+ * module box thread2 [ label="single TrajectoryAnalysisModule object",
+ * URL="\ref gmx::TrajectoryAnalysisModule" ];
+ * ...;
+ * --- [ label="loop over frames starts" ];
+ * runner => thread1 [ label="startFrames()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::startFrames()" ];
+ * thread1 => data [ label="startData()",
+ * URL="\ref gmx::AnalysisData::startData()" ];
+ * runner << thread1 [ label="pdata1" ];
+ * runner => thread2 [ label="startFrames()",
+ * URL="\ref gmx::TrajectoryAnalysisModule::startFrames()" ];
+ * thread2 => data [ label="startData()",
+ * URL="\ref gmx::AnalysisData::startData()" ];
+ * runner << thread2 [ label="pdata2" ];
+ * |||;
+ * runner => runner [ label="initialize frame 0" ];
+ * runner => thread1 [ label="analyzeFrame(0, pdata1)",
+ * URL="\ref gmx::TrajectoryAnalysisModule::analyzeFrame()" ];
+ * runner => runner [ label="read and initialize frame 1" ];
+ * runner => thread2 [ label="analyzeFrame(1, pdata2)",
+ * URL="\ref gmx::TrajectoryAnalysisModule::analyzeFrame()" ];
+ * thread1 => data [ label="add data",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * thread2 => data [ label="add data",
+ * URL="\ref gmx::AnalysisDataHandle" ];
+ * thread2 => data [ label="finishFrame(1)",
+ * URL="\ref gmx::AnalysisDataHandle::finishFrame()" ];
+ * runner << thread2 [ label="analyzeFrame() (frame 1)" ];
+ * runner => runner [ label="read and initialize frame 2" ];
+ * runner => thread2 [ label="analyzeFrame(2)",
+ * URL="\ref gmx::TrajectoryAnalysisModule::analyzeFrame()" ];
+ * thread1 => data [ label="finishFrame(0)",
+ * URL="\ref gmx::AnalysisDataHandle::finishFrame()" ];
+ * data => data [ label="process frame 0" ];
+ * data => data [ label="process frame 1" ];
+ * runner << thread1 [ label="analyzeFrame() (frame 0)" ];
+ * ...;
+ * runner => thread1 [ label="finishFrames(pdata1)",
+ * URL="\ref gmx::TrajectoryAnalysisModule::finishFrames()" ];
+ * thread1 => data [ label="finishData()",
+ * URL="\ref gmx::AnalysisData::finishData()" ];
+ * thread1 -> module [ label="accumulate results" ];
+ * runner << thread1;
+ * runner => thread2 [ label="finishFrames(pdata2)",
+ * URL="\ref gmx::TrajectoryAnalysisModule::finishFrames()" ];
+ * thread2 => data [ label="finishData()",
+ * URL="\ref gmx::AnalysisData::finishData()" ];
+ * thread2 -> module [ label="accumulate results" ];
+ * runner << thread2;
+ * --- [ label="loop over frames ends" ];
+ * ...;
+ * \endmsc
+ *
* In addition to the framework for defining analysis modules, this module also
* provides gmx::TrajectoryAnalysisCommandLineRunner, which implements a
* command-line program that runs a certain analysis module.
*
* Internally, the module also defines a set of trajectory analysis modules that
- * can be instantiated using createTrajectoryAnalysisModule().
+ * can currently be accessed only through gmx::registerTrajectoryAnalysisModules.
*
* For an example of how to implement an analysis tool using the framework, see
* \ref template.cpp.