Code beautification with uncrustify
[alexxy/gromacs.git] / src / gromacs / selection / selectionoption.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 selectionoption.h and selectionoptionstorage.h.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_selection
37  */
38 #include "selectionoption.h"
39 #include "selectionfileoption.h"
40 #include "selectionoptionstorage.h"
41 #include "selectionfileoptionstorage.h"
42
43 #include <string>
44
45 #include "gromacs/selection/selection.h"
46 #include "gromacs/selection/selectionoptionmanager.h"
47 #include "gromacs/utility/exceptions.h"
48 #include "gromacs/utility/gmxassert.h"
49 #include "gromacs/utility/messagestringcollector.h"
50
51 namespace gmx
52 {
53
54 /********************************************************************
55  * SelectionOptionStorage
56  */
57
58 SelectionOptionStorage::SelectionOptionStorage(const SelectionOption &settings)
59     : MyBase(settings, OptionFlags() | efOption_NoDefaultValue
60              | efOption_DontCheckMinimumCount),
61       info_(this), manager_(NULL), selectionFlags_(settings.selectionFlags_)
62 {
63     GMX_RELEASE_ASSERT(!hasFlag(efOption_MultipleTimes),
64                        "allowMultiple() is not supported for selection options");
65 }
66
67
68 void SelectionOptionStorage::setManager(SelectionOptionManager *manager)
69 {
70     GMX_RELEASE_ASSERT(manager_ == NULL || manager_ == manager,
71                        "Manager cannot be changed once set");
72     if (manager_ == NULL)
73     {
74         manager->registerOption(this);
75         manager_ = manager;
76     }
77 }
78
79
80 std::string SelectionOptionStorage::formatSingleValue(const Selection &value) const
81 {
82     return value.selectionText();
83 }
84
85
86 void SelectionOptionStorage::addSelections(
87         const SelectionList &selections,
88         bool                 bFullValue)
89 {
90     if (bFullValue && selections.size() < static_cast<size_t>(minValueCount()))
91     {
92         GMX_THROW(InvalidInputError("Too few selections provided"));
93     }
94     if (bFullValue)
95     {
96         clearSet();
97     }
98     SelectionList::const_iterator i;
99     for (i = selections.begin(); i != selections.end(); ++i)
100     {
101         // TODO: Having this check in the parser would make interactive input
102         // behave better.
103         if (selectionFlags_.test(efSelection_OnlyStatic) && i->isDynamic())
104         {
105             GMX_THROW(InvalidInputError("Dynamic selections not supported"));
106         }
107         addValue(*i);
108     }
109     if (bFullValue)
110     {
111         commitValues();
112         markAsSet();
113     }
114 }
115
116
117 void SelectionOptionStorage::convertValue(const std::string &value)
118 {
119     GMX_RELEASE_ASSERT(manager_ != NULL, "Manager is not set");
120
121     manager_->convertOptionValue(this, value);
122 }
123
124 void SelectionOptionStorage::processSetValues(ValueList *values)
125 {
126     GMX_RELEASE_ASSERT(manager_ != NULL, "Manager is not set");
127
128     if (values->size() == 0)
129     {
130         manager_->requestOptionDelayedParsing(this);
131     }
132     else if (values->size() < static_cast<size_t>(minValueCount()))
133     {
134         GMX_THROW(InvalidInputError("Too few (valid) values provided"));
135     }
136     ValueList::iterator i;
137     for (i = values->begin(); i != values->end(); ++i)
138     {
139         i->data().setFlags(selectionFlags_);
140     }
141 }
142
143 void SelectionOptionStorage::processAll()
144 {
145     if (isRequired() && !isSet())
146     {
147         GMX_RELEASE_ASSERT(manager_ != NULL, "Manager is not set");
148
149         manager_->requestOptionDelayedParsing(this);
150         markAsSet();
151     }
152 }
153
154 void SelectionOptionStorage::setAllowedValueCount(int count)
155 {
156     // TODO: It should be possible to have strong exception safety here.
157     MessageStringCollector errors;
158     errors.startContext("In option '" + name() + "'");
159     if (count >= 0)
160     {
161         // Should not throw because efOption_DontCheckMinimumCount is set.
162         setMinValueCount(count);
163         if (valueCount() > 0 && valueCount() < count)
164         {
165             errors.append("Too few (valid) values provided");
166         }
167     }
168     try
169     {
170         setMaxValueCount(count);
171     }
172     catch (const UserInputError &ex)
173     {
174         errors.append(ex.what());
175     }
176     errors.finishContext();
177     if (!errors.isEmpty())
178     {
179         GMX_THROW(InvalidInputError(errors.toString()));
180     }
181 }
182
183 void SelectionOptionStorage::setSelectionFlag(SelectionFlag flag, bool bSet)
184 {
185     ValueList::iterator i;
186     for (i = values().begin(); i != values().end(); ++i)
187     {
188         if (flag == efSelection_OnlyStatic && bSet && i->isDynamic())
189         {
190             MessageStringCollector errors;
191             errors.startContext("In option '" + name() + "'");
192             errors.append("Dynamic selections not supported");
193             errors.finishContext();
194             GMX_THROW(InvalidInputError(errors.toString()));
195         }
196     }
197     selectionFlags_.set(flag, bSet);
198     for (i = values().begin(); i != values().end(); ++i)
199     {
200         i->data().setFlags(selectionFlags_);
201     }
202 }
203
204
205 /********************************************************************
206  * SelectionOptionInfo
207  */
208
209 SelectionOptionInfo::SelectionOptionInfo(SelectionOptionStorage *option)
210     : OptionInfo(option)
211 {
212 }
213
214 SelectionOptionStorage &SelectionOptionInfo::option()
215 {
216     return static_cast<SelectionOptionStorage &>(OptionInfo::option());
217 }
218
219 const SelectionOptionStorage &SelectionOptionInfo::option() const
220 {
221     return static_cast<const SelectionOptionStorage &>(OptionInfo::option());
222 }
223
224 void SelectionOptionInfo::setManager(SelectionOptionManager *manager)
225 {
226     option().setManager(manager);
227 }
228
229 void SelectionOptionInfo::setValueCount(int count)
230 {
231     option().setAllowedValueCount(count);
232 }
233
234 void SelectionOptionInfo::setEvaluateVelocities(bool bEnabled)
235 {
236     option().setSelectionFlag(efSelection_EvaluateVelocities, bEnabled);
237 }
238
239 void SelectionOptionInfo::setEvaluateForces(bool bEnabled)
240 {
241     option().setSelectionFlag(efSelection_EvaluateForces, bEnabled);
242 }
243
244 void SelectionOptionInfo::setOnlyAtoms(bool bEnabled)
245 {
246     option().setSelectionFlag(efSelection_OnlyAtoms, bEnabled);
247 }
248
249 void SelectionOptionInfo::setOnlyStatic(bool bEnabled)
250 {
251     option().setSelectionFlag(efSelection_OnlyStatic, bEnabled);
252 }
253
254 void SelectionOptionInfo::setDynamicMask(bool bEnabled)
255 {
256     option().setSelectionFlag(efSelection_DynamicMask, bEnabled);
257 }
258
259 void SelectionOptionInfo::setDynamicOnlyWhole(bool bEnabled)
260 {
261     option().setSelectionFlag(efSelection_DynamicOnlyWhole, bEnabled);
262 }
263
264
265 /********************************************************************
266  * SelectionOption
267  */
268
269 AbstractOptionStoragePointer SelectionOption::createStorage() const
270 {
271     return AbstractOptionStoragePointer(new SelectionOptionStorage(*this));
272 }
273
274
275 /********************************************************************
276  * SelectionFileOptionStorage
277  */
278
279 SelectionFileOptionStorage::SelectionFileOptionStorage(const SelectionFileOption &settings)
280     : AbstractOptionStorage(settings, OptionFlags() | efOption_MultipleTimes
281                             | efOption_DontCheckMinimumCount),
282       info_(this), manager_(NULL), bValueParsed_(false)
283 {
284 }
285
286 void SelectionFileOptionStorage::clearSet()
287 {
288     bValueParsed_ = false;
289 }
290
291 void SelectionFileOptionStorage::convertValue(const std::string &value)
292 {
293     GMX_RELEASE_ASSERT(manager_ != NULL, "Manager is not set");
294
295     if (bValueParsed_)
296     {
297         GMX_THROW(InvalidInputError("More than one file name provided"));
298     }
299     bValueParsed_ = true;
300     // TODO: Should we throw an InvalidInputError if the file does not exist?
301     manager_->parseRequestedFromFile(value);
302 }
303
304 void SelectionFileOptionStorage::processSet()
305 {
306     if (!bValueParsed_)
307     {
308         GMX_THROW(InvalidInputError("No file name provided"));
309     }
310 }
311
312
313 /********************************************************************
314  * SelectionFileOptionInfo
315  */
316
317 SelectionFileOptionInfo::SelectionFileOptionInfo(SelectionFileOptionStorage *option)
318     : OptionInfo(option)
319 {
320 }
321
322 SelectionFileOptionStorage &SelectionFileOptionInfo::option()
323 {
324     return static_cast<SelectionFileOptionStorage &>(OptionInfo::option());
325 }
326
327 const SelectionFileOptionStorage &SelectionFileOptionInfo::option() const
328 {
329     return static_cast<const SelectionFileOptionStorage &>(OptionInfo::option());
330 }
331
332 void SelectionFileOptionInfo::setManager(SelectionOptionManager *manager)
333 {
334     option().setManager(manager);
335 }
336
337
338 /********************************************************************
339  * SelectionFileOption
340  */
341
342 SelectionFileOption::SelectionFileOption(const char *name)
343     : AbstractOption(name)
344 {
345     setDescription("Provide selections from files");
346 }
347
348 AbstractOptionStoragePointer SelectionFileOption::createStorage() const
349 {
350     return AbstractOptionStoragePointer(new SelectionFileOptionStorage(*this));
351 }
352
353 } // namespace gmx