cmdlinerunner.cpp: use ICommandLineOptionsModule
[alexxy/gromacs.git] / src / gromacs / trajectoryanalysis / cmdlinerunner.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2010,2011,2012,2013,2014,2015, 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 /*! \internal \file
36  * \brief
37  * Implements gmx::TrajectoryAnalysisCommandLineRunner.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \ingroup module_trajectoryanalysis
41  */
42 #include "gmxpre.h"
43
44 #include "cmdlinerunner.h"
45
46 #include "gromacs/analysisdata/paralleloptions.h"
47 #include "gromacs/commandline/cmdlinehelpcontext.h"
48 #include "gromacs/commandline/cmdlinehelpwriter.h"
49 #include "gromacs/commandline/cmdlineoptionsmodule.h"
50 #include "gromacs/commandline/cmdlinemodulemanager.h"
51 #include "gromacs/commandline/cmdlineparser.h"
52 #include "gromacs/fileio/trx.h"
53 #include "gromacs/options/filenameoptionmanager.h"
54 #include "gromacs/options/options.h"
55 #include "gromacs/pbcutil/pbc.h"
56 #include "gromacs/selection/selectioncollection.h"
57 #include "gromacs/selection/selectionoptionmanager.h"
58 #include "gromacs/trajectoryanalysis/analysismodule.h"
59 #include "gromacs/trajectoryanalysis/analysissettings.h"
60 #include "gromacs/utility/exceptions.h"
61 #include "gromacs/utility/filestream.h"
62 #include "gromacs/utility/gmxassert.h"
63
64 #include "runnercommon.h"
65
66 namespace gmx
67 {
68
69 /********************************************************************
70  * TrajectoryAnalysisCommandLineRunner::Impl
71  */
72
73 class TrajectoryAnalysisCommandLineRunner::Impl
74 {
75     public:
76         Impl(TrajectoryAnalysisModulePointer module);
77         ~Impl();
78
79         TrajectoryAnalysisModulePointer module_;
80         bool                            bUseDefaultGroups_;
81         int                             debugLevel_;
82         SelectionCollection             selections_;
83         SelectionOptionManager          selOptManager_;
84         TrajectoryAnalysisSettings      settings_;
85         TrajectoryAnalysisRunnerCommon  common_;
86 };
87
88
89 TrajectoryAnalysisCommandLineRunner::Impl::Impl(
90         TrajectoryAnalysisModulePointer module)
91     : module_(module), bUseDefaultGroups_(true), debugLevel_(0),
92       selOptManager_(&selections_), common_(&settings_)
93 {
94 }
95
96
97 TrajectoryAnalysisCommandLineRunner::Impl::~Impl()
98 {
99     module_.reset();
100 }
101
102
103 /********************************************************************
104  * TrajectoryAnalysisCommandLineRunner
105  */
106
107 TrajectoryAnalysisCommandLineRunner::TrajectoryAnalysisCommandLineRunner(
108         TrajectoryAnalysisCommandLineRunner::ModuleFactoryMethod factory)
109     : impl_(new Impl(factory()))
110 {
111 }
112
113 TrajectoryAnalysisCommandLineRunner::TrajectoryAnalysisCommandLineRunner(
114         TrajectoryAnalysisCommandLineRunner::ModuleFactoryFunctor *functor)
115     : impl_(new Impl((*functor)()))
116 {
117 }
118
119 TrajectoryAnalysisCommandLineRunner::~TrajectoryAnalysisCommandLineRunner()
120 {
121 }
122
123
124 void
125 TrajectoryAnalysisCommandLineRunner::setUseDefaultGroups(bool bUseDefaults)
126 {
127     impl_->bUseDefaultGroups_ = bUseDefaults;
128 }
129
130
131 void
132 TrajectoryAnalysisCommandLineRunner::setSelectionDebugLevel(int debuglevel)
133 {
134     impl_->debugLevel_ = debuglevel;
135 }
136
137 void TrajectoryAnalysisCommandLineRunner::init(CommandLineModuleSettings * /*settings*/)
138 {
139 }
140
141 void
142 TrajectoryAnalysisCommandLineRunner::initOptions(IOptionsContainer                 *options,
143                                                  ICommandLineOptionsModuleSettings *settings)
144 {
145     impl_->selections_.setDebugLevel(impl_->debugLevel_);
146
147     options->addManager(&impl_->selOptManager_);
148
149     IOptionsContainer &commonOptions = options->addGroup();
150     IOptionsContainer &moduleOptions = options->addGroup();
151
152     impl_->module_->initOptions(&moduleOptions, &impl_->settings_);
153     impl_->common_.initOptions(&commonOptions);
154     impl_->selections_.initOptions(&commonOptions);
155
156     const char *help[] = { impl_->settings_.helpText().data() };
157     settings->setHelpText(help);
158 }
159
160 void
161 TrajectoryAnalysisCommandLineRunner::optionsFinished()
162 {
163     // TODO: scaleTimeOptions? (maybe pass options here too, with default arg)
164     impl_->common_.optionsFinished();
165     impl_->module_->optionsFinished(&impl_->settings_);
166
167     impl_->common_.initIndexGroups(&impl_->selections_, impl_->bUseDefaultGroups_);
168
169     const bool bInteractive = StandardInputStream::instance().isInteractive();
170     impl_->selOptManager_.parseRequestedFromStdin(bInteractive);
171     impl_->common_.doneIndexGroups(&impl_->selections_);
172
173     impl_->common_.initTopology(&impl_->selections_);
174     impl_->selections_.compile();
175 }
176
177
178 int
179 TrajectoryAnalysisCommandLineRunner::run()
180 {
181     const TopologyInformation &topology = impl_->common_.topologyInformation();
182     impl_->module_->initAnalysis(impl_->settings_, topology);
183
184     // Load first frame.
185     impl_->common_.initFirstFrame();
186     impl_->module_->initAfterFirstFrame(impl_->settings_, impl_->common_.frame());
187
188     t_pbc  pbc;
189     t_pbc *ppbc = impl_->settings_.hasPBC() ? &pbc : NULL;
190
191     int    nframes = 0;
192     AnalysisDataParallelOptions         dataOptions;
193     TrajectoryAnalysisModuleDataPointer pdata(
194             impl_->module_->startFrames(dataOptions, impl_->selections_));
195     do
196     {
197         impl_->common_.initFrame();
198         t_trxframe &frame = impl_->common_.frame();
199         if (ppbc != NULL)
200         {
201             set_pbc(ppbc, topology.ePBC(), frame.box);
202         }
203
204         impl_->selections_.evaluate(&frame, ppbc);
205         impl_->module_->analyzeFrame(nframes, frame, ppbc, pdata.get());
206         impl_->module_->finishFrameSerial(nframes);
207
208         ++nframes;
209     }
210     while (impl_->common_.readNextFrame());
211     impl_->module_->finishFrames(pdata.get());
212     if (pdata.get() != NULL)
213     {
214         pdata->finish();
215     }
216     pdata.reset();
217
218     if (impl_->common_.hasTrajectory())
219     {
220         fprintf(stderr, "Analyzed %d frames, last time %.3f\n",
221                 nframes, impl_->common_.frame().time);
222     }
223     else
224     {
225         fprintf(stderr, "Analyzed topology coordinates\n");
226     }
227
228     // Restore the maximal groups for dynamic selections.
229     impl_->selections_.evaluateFinal(nframes);
230
231     impl_->module_->finishAnalysis(nframes);
232     impl_->module_->writeOutput();
233     return 0;
234 }
235
236 // static
237 int
238 TrajectoryAnalysisCommandLineRunner::runAsMain(
239         int argc, char *argv[], ModuleFactoryMethod factory)
240 {
241     TrajectoryAnalysisCommandLineRunner *module = new TrajectoryAnalysisCommandLineRunner(factory);
242     return ICommandLineOptionsModule::runAsMain(argc, argv, module);
243 }
244
245 // static
246 int
247 TrajectoryAnalysisCommandLineRunner::runAsMain(
248         int argc, char *argv[], ModuleFactoryFunctor *factory)
249 {
250     TrajectoryAnalysisCommandLineRunner *module = new TrajectoryAnalysisCommandLineRunner(factory);
251     return ICommandLineOptionsModule::runAsMain(argc, argv, module);
252 }
253
254 // static
255 void
256 TrajectoryAnalysisCommandLineRunner::registerModule(
257         CommandLineModuleManager *manager, const char *name,
258         const char *description, ModuleFactoryMethod factory)
259 {
260     ICommandLineOptionsModule::registerModule(manager, name, description,
261         new TrajectoryAnalysisCommandLineRunner(factory));
262 }
263
264 } // namespace gmx