From fdad87f6637e6a59152b851bd033195f4e376c0b Mon Sep 17 00:00:00 2001 From: Teemu Murtola Date: Thu, 14 Aug 2014 21:49:19 +0300 Subject: [PATCH] Add support for cumulative histograms Now the final, averaged histograms computed by the analysisdata histogram modules can also be made cumulative. This is needed to preserve some functionality of 'gmx rdf' when moving to the C++ framework. For now, only the unit test is using the function. Change-Id: Iaf7175dd904f9a615b8bd887d677aa8dc1e10f0d --- .../analysisdata/modules/histogram.cpp | 19 +++ src/gromacs/analysisdata/modules/histogram.h | 10 ++ src/gromacs/analysisdata/tests/histogram.cpp | 18 +++ ...togramTest_ComputesCumulativeHistogram.xml | 141 ++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 src/gromacs/analysisdata/tests/refdata/AbstractAverageHistogramTest_ComputesCumulativeHistogram.xml diff --git a/src/gromacs/analysisdata/modules/histogram.cpp b/src/gromacs/analysisdata/modules/histogram.cpp index 24f67024a7..fd6727ff91 100644 --- a/src/gromacs/analysisdata/modules/histogram.cpp +++ b/src/gromacs/analysisdata/modules/histogram.cpp @@ -333,6 +333,7 @@ AbstractAverageHistogram::clone() const { AverageHistogramPointer dest(new StaticAverageHistogram()); copyContents(this, dest.get()); + dest->settings_ = settings_; return dest; } @@ -354,6 +355,24 @@ AbstractAverageHistogram::normalizeProbability() } } +void +AbstractAverageHistogram::makeCumulative() +{ + for (int c = 0; c < columnCount(); ++c) + { + double sum = 0; + for (int i = 0; i < rowCount(); ++i) + { + sum += value(i, c).value(); + // Clear the error, as we don't cumulate that. + value(i, c).clear(); + value(i, c).setValue(sum); + } + } + setXAxis(settings().firstEdge() + settings().binWidth(), + settings().binWidth()); +} + void AbstractAverageHistogram::scaleSingle(int index, real factor) diff --git a/src/gromacs/analysisdata/modules/histogram.h b/src/gromacs/analysisdata/modules/histogram.h index fe47fe0840..0717b4b822 100644 --- a/src/gromacs/analysisdata/modules/histogram.h +++ b/src/gromacs/analysisdata/modules/histogram.h @@ -255,6 +255,8 @@ typedef boost::shared_ptr * * This class can represent multiple histograms in one object: each column in * the data is an independent histogram. + * The X values correspond to center of the bins, except for a cumulative + * histogram made with makeCumulative(). * * \inpublicapi * \ingroup module_analysisdata @@ -289,6 +291,14 @@ class AbstractAverageHistogram : public AbstractAnalysisArrayData AverageHistogramPointer clone() const; //! Normalizes the histogram such that the integral over it is one. void normalizeProbability(); + /*! \brief + * Makes the histograms cumulative by summing up each bin to all bins + * after it. + * + * The X values in the data are adjusted such that they match the right + * edges of bins instead of bin centers. + */ + void makeCumulative(); //! Scales a single histogram by a uniform scaling factor. void scaleSingle(int index, real factor); //! Scales all histograms by a uniform scaling factor. diff --git a/src/gromacs/analysisdata/tests/histogram.cpp b/src/gromacs/analysisdata/tests/histogram.cpp index f210b4b7ad..3fef0ef42c 100644 --- a/src/gromacs/analysisdata/tests/histogram.cpp +++ b/src/gromacs/analysisdata/tests/histogram.cpp @@ -523,6 +523,24 @@ TEST_F(AbstractAverageHistogramTest, ClonesCorrectly) } +TEST_F(AbstractAverageHistogramTest, ComputesCumulativeHistogram) +{ + const AnalysisDataTestInput &input = AverageInputData::get(); + MockAverageHistogram data( + gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); + setupArrayData(input, &data); + + ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); + ASSERT_NO_THROW_GMX(addReferenceCheckerModule("InputData", &data)); + ASSERT_NO_THROW_GMX(data.done()); + + gmx::AverageHistogramPointer cumulative(data.clone()); + cumulative->makeCumulative(); + ASSERT_NO_THROW_GMX(addReferenceCheckerModule("CumulativeHistogram", cumulative.get())); + ASSERT_NO_THROW_GMX(cumulative->done()); +} + + TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidth) { const AnalysisDataTestInput &input = AverageInputData::get(); diff --git a/src/gromacs/analysisdata/tests/refdata/AbstractAverageHistogramTest_ComputesCumulativeHistogram.xml b/src/gromacs/analysisdata/tests/refdata/AbstractAverageHistogramTest_ComputesCumulativeHistogram.xml new file mode 100644 index 0000000000..e7bd9d2e89 --- /dev/null +++ b/src/gromacs/analysisdata/tests/refdata/AbstractAverageHistogramTest_ComputesCumulativeHistogram.xml @@ -0,0 +1,141 @@ + + + + + + 1 + + 1 + + 2 + 1 + + + + + 1.5 + + 1 + + 1 + 1 + + + + + 2 + + 1 + + 3 + 2 + + + + + 2.5 + + 1 + + 4 + 2 + + + + + 3 + + 1 + + 2 + 1 + + + + + 3.5 + + 1 + + 0 + 3 + + + + + 4 + + 1 + + 1 + 3 + + + + + + + 1.25 + + 1 + + 2 + + + + + 1.75 + + 1 + + 3 + + + + + 2.25 + + 1 + + 6 + + + + + 2.75 + + 1 + + 10 + + + + + 3.25 + + 1 + + 12 + + + + + 3.75 + + 1 + + 12 + + + + + 4.25 + + 1 + + 13 + + + + + -- 2.22.0