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