Add a few C++ helper classes/macros.
[alexxy/gromacs.git] / src / gromacs / analysisdata / modules / plot.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \file
32  * \brief
33  * Declares gmx::AnalysisDataPlotModule for plotting data (into a file).
34  *
35  * \inpublicapi
36  * \ingroup module_analysisdata
37  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
38  */
39 #ifndef GMX_ANALYSISDATA_MODULES_PLOT_H
40 #define GMX_ANALYSISDATA_MODULES_PLOT_H
41
42 #include <string>
43
44 #include "../datamodule.h"
45 #include "../../options/timeunitmanager.h"
46 #include "../../utility/common.h"
47
48 namespace gmx
49 {
50
51 class Options;
52 class SelectionCollection;
53
54 /*! \brief
55  * Common settings for data plots.
56  *
57  * \inpublicapi
58  * \ingroup module_analysisdata
59  */
60 class AnalysisDataPlotSettings
61 {
62     public:
63         //! Constructs default analysis plot settings.
64         AnalysisDataPlotSettings();
65
66         //! Returns the selection collection set with setSelectionCollection().
67         const SelectionCollection *selectionCollection() const
68         {
69             return selections_;
70         }
71         //! Returns the time unit set with setTimeUnit().
72         TimeUnit timeUnit() const { return timeUnit_; }
73         /*! \brief
74          * Returns the plot format.
75          *
76          * \todo Use a proper enum.
77          */
78         int plotFormat() const { return plotFormat_; }
79
80         /*! \brief
81          * Set selection collection to print as comments into the output.
82          *
83          * Formatted selection text from all selections in \p selections is
84          * printed as comments in the output file.
85          * If this method is not called, no selection information is written
86          * to the output.
87          */
88         void setSelectionCollection(const SelectionCollection *selections);
89         /*! \brief
90          * Sets the time unit for the plot.
91          *
92          * The value is used only if AbstractPlotModule::setXAxisIsTime() is
93          * called, in which case it is used to print the appropriate axis label
94          * and to scale the values.
95          * If not called, the default time unit is ps.
96          */
97         void setTimeUnit(TimeUnit timeUnit) { timeUnit_ = timeUnit; }
98
99
100         /*! \brief
101          * Adds common options for setting plot options.
102          *
103          * \param[in,out] options Options object to which options are added.
104          */
105         void addOptions(Options *options);
106
107     private:
108         const SelectionCollection *selections_;
109         TimeUnit                timeUnit_;
110         int                     plotFormat_;
111 };
112
113 /*! \brief
114  * Abstract data module for writing data into a file.
115  *
116  * Implements features common to all plotting modules.  Subclasses implement
117  * features specific to certain applications (AnalysisDataPlotModule implements
118  * straightforward plotting).
119  *
120  * By default, the data is written into an xvgr file, according to the
121  * options read from the Options object given to the constructor.
122  * For non-xvgr data, it's possible to skip all headers by calling
123  * setPlainOutput().
124  *
125  * Multipoint data is supported, in which case all the points are written to
126  * the output, in the order in which they are added to the data.  A single
127  * output line corresponds to a single frame.  In most cases with multipoint
128  * data, setPlainOutput() should be called since the output does not make sense
129  * as an xvgr file, but this is not enforced.
130  *
131  * \ingroup module_analysisdata
132  */
133 class AbstractPlotModule : public AnalysisDataModuleInterface
134 {
135     public:
136         virtual ~AbstractPlotModule();
137
138         /*! \brief
139          * Set the output file name.
140          *
141          * If no file name is set (or if \p fnm is NULL), no output occurs.
142          */
143         void setFileName(const std::string &fnm);
144         /*! \brief
145          * Set plain output.
146          *
147          * If \p bPlain is true, no xvgr headers are written to the file.
148          * In this case, only setOmitX(), setXFormat(), and setYFormat()
149          * methods have any effect on the output.
150          */
151         void setPlainOutput(bool bPlain);
152         /*! \brief
153          * Omit the X coordinates from the output.
154          *
155          * This method only makes sense when combined with setPlainOutput().
156          */
157         void setOmitX(bool bOmitX);
158         /*! \brief
159          * Set plot title.
160          */
161         void setTitle(const char *title);
162         /*! \brief
163          * Set plot subtitle.
164          */
165         void setSubtitle(const char *subtitle);
166         /*! \brief
167          * Set X axis label.
168          */
169         void setXLabel(const char *label);
170         /*! \brief
171          * Treat X axis as time.
172          *
173          * Sets the label for the axis accordingly and also scales output to
174          * take into account the correct time unit.
175          */
176         void setXAxisIsTime();
177         /*! \brief
178          * Set Y axis label.
179          */
180         void setYLabel(const char *label);
181         /*! \brief
182          * Add legend from an array of strings.
183          *
184          * Multiple calls to setLegend() and/or appendLegend() are added
185          * together.
186          */
187         void setLegend(int nsets, const char * const *setname);
188         /*! \brief
189          * Add a legend string for the next data set.
190          *
191          * Multiple calls to setLegend() and/or appendLegend() are added
192          * together.
193          */
194         void appendLegend(const char *setname);
195         /*! \brief
196          * Set field width and precision for X value output.
197          */
198         void setXFormat(int width, int prec, char fmt = 'f');
199         /*! \brief
200          * Set field width and precision for Y value output.
201          */
202         void setYFormat(int width, int prec, char fmt = 'f');
203
204         virtual int flags() const;
205
206         virtual void dataStarted(AbstractAnalysisData *data);
207         virtual void frameStarted(const AnalysisDataFrameHeader &header);
208         virtual void pointsAdded(const AnalysisDataPointSetRef &points) = 0;
209         virtual void frameFinished(const AnalysisDataFrameHeader &header);
210         virtual void dataFinished();
211
212     protected:
213         /*! \cond libapi */
214         explicit AbstractPlotModule(const AnalysisDataPlotSettings &settings);
215
216         bool isFileOpen() const;
217         void writeValue(real value) const;
218         //! \endcond
219
220     private:
221         class Impl;
222
223         PrivateImplPointer<Impl> _impl;
224 };
225
226
227 /*! \brief
228  * Plotting module for straightforward plotting of data.
229  *
230  * See AbstractPlotModule for common plotting options.
231  *
232  * \inpublicapi
233  * \ingroup module_analysisdata
234  */
235 class AnalysisDataPlotModule : public AbstractPlotModule
236 {
237     public:
238         explicit AnalysisDataPlotModule(const AnalysisDataPlotSettings &settings);
239
240         virtual void pointsAdded(const AnalysisDataPointSetRef &points);
241
242         // Copy and assign disallowed by base.
243 };
244
245
246 /*! \brief
247  * Plotting module specifically for data consisting of vectors.
248  *
249  * See AbstractPlotModule for common plotting options.
250  *
251  * \inpublicapi
252  * \ingroup module_analysisdata
253  */
254 class AnalysisDataVectorPlotModule : public AbstractPlotModule
255 {
256     public:
257         explicit AnalysisDataVectorPlotModule(const AnalysisDataPlotSettings &settings);
258
259         /*! \brief
260          * Set whether to write X component.
261          */
262         void setWriteX(bool bWrite);
263         /*! \brief
264          * Set whether to write Y component.
265          */
266         void setWriteY(bool bWrite);
267         /*! \brief
268          * Set whether to write Z component.
269          */
270         void setWriteZ(bool bWrite);
271         /*! \brief
272          * Set whether to write norm of the vector.
273          */
274         void setWriteNorm(bool bWrite);
275         /*! \brief
276          * Set mask for what to write.
277          */
278         void setWriteMask(bool bWrite[4]);
279
280         virtual void pointsAdded(const AnalysisDataPointSetRef &points);
281
282     private:
283         bool                    _bWrite[4];
284
285         // Copy and assign disallowed by base.
286 };
287
288 } // namespace gmx
289
290 #endif