Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / analysisdata / modules / plot.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2012, 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 /*! \file
36  * \brief
37  * Declares gmx::AnalysisDataPlotModule for plotting data (into a file).
38  *
39  * \inpublicapi
40  * \ingroup module_analysisdata
41  * \author Teemu Murtola <teemu.murtola@gmail.com>
42  */
43 #ifndef GMX_ANALYSISDATA_MODULES_PLOT_H
44 #define GMX_ANALYSISDATA_MODULES_PLOT_H
45
46 #include <string>
47
48 #include <boost/shared_ptr.hpp>
49
50 #include "../datamodule.h"
51 #include "../../options/timeunitmanager.h"
52 #include "../../utility/common.h"
53
54 namespace gmx
55 {
56
57 class Options;
58 class SelectionCollection;
59
60 /*! \brief
61  * Common settings for data plots.
62  *
63  * \inpublicapi
64  * \ingroup module_analysisdata
65  */
66 class AnalysisDataPlotSettings
67 {
68     public:
69         //! Constructs default analysis plot settings.
70         AnalysisDataPlotSettings();
71
72         //! Returns the selection collection set with setSelectionCollection().
73         const SelectionCollection *selectionCollection() const
74         {
75             return selections_;
76         }
77         //! Returns the time unit set with setTimeUnit().
78         TimeUnit timeUnit() const { return timeUnit_; }
79         /*! \brief
80          * Returns the plot format.
81          *
82          * \todo Use a proper enum.
83          */
84         int plotFormat() const { return plotFormat_; }
85
86         /*! \brief
87          * Set selection collection to print as comments into the output.
88          *
89          * Formatted selection text from all selections in \p selections is
90          * printed as comments in the output file.
91          * If this method is not called, no selection information is written
92          * to the output.
93          */
94         void setSelectionCollection(const SelectionCollection *selections);
95         /*! \brief
96          * Sets the time unit for the plot.
97          *
98          * The value is used only if AbstractPlotModule::setXAxisIsTime() is
99          * called, in which case it is used to print the appropriate axis label
100          * and to scale the values.
101          * If not called, the default time unit is ps.
102          */
103         void setTimeUnit(TimeUnit timeUnit) { timeUnit_ = timeUnit; }
104
105
106         /*! \brief
107          * Adds common options for setting plot options.
108          *
109          * \param[in,out] options Options object to which options are added.
110          */
111         void addOptions(Options *options);
112
113     private:
114         const SelectionCollection *selections_;
115         TimeUnit                   timeUnit_;
116         int                        plotFormat_;
117 };
118
119 /*! \brief
120  * Abstract data module for writing data into a file.
121  *
122  * Implements features common to all plotting modules.  Subclasses implement
123  * features specific to certain applications (AnalysisDataPlotModule implements
124  * straightforward plotting).
125  *
126  * By default, the data is written into an xvgr file, according to the
127  * options read from the Options object given to the constructor.
128  * For non-xvgr data, it's possible to skip all headers by calling
129  * setPlainOutput().
130  *
131  * Multipoint data is supported, in which case all the points are written to
132  * the output, in the order in which they are added to the data.  A single
133  * output line corresponds to a single frame.  In most cases with multipoint
134  * data, setPlainOutput() should be called since the output does not make sense
135  * as an xvgr file, but this is not enforced.
136  *
137  * \ingroup module_analysisdata
138  */
139 class AbstractPlotModule : public AnalysisDataModuleInterface
140 {
141     public:
142         virtual ~AbstractPlotModule();
143
144         /*! \brief
145          * Set common settings for the plotting.
146          */
147         void setSettings(const AnalysisDataPlotSettings &settings);
148         /*! \brief
149          * Set the output file name.
150          *
151          * If no file name is set (or if \p filename is empty), no output occurs.
152          */
153         void setFileName(const std::string &filename);
154         /*! \brief
155          * Set plain output.
156          *
157          * If \p bPlain is true, no xvgr headers are written to the file.
158          * In this case, only setOmitX(), setXFormat(), and setYFormat()
159          * methods have any effect on the output.
160          */
161         void setPlainOutput(bool bPlain);
162         /*! \brief
163          * Omit the X coordinates from the output.
164          *
165          * This method only makes sense when combined with setPlainOutput().
166          */
167         void setOmitX(bool bOmitX);
168         /*! \brief
169          * Set plot title.
170          */
171         void setTitle(const char *title);
172         /*! \brief
173          * Set plot subtitle.
174          */
175         void setSubtitle(const char *subtitle);
176         /*! \brief
177          * Set X axis label.
178          */
179         void setXLabel(const char *label);
180         /*! \brief
181          * Treat X axis as time.
182          *
183          * Sets the label for the axis accordingly and also scales output to
184          * take into account the correct time unit.
185          */
186         void setXAxisIsTime();
187         /*! \brief
188          * Set Y axis label.
189          */
190         void setYLabel(const char *label);
191         /*! \brief
192          * Add legend from an array of strings.
193          *
194          * Multiple calls to setLegend() and/or appendLegend() are added
195          * together.
196          */
197         void setLegend(int nsets, const char * const *setname);
198         /*! \brief
199          * Add a legend string for the next data set.
200          *
201          * Multiple calls to setLegend() and/or appendLegend() are added
202          * together.
203          */
204         void appendLegend(const char *setname);
205         /*! \brief
206          * Set field width and precision for X value output.
207          */
208         void setXFormat(int width, int precision, char format = 'f');
209         /*! \brief
210          * Set field width and precision for Y value output.
211          */
212         void setYFormat(int width, int precision, char format = 'f');
213
214         virtual int flags() const;
215
216         virtual void dataStarted(AbstractAnalysisData *data);
217         virtual void frameStarted(const AnalysisDataFrameHeader &header);
218         virtual void pointsAdded(const AnalysisDataPointSetRef &points) = 0;
219         virtual void frameFinished(const AnalysisDataFrameHeader &header);
220         virtual void dataFinished();
221
222     protected:
223         /*! \cond libapi */
224         AbstractPlotModule();
225         //! Creates AbstractPlotModule and assign common settings.
226         explicit AbstractPlotModule(const AnalysisDataPlotSettings &settings);
227
228         //! Whether an output file has been opened.
229         bool isFileOpen() const;
230         /*! \brief
231          * Appends a single value to the current output line.
232          *
233          * \param[in] value  Value to append.
234          *
235          * Should be used from pointsAdded() implementations in derived classes
236          * to write out individual y values to the output.
237          *
238          * Must not be called if isFileOpen() returns false.
239          */
240         void writeValue(real value) const;
241         //! \endcond
242
243     private:
244         class Impl;
245
246         PrivateImplPointer<Impl> impl_;
247 };
248
249
250 /*! \brief
251  * Plotting module for straightforward plotting of data.
252  *
253  * See AbstractPlotModule for common plotting options.
254  *
255  * \inpublicapi
256  * \ingroup module_analysisdata
257  */
258 class AnalysisDataPlotModule : public AbstractPlotModule
259 {
260     public:
261         AnalysisDataPlotModule();
262         //! Creates AnalysisDataPlotModule and assign common settings.
263         explicit AnalysisDataPlotModule(const AnalysisDataPlotSettings &settings);
264
265         virtual void pointsAdded(const AnalysisDataPointSetRef &points);
266
267         // Copy and assign disallowed by base.
268 };
269
270
271 /*! \brief
272  * Plotting module specifically for data consisting of vectors.
273  *
274  * See AbstractPlotModule for common plotting options.
275  *
276  * \inpublicapi
277  * \ingroup module_analysisdata
278  */
279 class AnalysisDataVectorPlotModule : public AbstractPlotModule
280 {
281     public:
282         AnalysisDataVectorPlotModule();
283         //! Creates AnalysisDataVectorPlotModule and assign common settings.
284         explicit AnalysisDataVectorPlotModule(const AnalysisDataPlotSettings &settings);
285
286         /*! \brief
287          * Set whether to write X component.
288          */
289         void setWriteX(bool bWrite);
290         /*! \brief
291          * Set whether to write Y component.
292          */
293         void setWriteY(bool bWrite);
294         /*! \brief
295          * Set whether to write Z component.
296          */
297         void setWriteZ(bool bWrite);
298         /*! \brief
299          * Set whether to write norm of the vector.
300          */
301         void setWriteNorm(bool bWrite);
302         /*! \brief
303          * Set mask for what to write.
304          */
305         void setWriteMask(bool bWrite[4]);
306
307         virtual void pointsAdded(const AnalysisDataPointSetRef &points);
308
309     private:
310         bool                    bWrite_[4];
311
312         // Copy and assign disallowed by base.
313 };
314
315 //! Smart pointer to manage an AnalysisDataPlotModule object.
316 typedef boost::shared_ptr<AnalysisDataPlotModule>
317     AnalysisDataPlotModulePointer;
318 //! Smart pointer to manage an AnalysisDataVectorPlotModule object.
319 typedef boost::shared_ptr<AnalysisDataVectorPlotModule>
320     AnalysisDataVectorPlotModulePointer;
321
322 } // namespace gmx
323
324 #endif