2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012, by the GROMACS development team, led by
5 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
6 * others, as listed in the AUTHORS file in the top-level source
7 * 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 * Tests for functionality of analysis data histogram modules.
39 * These tests check that classes in histogram.h compute histograms correctly
40 * with simple input data. Also different ways of initializing the histograms
42 * Checking is done using gmx::test::AnalysisDataTestFixture and reference
43 * data. Also the input data is written to the reference data to catch
44 * out-of-date reference.
46 * \author Teemu Murtola <teemu.murtola@gmail.com>
47 * \ingroup module_analysisdata
49 #include <gtest/gtest.h>
51 #include "gromacs/analysisdata/analysisdata.h"
52 #include "gromacs/analysisdata/modules/histogram.h"
54 #include "testutils/datatest.h"
59 /********************************************************************
60 * Tests for gmx::AnalysisHistogramSettings.
62 * These tests check that gmx::AnalysisHistogramSettings objects can be
63 * initialized from various types of values, and that the bin positions are
64 * computed correctly based on the input values.
67 TEST(AnalysisHistogramSettingsTest, InitializesFromBins)
69 gmx::AnalysisHistogramSettings settings(
70 gmx::histogramFromBins(1.0, 5, 0.5));
71 EXPECT_FLOAT_EQ(1.0, settings.firstEdge());
72 EXPECT_EQ(5, settings.binCount());
73 EXPECT_FLOAT_EQ(0.5, settings.binWidth());
74 EXPECT_FLOAT_EQ(3.5, settings.lastEdge());
78 TEST(AnalysisHistogramSettingsTest, InitializesFromBinsWithIntegerBins)
80 gmx::AnalysisHistogramSettings settings(
81 gmx::histogramFromBins(1.0, 5, 0.5).integerBins());
82 EXPECT_FLOAT_EQ(0.75, settings.firstEdge());
83 EXPECT_EQ(5, settings.binCount());
84 EXPECT_FLOAT_EQ(0.5, settings.binWidth());
85 EXPECT_FLOAT_EQ(3.25, settings.lastEdge());
89 TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinCount)
91 gmx::AnalysisHistogramSettings settings(
92 gmx::histogramFromRange(1.0, 4.0).binCount(6));
93 EXPECT_FLOAT_EQ(1.0, settings.firstEdge());
94 EXPECT_FLOAT_EQ(4.0, settings.lastEdge());
95 EXPECT_EQ(6, settings.binCount());
96 EXPECT_FLOAT_EQ(0.5, settings.binWidth());
100 TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinWidth)
102 gmx::AnalysisHistogramSettings settings(
103 gmx::histogramFromRange(1.0, 4.0).binWidth(0.5));
104 EXPECT_FLOAT_EQ(1.0, settings.firstEdge());
105 EXPECT_FLOAT_EQ(4.0, settings.lastEdge());
106 EXPECT_FLOAT_EQ(0.5, settings.binWidth());
107 EXPECT_EQ(6, settings.binCount());
111 TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinCountAndIntegerBins)
113 gmx::AnalysisHistogramSettings settings(
114 gmx::histogramFromRange(1.0, 4.0).binCount(7).integerBins());
115 EXPECT_FLOAT_EQ(0.75, settings.firstEdge());
116 EXPECT_FLOAT_EQ(4.25, settings.lastEdge());
117 EXPECT_EQ(7, settings.binCount());
118 EXPECT_FLOAT_EQ(0.5, settings.binWidth());
122 TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinWidthAndIntegerBins)
124 gmx::AnalysisHistogramSettings settings(
125 gmx::histogramFromRange(1.0, 4.0).binWidth(0.5).integerBins());
126 EXPECT_FLOAT_EQ(0.75, settings.firstEdge());
127 EXPECT_FLOAT_EQ(4.25, settings.lastEdge());
128 EXPECT_FLOAT_EQ(0.5, settings.binWidth());
129 EXPECT_EQ(7, settings.binCount());
133 TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithRoundedRange)
135 gmx::AnalysisHistogramSettings settings(
136 gmx::histogramFromRange(1.2, 3.8).binWidth(0.5).roundRange());
137 EXPECT_FLOAT_EQ(1.0, settings.firstEdge());
138 EXPECT_FLOAT_EQ(4.0, settings.lastEdge());
139 EXPECT_FLOAT_EQ(0.5, settings.binWidth());
140 EXPECT_EQ(6, settings.binCount());
144 /********************************************************************
145 * Tests for gmx::AnalysisDataSimpleHistogramModule.
148 //! Test fixture for gmx::AnalysisDataSimpleHistogramModule.
149 typedef gmx::test::AnalysisDataTestFixture SimpleHistogramModuleTest;
151 using gmx::test::END_OF_FRAME;
152 using gmx::test::MPSTOP;
153 //! Input data for gmx::AnalysisDataSimpleHistogramModule tests.
154 const real simpleinputdata[] = {
155 1.0, 0.7, MPSTOP, 1.1, MPSTOP, 2.3, MPSTOP, 2.9, END_OF_FRAME,
156 2.0, 1.3, MPSTOP, 2.2, END_OF_FRAME,
157 3.0, 3.3, MPSTOP, 1.2, MPSTOP, 1.3, END_OF_FRAME
160 TEST_F(SimpleHistogramModuleTest, ComputesCorrectly)
162 gmx::test::AnalysisDataTestInput input(simpleinputdata);
163 gmx::AnalysisData data;
164 data.setColumnCount(input.columnCount());
165 data.setMultipoint(true);
166 gmx::AnalysisDataSimpleHistogramModulePointer module(
167 new gmx::AnalysisDataSimpleHistogramModule(
168 gmx::histogramFromRange(1.0, 3.0).binCount(4)));
169 data.addModule(module);
171 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
172 ASSERT_NO_THROW(addReferenceCheckerModule("InputData", &data));
173 ASSERT_NO_THROW(addReferenceCheckerModule("Histogram", module.get()));
174 ASSERT_NO_THROW(addReferenceCheckerModule("HistogramAverage",
175 &module->averager()));
176 ASSERT_NO_THROW(presentAllData(input, &data));
177 ASSERT_NO_THROW(module->averager().done());
181 TEST_F(SimpleHistogramModuleTest, ComputesCorrectlyWithAll)
183 gmx::test::AnalysisDataTestInput input(simpleinputdata);
184 gmx::AnalysisData data;
185 data.setColumnCount(input.columnCount());
186 data.setMultipoint(true);
187 gmx::AnalysisDataSimpleHistogramModulePointer module(
188 new gmx::AnalysisDataSimpleHistogramModule(
189 gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll()));
190 data.addModule(module);
192 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
193 ASSERT_NO_THROW(addReferenceCheckerModule("InputData", &data));
194 ASSERT_NO_THROW(addReferenceCheckerModule("Histogram", module.get()));
195 ASSERT_NO_THROW(addReferenceCheckerModule("HistogramAverage",
196 &module->averager()));
197 ASSERT_NO_THROW(presentAllData(input, &data));
198 ASSERT_NO_THROW(module->averager().done());
202 /********************************************************************
203 * Tests for gmx::AnalysisDataWeightedHistogramModule.
206 //! Test fixture for gmx::AnalysisDataWeightedHistogramModule.
207 typedef gmx::test::AnalysisDataTestFixture WeightedHistogramModuleTest;
209 //! Input data for both weighted histogram and bin average module tests.
210 const real weightedinputdata[] = {
211 1.0, 0.7, 0.5, MPSTOP, 1.1, 1.0, MPSTOP, 2.3, 1.0, MPSTOP, 2.9, 2.0, END_OF_FRAME,
212 2.0, 1.3, 1.0, MPSTOP, 2.2, 3.0, END_OF_FRAME,
213 3.0, 3.3, 0.5, MPSTOP, 1.2, 2.0, MPSTOP, 1.3, 1.0, END_OF_FRAME
216 TEST_F(WeightedHistogramModuleTest, ComputesCorrectly)
218 gmx::test::AnalysisDataTestInput input(weightedinputdata);
219 gmx::AnalysisData data;
220 data.setColumnCount(input.columnCount());
221 data.setMultipoint(true);
222 gmx::AnalysisDataWeightedHistogramModulePointer module(
223 new gmx::AnalysisDataWeightedHistogramModule(
224 gmx::histogramFromRange(1.0, 3.0).binCount(4)));
225 data.addModule(module);
227 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
228 ASSERT_NO_THROW(addReferenceCheckerModule("InputData", &data));
229 ASSERT_NO_THROW(addReferenceCheckerModule("Histogram", module.get()));
230 ASSERT_NO_THROW(addReferenceCheckerModule("HistogramAverage",
231 &module->averager()));
232 ASSERT_NO_THROW(presentAllData(input, &data));
233 ASSERT_NO_THROW(module->averager().done());
237 TEST_F(WeightedHistogramModuleTest, ComputesCorrectlyWithAll)
239 gmx::test::AnalysisDataTestInput input(weightedinputdata);
240 gmx::AnalysisData data;
241 data.setColumnCount(input.columnCount());
242 data.setMultipoint(true);
243 gmx::AnalysisDataWeightedHistogramModulePointer module(
244 new gmx::AnalysisDataWeightedHistogramModule(
245 gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll()));
246 data.addModule(module);
248 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
249 ASSERT_NO_THROW(addReferenceCheckerModule("InputData", &data));
250 ASSERT_NO_THROW(addReferenceCheckerModule("Histogram", module.get()));
251 ASSERT_NO_THROW(addReferenceCheckerModule("HistogramAverage",
252 &module->averager()));
253 ASSERT_NO_THROW(presentAllData(input, &data));
254 ASSERT_NO_THROW(module->averager().done());
258 /********************************************************************
259 * Tests for gmx::AnalysisDataBinAverageModule.
262 //! Test fixture for gmx::AnalysisDataBinAverageModule.
263 typedef gmx::test::AnalysisDataTestFixture BinAverageModuleTest;
265 TEST_F(BinAverageModuleTest, ComputesCorrectly)
267 gmx::test::AnalysisDataTestInput input(weightedinputdata);
268 gmx::AnalysisData data;
269 data.setColumnCount(input.columnCount());
270 data.setMultipoint(true);
271 gmx::AnalysisDataBinAverageModulePointer module(
272 new gmx::AnalysisDataBinAverageModule(
273 gmx::histogramFromRange(1.0, 3.0).binCount(4)));
274 data.addModule(module);
276 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
277 ASSERT_NO_THROW(addReferenceCheckerModule("InputData", &data));
278 ASSERT_NO_THROW(addReferenceCheckerModule("HistogramAverage", module.get()));
279 ASSERT_NO_THROW(presentAllData(input, &data));
283 TEST_F(BinAverageModuleTest, ComputesCorrectlyWithAll)
285 gmx::test::AnalysisDataTestInput input(weightedinputdata);
286 gmx::AnalysisData data;
287 data.setColumnCount(input.columnCount());
288 data.setMultipoint(true);
289 gmx::AnalysisDataBinAverageModulePointer module(
290 new gmx::AnalysisDataBinAverageModule(
291 gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll()));
292 data.addModule(module);
294 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
295 ASSERT_NO_THROW(addReferenceCheckerModule("InputData", &data));
296 ASSERT_NO_THROW(addReferenceCheckerModule("HistogramAverage", module.get()));
297 ASSERT_NO_THROW(presentAllData(input, &data));
301 /********************************************************************
302 * Tests for gmx::AbstractAverageHistogram.
304 * This class derives from gmx::AbstractAnalysisArrayData, and is tested using
305 * corresponding facilities in gmx::test::AnalysisDataTestFixture.
308 //! Test fixture for gmx::AbstractAverageHistogram.
309 typedef gmx::test::AnalysisDataTestFixture AbstractAverageHistogramTest;
311 //! Input data for gmx::AbstractAverageHistogram tests.
312 const real averageinputdata[] = {
313 1.0, 2.0, 1.0, END_OF_FRAME,
314 1.5, 1.0, 1.0, END_OF_FRAME,
315 2.0, 3.0, 2.0, END_OF_FRAME,
316 2.5, 4.0, 2.0, END_OF_FRAME,
317 3.0, 2.0, 1.0, END_OF_FRAME,
318 3.5, 0.0, 3.0, END_OF_FRAME,
319 4.0, 1.0, 3.0, END_OF_FRAME
323 * Mock object for testing gmx::AbstractAverageHistogram.
325 * Exposes necessary methods from gmx::AbstractAverageHistogram to use with
326 * gmx::test::AnalysisDataTestFixture::setupArrayData().
328 class MockAverageHistogram : public gmx::AbstractAverageHistogram
331 MockAverageHistogram() {}
332 //! Creates a histogram module with defined bin parameters.
333 explicit MockAverageHistogram(const gmx::AnalysisHistogramSettings &settings)
334 : AbstractAverageHistogram(settings)
338 using AbstractAverageHistogram::init;
339 using AbstractAverageHistogram::setColumnCount;
340 using AbstractAverageHistogram::setRowCount;
341 using AbstractAverageHistogram::allocateValues;
342 using AbstractAverageHistogram::setValue;
346 TEST_F(AbstractAverageHistogramTest, ClonesCorrectly)
348 gmx::test::AnalysisDataTestInput input(averageinputdata);
349 MockAverageHistogram data(
350 gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins());
351 setupArrayData(input, &data);
353 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
354 gmx::AverageHistogramPointer copy(data.clone());
355 ASSERT_NO_THROW(addStaticCheckerModule(input, copy.get()));
356 ASSERT_NO_THROW(copy->done());
357 ASSERT_NO_THROW(data.done());
358 gmx::AverageHistogramPointer copy2(data.clone());
359 ASSERT_NO_THROW(addStaticCheckerModule(input, copy2.get()));
360 ASSERT_NO_THROW(copy2->done());
364 TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidth)
366 gmx::test::AnalysisDataTestInput input(averageinputdata);
367 MockAverageHistogram data(
368 gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins());
369 setupArrayData(input, &data);
371 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
372 ASSERT_NO_THROW(addReferenceCheckerModule("InputData", &data));
373 gmx::AverageHistogramPointer resampled(data.resampleDoubleBinWidth(false));
374 ASSERT_NO_THROW(addReferenceCheckerModule("ResampledHistogram", resampled.get()));
375 ASSERT_NO_THROW(data.done());
376 ASSERT_NO_THROW(resampled->done());
380 TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidthWithIntegerBins)
382 gmx::test::AnalysisDataTestInput input(averageinputdata);
383 MockAverageHistogram data(
384 gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins());
385 setupArrayData(input, &data);
387 ASSERT_NO_THROW(addStaticCheckerModule(input, &data));
388 ASSERT_NO_THROW(addReferenceCheckerModule("InputData", &data));
389 gmx::AverageHistogramPointer resampled(data.resampleDoubleBinWidth(true));
390 ASSERT_NO_THROW(addReferenceCheckerModule("ResampledHistogram", resampled.get()));
391 ASSERT_NO_THROW(data.done());
392 ASSERT_NO_THROW(resampled->done());