3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
29 * For more info, check our website at http://www.gromacs.org
33 * Implements classes in analysismodule.h.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36 * \ingroup module_trajectoryanalysis
38 #include "gromacs/trajectoryanalysis/analysismodule.h"
42 #include "gromacs/analysisdata/analysisdata.h"
43 #include "gromacs/selection/selection.h"
44 #include "gromacs/utility/exceptions.h"
45 #include "gromacs/utility/gmxassert.h"
50 /********************************************************************
51 * TrajectoryAnalysisModule::Impl
55 * Private implementation class for TrajectoryAnalysisModule.
57 * \ingroup module_trajectoryanalysis
59 class TrajectoryAnalysisModule::Impl
62 //! Container that associates a data set with its name.
63 typedef std::map<std::string, AbstractAnalysisData *> DatasetContainer;
64 //! Container that associates a AnalysisData object with its name.
65 typedef std::map<std::string, AnalysisData *> AnalysisDatasetContainer;
67 //! Initializes analysis module data with given name and description.
68 Impl(const char *name, const char *description)
69 : name_(name), description_(description)
73 //! Name of the module.
75 //! Description of the module.
76 std::string description_;
77 //! List of registered data set names.
78 std::vector<std::string> datasetNames_;
80 * Keeps all registered data sets.
82 * This container also includes datasets from \a analysisDatasets_.
84 DatasetContainer datasets_;
85 //! Keeps registered AnalysisData objects.
86 AnalysisDatasetContainer analysisDatasets_;
89 /********************************************************************
90 * TrajectoryAnalysisModuleData::Impl
94 * Private implementation class for TrajectoryAnalysisModuleData.
96 * \ingroup module_trajectoryanalysis
98 class TrajectoryAnalysisModuleData::Impl
101 //! Container that associates a data handle to its AnalysisData object.
102 typedef std::map<const AnalysisData *, AnalysisDataHandle>
105 //! \copydoc TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData()
106 Impl(TrajectoryAnalysisModule *module,
107 const AnalysisDataParallelOptions &opt,
108 const SelectionCollection &selections);
110 //! Keeps a data handle for each AnalysisData object.
111 HandleContainer handles_;
112 //! Stores thread-local selections.
113 const SelectionCollection &selections_;
116 TrajectoryAnalysisModuleData::Impl::Impl(
117 TrajectoryAnalysisModule *module,
118 const AnalysisDataParallelOptions &opt,
119 const SelectionCollection &selections)
120 : selections_(selections)
122 TrajectoryAnalysisModule::Impl::AnalysisDatasetContainer::const_iterator i;
123 for (i = module->impl_->analysisDatasets_.begin();
124 i != module->impl_->analysisDatasets_.end(); ++i)
126 handles_.insert(std::make_pair(i->second, i->second->startData(opt)));
131 /********************************************************************
132 * TrajectoryAnalysisModuleData
135 TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData(
136 TrajectoryAnalysisModule *module,
137 const AnalysisDataParallelOptions &opt,
138 const SelectionCollection &selections)
139 : impl_(new Impl(module, opt, selections))
144 TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData()
149 void TrajectoryAnalysisModuleData::finishDataHandles()
151 // FIXME: Call finishData() for all handles even if one throws
152 Impl::HandleContainer::iterator i;
153 for (i = impl_->handles_.begin(); i != impl_->handles_.end(); ++i)
155 i->second.finishData();
157 impl_->handles_.clear();
162 TrajectoryAnalysisModuleData::dataHandle(const AnalysisData &data)
164 Impl::HandleContainer::const_iterator i = impl_->handles_.find(&data);
165 GMX_RELEASE_ASSERT(i != impl_->handles_.end(),
166 "Data handle requested on unknown dataset");
171 Selection TrajectoryAnalysisModuleData::parallelSelection(const Selection &selection)
173 // TODO: Implement properly.
179 TrajectoryAnalysisModuleData::parallelSelections(const SelectionList &selections)
181 // TODO: Consider an implementation that does not allocate memory every time.
182 SelectionList newSelections;
183 newSelections.reserve(selections.size());
184 SelectionList::const_iterator i = selections.begin();
185 for ( ; i != selections.end(); ++i)
187 newSelections.push_back(parallelSelection(*i));
189 return newSelections;
193 /********************************************************************
194 * TrajectoryAnalysisModuleDataBasic
201 * Basic thread-local trajectory analysis data storage class.
203 * Most simple tools should only require data handles and selections to be
204 * thread-local, so this class implements just that.
206 * \ingroup module_trajectoryanalysis
208 class TrajectoryAnalysisModuleDataBasic : public TrajectoryAnalysisModuleData
212 * Initializes thread-local storage for data handles and selections.
214 * \param[in] module Analysis module to use for data objects.
215 * \param[in] opt Data parallelization options.
216 * \param[in] selections Thread-local selection collection.
218 TrajectoryAnalysisModuleDataBasic(TrajectoryAnalysisModule *module,
219 const AnalysisDataParallelOptions &opt,
220 const SelectionCollection &selections);
222 virtual void finish();
225 TrajectoryAnalysisModuleDataBasic::TrajectoryAnalysisModuleDataBasic(
226 TrajectoryAnalysisModule *module,
227 const AnalysisDataParallelOptions &opt,
228 const SelectionCollection &selections)
229 : TrajectoryAnalysisModuleData(module, opt, selections)
235 TrajectoryAnalysisModuleDataBasic::finish()
243 /********************************************************************
244 * TrajectoryAnalysisModule
247 TrajectoryAnalysisModule::TrajectoryAnalysisModule(const char *name,
248 const char *description)
249 : impl_(new Impl(name, description))
254 TrajectoryAnalysisModule::~TrajectoryAnalysisModule()
259 void TrajectoryAnalysisModule::optionsFinished(
260 Options * /*options*/,
261 TrajectoryAnalysisSettings * /*settings*/)
266 void TrajectoryAnalysisModule::initAfterFirstFrame(const t_trxframe &/*fr*/)
271 TrajectoryAnalysisModuleDataPointer
272 TrajectoryAnalysisModule::startFrames(const AnalysisDataParallelOptions &opt,
273 const SelectionCollection &selections)
275 return TrajectoryAnalysisModuleDataPointer(
276 new TrajectoryAnalysisModuleDataBasic(this, opt, selections));
280 void TrajectoryAnalysisModule::finishFrames(TrajectoryAnalysisModuleData * /*pdata*/)
285 const char *TrajectoryAnalysisModule::name() const
287 return impl_->name_.c_str();
291 const char *TrajectoryAnalysisModule::description() const
293 return impl_->description_.c_str();
297 int TrajectoryAnalysisModule::datasetCount() const
299 return impl_->datasetNames_.size();
303 const std::vector<std::string> &TrajectoryAnalysisModule::datasetNames() const
305 return impl_->datasetNames_;
309 AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromIndex(int index) const
311 if (index < 0 || index >= datasetCount())
313 GMX_THROW(APIError("Out of range data set index"));
315 Impl::DatasetContainer::const_iterator item
316 = impl_->datasets_.find(impl_->datasetNames_[index]);
317 GMX_RELEASE_ASSERT(item != impl_->datasets_.end(),
318 "Inconsistent data set names");
319 return *item->second;
323 AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromName(const char *name) const
325 Impl::DatasetContainer::const_iterator item = impl_->datasets_.find(name);
326 if (item == impl_->datasets_.end())
328 GMX_THROW(APIError("Unknown data set name"));
330 return *item->second;
334 void TrajectoryAnalysisModule::registerBasicDataset(AbstractAnalysisData *data,
337 // TODO: Strong exception safety should be possible to implement.
338 GMX_RELEASE_ASSERT(impl_->datasets_.find(name) == impl_->datasets_.end(),
339 "Duplicate data set name registered");
340 impl_->datasets_[name] = data;
341 impl_->datasetNames_.push_back(name);
345 void TrajectoryAnalysisModule::registerAnalysisDataset(AnalysisData *data,
348 // TODO: Strong exception safety should be possible to implement.
349 registerBasicDataset(data, name);
350 impl_->analysisDatasets_[name] = data;