cmdlinerunner.cpp: use ICommandLineOptionsModule
[alexxy/gromacs.git] / src / gromacs / trajectoryanalysis / cmdlinerunner.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \file
36  * \brief
37  * Declares gmx::TrajectoryAnalysisCommandLineRunner.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inpublicapi
41  * \ingroup module_trajectoryanalysis
42  */
43 #ifndef GMX_TRAJECTORYANALYSIS_CMDLINERUNNER_H
44 #define GMX_TRAJECTORYANALYSIS_CMDLINERUNNER_H
45
46 #include "gromacs/commandline/cmdlineoptionsmodule.h"
47 #include "gromacs/trajectoryanalysis/analysismodule.h"
48 #include "gromacs/utility/classhelpers.h"
49
50 namespace gmx
51 {
52
53 class CommandLineModuleManager;
54 class CommandLineHelpContext;
55
56 /*! \brief
57  * Runner class for command-line analysis tools.
58  *
59  * This class implements a command-line analysis program, given a
60  * TrajectoryAnalysisModule object.  It takes care of converting command-line
61  * parameters to a form understood by the module, as well as parsing common
62  * options, initializing and evaluating selections, and looping over trajectory
63  * frames.
64  *
65  * \inpublicapi
66  * \ingroup module_trajectoryanalysis
67  */
68 class TrajectoryAnalysisCommandLineRunner : public ICommandLineOptionsModule
69 {
70     public:
71         /*! \brief
72          * Factory method type for creating a trajectory analysis module.
73          *
74          * This method allows the module creation to be postponed to be inside
75          * the try/catch block in runAsMain()/registerModule() implementation
76          * methods and still keep the implementation out of the header, making
77          * the ABI more stable.
78          */
79         typedef TrajectoryAnalysisModulePointer (*ModuleFactoryMethod)();
80
81         /*! \brief
82          * Factory functor class for creating a trajectory analysis module.
83          *
84          * Old compilers that still must be supported do not have std::function,
85          * so we have to implement runAsMain overload accepting a functor instead
86          * of a function pointer.
87          *
88          * This abstract class should be subclassed to be used. The main usage is for
89          * python bindings.
90          */
91         class ModuleFactoryFunctor
92         {
93             public:
94                 /*! \brief
95                  * operator() that returns a pointer to valid TrajectoryAnalysisModule
96                  */
97                 virtual TrajectoryAnalysisModulePointer operator() () = 0;
98                 virtual ~ModuleFactoryFunctor() {};
99         };
100
101         /*! \brief
102          * Implements a main() method that runs a given module.
103          *
104          * \tparam ModuleType  Trajectory analysis module.
105          * \param  argc        \c argc passed to main().
106          * \param  argv        \c argv passed to main().
107          *
108          * This method abstracts away all the logic required to implement a
109          * main() method in user tools, allowing that to be changed without
110          * requiring changes to the tools themselves.
111          *
112          * \p ModuleType should be default-constructible and derive from
113          * TrajectoryAnalysisModule.
114          *
115          * Does not throw.  All exceptions are caught and handled internally.
116          */
117         template <class ModuleType>
118         static int runAsMain(int argc, char *argv[])
119         {
120             return runAsMain(argc, argv, &createModule<ModuleType>);
121         }
122         /*! \brief
123          * Registers a command-line module that runs a given module.
124          *
125          * \tparam ModuleType  Trajectory analysis module.
126          * \param  manager     Manager to register the module to.
127          * \param  name        Name of the module to register.
128          * \param  description One-line description for the module to register.
129          *
130          * \p ModuleType should be default-constructible and derive from
131          * TrajectoryAnalysisModule.
132          *
133          * \p name and \p descriptions must be string constants or otherwise
134          * stay valid for the duration of the program execution.
135          */
136         template <class ModuleType>
137         static void registerModule(CommandLineModuleManager *manager,
138                                    const char *name, const char *description)
139         {
140             registerModule(manager, name, description, &createModule<ModuleType>);
141         }
142         /*! \brief
143          * Registers a command-line module that runs a given module.
144          *
145          * \tparam ModuleType  Trajectory analysis module.
146          * \param  manager     Manager to register the module to.
147          * \param  name        Name of the module to register.
148          * \param  description One-line description for the module to register.
149          * \param  factory     Function that creates the module on demand.
150          *
151          * \p name and \p descriptions must be string constants or otherwise
152          * stay valid for the duration of the program execution.
153          *
154          * Implements the template registerModule() method, but can also be
155          * used independently.
156          */
157         static void registerModule(CommandLineModuleManager *manager,
158                                    const char *name, const char *description,
159                                    ModuleFactoryMethod factory);
160
161         /*! \brief
162          * Constructs a module.
163          *
164          * \param[in] factory      Factory method to create the analysis module.
165          *
166          * Does not throw.  This is important for correct implementation of
167          * runAsMain().
168          */
169         TrajectoryAnalysisCommandLineRunner(ModuleFactoryMethod factory);
170
171         /*! \brief
172          * Overloaded constructor accepting a functor instead of function pointer.
173          */
174         TrajectoryAnalysisCommandLineRunner(ModuleFactoryFunctor *factory);
175         ~TrajectoryAnalysisCommandLineRunner();
176
177         /*! \brief
178          * Sets whether default index groups are initialized.
179          *
180          * This is intended only for internal unit testing purposes to avoid
181          * repeated, unnecessary initialization of the default groups, which
182          * can be expensive under, e.g., valgrind.
183          *
184          * Does not throw.
185          */
186         void setUseDefaultGroups(bool bUseDefaults);
187         /*! \brief
188          * Sets the default debugging level for selections.
189          *
190          * \param[in] debuglevel  Level of debugging verbosity.
191          *
192          * This is intended only for use by internal debugging tools.
193          *
194          * Does not throw.
195          *
196          * \see SelectionCollection::setDebugLevel()
197          */
198         void setSelectionDebugLevel(int debuglevel);
199
200         // From ICommandLineOptionsModule
201         virtual void init(CommandLineModuleSettings *settings);
202         void initOptions(IOptionsContainer                 *options,
203                          ICommandLineOptionsModuleSettings *settings);
204         void optionsFinished();
205         int run();
206
207         //! Implements the template runAsMain() method.
208         static int runAsMain(int argc, char *argv[],
209                              ModuleFactoryMethod factory);
210         //! Overload of runAsMain accepting functor.
211         static int runAsMain(int argc, char *argv[],
212                              ModuleFactoryFunctor *factory);
213     private:
214         /*! \brief
215          * Creates a trajectory analysis module of a given type.
216          *
217          * \tparam ModuleType  Module to create.
218          */
219         template <class ModuleType>
220         static TrajectoryAnalysisModulePointer createModule()
221         {
222             return TrajectoryAnalysisModulePointer(new ModuleType());
223         }
224
225
226         class Impl;
227
228         PrivateImplPointer<Impl> impl_;
229 };
230
231 } // namespace gmx
232
233 #endif