2 * This file is part of the GROMACS molecular simulation package.
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.
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.
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.
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.
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.
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.
37 * Implements classes in histogram.h.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \ingroup module_analysisdata
44 #include "histogram.h"
51 #include "gromacs/analysisdata/dataframe.h"
52 #include "gromacs/analysisdata/datastorage.h"
53 #include "gromacs/analysisdata/framelocaldata.h"
54 #include "gromacs/utility/basedefinitions.h"
55 #include "gromacs/utility/exceptions.h"
56 #include "gromacs/utility/gmxassert.h"
58 #include "frameaverager.h"
63 //! Value used to signify that a real-valued histogram setting is not set.
64 const real UNDEFINED = std::numeric_limits<real>::max();
65 //! Checks whether \p value is defined.
66 bool isDefined(real value)
68 return value != UNDEFINED;
76 /********************************************************************
77 * AnalysisHistogramSettingsInitializer
80 AnalysisHistogramSettingsInitializer::AnalysisHistogramSettingsInitializer()
81 : min_(UNDEFINED), max_(UNDEFINED), binWidth_(UNDEFINED),
82 binCount_(0), bIntegerBins_(false), bRoundRange_(false),
88 /********************************************************************
89 * AnalysisHistogramSettings
92 AnalysisHistogramSettings::AnalysisHistogramSettings()
93 : firstEdge_(0.0), lastEdge_(0.0), binWidth_(0.0), inverseBinWidth_(0.0),
94 binCount_(0), bAll_(false)
99 AnalysisHistogramSettings::AnalysisHistogramSettings(
100 const AnalysisHistogramSettingsInitializer &settings)
102 GMX_RELEASE_ASSERT(isDefined(settings.min_),
103 "Histogram start value must be defined");
104 GMX_RELEASE_ASSERT(!isDefined(settings.max_) || settings.max_ > settings.min_,
105 "Histogram end value must be larger than start value");
106 GMX_RELEASE_ASSERT(!isDefined(settings.binWidth_) || settings.binWidth_ > 0.0,
107 "Histogram bin width must be positive");
108 GMX_RELEASE_ASSERT(settings.binCount_ >= 0,
109 "Histogram bin count must be positive");
111 if (!isDefined(settings.max_))
113 GMX_RELEASE_ASSERT(isDefined(settings.binWidth_) && settings.binCount_ > 0,
114 "Not all required values provided");
115 GMX_RELEASE_ASSERT(!settings.bRoundRange_,
116 "Rounding only supported for min/max ranges");
118 firstEdge_ = settings.min_;
119 binCount_ = settings.binCount_;
120 binWidth_ = settings.binWidth_;
121 if (settings.bIntegerBins_)
123 firstEdge_ -= 0.5 * binWidth_;
125 lastEdge_ = firstEdge_ + binCount_ * binWidth_;
129 GMX_RELEASE_ASSERT(!(isDefined(settings.binWidth_) && settings.binCount_ > 0),
130 "Conflicting histogram bin specifications");
131 GMX_RELEASE_ASSERT(isDefined(settings.binWidth_) || settings.binCount_ > 0,
132 "Not all required values provided");
134 if (settings.bRoundRange_)
136 GMX_RELEASE_ASSERT(!settings.bIntegerBins_,
137 "Rounding and integer bins cannot be combined");
138 GMX_RELEASE_ASSERT(isDefined(settings.binWidth_),
139 "Rounding only makes sense with defined binwidth");
140 binWidth_ = settings.binWidth_;
141 firstEdge_ = binWidth_ * floor(settings.min_ / binWidth_);
142 lastEdge_ = binWidth_ * ceil(settings.max_ / binWidth_);
143 binCount_ = static_cast<int>((lastEdge_ - firstEdge_) / binWidth_ + 0.5);
147 firstEdge_ = settings.min_;
148 lastEdge_ = settings.max_;
149 if (settings.binCount_ > 0)
151 binCount_ = settings.binCount_;
152 if (settings.bIntegerBins_)
154 GMX_RELEASE_ASSERT(settings.binCount_ > 1,
155 "Bin count must be at least two with integer bins");
156 binWidth_ = (lastEdge_ - firstEdge_) / (binCount_ - 1);
157 firstEdge_ -= 0.5 * binWidth_;
158 lastEdge_ += 0.5 * binWidth_;
162 binWidth_ = (lastEdge_ - firstEdge_) / binCount_;
167 binWidth_ = settings.binWidth_;
168 binCount_ = static_cast<int>((lastEdge_ - firstEdge_) / binWidth_ + 0.5);
169 if (settings.bIntegerBins_)
171 firstEdge_ -= 0.5 * binWidth_;
174 lastEdge_ = firstEdge_ + binCount_ * binWidth_;
179 inverseBinWidth_ = 1.0 / binWidth_;
180 bAll_ = settings.bIncludeAll_;
185 AnalysisHistogramSettings::findBin(real y) const
189 return bAll_ ? 0 : -1;
191 int bin = static_cast<int>((y - firstEdge_) * inverseBinWidth_);
192 if (bin >= binCount_)
194 return bAll_ ? binCount_ - 1 : -1;
200 /********************************************************************
201 * StaticAverageHistogram
208 * Represents copies of average histograms.
210 * Methods in AbstractAverageHistogram that return new histogram instances
211 * return objects of this class.
212 * Initialization of values is handled in those methods.
214 * \ingroup module_analysisdata
216 class StaticAverageHistogram : public AbstractAverageHistogram
219 StaticAverageHistogram();
220 //! Creates an average histogram module with defined bin parameters.
221 explicit StaticAverageHistogram(const AnalysisHistogramSettings &settings);
223 // Copy and assign disallowed by base.
226 StaticAverageHistogram::StaticAverageHistogram()
231 StaticAverageHistogram::StaticAverageHistogram(
232 const AnalysisHistogramSettings &settings)
233 : AbstractAverageHistogram(settings)
240 /********************************************************************
241 * AbstractAverageHistogram
244 AbstractAverageHistogram::AbstractAverageHistogram()
249 AbstractAverageHistogram::AbstractAverageHistogram(
250 const AnalysisHistogramSettings &settings)
251 : settings_(settings)
253 setRowCount(settings.binCount());
254 setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(),
255 settings.binWidth());
259 AbstractAverageHistogram::~AbstractAverageHistogram()
265 AbstractAverageHistogram::init(const AnalysisHistogramSettings &settings)
267 settings_ = settings;
268 setRowCount(settings.binCount());
269 setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(),
270 settings.binWidth());
274 AverageHistogramPointer
275 AbstractAverageHistogram::resampleDoubleBinWidth(bool bIntegerBins) const
280 nbins = (rowCount() + 1) / 2;
284 nbins = rowCount() / 2;
287 AverageHistogramPointer dest(
288 new StaticAverageHistogram(
289 histogramFromBins(xstart(), nbins, 2*xstep())
290 .integerBins(bIntegerBins)));
291 dest->setColumnCount(columnCount());
292 dest->allocateValues();
295 for (i = j = 0; i < nbins; ++i)
297 const bool bFirstHalfBin = (bIntegerBins && i == 0);
298 for (int c = 0; c < columnCount(); ++c)
304 v1 = value(0, c).value();
305 e1 = value(0, c).error();
311 v1 = value(j, c).value();
312 e1 = value(j, c).error();
313 v2 = value(j + 1, c).value();
314 e2 = value(j + 1, c).error();
316 dest->value(i, c).setValue(v1 + v2, std::sqrt(e1 * e1 + e2 * e2));
331 AverageHistogramPointer
332 AbstractAverageHistogram::clone() const
334 AverageHistogramPointer dest(new StaticAverageHistogram());
335 copyContents(this, dest.get());
336 dest->settings_ = settings_;
342 AbstractAverageHistogram::normalizeProbability()
344 for (int c = 0; c < columnCount(); ++c)
347 for (int i = 0; i < rowCount(); ++i)
349 sum += value(i, c).value();
353 scaleSingle(c, 1.0 / (sum * xstep()));
359 AbstractAverageHistogram::makeCumulative()
361 for (int c = 0; c < columnCount(); ++c)
364 for (int i = 0; i < rowCount(); ++i)
366 sum += value(i, c).value();
367 // Clear the error, as we don't cumulate that.
369 value(i, c).setValue(sum);
372 setXAxis(settings().firstEdge() + settings().binWidth(),
373 settings().binWidth());
378 AbstractAverageHistogram::scaleSingle(int index, real factor)
380 for (int i = 0; i < rowCount(); ++i)
382 value(i, index).value() *= factor;
383 value(i, index).error() *= factor;
389 AbstractAverageHistogram::scaleAll(real factor)
391 for (int i = 0; i < columnCount(); ++i)
393 scaleSingle(i, factor);
399 AbstractAverageHistogram::scaleAllByVector(real factor[])
401 for (int c = 0; c < columnCount(); ++c)
403 for (int i = 0; i < rowCount(); ++i)
405 value(i, c).value() *= factor[i];
406 value(i, c).error() *= factor[i];
412 /********************************************************************
413 * BasicAverageHistogramModule
421 * Implements average histogram module that averages per-frame histograms.
423 * This class is used for accumulating average histograms in per-frame
424 * histogram modules (those that use BasicHistogramImpl as their implementation
426 * There are two columns, first for the average and second for standard
429 * \ingroup module_analysisdata
431 class BasicAverageHistogramModule : public AbstractAverageHistogram,
432 public AnalysisDataModuleSerial
435 BasicAverageHistogramModule();
436 //! Creates an average histogram module with defined bin parameters.
437 explicit BasicAverageHistogramModule(const AnalysisHistogramSettings &settings);
439 using AbstractAverageHistogram::init;
441 virtual int flags() const;
443 virtual void dataStarted(AbstractAnalysisData *data);
444 virtual void frameStarted(const AnalysisDataFrameHeader &header);
445 virtual void pointsAdded(const AnalysisDataPointSetRef &points);
446 virtual void frameFinished(const AnalysisDataFrameHeader &header);
447 virtual void dataFinished();
450 //! Averaging helper objects for each input data set.
451 std::vector<AnalysisDataFrameAverager> averagers_;
453 // Copy and assign disallowed by base.
456 BasicAverageHistogramModule::BasicAverageHistogramModule()
461 BasicAverageHistogramModule::BasicAverageHistogramModule(
462 const AnalysisHistogramSettings &settings)
463 : AbstractAverageHistogram(settings)
469 BasicAverageHistogramModule::flags() const
471 return efAllowMulticolumn | efAllowMultipleDataSets;
476 BasicAverageHistogramModule::dataStarted(AbstractAnalysisData *data)
478 setColumnCount(data->dataSetCount());
479 averagers_.resize(data->dataSetCount());
480 for (int i = 0; i < data->dataSetCount(); ++i)
482 GMX_RELEASE_ASSERT(rowCount() == data->columnCount(i),
483 "Inconsistent data sizes, something is wrong in the initialization");
484 averagers_[i].setColumnCount(data->columnCount(i));
490 BasicAverageHistogramModule::frameStarted(const AnalysisDataFrameHeader & /*header*/)
496 BasicAverageHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points)
498 averagers_[points.dataSetIndex()].addPoints(points);
503 BasicAverageHistogramModule::frameFinished(const AnalysisDataFrameHeader & /*header*/)
509 BasicAverageHistogramModule::dataFinished()
512 for (int i = 0; i < columnCount(); ++i)
514 averagers_[i].finish();
515 for (int j = 0; j < rowCount(); ++j)
517 value(j, i).setValue(averagers_[i].average(j),
518 std::sqrt(averagers_[i].variance(j)));
524 /********************************************************************
530 * Base class for private implementation classes for histogram modules.
532 * Actual implementation classes are derived from this and add an accumulation
533 * data member that is specific to the histogram type in question.
534 * This is done like this to keep implementation details out of the header, and
535 * to not unnecessarily duplicate code.
537 * \ingroup module_analysisdata
539 class BasicHistogramImpl
542 //! Smart pointer to manage an BasicAverageHistogramModule object.
543 typedef boost::shared_ptr<BasicAverageHistogramModule>
544 BasicAverageHistogramModulePointer;
546 BasicHistogramImpl();
547 //! Creates an histogram impl with defined bin parameters.
548 explicit BasicHistogramImpl(const AnalysisHistogramSettings &settings);
549 // Virtual only for simplicity.
550 virtual ~BasicHistogramImpl();
553 * (Re)initializes the histogram from settings.
555 void init(const AnalysisHistogramSettings &settings);
557 //! Storage implementation object.
558 AnalysisDataStorage storage_;
559 //! Settings for the histogram object.
560 AnalysisHistogramSettings settings_;
562 BasicAverageHistogramModulePointer averager_;
565 BasicHistogramImpl::BasicHistogramImpl()
566 : averager_(new BasicAverageHistogramModule())
571 BasicHistogramImpl::BasicHistogramImpl(const AnalysisHistogramSettings &settings)
572 : settings_(settings), averager_(new BasicAverageHistogramModule(settings))
577 BasicHistogramImpl::~BasicHistogramImpl()
582 void BasicHistogramImpl::init(const AnalysisHistogramSettings &settings)
584 settings_ = settings;
585 averager_->init(settings);
588 } // namespace internal
591 /********************************************************************
592 * AnalysisDataSimpleHistogramModule
596 * Private implementation class for AnalysisDataSimpleHistogramModule.
598 * \ingroup module_analysisdata
600 class AnalysisDataSimpleHistogramModule::Impl : public internal::BasicHistogramImpl
603 //! Shorthand for the per-frame accumulation data structure type.
604 typedef AnalysisDataFrameLocalData<gmx_int64_t> FrameLocalData;
607 //! Creates an histogram impl with defined bin parameters.
608 explicit Impl(const AnalysisHistogramSettings &settings)
609 : BasicHistogramImpl(settings)
613 //! Accumulates the histogram within a frame.
614 FrameLocalData accumulator_;
617 AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule()
623 AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(
624 const AnalysisHistogramSettings &settings)
625 : impl_(new Impl(settings))
630 AnalysisDataSimpleHistogramModule::~AnalysisDataSimpleHistogramModule()
635 void AnalysisDataSimpleHistogramModule::init(const AnalysisHistogramSettings &settings)
637 impl_->init(settings);
641 AbstractAverageHistogram &
642 AnalysisDataSimpleHistogramModule::averager()
644 return *impl_->averager_;
648 const AnalysisHistogramSettings &
649 AnalysisDataSimpleHistogramModule::settings() const
651 return impl_->settings_;
656 AnalysisDataSimpleHistogramModule::frameCount() const
658 return impl_->storage_.frameCount();
663 AnalysisDataSimpleHistogramModule::flags() const
665 return efAllowMulticolumn | efAllowMultipoint | efAllowMissing
666 | efAllowMultipleDataSets;
671 AnalysisDataSimpleHistogramModule::parallelDataStarted(
672 AbstractAnalysisData *data,
673 const AnalysisDataParallelOptions &options)
675 addModule(impl_->averager_);
676 const int dataSetCount = data->dataSetCount();
677 const int columnCount = settings().binCount();
678 setDataSetCount(dataSetCount);
679 impl_->accumulator_.setDataSetCount(dataSetCount);
680 for (int i = 0; i < dataSetCount; ++i)
682 setColumnCount(i, columnCount);
683 impl_->accumulator_.setColumnCount(i, columnCount);
685 impl_->accumulator_.init(options);
686 impl_->storage_.startParallelDataStorage(this, &moduleManager(), options);
692 AnalysisDataSimpleHistogramModule::frameStarted(const AnalysisDataFrameHeader &header)
694 impl_->accumulator_.frameData(header.index()).clear();
699 AnalysisDataSimpleHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points)
701 Impl::FrameLocalData::DataSetHandle handle
702 = impl_->accumulator_.frameDataSet(points.frameIndex(), points.dataSetIndex());
703 for (int i = 0; i < points.columnCount(); ++i)
705 if (points.present(i))
707 const int bin = settings().findBin(points.y(i));
710 handle.value(bin) += 1;
718 AnalysisDataSimpleHistogramModule::frameFinished(const AnalysisDataFrameHeader &header)
720 Impl::FrameLocalData::FrameHandle handle
721 = impl_->accumulator_.frameData(header.index());
722 AnalysisDataStorageFrame &frame = impl_->storage_.startFrame(header);
723 const int columnCount = settings().binCount();
724 for (int s = 0; s < dataSetCount(); ++s)
726 Impl::FrameLocalData::DataSetHandle dataSet = handle.dataSet(s);
727 frame.selectDataSet(s);
728 for (int i = 0; i < columnCount; ++i)
730 frame.setValue(i, dataSet.value(i));
738 AnalysisDataSimpleHistogramModule::dataFinished()
740 impl_->storage_.finishDataStorage();
745 AnalysisDataSimpleHistogramModule::tryGetDataFrameInternal(int index) const
747 return impl_->storage_.tryGetDataFrame(index);
752 AnalysisDataSimpleHistogramModule::requestStorageInternal(int nframes)
754 return impl_->storage_.requestStorage(nframes);
758 /********************************************************************
759 * AnalysisDataWeightedHistogramModule
763 * Private implementation class for AnalysisDataWeightedHistogramModule.
765 * \ingroup module_analysisdata
767 class AnalysisDataWeightedHistogramModule::Impl : public internal::BasicHistogramImpl
770 //! Shorthand for the per-frame accumulation data structure type.
771 typedef AnalysisDataFrameLocalData<double> FrameLocalData;
774 //! Creates an histogram impl with defined bin parameters.
775 explicit Impl(const AnalysisHistogramSettings &settings)
776 : BasicHistogramImpl(settings)
780 //! Accumulates the histogram within a frame.
781 FrameLocalData accumulator_;
784 AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule()
790 AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule(
791 const AnalysisHistogramSettings &settings)
792 : impl_(new Impl(settings))
797 AnalysisDataWeightedHistogramModule::~AnalysisDataWeightedHistogramModule()
802 void AnalysisDataWeightedHistogramModule::init(const AnalysisHistogramSettings &settings)
804 impl_->init(settings);
808 AbstractAverageHistogram &
809 AnalysisDataWeightedHistogramModule::averager()
811 return *impl_->averager_;
815 const AnalysisHistogramSettings &
816 AnalysisDataWeightedHistogramModule::settings() const
818 return impl_->settings_;
823 AnalysisDataWeightedHistogramModule::frameCount() const
825 return impl_->storage_.frameCount();
830 AnalysisDataWeightedHistogramModule::flags() const
832 return efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets;
837 AnalysisDataWeightedHistogramModule::parallelDataStarted(
838 AbstractAnalysisData *data,
839 const AnalysisDataParallelOptions &options)
841 addModule(impl_->averager_);
842 const int dataSetCount = data->dataSetCount();
843 const int columnCount = settings().binCount();
844 setDataSetCount(dataSetCount);
845 impl_->accumulator_.setDataSetCount(dataSetCount);
846 for (int i = 0; i < dataSetCount; ++i)
848 setColumnCount(i, columnCount);
849 impl_->accumulator_.setColumnCount(i, columnCount);
851 impl_->accumulator_.init(options);
852 impl_->storage_.startParallelDataStorage(this, &moduleManager(), options);
858 AnalysisDataWeightedHistogramModule::frameStarted(const AnalysisDataFrameHeader &header)
860 impl_->accumulator_.frameData(header.index()).clear();
865 AnalysisDataWeightedHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points)
867 if (points.firstColumn() != 0 || points.columnCount() < 2)
869 GMX_THROW(APIError("Invalid data layout"));
871 int bin = settings().findBin(points.y(0));
874 Impl::FrameLocalData::DataSetHandle handle
875 = impl_->accumulator_.frameDataSet(points.frameIndex(), points.dataSetIndex());
876 for (int i = 1; i < points.columnCount(); ++i)
878 handle.value(bin) += points.y(i);
885 AnalysisDataWeightedHistogramModule::frameFinished(const AnalysisDataFrameHeader &header)
887 Impl::FrameLocalData::FrameHandle handle
888 = impl_->accumulator_.frameData(header.index());
889 AnalysisDataStorageFrame &frame = impl_->storage_.startFrame(header);
890 const int columnCount = settings().binCount();
891 for (int s = 0; s < dataSetCount(); ++s)
893 Impl::FrameLocalData::DataSetHandle dataSet = handle.dataSet(s);
894 frame.selectDataSet(s);
895 for (int i = 0; i < columnCount; ++i)
897 frame.setValue(i, dataSet.value(i));
905 AnalysisDataWeightedHistogramModule::dataFinished()
907 impl_->storage_.finishDataStorage();
912 AnalysisDataWeightedHistogramModule::tryGetDataFrameInternal(int index) const
914 return impl_->storage_.tryGetDataFrame(index);
919 AnalysisDataWeightedHistogramModule::requestStorageInternal(int nframes)
921 return impl_->storage_.requestStorage(nframes);
925 /********************************************************************
926 * AnalysisDataBinAverageModule
929 class AnalysisDataBinAverageModule::Impl
933 explicit Impl(const AnalysisHistogramSettings &settings)
934 : settings_(settings)
938 //! Histogram settings.
939 AnalysisHistogramSettings settings_;
940 //! Averaging helper objects for each input data set.
941 std::vector<AnalysisDataFrameAverager> averagers_;
944 AnalysisDataBinAverageModule::AnalysisDataBinAverageModule()
951 AnalysisDataBinAverageModule::AnalysisDataBinAverageModule(
952 const AnalysisHistogramSettings &settings)
953 : impl_(new Impl(settings))
955 setRowCount(settings.binCount());
956 setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(),
957 settings.binWidth());
961 AnalysisDataBinAverageModule::~AnalysisDataBinAverageModule()
967 AnalysisDataBinAverageModule::init(const AnalysisHistogramSettings &settings)
969 impl_->settings_ = settings;
970 setRowCount(settings.binCount());
971 setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(),
972 settings.binWidth());
976 const AnalysisHistogramSettings &
977 AnalysisDataBinAverageModule::settings() const
979 return impl_->settings_;
984 AnalysisDataBinAverageModule::flags() const
986 return efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets;
991 AnalysisDataBinAverageModule::dataStarted(AbstractAnalysisData *data)
993 setColumnCount(data->dataSetCount());
994 impl_->averagers_.resize(data->dataSetCount());
995 for (int i = 0; i < data->dataSetCount(); ++i)
997 impl_->averagers_[i].setColumnCount(rowCount());
1003 AnalysisDataBinAverageModule::frameStarted(const AnalysisDataFrameHeader & /*header*/)
1009 AnalysisDataBinAverageModule::pointsAdded(const AnalysisDataPointSetRef &points)
1011 if (points.firstColumn() != 0 || points.columnCount() < 2)
1013 GMX_THROW(APIError("Invalid data layout"));
1015 int bin = settings().findBin(points.y(0));
1018 AnalysisDataFrameAverager &averager = impl_->averagers_[points.dataSetIndex()];
1019 for (int i = 1; i < points.columnCount(); ++i)
1021 averager.addValue(bin, points.y(i));
1028 AnalysisDataBinAverageModule::frameFinished(const AnalysisDataFrameHeader & /*header*/)
1034 AnalysisDataBinAverageModule::dataFinished()
1037 for (int i = 0; i < columnCount(); ++i)
1039 AnalysisDataFrameAverager &averager = impl_->averagers_[i];
1041 for (int j = 0; j < rowCount(); ++j)
1043 value(j, i).setValue(averager.average(j),
1044 std::sqrt(averager.variance(j)));