Split lines with many copyright years
[gromacs.git] / src / gromacs / analysisdata / modules / average.cpp
blob38b20682014b296cd3e5afa605133c3aee0ec6b0
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2010,2011,2012,2013,2014 by the GROMACS development team.
5 * Copyright (c) 2019,2020, by the GROMACS development team, led by
6 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7 * and including many others, as listed in the AUTHORS file in the
8 * top-level source directory and at http://www.gromacs.org.
10 * GROMACS is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1
13 * of the License, or (at your option) any later version.
15 * GROMACS is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with GROMACS; if not, see
22 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 * If you want to redistribute modifications to GROMACS, please
26 * consider that scientific software is very special. Version
27 * control is crucial - bugs must be traceable. We will be happy to
28 * consider code for inclusion in the official distribution, but
29 * derived work must not be called official GROMACS. Details are found
30 * in the README & COPYING files - if they are missing, get the
31 * official version at http://www.gromacs.org.
33 * To help us fund GROMACS development, we humbly ask that you cite
34 * the research papers on the package. Check out http://www.gromacs.org.
36 /*! \internal \file
37 * \brief
38 * Implements gmx::AnalysisDataAverageModule.
40 * \author Teemu Murtola <teemu.murtola@gmail.com>
41 * \ingroup module_analysisdata
43 #include "gmxpre.h"
45 #include "average.h"
47 #include <cmath>
49 #include <algorithm>
50 #include <vector>
52 #include "gromacs/analysisdata/dataframe.h"
53 #include "gromacs/analysisdata/datastorage.h"
55 #include "frameaverager.h"
57 namespace gmx
60 /********************************************************************
61 * AnalysisDataAverageModule
64 class AnalysisDataAverageModule::Impl
66 public:
67 Impl() : bDataSets_(false) {}
69 //! Averaging helper objects for each input data set.
70 std::vector<AnalysisDataFrameAverager> averagers_;
71 //! Whether to average all columns in a data set into a single value.
72 bool bDataSets_;
75 AnalysisDataAverageModule::AnalysisDataAverageModule() : impl_(new Impl()) {}
77 AnalysisDataAverageModule::~AnalysisDataAverageModule() {}
79 void AnalysisDataAverageModule::setAverageDataSets(bool bDataSets)
81 impl_->bDataSets_ = bDataSets;
84 int AnalysisDataAverageModule::flags() const
86 return efAllowMultipoint | efAllowMulticolumn | efAllowMissing | efAllowMultipleDataSets;
89 void AnalysisDataAverageModule::dataStarted(AbstractAnalysisData* data)
91 if (impl_->bDataSets_)
93 setColumnCount(1);
94 setRowCount(data->dataSetCount());
95 impl_->averagers_.resize(1);
96 impl_->averagers_[0].setColumnCount(data->dataSetCount());
98 else
100 setColumnCount(data->dataSetCount());
101 impl_->averagers_.resize(data->dataSetCount());
102 int rowCount = 0;
103 for (int i = 0; i < data->dataSetCount(); ++i)
105 impl_->averagers_[i].setColumnCount(data->columnCount(i));
106 rowCount = std::max(rowCount, data->columnCount(i));
108 setRowCount(rowCount);
112 void AnalysisDataAverageModule::frameStarted(const AnalysisDataFrameHeader& /*header*/) {}
114 void AnalysisDataAverageModule::pointsAdded(const AnalysisDataPointSetRef& points)
116 if (impl_->bDataSets_)
118 const int dataSet = points.dataSetIndex();
119 for (int i = 0; i < points.columnCount(); ++i)
121 if (points.present(i))
123 impl_->averagers_[0].addValue(dataSet, points.y(i));
127 else
129 impl_->averagers_[points.dataSetIndex()].addPoints(points);
133 void AnalysisDataAverageModule::frameFinished(const AnalysisDataFrameHeader& /*header*/) {}
135 void AnalysisDataAverageModule::dataFinished()
137 allocateValues();
138 for (int i = 0; i < columnCount(); ++i)
140 impl_->averagers_[i].finish();
141 int j = 0;
142 for (; j < impl_->averagers_[i].columnCount(); ++j)
144 value(j, i).setValue(impl_->averagers_[i].average(j),
145 std::sqrt(impl_->averagers_[i].variance(j)));
147 for (; j < rowCount(); ++j)
149 value(j, i).setValue(0.0, 0.0, false);
152 valuesReady();
155 real AnalysisDataAverageModule::average(int dataSet, int column) const
157 if (impl_->bDataSets_)
159 GMX_ASSERT(column == 0, "Column should be zero with setAverageDataSets(true)");
160 std::swap(dataSet, column);
162 return value(column, dataSet).value();
165 real AnalysisDataAverageModule::standardDeviation(int dataSet, int column) const
167 if (impl_->bDataSets_)
169 GMX_ASSERT(column == 0, "Column should be zero with setAverageDataSets(true)");
170 std::swap(dataSet, column);
172 return value(column, dataSet).error();
175 int AnalysisDataAverageModule::sampleCount(int dataSet, int column) const
177 if (impl_->bDataSets_)
179 GMX_ASSERT(column == 0, "Column should be zero with setAverageDataSets(true)");
180 std::swap(dataSet, column);
182 return impl_->averagers_[dataSet].sampleCount(column);
186 /********************************************************************
187 * AnalysisDataFrameAverageModule
190 class AnalysisDataFrameAverageModule::Impl
192 public:
193 //! Storage implementation object.
194 AnalysisDataStorage storage_;
195 //! Number of samples in a frame for each data set.
196 std::vector<int> sampleCount_;
199 AnalysisDataFrameAverageModule::AnalysisDataFrameAverageModule() : impl_(new Impl()) {}
201 AnalysisDataFrameAverageModule::~AnalysisDataFrameAverageModule() {}
203 int AnalysisDataFrameAverageModule::frameCount() const
205 return impl_->storage_.frameCount();
208 int AnalysisDataFrameAverageModule::flags() const
210 return efAllowMultipoint | efAllowMulticolumn | efAllowMissing | efAllowMultipleDataSets;
213 void AnalysisDataFrameAverageModule::dataStarted(AbstractAnalysisData* data)
215 setColumnCount(0, data->dataSetCount());
216 impl_->sampleCount_.resize(data->dataSetCount());
217 impl_->storage_.startDataStorage(this, &moduleManager());
220 void AnalysisDataFrameAverageModule::frameStarted(const AnalysisDataFrameHeader& header)
222 AnalysisDataStorageFrame& frame = impl_->storage_.startFrame(header);
223 for (int i = 0; i < columnCount(); ++i)
225 impl_->sampleCount_[i] = 0;
226 frame.setValue(i, 0.0);
230 void AnalysisDataFrameAverageModule::pointsAdded(const AnalysisDataPointSetRef& points)
232 const int dataSet = points.dataSetIndex();
233 AnalysisDataStorageFrame& frame = impl_->storage_.currentFrame(points.frameIndex());
234 for (int i = 0; i < points.columnCount(); ++i)
236 if (points.present(i))
238 // TODO: Consider using AnalysisDataFrameAverager
239 const real y = points.y(i);
240 const real delta = y - frame.value(dataSet);
241 impl_->sampleCount_[dataSet] += 1;
242 frame.value(dataSet) += delta / impl_->sampleCount_[dataSet];
247 void AnalysisDataFrameAverageModule::frameFinished(const AnalysisDataFrameHeader& header)
249 impl_->storage_.finishFrame(header.index());
252 void AnalysisDataFrameAverageModule::dataFinished()
254 impl_->storage_.finishDataStorage();
257 AnalysisDataFrameRef AnalysisDataFrameAverageModule::tryGetDataFrameInternal(int index) const
259 return impl_->storage_.tryGetDataFrame(index);
262 bool AnalysisDataFrameAverageModule::requestStorageInternal(int nframes)
264 return impl_->storage_.requestStorage(nframes);
267 } // namespace gmx