AbstractAnalysisData module handling into a separate class.
[alexxy/gromacs.git] / src / gromacs / analysisdata / datamodulemanager.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
5  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
6  * others, as listed in the AUTHORS file in the top-level source
7  * directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \libinternal \file
36  * \brief
37  * Declares gmx::AnalysisDataModuleManager.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inlibraryapi
41  * \ingroup module_analysisdata
42  */
43 #ifndef GMX_ANALYSISDATA_DATAMODULEMANAGER_H
44 #define GMX_ANALYSISDATA_DATAMODULEMANAGER_H
45
46 #include "abstractdata.h"
47
48 #include "../utility/common.h"
49
50 namespace gmx
51 {
52
53 /*! \libinternal \brief
54  * Encapsulates handling of data modules attached to AbstractAnalysisData.
55  *
56  * \inlibraryapi
57  * \ingroup module_analysisdata
58  */
59 class AnalysisDataModuleManager
60 {
61     public:
62         /*! \brief
63          * Identifies data properties to check with data modules.
64          *
65          * \see AnalysisDataModuleInterface::Flag
66          */
67         enum DataProperty
68         {
69             eMultipleDataSets, //!< Data has multiple data sets.
70             eMultipleColumns,  //!< Data has multiple columns.
71             eMultipoint,       //!< Data is multipoint.
72             eDataPropertyNR    //!< Number of properties; for internal use only.
73         };
74
75         AnalysisDataModuleManager();
76         ~AnalysisDataModuleManager();
77
78         /*! \brief
79          * Allows the manager to check modules for compatibility with the data.
80          *
81          * \throws  APIError if any data module already added is not compatible
82          *      with the new setting.
83          *
84          * Does two things: checks any modules already attached to the data and
85          * throws if any of them is not compatible, and stores the property
86          * to check modules attached in the future.
87          *
88          * Strong exception safety.
89          */
90         void dataPropertyAboutToChange(DataProperty property, bool bSet);
91
92         /*! \brief
93          * Adds a module to process the data.
94          *
95          * \param     data    Data object to add the module to.
96          * \param     module  Module to add.
97          * \throws    std::bad_alloc if out of memory.
98          * \throws    APIError if
99          *      - \p module is not compatible with the data object
100          *      - data has already been added to the data object and everything
101          *        is not available through getDataFrame().
102          * \throws    unspecified Any exception thrown by \p module in its
103          *      notification methods (if data has been added).
104          *
105          * \see AbstractAnalysisData::addModule()
106          */
107         void addModule(AbstractAnalysisData      *data,
108                        AnalysisDataModulePointer  module);
109         /*! \brief
110          * Applies a module to process data that is ready.
111          *
112          * \param     data    Data object to apply the module to.
113          * \param     module  Module to apply.
114          * \throws    APIError in same situations as addModule().
115          * \throws    unspecified Any exception thrown by \p module in its
116          *      notification methods.
117          *
118          * \see AbstractAnalysisData::applyModule()
119          */
120         void applyModule(AbstractAnalysisData        *data,
121                          AnalysisDataModuleInterface *module);
122
123         /*! \brief
124          * Notifies attached modules of the start of data.
125          *
126          * \param   data  Data object that is starting.
127          * \throws  APIError if any attached data module is not compatible.
128          * \throws  unspecified Any exception thrown by attached data modules
129          *      in AnalysisDataModuleInterface::dataStarted().
130          *
131          * Should be called once, after data properties have been set with
132          * the methods in AbstractAnalysisData, and before any other
133          * notification methods.
134          * The caller should be prepared for requestStorage() calls to \p data
135          * from the attached modules.
136          *
137          * \p data should typically be \c this when calling from a class
138          * derived from AbstractAnalysisData.
139          */
140         void notifyDataStart(AbstractAnalysisData *data) const;
141         /*! \brief
142          * Notifies attached modules of the start of a frame.
143          *
144          * \param[in] header  Header information for the frame that is starting.
145          * \throws    unspecified Any exception thrown by attached data modules
146          *      in AnalysisDataModuleInterface::frameStarted().
147          *
148          * Should be called once for each frame, before notifyPointsAdd() calls
149          * for that frame.
150          */
151         void notifyFrameStart(const AnalysisDataFrameHeader &header) const;
152         /*! \brief
153          * Notifies attached modules of the addition of points to the
154          * current frame.
155          *
156          * \param[in] points  Set of points added (also provides access to
157          *      frame-level data).
158          * \throws    APIError if any attached data module is not compatible.
159          * \throws    unspecified Any exception thrown by attached data modules
160          *      in AnalysisDataModuleInterface::pointsAdded().
161          *
162          * Can be called zero or more times for each frame.
163          * The caller should ensure that any column occurs at most once in the
164          * calls, unless the data is multipoint.
165          * For efficiency reasons, calls to this method should be aggregated
166          * whenever possible, i.e., it's better to handle multiple columns or
167          * even the whole frame in a single call rather than calling the method
168          * for each column separately.
169          */
170         void notifyPointsAdd(const AnalysisDataPointSetRef &points) const;
171         /*! \brief
172          * Notifies attached modules of the end of a frame.
173          *
174          * \param[in] header  Header information for the frame that is ending.
175          * \throws    unspecified Any exception thrown by attached data modules
176          *      in AnalysisDataModuleInterface::frameFinished().
177          *
178          * Should be called once for each call of notifyFrameStart(), after any
179          * notifyPointsAdd() calls for the frame.
180          * \p header should be identical to that used in the corresponding
181          * notifyFrameStart() call.
182          */
183         void notifyFrameFinish(const AnalysisDataFrameHeader &header) const;
184         /*! \brief
185          * Notifies attached modules of the end of data.
186          *
187          * \throws    unspecified Any exception thrown by attached data modules
188          *      in AnalysisDataModuleInterface::dataFinished().
189          *
190          * Should be called once, after all the other notification calls.
191          */
192         void notifyDataFinish() const;
193
194     private:
195         class Impl;
196
197         PrivateImplPointer<Impl> impl_;
198 };
199
200 } // namespace gmx
201
202 #endif