Improve selection interface (remove some pointers).
[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 #include "gromacs/selection/selection.h"
46
47 #include "analysismodule-impl.h"
48
49 namespace gmx
50 {
51
52 /********************************************************************
53  * TrajectoryAnalysisModuleData::Impl
54  */
55
56 TrajectoryAnalysisModuleData::Impl::Impl(
57         TrajectoryAnalysisModule *module,
58         const AnalysisDataParallelOptions &opt,
59         const SelectionCollection &selections)
60     : _selections(selections)
61 {
62     TrajectoryAnalysisModule::Impl::AnalysisDatasetContainer::const_iterator i;
63     for (i = module->_impl->_analysisDatasets.begin();
64          i != module->_impl->_analysisDatasets.end(); ++i)
65     {
66         _handles.insert(std::make_pair(i->second, i->second->startData(opt)));
67     }
68 }
69
70 TrajectoryAnalysisModuleData::Impl::~Impl()
71 {
72 }
73
74
75 void TrajectoryAnalysisModuleData::Impl::finishHandles()
76 {
77     // FIXME: Call finishData() for all handles even if one throws
78     HandleContainer::iterator i;
79     for (i = _handles.begin(); i != _handles.end(); ++i)
80     {
81         i->second.finishData();
82     }
83     _handles.clear();
84 }
85
86
87 /********************************************************************
88  * TrajectoryAnalysisModuleData
89  */
90
91 TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData(
92         TrajectoryAnalysisModule *module,
93         const AnalysisDataParallelOptions &opt,
94         const SelectionCollection &selections)
95     : _impl(new Impl(module, opt, selections))
96 {
97 }
98
99
100 TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData()
101 {
102 }
103
104
105 void TrajectoryAnalysisModuleData::finishDataHandles()
106 {
107     _impl->finishHandles();
108 }
109
110
111 AnalysisDataHandle
112 TrajectoryAnalysisModuleData::dataHandle(const AnalysisData &data)
113 {
114     Impl::HandleContainer::const_iterator i = _impl->_handles.find(&data);
115     GMX_RELEASE_ASSERT(i != _impl->_handles.end(),
116                        "Data handle requested on unknown dataset");
117     return i->second;
118 }
119
120
121 Selection TrajectoryAnalysisModuleData::parallelSelection(const Selection &selection)
122 {
123     // TODO: Implement properly.
124     return selection;
125 }
126
127
128 SelectionList
129 TrajectoryAnalysisModuleData::parallelSelections(const SelectionList &selections)
130 {
131     // TODO: Consider an implementation that does not allocate memory every time.
132     SelectionList newSelections;
133     newSelections.reserve(selections.size());
134     SelectionList::const_iterator i = selections.begin();
135     for ( ; i != selections.end(); ++i)
136     {
137         newSelections.push_back(parallelSelection(*i));
138     }
139     return newSelections;
140 }
141
142
143 /********************************************************************
144  * TrajectoryAnalysisModuleDataBasic
145  */
146 TrajectoryAnalysisModuleDataBasic::TrajectoryAnalysisModuleDataBasic(
147         TrajectoryAnalysisModule *module,
148         const AnalysisDataParallelOptions &opt,
149         const SelectionCollection &selections)
150     : TrajectoryAnalysisModuleData(module, opt, selections)
151 {
152 }
153
154
155 void
156 TrajectoryAnalysisModuleDataBasic::finish()
157 {
158     finishDataHandles();
159 }
160
161
162 /********************************************************************
163  * TrajectoryAnalysisModule
164  */
165
166 TrajectoryAnalysisModule::TrajectoryAnalysisModule()
167     : _impl(new Impl)
168 {
169 }
170
171
172 TrajectoryAnalysisModule::~TrajectoryAnalysisModule()
173 {
174 }
175
176
177 void TrajectoryAnalysisModule::initOptionsDone(TrajectoryAnalysisSettings * /*settings*/)
178 {
179 }
180
181
182 void TrajectoryAnalysisModule::initAfterFirstFrame(const t_trxframe &/*fr*/)
183 {
184 }
185
186
187 TrajectoryAnalysisModuleDataPointer
188 TrajectoryAnalysisModule::startFrames(const AnalysisDataParallelOptions &opt,
189                                       const SelectionCollection &selections)
190 {
191     return TrajectoryAnalysisModuleDataPointer(
192             new TrajectoryAnalysisModuleDataBasic(this, opt, selections));
193 }
194
195
196 void TrajectoryAnalysisModule::finishFrames(TrajectoryAnalysisModuleData * /*pdata*/)
197 {
198 }
199
200
201 int TrajectoryAnalysisModule::datasetCount() const
202 {
203     return _impl->_datasetNames.size();
204 }
205
206
207 const std::vector<std::string> &TrajectoryAnalysisModule::datasetNames() const
208 {
209     return _impl->_datasetNames;
210 }
211
212
213 AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromIndex(int index) const
214 {
215     if (index < 0 || index >= datasetCount())
216     {
217         GMX_THROW(APIError("Out of range data set index"));
218     }
219     Impl::DatasetContainer::const_iterator item
220         = _impl->_datasets.find(_impl->_datasetNames[index]);
221     GMX_RELEASE_ASSERT(item != _impl->_datasets.end(),
222                        "Inconsistent data set names");
223     return *item->second;
224 }
225
226
227 AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromName(const char *name) const
228 {
229     Impl::DatasetContainer::const_iterator item = _impl->_datasets.find(name);
230     if (item == _impl->_datasets.end())
231     {
232         GMX_THROW(APIError("Unknown data set name"));
233     }
234     return *item->second;
235 }
236
237
238 void TrajectoryAnalysisModule::registerBasicDataset(AbstractAnalysisData *data,
239                                                     const char *name)
240 {
241     GMX_RELEASE_ASSERT(_impl->_datasets.find(name) == _impl->_datasets.end(),
242                        "Duplicate data set name registered");
243     _impl->_datasets[name] = data;
244     _impl->_datasetNames.push_back(name);
245 }
246
247
248 void TrajectoryAnalysisModule::registerAnalysisDataset(AnalysisData *data,
249                                                        const char *name)
250 {
251     registerBasicDataset(data, name);
252     _impl->_analysisDatasets[name] = data;
253 }
254
255 } // namespace gmx