clang-tidy: readability-non-const-parameter (2/2)
[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,2013,2014,2015,2018, 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 /*! \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 <memory>
47 #include <string>
48
49 #include "gromacs/analysisdata/datamodule.h"
50 #include "gromacs/options/timeunitmanager.h"
51 #include "gromacs/utility/classhelpers.h"
52
53 namespace gmx
54 {
55
56 class AnalysisDataValue;
57 class IOptionsContainer;
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 initOptions(IOptionsContainer *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 AnalysisDataPlotSettings object given to the
128  * constructor.
129  * For non-xvgr data, it's possible to skip all headers by calling
130  * setPlainOutput().
131  *
132  * A single output line corresponds to a single frame.  In most cases with
133  * multipoint data, setPlainOutput() should be called since the output does not
134  * make sense as an xvgr file, but this is not enforced.
135  *
136  * Multipoint data and multiple data sets are both supported, in which case all
137  * the points are written to the output, in the order in which they are added
138  * to the data.
139  *
140  * \ingroup module_analysisdata
141  */
142 class AbstractPlotModule : public AnalysisDataModuleSerial
143 {
144     public:
145         virtual ~AbstractPlotModule();
146
147         /*! \brief
148          * Set common settings for the plotting.
149          */
150         void setSettings(const AnalysisDataPlotSettings &settings);
151         /*! \brief
152          * Set the output file name.
153          *
154          * If no file name is set (or if \p filename is empty), no output occurs.
155          */
156         void setFileName(const std::string &filename);
157         /*! \brief
158          * Set plain output.
159          *
160          * If \p bPlain is true, no xvgr headers are written to the file.
161          * In this case, only setOmitX(), setXFormat(), and setYFormat()
162          * methods have any effect on the output.
163          */
164         void setPlainOutput(bool bPlain);
165         /*! \brief
166          * Plot errors as a separate output column after each value column.
167          */
168         void setErrorsAsSeparateColumn(bool bSeparate);
169         /*! \brief
170          * Omit the X coordinates from the output.
171          *
172          * This method only makes sense when combined with setPlainOutput().
173          */
174         void setOmitX(bool bOmitX);
175         /*! \brief
176          * Set plot title.
177          */
178         void setTitle(const char *title);
179         //! \copydoc setTitle(const char *)
180         void setTitle(const std::string &title);
181         /*! \brief
182          * Set plot subtitle.
183          */
184         void setSubtitle(const char *subtitle);
185         //! \copydoc setSubtitle(const char *)
186         void setSubtitle(const std::string &subtitle);
187         /*! \brief
188          * Set X axis label.
189          */
190         void setXLabel(const char *label);
191         /*! \brief
192          * Treat X axis as time.
193          *
194          * Sets the label for the axis accordingly and also scales output to
195          * take into account the correct time unit.
196          */
197         void setXAxisIsTime();
198         /*! \brief
199          * Set Y axis label.
200          */
201         void setYLabel(const char *label);
202         /*! \brief
203          * Add legend from an array of strings.
204          *
205          * Multiple calls to setLegend() and/or appendLegend() are added
206          * together.
207          */
208         void setLegend(int nsets, const char * const *setname);
209         /*! \brief
210          * Add a legend string for the next data set.
211          *
212          * Multiple calls to setLegend() and/or appendLegend() are added
213          * together.
214          */
215         void appendLegend(const char *setname);
216         //! \copydoc appendLegend(const char *)
217         void appendLegend(const std::string &setname);
218         /*! \brief
219          * Set field width and precision for X value output.
220          */
221         void setXFormat(int width, int precision, char format = 'f');
222         /*! \brief
223          * Set field width and precision for Y value output.
224          */
225         void setYFormat(int width, int precision, char format = 'f');
226
227         virtual int flags() const;
228
229         virtual void dataStarted(AbstractAnalysisData *data);
230         virtual void frameStarted(const AnalysisDataFrameHeader &header);
231         virtual void pointsAdded(const AnalysisDataPointSetRef &points) = 0;
232         virtual void frameFinished(const AnalysisDataFrameHeader &header);
233         virtual void dataFinished();
234
235     protected:
236         /*! \cond libapi */
237         AbstractPlotModule();
238         //! Creates AbstractPlotModule and assign common settings.
239         explicit AbstractPlotModule(const AnalysisDataPlotSettings &settings);
240
241         //! Whether an output file has been opened.
242         bool isFileOpen() const;
243         /*! \brief
244          * Appends a single value to the current output line.
245          *
246          * \param[in] value  Value to append.
247          *
248          * Should be used from pointsAdded() implementations in derived classes
249          * to write out individual y values to the output.
250          *
251          * Must not be called if isFileOpen() returns false.
252          */
253         void writeValue(const AnalysisDataValue &value) const;
254         //! \endcond
255
256     private:
257         class Impl;
258
259         PrivateImplPointer<Impl> impl_;
260 };
261
262
263 /*! \brief
264  * Plotting module for straightforward plotting of data.
265  *
266  * See AbstractPlotModule for common plotting options.
267  *
268  * \inpublicapi
269  * \ingroup module_analysisdata
270  */
271 class AnalysisDataPlotModule : public AbstractPlotModule
272 {
273     public:
274         AnalysisDataPlotModule();
275         //! Creates AnalysisDataPlotModule and assign common settings.
276         explicit AnalysisDataPlotModule(const AnalysisDataPlotSettings &settings);
277
278         virtual void pointsAdded(const AnalysisDataPointSetRef &points);
279
280         // Copy and assign disallowed by base.
281 };
282
283
284 /*! \brief
285  * Plotting module specifically for data consisting of vectors.
286  *
287  * See AbstractPlotModule for common plotting options.
288  *
289  * \inpublicapi
290  * \ingroup module_analysisdata
291  */
292 class AnalysisDataVectorPlotModule : public AbstractPlotModule
293 {
294     public:
295         AnalysisDataVectorPlotModule();
296         //! Creates AnalysisDataVectorPlotModule and assign common settings.
297         explicit AnalysisDataVectorPlotModule(const AnalysisDataPlotSettings &settings);
298
299         /*! \brief
300          * Set whether to write X component.
301          */
302         void setWriteX(bool bWrite);
303         /*! \brief
304          * Set whether to write Y component.
305          */
306         void setWriteY(bool bWrite);
307         /*! \brief
308          * Set whether to write Z component.
309          */
310         void setWriteZ(bool bWrite);
311         /*! \brief
312          * Set whether to write norm of the vector.
313          */
314         void setWriteNorm(bool bWrite);
315         /*! \brief
316          * Set mask for what to write.
317          */
318         void setWriteMask(const bool bWrite[4]);
319
320         virtual void pointsAdded(const AnalysisDataPointSetRef &points);
321
322     private:
323         bool                    bWrite_[4];
324
325         // Copy and assign disallowed by base.
326 };
327
328 //! Smart pointer to manage an AnalysisDataPlotModule object.
329 typedef std::shared_ptr<AnalysisDataPlotModule>
330     AnalysisDataPlotModulePointer;
331 //! Smart pointer to manage an AnalysisDataVectorPlotModule object.
332 typedef std::shared_ptr<AnalysisDataVectorPlotModule>
333     AnalysisDataVectorPlotModulePointer;
334
335 } // namespace gmx
336
337 #endif