Sort all includes in src/gromacs
[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,2014, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source 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 "gromacs/analysisdata/abstractdata.h"
47 #include "gromacs/utility/common.h"
48
49 namespace gmx
50 {
51
52 class AnalysisDataParallelOptions;
53
54 /*! \libinternal \brief
55  * Encapsulates handling of data modules attached to AbstractAnalysisData.
56  *
57  * \inlibraryapi
58  * \ingroup module_analysisdata
59  */
60 class AnalysisDataModuleManager
61 {
62     public:
63         /*! \brief
64          * Identifies data properties to check with data modules.
65          *
66          * \see AnalysisDataModuleInterface::Flag
67          */
68         enum DataProperty
69         {
70             eMultipleDataSets, //!< Data has multiple data sets.
71             eMultipleColumns,  //!< Data has multiple columns.
72             eMultipoint,       //!< Data is multipoint.
73             eDataPropertyNR    //!< Number of properties; for internal use only.
74         };
75
76         AnalysisDataModuleManager();
77         ~AnalysisDataModuleManager();
78
79         /*! \brief
80          * Allows the manager to check modules for compatibility with the data.
81          *
82          * \throws  APIError if any data module already added is not compatible
83          *      with the new setting.
84          *
85          * Does two things: checks any modules already attached to the data and
86          * throws if any of them is not compatible, and stores the property
87          * to check modules attached in the future.
88          *
89          * Strong exception safety.
90          */
91         void dataPropertyAboutToChange(DataProperty property, bool bSet);
92
93         /*! \brief
94          * Whether there are modules that do not support parallel processing.
95          *
96          * Must not be called before notifyDataStart()/notifyParallelDataStart().
97          * If notifyDataStart() has been called, returns true if there are any
98          * modules (all modules are treated as serial).
99          *
100          * Does not throw.
101          */
102         bool hasSerialModules() const;
103
104         /*! \brief
105          * Adds a module to process the data.
106          *
107          * \param     data    Data object to add the module to.
108          * \param     module  Module to add.
109          * \throws    std::bad_alloc if out of memory.
110          * \throws    APIError if
111          *      - \p module is not compatible with the data object
112          *      - data has already been added to the data object and everything
113          *        is not available through getDataFrame().
114          * \throws    unspecified Any exception thrown by \p module in its
115          *      notification methods (if data has been added).
116          *
117          * \see AbstractAnalysisData::addModule()
118          */
119         void addModule(AbstractAnalysisData      *data,
120                        AnalysisDataModulePointer  module);
121         /*! \brief
122          * Applies a module to process data that is ready.
123          *
124          * \param     data    Data object to apply the module to.
125          * \param     module  Module to apply.
126          * \throws    APIError in same situations as addModule().
127          * \throws    unspecified Any exception thrown by \p module in its
128          *      notification methods.
129          *
130          * \see AbstractAnalysisData::applyModule()
131          */
132         void applyModule(AbstractAnalysisData        *data,
133                          AnalysisDataModuleInterface *module);
134
135         /*! \brief
136          * Notifies attached modules of the start of serial data.
137          *
138          * \param   data  Data object that is starting.
139          * \throws  APIError if any attached data module is not compatible.
140          * \throws  unspecified Any exception thrown by attached data modules
141          *      in AnalysisDataModuleInterface::dataStarted().
142          *
143          * Should be called once, after data properties have been set with
144          * the methods in AbstractAnalysisData, and before any other
145          * notification methods.
146          * The caller should be prepared for requestStorage() calls to \p data
147          * from the attached modules.
148          *
149          * \p data should typically be \c this when calling from a class
150          * derived from AbstractAnalysisData.
151          *
152          * This method initializes all modules for serial processing by calling
153          * AnalysisDataModuleInterface::dataStarted().
154          */
155         void notifyDataStart(AbstractAnalysisData *data);
156         /*! \brief
157          * Notifies attached modules of the start of parallel data.
158          *
159          * \param     data    Data object that is starting.
160          * \param[in] options Parallelization properties of the input data.
161          * \throws  APIError if any attached data module is not compatible.
162          * \throws  unspecified Any exception thrown by attached data modules
163          *      in AnalysisDataModuleInterface::parallelDataStarted().
164          *
165          * Can be called instead of notifyDataStart() if \p data supports
166          * non-sequential creation of frames.  Works as notifyDataStart(),
167          * but instead calls AnalysisDataModuleInterface::parallelDataStarted()
168          * and records whether the module supports the parallel mode.
169          * Subsequent notification calls then notify the modules according to
170          * the mode they accept.
171          *
172          * See notifyDataStart() for general constraints.
173          */
174         void notifyParallelDataStart(
175             AbstractAnalysisData              *data,
176             const AnalysisDataParallelOptions &options);
177         /*! \brief
178          * Notifies attached serial modules of the start of a frame.
179          *
180          * \param[in] header  Header information for the frame that is starting.
181          * \throws    unspecified Any exception thrown by attached data modules
182          *      in AnalysisDataModuleInterface::frameStarted().
183          *
184          * Should be called once for each frame, before notifyPointsAdd() calls
185          * for that frame.
186          */
187         void notifyFrameStart(const AnalysisDataFrameHeader &header) const;
188         /*! \brief
189          * Notifies attached parallel modules of the start of a frame.
190          *
191          * \param[in] header  Header information for the frame that is starting.
192          * \throws    unspecified Any exception thrown by attached data modules
193          *      in AnalysisDataModuleInterface::frameStarted().
194          *
195          * If notifyParallelDataStart() has been called, should be called once
196          * for each frame, before notifyParallelPointsAdd() calls for that
197          * frame.
198          * It is allowed to call this method in any order for the frames, but
199          * should be called exactly once for each frame.
200          */
201         void notifyParallelFrameStart(const AnalysisDataFrameHeader &header) const;
202         /*! \brief
203          * Notifies attached serial modules of the addition of points to the
204          * current frame.
205          *
206          * \param[in] points  Set of points added (also provides access to
207          *      frame-level data).
208          * \throws    APIError if any attached data module is not compatible.
209          * \throws    unspecified Any exception thrown by attached data modules
210          *      in AnalysisDataModuleInterface::pointsAdded().
211          *
212          * Can be called zero or more times for each frame.
213          * The caller should ensure that any column occurs at most once in the
214          * calls, unless the data is multipoint.
215          * For efficiency reasons, calls to this method should be aggregated
216          * whenever possible, i.e., it's better to handle multiple columns or
217          * even the whole frame in a single call rather than calling the method
218          * for each column separately.
219          */
220         void notifyPointsAdd(const AnalysisDataPointSetRef &points) const;
221         /*! \brief
222          * Notifies attached parallel modules of the addition of points to a frame.
223          *
224          * \param[in] points  Set of points added (also provides access to
225          *      frame-level data).
226          * \throws    APIError if any attached data module is not compatible.
227          * \throws    unspecified Any exception thrown by attached data modules
228          *      in AnalysisDataModuleInterface::pointsAdded().
229          *
230          * See notifyPointsAdd() for information on the structure of the point
231          * sets.
232          */
233         void notifyParallelPointsAdd(const AnalysisDataPointSetRef &points) const;
234         /*! \brief
235          * Notifies attached serial modules of the end of a frame.
236          *
237          * \param[in] header  Header information for the frame that is ending.
238          * \throws    unspecified Any exception thrown by attached data modules
239          *      in AnalysisDataModuleInterface::frameFinished().
240          *
241          * Should be called once for each call of notifyFrameStart(), after any
242          * notifyPointsAdd() calls for the frame.
243          * \p header should be identical to that used in the corresponding
244          * notifyFrameStart() call.
245          */
246         void notifyFrameFinish(const AnalysisDataFrameHeader &header) const;
247         /*! \brief
248          * Notifies attached parallel modules of the end of a frame.
249          *
250          * \param[in] header  Header information for the frame that is ending.
251          * \throws    unspecified Any exception thrown by attached data modules
252          *      in AnalysisDataModuleInterface::frameFinished().
253          *
254          * Should be called once for each call of notifyParallelFrameStart(),
255          * after any notifyParallelPointsAdd() calls for the frame.
256          * \p header should be identical to that used in the corresponding
257          * notifyParallelFrameStart() call.
258          */
259         void notifyParallelFrameFinish(const AnalysisDataFrameHeader &header) const;
260         /*! \brief
261          * Notifies attached modules of the end of data.
262          *
263          * \throws    unspecified Any exception thrown by attached data modules
264          *      in AnalysisDataModuleInterface::dataFinished().
265          *
266          * Should be called once, after all the other notification calls.
267          */
268         void notifyDataFinish() const;
269
270     private:
271         class Impl;
272
273         PrivateImplPointer<Impl> impl_;
274 };
275
276 } // namespace gmx
277
278 #endif