3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
29 * For more info, check our website at http://www.gromacs.org
33 * Declares analysis data modules for calculating histograms.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
37 * \ingroup module_analysisdata
39 #ifndef GMX_ANALYSISDATA_MODULES_HISTOGRAM_H
40 #define GMX_ANALYSISDATA_MODULES_HISTOGRAM_H
42 #include "../abstractdata.h"
43 #include "../arraydata.h"
44 #include "../datamodule.h"
45 #include "../../utility/uniqueptr.h"
50 class AnalysisHistogramSettings;
53 * Provides "named parameter" idiom for constructing histograms.
55 * \see histogramFromBins()
56 * \see histogramFromRange()
58 * Methods in this class do not throw.
61 * \ingroup module_analysisdata
63 class AnalysisHistogramSettingsInitializer
67 * Creates an empty initializer.
69 * Should not be called directly, but histogramFromRange() or
70 * histogramFromBins() should be used instead.
72 AnalysisHistogramSettingsInitializer();
75 * Sets the first bin location.
77 * Typically should not be called directly, but through
78 * histogramFromBins().
80 AnalysisHistogramSettingsInitializer &start(real min)
81 { min_ = min; return *this; }
83 * Sets the number of bins in the histogram.
85 * If only the first bin location is specified, this value is required
86 * (and automatically provided if histogramFromBins() is used).
87 * If both the first and last bins are specified, either this value or
88 * binWidth() is required.
90 AnalysisHistogramSettingsInitializer &binCount(int binCount)
91 { binCount_ = binCount; return *this; }
93 * Sets the first and last bin locations.
95 * Typically should not be called directly, but through
96 * histogramFromRange().
98 AnalysisHistogramSettingsInitializer &range(real min, real max)
99 { min_ = min; max_ = max; return *this; }
101 * Sets the bin width of the histogram.
103 * If only the first bin location is specified, this value is required
104 * (and automatically provided if histogramFromBins() is used).
105 * If both the first and last bins are specified, either this value or
106 * binCount() is required.
107 * If a bin width is provided with both first and last bin locations,
108 * and the given bin width does not divide the range exactly, the last
109 * bin location is adjusted to match.
111 AnalysisHistogramSettingsInitializer &binWidth(real binWidth)
112 { binWidth_ = binWidth; return *this; }
114 * Indicate that first and last bin locations to specify bin centers.
116 * If set, the first and last bin locations are interpreted as bin
118 * If not set (the default), the first and last bin locations are
119 * interpreted as the edges of the whole histogram.
121 * Cannot be specified together with roundRange().
123 AnalysisHistogramSettingsInitializer &integerBins(bool enabled = true)
124 { bIntegerBins_ = enabled; return *this; }
126 * Round first and last bin locations.
128 * If set, the resulting histogram will cover the range specified, but
129 * the actual bin locations will be rounded such that the edges fall
130 * on multiples of the bin width.
131 * Only implemented when both first and last bin location and bin width
133 * Cannot be specified together with integerBins() or with binCount().
135 AnalysisHistogramSettingsInitializer &roundRange(bool enabled = true)
136 { bRoundRange_ = enabled; return *this; }
138 * Sets the histogram to match all values.
140 * If set, the histogram behaves as if the bins at the ends extended to
143 AnalysisHistogramSettingsInitializer &includeAll(bool enabled = true)
144 { bIncludeAll_ = enabled; return *this; }
155 friend class AnalysisHistogramSettings;
159 * Initializes a histogram using a range and a bin width.
165 inline AnalysisHistogramSettingsInitializer
166 histogramFromRange(real min, real max)
168 return AnalysisHistogramSettingsInitializer().range(min, max);
172 * Initializes a histogram using bin width and the number of bins.
178 inline AnalysisHistogramSettingsInitializer
179 histogramFromBins(real start, int nbins, real binwidth)
181 return AnalysisHistogramSettingsInitializer()
182 .start(start).binCount(nbins).binWidth(binwidth);
187 * Contains parameters that specify histogram bin locations.
189 * Methods in this class do not throw.
192 * \ingroup module_analysisdata
194 class AnalysisHistogramSettings
197 //! Initializes undefined parameters.
198 AnalysisHistogramSettings();
200 * Initializes parameters based on a named parameter object.
202 * This constructor is not explicit to allow initialization of
203 * histograms directly from AnalysisHistogramSettingsInitializer:
205 gmx::AnalysisDataSimpleHistogramModule *hist =
206 new gmx::AnalysisDataSimpleHistogramModule(
207 histogramFromRange(0.0, 5.0).binWidth(0.5));
210 AnalysisHistogramSettings(const AnalysisHistogramSettingsInitializer &settings);
212 //! Returns the left edge of the first bin.
213 real firstEdge() const { return firstEdge_; }
214 //! Returns the right edge of the first bin.
215 real lastEdge() const { return lastEdge_; }
216 //! Returns the number of bins in the histogram.
217 int binCount() const { return binCount_; }
218 //! Returns the width of a bin in the histogram.
219 real binWidth() const { return binWidth_; }
220 //! Whether values beyond the edges are mapped to the edge bins.
221 bool includeAll() const { return bAll_; }
222 //! Returns a zero-based bin index for a value, or -1 if not in range.
223 int findBin(real y) const;
229 real inverseBinWidth_;
238 class BasicHistogramImpl;
240 } // namespace internal
242 class AbstractAverageHistogram;
244 //! Smart pointer to manage an AbstractAverageHistogram object.
245 typedef gmx_unique_ptr<AbstractAverageHistogram>::type
246 AverageHistogramPointer;
249 * Base class for representing histograms averaged over frames.
251 * The averaging module for a per-frame histogram is always created by the
252 * histogram module class (e.g., AnalysisDataSimpleHistogramModule), and can be
253 * accessed using, e.g., AnalysisDataSimpleHistogramModule::averager().
254 * The user can alter some properties of the average histogram directly, but
255 * the main use of the object is to postprocess the histogram once the
256 * calculation is finished.
259 * \ingroup module_analysisdata
261 class AbstractAverageHistogram : public AbstractAnalysisArrayData
264 virtual ~AbstractAverageHistogram();
266 //! Returns bin properties for the histogram.
267 const AnalysisHistogramSettings &settings() const { return settings_; }
270 * Creates a copy of the histogram with double the bin width.
272 * \throws std::bad_alloc if out of memory.
274 * The caller is responsible of deleting the returned object.
276 AverageHistogramPointer resampleDoubleBinWidth(bool bIntegerBins) const;
278 * Creates a deep copy of the histogram.
280 * \throws std::bad_alloc if out of memory.
282 * The returned histogram is not necessarily of the same dynamic type
283 * as the original object, but contains the same data from the point of
284 * view of the AbstractAverageHistogram interface.
286 * The caller is responsible of deleting the returned object.
288 AverageHistogramPointer clone() const;
289 //! Normalizes the histogram such that the integral over it is one.
290 void normalizeProbability();
291 //! Scales the value of each bin by an uniform scaling factor.
292 void scale(real norm);
293 //! Scales the value of each bin by a different scaling factor.
294 void scaleVector(real norm[]);
296 * Notifies attached modules of the histogram data.
298 * After this function has been called, it is no longer possible to
299 * alter the histogram.
301 void done() { AbstractAnalysisArrayData::valuesReady(); }
305 * Creates a histogram module with undefined bins.
307 * Bin parameters must be defined with init() before data input is
310 AbstractAverageHistogram();
311 //! Creates a histogram module with defined bin parameters.
312 explicit AbstractAverageHistogram(const AnalysisHistogramSettings &settings);
315 * (Re)initializes the histogram from settings.
317 void init(const AnalysisHistogramSettings &settings);
320 AnalysisHistogramSettings settings_;
322 // Copy and assign disallowed by base.
327 * Data module for per-frame histograms.
329 * Output data contains the same number of frames as the input data.
330 * Each frame contains the histogram for the points in that frame.
331 * All input columns are averaged into the same histogram.
332 * The number of columns equals the number of bins in the histogram.
335 * \ingroup module_analysisdata
337 class AnalysisDataSimpleHistogramModule : public AbstractAnalysisData,
338 public AnalysisDataModuleInterface
342 * Creates a histogram module with undefined bins.
344 * Bin parameters must be defined with init() before data input is
347 AnalysisDataSimpleHistogramModule();
348 //! Creates a histogram module with defined bin parameters.
349 explicit AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings &settings);
350 virtual ~AnalysisDataSimpleHistogramModule();
353 * (Re)initializes the histogram from settings.
355 void init(const AnalysisHistogramSettings &settings);
358 * Returns the average histogram over all frames.
360 * Can be called already before the histogram is calculated to
361 * customize the way the average histogram is calculated.
363 * \see AbstractAverageHistogram
365 AbstractAverageHistogram &averager();
367 //! Returns bin properties for the histogram.
368 const AnalysisHistogramSettings &settings() const;
370 virtual int flags() const;
372 virtual void dataStarted(AbstractAnalysisData *data);
373 virtual void frameStarted(const AnalysisDataFrameHeader &header);
374 virtual void pointsAdded(const AnalysisDataPointSetRef &points);
375 virtual void frameFinished(const AnalysisDataFrameHeader &header);
376 virtual void dataFinished();
379 virtual AnalysisDataFrameRef tryGetDataFrameInternal(int index) const;
380 virtual bool requestStorageInternal(int nframes);
382 PrivateImplPointer<internal::BasicHistogramImpl> impl_;
384 // Copy and assign disallowed by base.
389 * Data module for per-frame weighted histograms.
391 * Output data contains the same number of frames as the input data.
392 * Each frame contains the histogram for the points in that frame, interpreted
393 * such that the first column passed to pointsAdded() determines the bin and
394 * the rest give weights to be added to that bin (input data should have at
395 * least two colums, and at least two columns should be added at the same time).
396 * All input columns are averaged into the same histogram.
397 * The number of columns equals the number of bins in the histogram.
400 * \ingroup module_analysisdata
402 class AnalysisDataWeightedHistogramModule : public AbstractAnalysisData,
403 public AnalysisDataModuleInterface
406 //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule()
407 AnalysisDataWeightedHistogramModule();
408 //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings &)
409 explicit AnalysisDataWeightedHistogramModule(const AnalysisHistogramSettings &settings);
410 virtual ~AnalysisDataWeightedHistogramModule();
412 //! \copydoc AnalysisDataSimpleHistogramModule::init()
413 void init(const AnalysisHistogramSettings &settings);
415 //! \copydoc AnalysisDataSimpleHistogramModule::averager()
416 AbstractAverageHistogram &averager();
418 //! \copydoc AnalysisDataSimpleHistogramModule::settings()
419 const AnalysisHistogramSettings &settings() const;
421 virtual int flags() const;
423 virtual void dataStarted(AbstractAnalysisData *data);
424 virtual void frameStarted(const AnalysisDataFrameHeader &header);
425 virtual void pointsAdded(const AnalysisDataPointSetRef &points);
426 virtual void frameFinished(const AnalysisDataFrameHeader &header);
427 virtual void dataFinished();
430 virtual AnalysisDataFrameRef tryGetDataFrameInternal(int index) const;
431 virtual bool requestStorageInternal(int nframes);
433 PrivateImplPointer<internal::BasicHistogramImpl> impl_;
435 // Copy and assign disallowed by base.
440 * Data module for bin averages.
442 * Output data contains one row for each bin; see AbstractAverageHistogram.
443 * Output data contains three columns: the first is the average over all frames
444 * for that bin, the second is the standard deviation of the values, and the
445 * third is the number of samples in that bin.
446 * The input data is interpreted such that the first column passed to
447 * pointsAdded() determines the bin and the rest give values to be added to
448 * that bin (input data should have at least two colums, and at least two
449 * columns should be added at the same time).
450 * All input columns are averaged into the same histogram.
453 * \ingroup module_analysisdata
455 class AnalysisDataBinAverageModule : public AbstractAnalysisArrayData,
456 public AnalysisDataModuleInterface
459 //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule()
460 AnalysisDataBinAverageModule();
461 //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings &)
462 explicit AnalysisDataBinAverageModule(const AnalysisHistogramSettings &settings);
463 virtual ~AnalysisDataBinAverageModule();
465 //! \copydoc AnalysisDataSimpleHistogramModule::init()
466 void init(const AnalysisHistogramSettings &settings);
468 //! \copydoc AnalysisDataSimpleHistogramModule::settings()
469 const AnalysisHistogramSettings &settings() const { return settings_; }
471 virtual int flags() const;
473 virtual void dataStarted(AbstractAnalysisData *data);
474 virtual void frameStarted(const AnalysisDataFrameHeader &header);
475 virtual void pointsAdded(const AnalysisDataPointSetRef &points);
476 virtual void frameFinished(const AnalysisDataFrameHeader &header);
477 virtual void dataFinished();
480 AnalysisHistogramSettings settings_;
482 // Copy and assign disallowed by base.
485 //! Smart pointer to manage an AnalysisDataSimpleHistogramModule object.
486 typedef boost::shared_ptr<AnalysisDataSimpleHistogramModule>
487 AnalysisDataSimpleHistogramModulePointer;
488 //! Smart pointer to manage an AnalysisDataWeightedHistogramModule object.
489 typedef boost::shared_ptr<AnalysisDataWeightedHistogramModule>
490 AnalysisDataWeightedHistogramModulePointer;
491 //! Smart pointer to manage an AnalysisDataBinAverageModule object.
492 typedef boost::shared_ptr<AnalysisDataBinAverageModule>
493 AnalysisDataBinAverageModulePointer;