Merge branch 'release-4-6', adds the nbnxn functionality
[alexxy/gromacs.git] / src / gromacs / trajectoryanalysis / cmdlinerunner.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 gmx::TrajectoryAnalysisCommandLineRunner.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_trajectoryanalysis
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include "copyrite.h"
43 #include "pbc.h"
44 #include "rmpbc.h"
45 #include "statutil.h"
46
47 #include "gromacs/analysisdata/paralleloptions.h"
48 #include "gromacs/commandline/cmdlinehelpwriter.h"
49 #include "gromacs/commandline/cmdlineparser.h"
50 #include "gromacs/onlinehelp/helpwritercontext.h"
51 #include "gromacs/options/options.h"
52 #include "gromacs/selection/selectioncollection.h"
53 #include "gromacs/selection/selectionoptionmanager.h"
54 #include "gromacs/trajectoryanalysis/analysismodule.h"
55 #include "gromacs/trajectoryanalysis/analysissettings.h"
56 #include "gromacs/trajectoryanalysis/cmdlinerunner.h"
57 #include "gromacs/trajectoryanalysis/runnercommon.h"
58 #include "gromacs/utility/exceptions.h"
59 #include "gromacs/utility/file.h"
60 #include "gromacs/utility/gmxassert.h"
61
62 namespace gmx
63 {
64
65 /********************************************************************
66  * TrajectoryAnalysisCommandLineRunner::Impl
67  */
68
69 class TrajectoryAnalysisCommandLineRunner::Impl
70 {
71     public:
72         Impl(TrajectoryAnalysisModule *module);
73         ~Impl();
74
75         void printHelp(const Options &options,
76                        const TrajectoryAnalysisSettings &settings,
77                        const TrajectoryAnalysisRunnerCommon &common);
78         bool parseOptions(TrajectoryAnalysisSettings *settings,
79                           TrajectoryAnalysisRunnerCommon *common,
80                           SelectionCollection *selections,
81                           int *argc, char *argv[]);
82
83         TrajectoryAnalysisModule *module_;
84         int                     debugLevel_;
85         bool                    bPrintCopyright_;
86 };
87
88
89 TrajectoryAnalysisCommandLineRunner::Impl::Impl(
90         TrajectoryAnalysisModule *module)
91     : module_(module), debugLevel_(0), bPrintCopyright_(true)
92 {
93 }
94
95
96 TrajectoryAnalysisCommandLineRunner::Impl::~Impl()
97 {
98 }
99
100
101 void
102 TrajectoryAnalysisCommandLineRunner::Impl::printHelp(
103         const Options &options,
104         const TrajectoryAnalysisSettings &settings,
105         const TrajectoryAnalysisRunnerCommon &common)
106 {
107     TrajectoryAnalysisRunnerCommon::HelpFlags flags = common.helpFlags();
108     if (flags != 0)
109     {
110         HelpWriterContext context(&File::standardError(),
111                                   eHelpOutputFormat_Console);
112         CommandLineHelpWriter(options)
113             .setShowDescriptions(flags & TrajectoryAnalysisRunnerCommon::efHelpShowDescriptions)
114             .setShowHidden(flags & TrajectoryAnalysisRunnerCommon::efHelpShowHidden)
115             .setTimeUnitString(settings.timeUnitManager().timeUnitAsString())
116             .writeHelp(context);
117     }
118 }
119
120
121 bool
122 TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
123         TrajectoryAnalysisSettings *settings,
124         TrajectoryAnalysisRunnerCommon *common,
125         SelectionCollection *selections,
126         int *argc, char *argv[])
127 {
128     Options options(NULL, NULL);
129     Options moduleOptions(module_->name(), module_->description());
130     Options commonOptions("common", "Common analysis control");
131     Options selectionOptions("selection", "Common selection control");
132     module_->initOptions(&moduleOptions, settings);
133     common->initOptions(&commonOptions);
134     selections->initOptions(&selectionOptions);
135
136     options.addSubSection(&commonOptions);
137     options.addSubSection(&selectionOptions);
138     options.addSubSection(&moduleOptions);
139
140     SelectionOptionManager seloptManager(selections);
141     setManagerForSelectionOptions(&options, &seloptManager);
142
143     {
144         CommandLineParser  parser(&options);
145         try
146         {
147             parser.parse(argc, argv);
148         }
149         catch (const UserInputError &ex)
150         {
151             printHelp(options, *settings, *common);
152             throw;
153         }
154         printHelp(options, *settings, *common);
155         common->scaleTimeOptions(&options);
156         options.finish();
157     }
158
159     if (!common->optionsFinished(&commonOptions))
160     {
161         return false;
162     }
163     module_->optionsFinished(&moduleOptions, settings);
164
165     common->initIndexGroups(selections);
166
167     // TODO: Check whether the input is a pipe.
168     bool bInteractive = true;
169     seloptManager.parseRequestedFromStdin(bInteractive);
170     common->doneIndexGroups(selections);
171
172     return true;
173 }
174
175
176 /********************************************************************
177  * TrajectoryAnalysisCommandLineRunner
178  */
179
180 TrajectoryAnalysisCommandLineRunner::TrajectoryAnalysisCommandLineRunner(
181         TrajectoryAnalysisModule *module)
182     : impl_(new Impl(module))
183 {
184 }
185
186
187 TrajectoryAnalysisCommandLineRunner::~TrajectoryAnalysisCommandLineRunner()
188 {
189 }
190
191
192 void
193 TrajectoryAnalysisCommandLineRunner::setPrintCopyright(bool bPrint)
194 {
195     impl_->bPrintCopyright_ = bPrint;
196 }
197
198
199 void
200 TrajectoryAnalysisCommandLineRunner::setSelectionDebugLevel(int debuglevel)
201 {
202     impl_->debugLevel_ = 1;
203 }
204
205
206 int
207 TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
208 {
209     TrajectoryAnalysisModule *module = impl_->module_;
210
211     if (impl_->bPrintCopyright_)
212     {
213         CopyRight(stderr, argv[0]);
214     }
215
216     SelectionCollection  selections;
217     selections.setDebugLevel(impl_->debugLevel_);
218
219     TrajectoryAnalysisSettings  settings;
220     TrajectoryAnalysisRunnerCommon  common(&settings);
221
222     if (!impl_->parseOptions(&settings, &common, &selections, &argc, argv))
223     {
224         return 0;
225     }
226
227     common.initTopology(&selections);
228     selections.compile();
229
230     const TopologyInformation &topology = common.topologyInformation();
231     module->initAnalysis(settings, topology);
232
233     // Load first frame.
234     common.initFirstFrame();
235     module->initAfterFirstFrame(common.frame());
236
237     t_pbc  pbc;
238     t_pbc *ppbc = settings.hasPBC() ? &pbc : NULL;
239
240     int nframes = 0;
241     AnalysisDataParallelOptions dataOptions;
242     TrajectoryAnalysisModuleDataPointer pdata(
243             module->startFrames(dataOptions, selections));
244     do
245     {
246         common.initFrame();
247         t_trxframe &frame = common.frame();
248         if (ppbc != NULL)
249         {
250             set_pbc(ppbc, topology.ePBC(), frame.box);
251         }
252
253         selections.evaluate(&frame, ppbc);
254         module->analyzeFrame(nframes, frame, ppbc, pdata.get());
255
256         nframes++;
257     }
258     while (common.readNextFrame());
259     module->finishFrames(pdata.get());
260     if (pdata.get() != NULL)
261     {
262         pdata->finish();
263     }
264     pdata.reset();
265
266     if (common.hasTrajectory())
267     {
268         fprintf(stderr, "Analyzed %d frames, last time %.3f\n",
269                 nframes, common.frame().time);
270     }
271     else
272     {
273         fprintf(stderr, "Analyzed topology coordinates\n");
274     }
275
276     // Restore the maximal groups for dynamic selections.
277     selections.evaluateFinal(nframes);
278
279     module->finishAnalysis(nframes);
280     module->writeOutput();
281
282     return 0;
283 }
284
285
286 void
287 TrajectoryAnalysisCommandLineRunner::writeHelp(const HelpWriterContext &context)
288 {
289     // TODO: This method duplicates some code from run() and Impl::printHelp().
290     // See how to best refactor it to share the common code.
291     SelectionCollection             selections;
292     TrajectoryAnalysisSettings      settings;
293     TrajectoryAnalysisRunnerCommon  common(&settings);
294
295     Options options(NULL, NULL);
296     Options moduleOptions(impl_->module_->name(), impl_->module_->description());
297     Options commonOptions("common", "Common analysis control");
298     Options selectionOptions("selection", "Common selection control");
299
300     impl_->module_->initOptions(&moduleOptions, &settings);
301     common.initOptions(&commonOptions);
302     selections.initOptions(&selectionOptions);
303
304     options.addSubSection(&commonOptions);
305     options.addSubSection(&selectionOptions);
306     options.addSubSection(&moduleOptions);
307
308     SelectionOptionManager seloptManager(&selections);
309     setManagerForSelectionOptions(&options, &seloptManager);
310
311     CommandLineHelpWriter(options)
312         .setShowDescriptions(true)
313         .setTimeUnitString(settings.timeUnitManager().timeUnitAsString())
314         .writeHelp(context);
315 }
316
317 } // namespace gmx