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());
341 AbstractAverageHistogram::normalizeProbability()
343 for (int c = 0; c < columnCount(); ++c)
346 for (int i = 0; i < rowCount(); ++i)
348 sum += value(i, c).value();
352 scaleSingle(c, 1.0 / (sum * xstep()));
359 AbstractAverageHistogram::scaleSingle(int index, real factor)
361 for (int i = 0; i < rowCount(); ++i)
363 value(i, index).value() *= factor;
364 value(i, index).error() *= factor;
370 AbstractAverageHistogram::scaleAll(real factor)
372 for (int i = 0; i < columnCount(); ++i)
374 scaleSingle(i, factor);
380 AbstractAverageHistogram::scaleAllByVector(real factor[])
382 for (int c = 0; c < columnCount(); ++c)
384 for (int i = 0; i < rowCount(); ++i)
386 value(i, c).value() *= factor[i];
387 value(i, c).error() *= factor[i];
393 /********************************************************************
394 * BasicAverageHistogramModule
402 * Implements average histogram module that averages per-frame histograms.
404 * This class is used for accumulating average histograms in per-frame
405 * histogram modules (those that use BasicHistogramImpl as their implementation
407 * There are two columns, first for the average and second for standard
410 * \ingroup module_analysisdata
412 class BasicAverageHistogramModule : public AbstractAverageHistogram,
413 public AnalysisDataModuleSerial
416 BasicAverageHistogramModule();
417 //! Creates an average histogram module with defined bin parameters.
418 explicit BasicAverageHistogramModule(const AnalysisHistogramSettings &settings);
420 using AbstractAverageHistogram::init;
422 virtual int flags() const;
424 virtual void dataStarted(AbstractAnalysisData *data);
425 virtual void frameStarted(const AnalysisDataFrameHeader &header);
426 virtual void pointsAdded(const AnalysisDataPointSetRef &points);
427 virtual void frameFinished(const AnalysisDataFrameHeader &header);
428 virtual void dataFinished();
431 //! Averaging helper objects for each input data set.
432 std::vector<AnalysisDataFrameAverager> averagers_;
434 // Copy and assign disallowed by base.
437 BasicAverageHistogramModule::BasicAverageHistogramModule()
442 BasicAverageHistogramModule::BasicAverageHistogramModule(
443 const AnalysisHistogramSettings &settings)
444 : AbstractAverageHistogram(settings)
450 BasicAverageHistogramModule::flags() const
452 return efAllowMulticolumn | efAllowMultipleDataSets;
457 BasicAverageHistogramModule::dataStarted(AbstractAnalysisData *data)
459 setColumnCount(data->dataSetCount());
460 averagers_.resize(data->dataSetCount());
461 for (int i = 0; i < data->dataSetCount(); ++i)
463 GMX_RELEASE_ASSERT(rowCount() == data->columnCount(i),
464 "Inconsistent data sizes, something is wrong in the initialization");
465 averagers_[i].setColumnCount(data->columnCount(i));
471 BasicAverageHistogramModule::frameStarted(const AnalysisDataFrameHeader & /*header*/)
477 BasicAverageHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points)
479 averagers_[points.dataSetIndex()].addPoints(points);
484 BasicAverageHistogramModule::frameFinished(const AnalysisDataFrameHeader & /*header*/)
490 BasicAverageHistogramModule::dataFinished()
493 for (int i = 0; i < columnCount(); ++i)
495 averagers_[i].finish();
496 for (int j = 0; j < rowCount(); ++j)
498 value(j, i).setValue(averagers_[i].average(j),
499 std::sqrt(averagers_[i].variance(j)));
505 /********************************************************************
511 * Base class for private implementation classes for histogram modules.
513 * Actual implementation classes are derived from this and add an accumulation
514 * data member that is specific to the histogram type in question.
515 * This is done like this to keep implementation details out of the header, and
516 * to not unnecessarily duplicate code.
518 * \ingroup module_analysisdata
520 class BasicHistogramImpl
523 //! Smart pointer to manage an BasicAverageHistogramModule object.
524 typedef boost::shared_ptr<BasicAverageHistogramModule>
525 BasicAverageHistogramModulePointer;
527 BasicHistogramImpl();
528 //! Creates an histogram impl with defined bin parameters.
529 explicit BasicHistogramImpl(const AnalysisHistogramSettings &settings);
530 // Virtual only for simplicity.
531 virtual ~BasicHistogramImpl();
534 * (Re)initializes the histogram from settings.
536 void init(const AnalysisHistogramSettings &settings);
538 //! Storage implementation object.
539 AnalysisDataStorage storage_;
540 //! Settings for the histogram object.
541 AnalysisHistogramSettings settings_;
543 BasicAverageHistogramModulePointer averager_;
546 BasicHistogramImpl::BasicHistogramImpl()
547 : averager_(new BasicAverageHistogramModule())
552 BasicHistogramImpl::BasicHistogramImpl(const AnalysisHistogramSettings &settings)
553 : settings_(settings), averager_(new BasicAverageHistogramModule(settings))
558 BasicHistogramImpl::~BasicHistogramImpl()
563 void BasicHistogramImpl::init(const AnalysisHistogramSettings &settings)
565 settings_ = settings;
566 averager_->init(settings);
569 } // namespace internal
572 /********************************************************************
573 * AnalysisDataSimpleHistogramModule
577 * Private implementation class for AnalysisDataSimpleHistogramModule.
579 * \ingroup module_analysisdata
581 class AnalysisDataSimpleHistogramModule::Impl : public internal::BasicHistogramImpl
584 //! Shorthand for the per-frame accumulation data structure type.
585 typedef AnalysisDataFrameLocalData<gmx_int64_t> FrameLocalData;
588 //! Creates an histogram impl with defined bin parameters.
589 explicit Impl(const AnalysisHistogramSettings &settings)
590 : BasicHistogramImpl(settings)
594 //! Accumulates the histogram within a frame.
595 FrameLocalData accumulator_;
598 AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule()
604 AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(
605 const AnalysisHistogramSettings &settings)
606 : impl_(new Impl(settings))
611 AnalysisDataSimpleHistogramModule::~AnalysisDataSimpleHistogramModule()
616 void AnalysisDataSimpleHistogramModule::init(const AnalysisHistogramSettings &settings)
618 impl_->init(settings);
622 AbstractAverageHistogram &
623 AnalysisDataSimpleHistogramModule::averager()
625 return *impl_->averager_;
629 const AnalysisHistogramSettings &
630 AnalysisDataSimpleHistogramModule::settings() const
632 return impl_->settings_;
637 AnalysisDataSimpleHistogramModule::frameCount() const
639 return impl_->storage_.frameCount();
644 AnalysisDataSimpleHistogramModule::flags() const
646 return efAllowMulticolumn | efAllowMultipoint | efAllowMissing
647 | efAllowMultipleDataSets;
652 AnalysisDataSimpleHistogramModule::parallelDataStarted(
653 AbstractAnalysisData *data,
654 const AnalysisDataParallelOptions &options)
656 addModule(impl_->averager_);
657 const int dataSetCount = data->dataSetCount();
658 const int columnCount = settings().binCount();
659 setDataSetCount(dataSetCount);
660 impl_->accumulator_.setDataSetCount(dataSetCount);
661 for (int i = 0; i < dataSetCount; ++i)
663 setColumnCount(i, columnCount);
664 impl_->accumulator_.setColumnCount(i, columnCount);
666 impl_->accumulator_.init(options);
667 impl_->storage_.startParallelDataStorage(this, &moduleManager(), options);
673 AnalysisDataSimpleHistogramModule::frameStarted(const AnalysisDataFrameHeader &header)
675 impl_->accumulator_.frameData(header.index()).clear();
680 AnalysisDataSimpleHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points)
682 Impl::FrameLocalData::DataSetHandle handle
683 = impl_->accumulator_.frameDataSet(points.frameIndex(), points.dataSetIndex());
684 for (int i = 0; i < points.columnCount(); ++i)
686 if (points.present(i))
688 const int bin = settings().findBin(points.y(i));
691 handle.value(bin) += 1;
699 AnalysisDataSimpleHistogramModule::frameFinished(const AnalysisDataFrameHeader &header)
701 Impl::FrameLocalData::FrameHandle handle
702 = impl_->accumulator_.frameData(header.index());
703 AnalysisDataStorageFrame &frame = impl_->storage_.startFrame(header);
704 const int columnCount = settings().binCount();
705 for (int s = 0; s < dataSetCount(); ++s)
707 Impl::FrameLocalData::DataSetHandle dataSet = handle.dataSet(s);
708 frame.selectDataSet(s);
709 for (int i = 0; i < columnCount; ++i)
711 frame.setValue(i, dataSet.value(i));
719 AnalysisDataSimpleHistogramModule::dataFinished()
721 impl_->storage_.finishDataStorage();
726 AnalysisDataSimpleHistogramModule::tryGetDataFrameInternal(int index) const
728 return impl_->storage_.tryGetDataFrame(index);
733 AnalysisDataSimpleHistogramModule::requestStorageInternal(int nframes)
735 return impl_->storage_.requestStorage(nframes);
739 /********************************************************************
740 * AnalysisDataWeightedHistogramModule
744 * Private implementation class for AnalysisDataWeightedHistogramModule.
746 * \ingroup module_analysisdata
748 class AnalysisDataWeightedHistogramModule::Impl : public internal::BasicHistogramImpl
751 //! Shorthand for the per-frame accumulation data structure type.
752 typedef AnalysisDataFrameLocalData<double> FrameLocalData;
755 //! Creates an histogram impl with defined bin parameters.
756 explicit Impl(const AnalysisHistogramSettings &settings)
757 : BasicHistogramImpl(settings)
761 //! Accumulates the histogram within a frame.
762 FrameLocalData accumulator_;
765 AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule()
771 AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule(
772 const AnalysisHistogramSettings &settings)
773 : impl_(new Impl(settings))
778 AnalysisDataWeightedHistogramModule::~AnalysisDataWeightedHistogramModule()
783 void AnalysisDataWeightedHistogramModule::init(const AnalysisHistogramSettings &settings)
785 impl_->init(settings);
789 AbstractAverageHistogram &
790 AnalysisDataWeightedHistogramModule::averager()
792 return *impl_->averager_;
796 const AnalysisHistogramSettings &
797 AnalysisDataWeightedHistogramModule::settings() const
799 return impl_->settings_;
804 AnalysisDataWeightedHistogramModule::frameCount() const
806 return impl_->storage_.frameCount();
811 AnalysisDataWeightedHistogramModule::flags() const
813 return efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets;
818 AnalysisDataWeightedHistogramModule::parallelDataStarted(
819 AbstractAnalysisData *data,
820 const AnalysisDataParallelOptions &options)
822 addModule(impl_->averager_);
823 const int dataSetCount = data->dataSetCount();
824 const int columnCount = settings().binCount();
825 setDataSetCount(dataSetCount);
826 impl_->accumulator_.setDataSetCount(dataSetCount);
827 for (int i = 0; i < dataSetCount; ++i)
829 setColumnCount(i, columnCount);
830 impl_->accumulator_.setColumnCount(i, columnCount);
832 impl_->accumulator_.init(options);
833 impl_->storage_.startParallelDataStorage(this, &moduleManager(), options);
839 AnalysisDataWeightedHistogramModule::frameStarted(const AnalysisDataFrameHeader &header)
841 impl_->accumulator_.frameData(header.index()).clear();
846 AnalysisDataWeightedHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points)
848 if (points.firstColumn() != 0 || points.columnCount() < 2)
850 GMX_THROW(APIError("Invalid data layout"));
852 int bin = settings().findBin(points.y(0));
855 Impl::FrameLocalData::DataSetHandle handle
856 = impl_->accumulator_.frameDataSet(points.frameIndex(), points.dataSetIndex());
857 for (int i = 1; i < points.columnCount(); ++i)
859 handle.value(bin) += points.y(i);
866 AnalysisDataWeightedHistogramModule::frameFinished(const AnalysisDataFrameHeader &header)
868 Impl::FrameLocalData::FrameHandle handle
869 = impl_->accumulator_.frameData(header.index());
870 AnalysisDataStorageFrame &frame = impl_->storage_.startFrame(header);
871 const int columnCount = settings().binCount();
872 for (int s = 0; s < dataSetCount(); ++s)
874 Impl::FrameLocalData::DataSetHandle dataSet = handle.dataSet(s);
875 frame.selectDataSet(s);
876 for (int i = 0; i < columnCount; ++i)
878 frame.setValue(i, dataSet.value(i));
886 AnalysisDataWeightedHistogramModule::dataFinished()
888 impl_->storage_.finishDataStorage();
893 AnalysisDataWeightedHistogramModule::tryGetDataFrameInternal(int index) const
895 return impl_->storage_.tryGetDataFrame(index);
900 AnalysisDataWeightedHistogramModule::requestStorageInternal(int nframes)
902 return impl_->storage_.requestStorage(nframes);
906 /********************************************************************
907 * AnalysisDataBinAverageModule
910 class AnalysisDataBinAverageModule::Impl
914 explicit Impl(const AnalysisHistogramSettings &settings)
915 : settings_(settings)
919 //! Histogram settings.
920 AnalysisHistogramSettings settings_;
921 //! Averaging helper objects for each input data set.
922 std::vector<AnalysisDataFrameAverager> averagers_;
925 AnalysisDataBinAverageModule::AnalysisDataBinAverageModule()
932 AnalysisDataBinAverageModule::AnalysisDataBinAverageModule(
933 const AnalysisHistogramSettings &settings)
934 : impl_(new Impl(settings))
936 setRowCount(settings.binCount());
937 setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(),
938 settings.binWidth());
942 AnalysisDataBinAverageModule::~AnalysisDataBinAverageModule()
948 AnalysisDataBinAverageModule::init(const AnalysisHistogramSettings &settings)
950 impl_->settings_ = settings;
951 setRowCount(settings.binCount());
952 setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(),
953 settings.binWidth());
957 const AnalysisHistogramSettings &
958 AnalysisDataBinAverageModule::settings() const
960 return impl_->settings_;
965 AnalysisDataBinAverageModule::flags() const
967 return efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets;
972 AnalysisDataBinAverageModule::dataStarted(AbstractAnalysisData *data)
974 setColumnCount(data->dataSetCount());
975 impl_->averagers_.resize(data->dataSetCount());
976 for (int i = 0; i < data->dataSetCount(); ++i)
978 impl_->averagers_[i].setColumnCount(rowCount());
984 AnalysisDataBinAverageModule::frameStarted(const AnalysisDataFrameHeader & /*header*/)
990 AnalysisDataBinAverageModule::pointsAdded(const AnalysisDataPointSetRef &points)
992 if (points.firstColumn() != 0 || points.columnCount() < 2)
994 GMX_THROW(APIError("Invalid data layout"));
996 int bin = settings().findBin(points.y(0));
999 AnalysisDataFrameAverager &averager = impl_->averagers_[points.dataSetIndex()];
1000 for (int i = 1; i < points.columnCount(); ++i)
1002 averager.addValue(bin, points.y(i));
1009 AnalysisDataBinAverageModule::frameFinished(const AnalysisDataFrameHeader & /*header*/)
1015 AnalysisDataBinAverageModule::dataFinished()
1018 for (int i = 0; i < columnCount(); ++i)
1020 AnalysisDataFrameAverager &averager = impl_->averagers_[i];
1022 for (int j = 0; j < rowCount(); ++j)
1024 value(j, i).setValue(averager.average(j),
1025 std::sqrt(averager.variance(j)));