handled by the framework).
See the documentation for gmx::TrajectoryAnalysisModule and the
[options module documentation](\ref module_options) for more details.
+
+Coordinate data output
+======================
+
+The \ref module_coordinateio module allows modules to output coordinate data
+used or generated during the analysis. It provides two main components:
+
+ - An OutputManager for handling the file opening, writing, closing and
+ registration of modules to change metainformation.
+ - A set of modules to change the metainformation in coordinate data frames
+ and to cross check the requirements for data output and file formats.
+
+More detailed information, as well as an interaction diagram can be found in the
+[module documentation](\ref module_coordinateio).
add_subdirectory(correlationfunctions)
add_subdirectory(statistics)
add_subdirectory(analysisdata)
+ add_subdirectory(coordinateio)
add_subdirectory(selection)
add_subdirectory(trajectoryanalysis)
add_subdirectory(energyanalysis)
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*! \defgroup module_coordinateio Handling of writing new coordinate files
+ * \ingroup group_analysismodules
+ * \brief
+ * Provides basic functions to handle writing of new coordinate files.
+ *
+ * The methods included in the coordinateio module implement the basics
+ * for manipulating and writing coordinate trajectory files
+ * and changing metadata in the underlying datastructures. Included are a container for storing
+ * modules that change trajectory data, as well as a manager to write output files that uses
+ * those methods. It can be used from within \ref module_trajectoryanalysis, and uses
+ * methods from:
+ * - \ref module_options
+ * - \ref module_selection
+ *
+ * <H3>Overview</H3>
+ * The methods in coordinateio provide the infrastructure to perform operations on coordinate data files
+ * and structures during data analysis. It implements ways to change the information
+ * in coordinate data structures as well as checking that both input data and output
+ * method are matching for a given coordinate file writing operation. For this
+ * components verify first that all the requirements can be satisfied. Then
+ * components are build that will change the coordinate information accordingly.
+ *
+ * The main parts are the outputadapters implemented using the
+ * IOutputAdapter interface to change information in a local (deep) copy of t_trxframes
+ * stored in the outputmanager.
+ *
+ * <H3>Outputadapter</H3>
+ * Each OutputAdapter module implements the same IOutputAdapter interface and
+ * has to set its requirements for final
+ * processing as a flag from the enum in requirementflags. During processing, they implement a custom
+ * version of the processFrame directive that modifies the stored trajectory data before writing
+ * a new file to disk.
+ *
+ *
+ * The interaction between the OutputManager and the OutputAdapter modules derived from
+ * IOutputAdapter is shown in the diagram below.
+ *
+ * \msc
+ wordwraparcs=true,
+ hscale="2";
+
+ analysistool,
+ builder [ label="OutputManagerBuilder" ],
+ outputmanager [ label="OutputManager" ],
+ container [ label="OutputAdapterStorage" ],
+ outputadapters [ label="OutputAdapters" ];
+
+ analysistool => builder [ label="Requests new coordinate output" ];
+ analysistool => builder [ label="Specifies required OutputAdapters" ];
+ builder => outputadapters [ label="Tries to construct new outputadapters" ];
+ outputadapters => builder [ label="Return or give error for wrong preconditions" ];
+ outputadapters => container [ label="Outputadapters are stored" ];
+ container => builder [ label="Gives error if storage conditions are violated" ];
+ builder => outputmanager [ label="Constructs new manager according to specifications" ];
+ builder => container [ label="Requests storage object with registered outputadapters" ];
+ container => builder [ label="Gives ownership of stored outputadapters" ];
+ builder box builder [ label="Tests preconditions of storage object and new outputmanager" ];
+ builder => analysistool [ label="Raise error if preconditions don't match" ];
+ builder => outputmanager [ label="Add storage object to new outputmanager" ];
+ outputmanager => analysistool [ label="Returns finished outputmanager" ];
+ builder box builder [ label="outputmanager created, can start to work on input data" ];
+
+ * \endmsc
+ *
+ * Once the OutputManager object and its registered modules are created, they can be used to
+ * iterate over input data to write new coordinate frames.
+ *
+ * \msc
+ wordwraparcs=true,
+ hscale="2";
+
+ analysistool,
+ analysisloop,
+ outputmanager [ label="OutputManager" ],
+ outputadapters [ label="OutputAdapters" ] ,
+ filewriting;
+
+ --- [ label="Setup of outputmanager complete, analysis phase begins" ];
+ analysistool => analysisloop [ label="Starts iteration over frames" ];
+ analysisloop => outputmanager [ label="Provides coordinates" ];
+ outputmanager => outputadapters [ label="Provide coordinate frames for changing" ];
+ outputadapters => outputmanager [ label="Return after changing data" ];
+ outputmanager => filewriting [ label="Send new coordinates for writing" ];
+ filewriting => outputmanager [ label="Continue after writing to disk" ];
+ outputmanager => analysisloop [ label="Returns after writing" ];
+ analysisloop box analysisloop [ label="Iterates over frames" ];
+ --- [ label="Analysis complete, object is destructed and files are closed" ];
+
+ * \endmsc
+ *
+ *
+ *
+ * \if libapi
+ * <H3>Preparing new OutputAdapters</H3>
+ *
+ * If additional methods are needed to perform changes to the t_trxframe metadata,
+ * new OutputAdapters can be written that again implement the IOutputAdapter interface.
+ * The new method should follow the approach of the other modules that are present
+ * in changing a minimal set of t_trxframe data.
+ * \endif
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ */
+/*! \file
+ * \libinternal
+ * \brief
+ * Public API convenience header for coordinate file output.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_coordinateio
+ */
+#ifndef GMX_COORDINATEIO_H
+#define GMX_COORDINATEIO_H
+
+#include "gromacs/coordinateio/enums.h"
+#include "gromacs/coordinateio/ioutputadapter.h"
+#include "gromacs/coordinateio/outputadaptercontainer.h"
+#include "gromacs/coordinateio/outputadapters.h"
+
+#endif
--- /dev/null
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2019, 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.
+
+file(GLOB COORDINATEIO_SOURCES *.cpp outputadapters/*.cpp)
+
+set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${COORDINATEIO_SOURCES} PARENT_SCOPE)
+
+gmx_install_headers(
+ ioutputadapter.h
+ outputadaptercontainer.h
+ outputadapters.h
+ enums.h
+ )
+
+if (BUILD_TESTING)
+ add_subdirectory(tests)
+endif()
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*! \file
+ * \brief
+ * Enum class defining the different requirements that outputadapters
+ * have for the output file type. OutputManager objects can only be built
+ * with OutputAdapters whose requirements can be implemented with the available input.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \libinternal
+ * \ingroup module_coordinateio
+ */
+#ifndef GMX_COORDINATEIO_ENUMS_H
+#define GMX_COORDINATEIO_ENUMS_H
+
+namespace gmx
+{
+
+/*!\brief
+ * The enums here define the flags specifying the requirements
+ * of different outputadapter modules.
+ *
+ * When building the object for deciding on the output to a new coordinate file,
+ * the CoordinateFile object needs to be able to validate that the dependencies of
+ * attached IOutputAdapters are fulfilled. Classes and interfaces that use
+ * the enum can check their dependencies against the information encoded in the
+ * flags and can then perform an appropriate reaction if there is a mismatch.
+ * \todo Use std::bitset<16> for the entries.
+ *
+ * \libinternal
+ * \ingroup module_coordinateio
+ *
+ */
+enum class CoordinateFileFlags : unsigned long
+{
+ /*! \brief
+ * Base setting that says that the module has no requirements.
+ *
+ * Sets the flags to default setting to make sure all output methods
+ * are supported.
+ */
+ Base = 1<<0,
+ /*! \brief
+ * Requires output method to support force output.
+ *
+ * If set, only output methods supporting writing of forces will work,
+ * others will generate an invalid input error.
+ */
+ RequireForceOutput = 1<<1,
+ /*! \brief
+ * Requires output method to support velocity output.
+ *
+ * If set, only writing to files that support velocity output will succeed.
+ * Other writing methods will generate an error.
+ */
+ RequireVelocityOutput = 1<<2,
+ /*! \brief
+ * Requires support for connection information in output format.
+ *
+ * If set, only file output that supports writing of connection information will succeed.
+ * This means for now that only PDB and TNG files can be written. Other file writing
+ * methods will fail.
+ */
+ RequireAtomConnections = 1<<3,
+ /*! \brief
+ * Requires that output format supports the writing of atom information to the file.
+ *
+ * If set, files will only be written if they can output the information from t_atoms
+ * and otherwise create an error while writing.
+ */
+ RequireAtomInformation = 1<<4,
+ /*! \brief
+ * Requires that output format supports writing user-specified output precision.
+ *
+ * If set, output will only be written if the format supports the writing
+ * of custom precision of the included data.
+ */
+ RequireChangedOutputPrecision = 1<<5,
+ /*! \brief
+ * Requires that output format supports writing time to the file.
+ */
+ RequireNewFrameTime = 1<<6,
+ /*! \brief
+ * Requires that output format supports writing box information.
+ */
+ RequireNewBox = 1<<7,
+ /*! \brief
+ * Requires output to support changes to selection of coordinates.
+ *
+ * Default for most methods, will need to be able to write coordinates to
+ * output file or generate an error.
+ */
+ RequireCoordianteSelection = 1<<8,
+ //! Needed for enumeration array.
+ Count
+};
+
+//! Conversion of flag to its corresponding unsigned long value.
+inline unsigned long convertFlag(CoordinateFileFlags flag)
+{
+ return static_cast<unsigned long>(flag);
+}
+
+//! Enum class for setting basic flags in a t_trxframe
+enum class ChangeSettingType
+{
+ PreservedIfPresent,
+ Always,
+ Never
+};
+//! Mapping for enums from \ref ChangeSettingType.
+const char *const cChangeSettingTypeEnum[] = {
+ "preserved-if-present", "always", "never"
+};
+
+//! Enum class for t_atoms settings
+enum class ChangeAtomsType
+{
+ PreservedIfPresent,
+ AlwaysFromStructure,
+ Never,
+ Always
+};
+
+//! Mapping for enums from \ref ChangeAtomsType.
+const char *const cChangeAtomsTypeEnum[] = {
+ "preserved-if-present", "always-from-structure", "never", "always"
+};
+
+//! Enum class for setting fields new or not.
+enum class ChangeFrameInfoType
+{
+ PreservedIfPresent,
+ Always
+};
+//! Mapping for enums from \ref ChangeFrameInfoType.
+const char *const cChangeFrameInfoTypeEnum[] = {
+ "preserved-if-present", "always"
+};
+
+//! Enum class for setting frame time from user input.
+enum class ChangeFrameTimeType
+{
+ PreservedIfPresent,
+ StartTime,
+ TimeStep,
+ Both
+};
+
+//! Mapping for values from \ref ChangeFrameTimeType.
+const char *const cChangeFrameTimeTypeEnum[] = {
+ "preserved-if-present", "starttime", "timestep", "both"
+};
+
+
+} // namespace gmx
+
+#endif
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*! \file
+ * \brief
+ * Declares gmx::IOutputAdapter interface for modifying coordinate
+ * file structures before writing them to disk.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_coordinateio
+ */
+#ifndef GMX_COORDINATEIO_IOUTPUTADAPTER_H
+#define GMX_COORDINATEIO_IOUTPUTADAPTER_H
+
+#include <memory>
+
+#include "gromacs/coordinateio/enums.h"
+#include "gromacs/utility/classhelpers.h"
+
+struct t_trxframe;
+
+namespace gmx
+{
+
+/*!\brief
+ * OutputAdapter class for handling trajectory file flag setting and processing.
+ *
+ * This interface provides the base point upon which modules that modify trajectory frame
+ * datastructures should be build. The interface itself does not provide any direct means
+ * to modify the data, but only gives the virtual method to perform work on a
+ * t_trxframe object. Classes that modify trajectory frames should implement this interface.
+ *
+ * \inlibraryapi
+ * \ingroup module_coordinateio
+ *
+ */
+class IOutputAdapter
+{
+ public:
+ /*! \brief
+ * Default constructor for IOutputAdapter interface.
+ */
+ IOutputAdapter()
+ {
+ }
+ virtual ~IOutputAdapter()
+ {
+ }
+ //! Move constructor for old object.
+ explicit IOutputAdapter(IOutputAdapter &&old) noexcept = default;
+
+ /*! \brief
+ * Change t_trxframe according to user input.
+ *
+ * \param[in] framenumber Frame number as reported from the
+ * trajectoryanalysis framework or set by user.
+ * \param[in,out] input Pointer to trajectory analysis frame that will
+ * be worked on.
+ */
+ virtual void processFrame(int framenumber, t_trxframe *input) = 0;
+
+ /*! \brief
+ * Checks that the abilities of the output writer are sufficient for this adapter.
+ *
+ * It can happen that a method to write coordinate files does not match with
+ * a requested operation on the input data (e.g. the user requires velocities or
+ * forces to be written to a PDB file).
+ * To check those dependencies, derived classes need to implement a version of this
+ * function to make sure that only matching methods can be used.
+ *
+ * \param[in] abilities The abilities of an output method that need to be checked against
+ * the dependencies created by using the derived method.
+ * \throws InconsistentInputError If dependencies can not be matched to abilities.
+ */
+ virtual void checkAbilityDependencies(unsigned long abilities) const = 0;
+
+ GMX_DISALLOW_COPY_AND_ASSIGN(IOutputAdapter);
+
+};
+
+//! Smart pointer to manage the frame adapter object.
+using OutputAdapterPointer = std::unique_ptr<IOutputAdapter>;
+
+} // namespace gmx
+
+#endif
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*!\file
+ * \internal
+ * \brief
+ * Implements gmx::OutputAdapterContainer.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \ingroup module_coordinateio
+ */
+
+#include "gmxpre.h"
+
+#include "outputadaptercontainer.h"
+
+#include <algorithm>
+
+#include "gromacs/utility/exceptions.h"
+
+namespace gmx
+{
+
+void
+OutputAdapterContainer::addAdapter(OutputAdapterPointer adapter,
+ CoordinateFileFlags type)
+{
+ if (outputAdapters_[type] != nullptr)
+ {
+ GMX_THROW(InternalError("Trying to add adapter that has already been added"));
+ }
+ adapter->checkAbilityDependencies(abilities_);
+ outputAdapters_[type] = std::move(adapter);
+}
+
+bool
+OutputAdapterContainer::isEmpty() const
+{
+ return std::none_of(outputAdapters_.begin(), outputAdapters_.end(),
+ [](const auto &adapter){ return adapter != nullptr; });
+}
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*! \file
+ * \brief
+ * Declares gmx::OutputAdapterContainer, a storage object for
+ * multiple outputadapters derived from the IOutputadaper interface.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_coordinateio
+ */
+#ifndef GMX_COORDINATEIO_OUTPUTADAPTERCONTAINER_H
+#define GMX_COORDINATEIO_OUTPUTADAPTERCONTAINER_H
+
+#include <memory>
+#include <vector>
+
+#include "gromacs/coordinateio/ioutputadapter.h"
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/enumerationhelpers.h"
+
+namespace gmx
+{
+
+/*! \libinternal \brief
+ * Storage for output adapters that modify the state of a t_trxframe object.
+ *
+ * The OutputAdapterContainer is responsible for storing the number of
+ * OutputAdapters, as well as the bitmask representing the current requirements
+ * for constructing an CoordinateFile object with the modules registered. It is responsible
+ * for ensuring that no module can be registered multiple times, and that the
+ * correct order for some modifications is observed (e.g. we can not reduce the
+ * number of coordinates written to a file before we have set all the other flags).
+ * Any other behaviour indicates a programming error and triggers an assertion.
+ *
+ * The abilities that need to be cross checked for the container are usually constrained
+ * by the file format the coordinate data will be written to. When declaring new abilities,
+ * these must match the file type for the output.
+ *
+ * \todo Keeping track of those abilities has to be the responsibility of an object
+ * implementing and interface that declares it capabilities and will execute the
+ * the function of writing to a file.
+ * \todo This could be changed to instead construct the container with a pointer to an
+ * ICoordinateOutputWriter that can be passed to the IOutputAdapter modules to check
+ * their cross-dependencies.
+ */
+class OutputAdapterContainer
+{
+ public:
+ //! Only allow constructing the container with defined output abilities.
+ explicit OutputAdapterContainer(unsigned long abilities)
+ : abilities_(abilities)
+ {}
+ //! Allow abilities to be also defined using the enum class.
+ explicit OutputAdapterContainer(CoordinateFileFlags abilities)
+ : abilities_(convertFlag(abilities))
+ {}
+
+ /*! \brief
+ * Add an adapter of a type not previously added.
+ *
+ * Only one adapter of each type can be registered, and the order of adapters
+ * is predefined in the underlying storage object.
+ * Calls internal checks to make sure that the new adapter does not violate
+ * any of the preconditions set to make an CoordinateFile object containing
+ * the registered modules.
+ *
+ * \param[in] adapter unique_ptr to adapter, with container taking ownership here.
+ * \param[in] type What kind of adapter is being added.
+ * \throws InternalError When registering an adapter of a type already registered .
+ * \throws InconsistentInputError When incompatible modules are added.
+ */
+ void addAdapter(OutputAdapterPointer adapter,
+ CoordinateFileFlags type);
+
+ //! Get vector of all registered adapters.
+ ArrayRef<const OutputAdapterPointer> getAdapters() { return outputAdapters_; }
+ //! Get info if we have any registered adapters.
+ bool isEmpty() const;
+
+ private:
+ //! Array of registered modules.
+ EnumerationArray<CoordinateFileFlags, OutputAdapterPointer> outputAdapters_;
+ //! Construction time bitmask declaring what the OutputManager can do.
+ unsigned long abilities_ = convertFlag(CoordinateFileFlags::Base);
+};
+
+} // namespace gmx
+
+#endif
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*! \file
+ * \brief
+ * Public API convenience header for accessing outputadapters.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \inpublicapi
+ * \ingroup module_coordinateio
+ */
+#ifndef GMX_COORDINATEIO_OUTPUTADAPTERS_H
+#define GMX_COORDINATEIO_OUTPUTADAPTERS_H
+
+#endif
--- /dev/null
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2019, 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.
+
+set(test_sources
+ outputadaptercontainer.cpp
+ testmodule.cpp
+ )
+gmx_add_unit_test(CoordinateIOTests coordinateio-test ${test_sources})
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*!\file
+ * \internal
+ * \brief
+ * Tests for outputadaptercontainer.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \ingroup module_coordinateio
+ */
+
+
+#include "gmxpre.h"
+
+#include "gromacs/coordinateio/outputadaptercontainer.h"
+
+#include <algorithm>
+#include <memory>
+
+#include <gtest/gtest.h>
+
+#include "gromacs/utility/exceptions.h"
+
+#include "testmodule.h"
+
+namespace gmx
+{
+
+namespace test
+{
+
+TEST(OutputAdapterContainer, MakeEmpty)
+{
+ OutputAdapterContainer container(CoordinateFileFlags::Base);
+ EXPECT_TRUE(container.isEmpty());
+}
+
+TEST(OutputAdapterContainer, AddAdapter)
+{
+ OutputAdapterContainer container(CoordinateFileFlags::Base);
+ container.addAdapter(
+ std::make_unique<DummyOutputModule>(CoordinateFileFlags::Base),
+ CoordinateFileFlags::RequireNewFrameTime);
+ EXPECT_FALSE(container.isEmpty());
+}
+
+TEST(OutputAdapterContainer, RejectBadAdapter)
+{
+ OutputAdapterContainer container(CoordinateFileFlags::Base);
+ EXPECT_THROW(container.addAdapter(
+ std::make_unique<DummyOutputModule>(CoordinateFileFlags::RequireVelocityOutput),
+ CoordinateFileFlags::RequireVelocityOutput),
+ InconsistentInputError);
+ EXPECT_TRUE(container.isEmpty());
+}
+
+TEST(OutputAdapterContainer, RejectDuplicateAdapter)
+{
+ OutputAdapterContainer container(CoordinateFileFlags::Base);
+ EXPECT_NO_THROW(container.addAdapter(
+ std::make_unique<DummyOutputModule>(CoordinateFileFlags::Base),
+ CoordinateFileFlags::RequireNewFrameTime));
+ EXPECT_FALSE(container.isEmpty());
+ EXPECT_THROW(container.addAdapter(
+ std::make_unique<DummyOutputModule>(CoordinateFileFlags::Base),
+ CoordinateFileFlags::RequireNewFrameTime),
+ InternalError);
+}
+
+TEST(OutputAdapterContainer, AcceptMultipleAdapters)
+{
+ OutputAdapterContainer container(CoordinateFileFlags::Base);
+ EXPECT_NO_THROW(container.addAdapter(
+ std::make_unique<DummyOutputModule>(CoordinateFileFlags::Base),
+ CoordinateFileFlags::RequireForceOutput));
+ EXPECT_FALSE(container.isEmpty());
+ EXPECT_NO_THROW(container.addAdapter(
+ std::make_unique<DummyOutputModule>(CoordinateFileFlags::Base),
+ CoordinateFileFlags::RequireVelocityOutput));
+ EXPECT_FALSE(container.isEmpty());
+}
+
+} // namespace test
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*!\file
+ * \internal
+ * \brief
+ * Implements test module.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \ingroup module_coordinateio
+ */
+
+
+#include "gmxpre.h"
+
+#include "testmodule.h"
+
+#include <gtest/gtest.h>
+
+#include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/stringutil.h"
+
+namespace gmx
+{
+
+namespace test
+{
+
+void DummyOutputModule::checkAbilityDependencies(const unsigned long abilities) const
+{
+ if ((abilities & convertFlag(moduleRequirements_)) == 0u)
+ {
+ std::string errorMessage = "Unhandled module requirements.";
+ GMX_THROW(InconsistentInputError(errorMessage.c_str()));
+ }
+}
+
+} // namespace test
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+/*!\file
+ * \internal
+ * \brief
+ * Dummy module used for tests and as an implementation example.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \libinternal
+ * \ingroup module_coordinateio
+ */
+
+#ifndef GMX_COORDINATEIO_TESTMODULE_H
+#define GMX_COORDINATEIO_TESTMODULE_H
+
+#include "gromacs/coordinateio/ioutputadapter.h"
+
+namespace gmx
+{
+
+namespace test
+{
+
+class DummyOutputModule : public IOutputAdapter
+{
+ public:
+ explicit DummyOutputModule(CoordinateFileFlags requirementsFlag) :
+ moduleRequirements_(requirementsFlag)
+ {}
+
+ DummyOutputModule(DummyOutputModule &&old) noexcept = default;
+
+ ~DummyOutputModule() override {}
+
+ void processFrame(int /*framenumber*/, t_trxframe * /*input*/) override
+ {}
+
+ void checkAbilityDependencies(unsigned long abilities) const override;
+
+ private:
+ //! Local requirements
+ CoordinateFileFlags moduleRequirements_;
+};
+
+} // namespace test
+
+} // namespace gmx
+
+#endif