6822878a9882ea48b5c2b348b3a534700fd28942
[alexxy/gromacs.git] / src / gromacs / analysisdata / abstractdata.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, 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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \internal \file
36  * \brief
37  * Implements gmx::AbstractAnalysisData.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \ingroup module_analysisdata
41  */
42 #include "gmxpre.h"
43
44 #include "abstractdata.h"
45
46 #include <utility>
47 #include <vector>
48
49 #include "gromacs/analysisdata/dataframe.h"
50 #include "gromacs/analysisdata/datamodule.h"
51 #include "gromacs/analysisdata/datamodulemanager.h"
52 #include "gromacs/utility/exceptions.h"
53 #include "gromacs/utility/gmxassert.h"
54
55 #include "dataproxy.h"
56
57 namespace gmx
58 {
59
60 /********************************************************************
61  * AbstractAnalysisData::Impl
62  */
63
64 /*! \internal \brief
65  * Private implementation class for AbstractAnalysisData.
66  *
67  * \ingroup module_analysisdata
68  */
69 class AbstractAnalysisData::Impl
70 {
71 public:
72     Impl();
73
74     //! Column counts for each data set in the data.
75     std::vector<int> columnCounts_;
76     //! Whether the data is multipoint.
77     bool bMultipoint_;
78     //! Manager for the added modules.
79     AnalysisDataModuleManager modules_;
80 };
81
82 AbstractAnalysisData::Impl::Impl() : bMultipoint_(false)
83 {
84     columnCounts_.push_back(0);
85 }
86
87
88 /********************************************************************
89  * AbstractAnalysisData
90  */
91 /*! \cond libapi */
92 AbstractAnalysisData::AbstractAnalysisData() : impl_(new Impl()) {}
93 //! \endcond
94
95 AbstractAnalysisData::~AbstractAnalysisData() {}
96
97 bool AbstractAnalysisData::isMultipoint() const
98 {
99     return impl_->bMultipoint_;
100 }
101
102 int AbstractAnalysisData::dataSetCount() const
103 {
104     return impl_->columnCounts_.size();
105 }
106
107 int AbstractAnalysisData::columnCount(int dataSet) const
108 {
109     GMX_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), "Out of range data set index");
110     return impl_->columnCounts_[dataSet];
111 }
112
113 int AbstractAnalysisData::columnCount() const
114 {
115     GMX_ASSERT(dataSetCount() == 1, "Convenience method not available for multiple data sets");
116     return columnCount(0);
117 }
118
119
120 AnalysisDataFrameRef AbstractAnalysisData::tryGetDataFrame(int index) const
121 {
122     if (index < 0 || index >= frameCount())
123     {
124         return AnalysisDataFrameRef();
125     }
126     return tryGetDataFrameInternal(index);
127 }
128
129
130 AnalysisDataFrameRef AbstractAnalysisData::getDataFrame(int index) const
131 {
132     AnalysisDataFrameRef frame = tryGetDataFrame(index);
133     if (!frame.isValid())
134     {
135         GMX_THROW(APIError("Invalid frame accessed"));
136     }
137     return frame;
138 }
139
140
141 bool AbstractAnalysisData::requestStorage(int nframes)
142 {
143     GMX_RELEASE_ASSERT(nframes >= -1, "Invalid number of frames requested");
144     if (nframes == 0)
145     {
146         return true;
147     }
148     return requestStorageInternal(nframes);
149 }
150
151
152 void AbstractAnalysisData::addModule(const AnalysisDataModulePointer& module)
153 {
154     impl_->modules_.addModule(this, module);
155 }
156
157
158 void AbstractAnalysisData::addColumnModule(int col, int span, const AnalysisDataModulePointer& module)
159 {
160     GMX_RELEASE_ASSERT(col >= 0 && span >= 1, "Invalid columns specified for a column module");
161     std::shared_ptr<AnalysisDataProxy> proxy(new AnalysisDataProxy(col, span, this));
162     proxy->addModule(module);
163     addModule(proxy);
164 }
165
166
167 void AbstractAnalysisData::applyModule(IAnalysisDataModule* module)
168 {
169     impl_->modules_.applyModule(this, module);
170 }
171
172 /*! \cond libapi */
173 void AbstractAnalysisData::setDataSetCount(int dataSetCount)
174 {
175     GMX_RELEASE_ASSERT(dataSetCount > 0, "Invalid data column count");
176     impl_->modules_.dataPropertyAboutToChange(AnalysisDataModuleManager::eMultipleDataSets,
177                                               dataSetCount > 1);
178     impl_->columnCounts_.resize(dataSetCount);
179 }
180
181 void AbstractAnalysisData::setColumnCount(int dataSet, int columnCount)
182 {
183     GMX_RELEASE_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), "Out of range data set index");
184     GMX_RELEASE_ASSERT(columnCount > 0, "Invalid data column count");
185
186     bool bMultipleColumns = columnCount > 1;
187     for (int i = 0; i < dataSetCount() && !bMultipleColumns; ++i)
188     {
189         if (i != dataSet && this->columnCount(i) > 1)
190         {
191             bMultipleColumns = true;
192         }
193     }
194     impl_->modules_.dataPropertyAboutToChange(AnalysisDataModuleManager::eMultipleColumns, bMultipleColumns);
195     impl_->columnCounts_[dataSet] = columnCount;
196 }
197
198 void AbstractAnalysisData::setMultipoint(bool bMultipoint)
199 {
200     impl_->modules_.dataPropertyAboutToChange(AnalysisDataModuleManager::eMultipoint, bMultipoint);
201     impl_->bMultipoint_ = bMultipoint;
202 }
203
204 AnalysisDataModuleManager& AbstractAnalysisData::moduleManager()
205 {
206     return impl_->modules_;
207 }
208
209 const AnalysisDataModuleManager& AbstractAnalysisData::moduleManager() const
210 {
211     return impl_->modules_;
212 }
213 //! \endcond
214
215 } // namespace gmx