Use smart pointer to pass ownership across functions.
[alexxy/gromacs.git] / src / gromacs / trajectoryanalysis / analysismodule.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Implements classes in analysismodule.h.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_trajectoryanalysis
37  */
38 #include "gromacs/trajectoryanalysis/analysismodule.h"
39
40 #include <utility>
41
42 #include "gromacs/analysisdata/analysisdata.h"
43 #include "gromacs/fatalerror/exceptions.h"
44 #include "gromacs/fatalerror/gmxassert.h"
45
46 #include "analysismodule-impl.h"
47
48 namespace gmx
49 {
50
51 /********************************************************************
52  * TrajectoryAnalysisModuleData::Impl
53  */
54
55 TrajectoryAnalysisModuleData::Impl::Impl(
56         TrajectoryAnalysisModule *module,
57         const AnalysisDataParallelOptions &opt,
58         const SelectionCollection &selections)
59     : _selections(selections)
60 {
61     TrajectoryAnalysisModule::Impl::AnalysisDatasetContainer::const_iterator i;
62     for (i = module->_impl->_analysisDatasets.begin();
63          i != module->_impl->_analysisDatasets.end(); ++i)
64     {
65         _handles.insert(std::make_pair(i->second, i->second->startData(opt)));
66     }
67 }
68
69 TrajectoryAnalysisModuleData::Impl::~Impl()
70 {
71 }
72
73
74 void TrajectoryAnalysisModuleData::Impl::finishHandles()
75 {
76     // FIXME: Call finishData() for all handles even if one throws
77     HandleContainer::iterator i;
78     for (i = _handles.begin(); i != _handles.end(); ++i)
79     {
80         i->second.finishData();
81     }
82     _handles.clear();
83 }
84
85
86 /********************************************************************
87  * TrajectoryAnalysisModuleData
88  */
89
90 TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData(
91         TrajectoryAnalysisModule *module,
92         const AnalysisDataParallelOptions &opt,
93         const SelectionCollection &selections)
94     : _impl(new Impl(module, opt, selections))
95 {
96 }
97
98
99 TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData()
100 {
101 }
102
103
104 void TrajectoryAnalysisModuleData::finishDataHandles()
105 {
106     _impl->finishHandles();
107 }
108
109
110 AnalysisDataHandle
111 TrajectoryAnalysisModuleData::dataHandle(const AnalysisData &data)
112 {
113     Impl::HandleContainer::const_iterator i = _impl->_handles.find(&data);
114     GMX_RELEASE_ASSERT(i != _impl->_handles.end(),
115                        "Data handle requested on unknown dataset");
116     return i->second;
117 }
118
119
120 Selection *TrajectoryAnalysisModuleData::parallelSelection(Selection *selection)
121 {
122     // TODO: Implement properly.
123     return selection;
124 }
125
126
127 std::vector<Selection *>
128 TrajectoryAnalysisModuleData::parallelSelections(const std::vector<Selection *> &selections)
129 {
130     std::vector<Selection *> newSelections;
131     newSelections.reserve(selections.size());
132     std::vector<Selection *>::const_iterator i = selections.begin();
133     for ( ; i != selections.end(); ++i)
134     {
135         newSelections.push_back(parallelSelection(*i));
136     }
137     return newSelections;
138 }
139
140
141 /********************************************************************
142  * TrajectoryAnalysisModuleDataBasic
143  */
144 TrajectoryAnalysisModuleDataBasic::TrajectoryAnalysisModuleDataBasic(
145         TrajectoryAnalysisModule *module,
146         const AnalysisDataParallelOptions &opt,
147         const SelectionCollection &selections)
148     : TrajectoryAnalysisModuleData(module, opt, selections)
149 {
150 }
151
152
153 void
154 TrajectoryAnalysisModuleDataBasic::finish()
155 {
156     finishDataHandles();
157 }
158
159
160 /********************************************************************
161  * TrajectoryAnalysisModule
162  */
163
164 TrajectoryAnalysisModule::TrajectoryAnalysisModule()
165     : _impl(new Impl)
166 {
167 }
168
169
170 TrajectoryAnalysisModule::~TrajectoryAnalysisModule()
171 {
172 }
173
174
175 void TrajectoryAnalysisModule::initOptionsDone(TrajectoryAnalysisSettings * /*settings*/)
176 {
177 }
178
179
180 void TrajectoryAnalysisModule::initAfterFirstFrame(const t_trxframe &/*fr*/)
181 {
182 }
183
184
185 TrajectoryAnalysisModuleDataPointer
186 TrajectoryAnalysisModule::startFrames(const AnalysisDataParallelOptions &opt,
187                                       const SelectionCollection &selections)
188 {
189     return TrajectoryAnalysisModuleDataPointer(
190             new TrajectoryAnalysisModuleDataBasic(this, opt, selections));
191 }
192
193
194 void TrajectoryAnalysisModule::finishFrames(TrajectoryAnalysisModuleData * /*pdata*/)
195 {
196 }
197
198
199 int TrajectoryAnalysisModule::datasetCount() const
200 {
201     return _impl->_datasetNames.size();
202 }
203
204
205 const std::vector<std::string> &TrajectoryAnalysisModule::datasetNames() const
206 {
207     return _impl->_datasetNames;
208 }
209
210
211 AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromIndex(int index) const
212 {
213     if (index < 0 || index >= datasetCount())
214     {
215         GMX_THROW(APIError("Out of range data set index"));
216     }
217     Impl::DatasetContainer::const_iterator item
218         = _impl->_datasets.find(_impl->_datasetNames[index]);
219     GMX_RELEASE_ASSERT(item != _impl->_datasets.end(),
220                        "Inconsistent data set names");
221     return *item->second;
222 }
223
224
225 AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromName(const char *name) const
226 {
227     Impl::DatasetContainer::const_iterator item = _impl->_datasets.find(name);
228     if (item == _impl->_datasets.end())
229     {
230         GMX_THROW(APIError("Unknown data set name"));
231     }
232     return *item->second;
233 }
234
235
236 void TrajectoryAnalysisModule::registerBasicDataset(AbstractAnalysisData *data,
237                                                     const char *name)
238 {
239     GMX_RELEASE_ASSERT(_impl->_datasets.find(name) == _impl->_datasets.end(),
240                        "Duplicate data set name registered");
241     _impl->_datasets[name] = data;
242     _impl->_datasetNames.push_back(name);
243 }
244
245
246 void TrajectoryAnalysisModule::registerAnalysisDataset(AnalysisData *data,
247                                                        const char *name)
248 {
249     registerBasicDataset(data, name);
250     _impl->_analysisDatasets[name] = data;
251 }
252
253 } // namespace gmx