Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / selection / selectionoption.h
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 /*! \file
32  * \brief
33  * Declares gmx::SelectionOption and gmx::SelectionOptionInfo.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \inpublicapi
37  * \ingroup module_selection
38  */
39 #ifndef GMX_SELECTION_SELECTIONOPTION_H
40 #define GMX_SELECTION_SELECTIONOPTION_H
41
42 #include "../options/abstractoption.h"
43
44 #include "selection.h"
45 #include "selectionenums.h"
46
47 namespace gmx
48 {
49
50 class SelectionOptionInfo;
51 class SelectionOptionManager;
52 class SelectionOptionStorage;
53
54 /*! \brief
55  * Specifies an option that provides selection(s).
56  *
57  * Public methods in this class do not throw.
58  *
59  * \todo
60  * Support for specifying that an option accepts, e.g., two to four selections.
61  * Currently, only a fixed count or any number of selections is possible.
62  * \if internal
63  * In addition to allowing this in OptionTemplate, also SelectionOptionManager
64  * needs to be updated.
65  * \endif
66  *
67  * \inpublicapi
68  * \ingroup module_selection
69  */
70 class SelectionOption : public OptionTemplate<Selection, SelectionOption>
71 {
72     public:
73         //! OptionInfo subclass corresponding to this option type.
74         typedef SelectionOptionInfo InfoType;
75
76         //! Initializes an option with the given name.
77         explicit SelectionOption(const char *name) : MyBase(name) { }
78
79         /*! \brief
80          * Request velocity evaluation for output positions.
81          *
82          * Note that even with this flag set, velocities may not be available,
83          * in which case SelectionPosition::hasVelocity() returns false.
84          */
85         MyClass &evaluateVelocities()
86         { selectionFlags_.set(efSelection_EvaluateVelocities); return me(); }
87         /*! \brief
88          * Request force evaluation for output positions.
89          *
90          * Note that even with this flag set, forces may not be available,
91          * in which case SelectionPosition::hasForce() returns false.
92          */
93         MyClass &evaluateForces()
94         { selectionFlags_.set(efSelection_EvaluateForces); return me(); }
95         /*! \brief
96          * Only accept selections that evaluate to atom positions.
97          *
98          * TODO: This option is not yet implemented.
99          */
100         MyClass &onlyAtoms()
101         { selectionFlags_.set(efSelection_OnlyAtoms); return me(); }
102         /*! \brief
103          * Only accept static selections for this option.
104          */
105         MyClass &onlyStatic()
106         { selectionFlags_.set(efSelection_OnlyStatic); return me(); }
107         /*! \brief
108          * Handle dynamic selections for this option with position masks.
109          *
110          * \see Selection
111          * \see SelectionPosition::selected()
112          */
113         MyClass &dynamicMask()
114         { selectionFlags_.set(efSelection_DynamicMask); return me(); }
115         /*! \brief
116          * Disallow using atom coordinates as the reference positions.
117          *
118          * TODO: This option is not yet implemented.
119          */
120         MyClass &dynamicOnlyWhole()
121         { selectionFlags_.set(efSelection_DynamicOnlyWhole); return me(); }
122
123     private:
124         // Disable possibility to allow multiple occurrences, since it isn't
125         // implemented.
126         using MyBase::allowMultiple;
127         // Disable default value because it is impossible to provide a
128         // Selection object.
129         using MyBase::defaultValue;
130         using MyBase::defaultValueIfSet;
131
132         virtual AbstractOptionStoragePointer createStorage() const;
133
134         SelectionFlags          selectionFlags_;
135
136         /*! \brief
137          * Needed to initialize SelectionOptionStorage from this class without
138          * otherwise unnecessary accessors.
139          */
140         friend class SelectionOptionStorage;
141 };
142
143 /*! \brief
144  * Wrapper class for accessing and modifying selection option information.
145  *
146  * Allows changes to a selection option after creation.
147  *
148  * This class provides the necessary interface for changing, e.g., the number
149  * of allowed selections for a selection option after the option has been
150  * created with Options::addOption().  This is needed if the number or other
151  * flags are only known after other options have been parsed.  The main
152  * advantage of this class over custom checks is that if used before
153  * interactive selection prompt, the interactive prompt is updated accordingly.
154  *
155  * When using this class, the option should be initially created with the most
156  * permissive flags, and this class should be used to place restrictions where
157  * appropriate.  Otherwise, values that are provided before adjustments will
158  * need to follow the more strict checks.  In most cases in trajectory analysis
159  * (which is the main use case for selection options), the adjustments should
160  * be done in TrajectoryAnalysisModule::initOptionsDone() for them to take
161  * place before interactive selection prompts.
162  *
163  * An instance of this class for a selection option can be obtained with
164  * SelectionOption::getAdjuster() when the option is created.
165  *
166  * Example use:
167  * \code
168 SelectionList sel;
169 Options options("example", "Example options");
170 SelectionOptionInfo *info;
171 info = options.addOption(SelectionOption("sel").storeVector(&sel)
172                              .multiValue());
173 // < ... assign values to options ...>
174 if ( condition )
175 {
176     // Put limitations on the selections based on the condition,
177     // which can depend on other option values.
178     // Throws if input given so far violates the limitations.
179     info->setValueCount(2);
180     info->setOnlyStatic(true);
181 }
182  * \endcode
183  *
184  * \inpublicapi
185  * \ingroup module_selection
186  */
187 class SelectionOptionInfo : public OptionInfo
188 {
189     public:
190         /*! \brief
191          * Creates option info object for given storage object.
192          *
193          * Does not throw.
194          */
195         explicit SelectionOptionInfo(SelectionOptionStorage *option);
196
197         /*! \brief
198          * Set manager for handling interaction with other options and the
199          * selection collection.
200          *
201          * \param   manager  Selection manager to set.
202          *
203          * This must be called before the values are added.
204          *
205          * Typically it is called through setManagerForSelectionOptions(),
206          * which recursively sets the manager for all selection options in
207          * an Options object.
208          *
209          * Does not throw.
210          */
211         void setManager(SelectionOptionManager *manager);
212
213         /*! \brief
214          * Sets the number of selections allowed for the option.
215          *
216          * \param[in] count  Number of allowed selections.
217          * \throws    std::bad_alloc if out of memory.
218          * \throws    InvalidInputError if values have already been provided
219          *      and their count does not match.
220          */
221         void setValueCount(int count);
222
223         /*! \brief
224          * Sets whether this option evaluates velocities for positions.
225          *
226          * \param[in] bEnabled  If true, velocities are evaluated.
227          *
228          * Does not throw.
229          *
230          * \see SelectionOption::evaluateVelocities()
231          */
232         void setEvaluateVelocities(bool bEnabled);
233         /*! \brief
234          * Sets whether this option evaluates forces for positions.
235          *
236          * \param[in] bEnabled  If true, forces are evaluated.
237          *
238          * Does not throw.
239          *
240          * \see SelectionOption::evaluateForces()
241          */
242         void setEvaluateForces(bool bEnabled);
243         /*! \brief
244          * Sets whether this option accepts positions that come from multiple
245          * atoms.
246          *
247          * \param[in] bEnabled  If true, the option accepts only positions that
248          *      evaluate to atom positions.
249          *
250          * TODO: This is not yet implemented.
251          *
252          * \see SelectionOption::onlyAtoms()
253          */
254         void setOnlyAtoms(bool bEnabled);
255         /*! \brief
256          * Sets whether this option accepts dynamic selections.
257          *
258          * \param[in] bEnabled  If true, the option accepts only static
259          *      selections.
260          * \throws    std::bad_alloc if out of memory.
261          * \throws    InvalidInputError if dynamic selections have already been
262          *      provided.
263          *
264          * Strong exception safety guarantee.
265          *
266          * \see SelectionOption::onlyStatic()
267          */
268         void setOnlyStatic(bool bEnabled);
269         /*! \brief
270          * Sets whether this option uses position masks for dynamic selections.
271          *
272          * \param[in] bEnabled  If true, the position masks are used.
273          *
274          * Does not throw.
275          *
276          * \see SelectionOption::dynamicMask()
277          */
278         void setDynamicMask(bool bEnabled);
279         /*! \brief
280          * Sets whether atom coordinates are allowed as reference positions.
281          *
282          * \param[in] bEnabled  If true, the option does not accept atom
283          *      coordinates as reference positions.
284          *
285          * TODO: This is not yet implemented.
286          *
287          * \see SelectionOption::dynamicOnlyWhole()
288          */
289         void setDynamicOnlyWhole(bool bEnabled);
290
291     private:
292         SelectionOptionStorage &option();
293         const SelectionOptionStorage &option() const;
294 };
295
296 } // namespace gmx
297
298 #endif