3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
29 * For more info, check our website at http://www.gromacs.org
33 * Implements gmx::TrajectoryAnalysisCommandLineRunner.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36 * \ingroup module_trajectoryanalysis
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"
65 /********************************************************************
66 * TrajectoryAnalysisCommandLineRunner::Impl
69 class TrajectoryAnalysisCommandLineRunner::Impl
72 Impl(TrajectoryAnalysisModule *module);
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[]);
83 TrajectoryAnalysisModule *module_;
85 bool bPrintCopyright_;
89 TrajectoryAnalysisCommandLineRunner::Impl::Impl(
90 TrajectoryAnalysisModule *module)
91 : module_(module), debugLevel_(0), bPrintCopyright_(true)
96 TrajectoryAnalysisCommandLineRunner::Impl::~Impl()
102 TrajectoryAnalysisCommandLineRunner::Impl::printHelp(
103 const Options &options,
104 const TrajectoryAnalysisSettings &settings,
105 const TrajectoryAnalysisRunnerCommon &common)
107 TrajectoryAnalysisRunnerCommon::HelpFlags flags = common.helpFlags();
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())
122 TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
123 TrajectoryAnalysisSettings *settings,
124 TrajectoryAnalysisRunnerCommon *common,
125 SelectionCollection *selections,
126 int *argc, char *argv[])
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);
136 options.addSubSection(&commonOptions);
137 options.addSubSection(&selectionOptions);
138 options.addSubSection(&moduleOptions);
140 SelectionOptionManager seloptManager(selections);
141 setManagerForSelectionOptions(&options, &seloptManager);
144 CommandLineParser parser(&options);
147 parser.parse(argc, argv);
149 catch (const UserInputError &ex)
151 printHelp(options, *settings, *common);
154 printHelp(options, *settings, *common);
155 common->scaleTimeOptions(&options);
159 if (!common->optionsFinished(&commonOptions))
163 module_->optionsFinished(&moduleOptions, settings);
165 common->initIndexGroups(selections);
167 // TODO: Check whether the input is a pipe.
168 bool bInteractive = true;
169 seloptManager.parseRequestedFromStdin(bInteractive);
170 common->doneIndexGroups(selections);
176 /********************************************************************
177 * TrajectoryAnalysisCommandLineRunner
180 TrajectoryAnalysisCommandLineRunner::TrajectoryAnalysisCommandLineRunner(
181 TrajectoryAnalysisModule *module)
182 : impl_(new Impl(module))
187 TrajectoryAnalysisCommandLineRunner::~TrajectoryAnalysisCommandLineRunner()
193 TrajectoryAnalysisCommandLineRunner::setPrintCopyright(bool bPrint)
195 impl_->bPrintCopyright_ = bPrint;
200 TrajectoryAnalysisCommandLineRunner::setSelectionDebugLevel(int debuglevel)
202 impl_->debugLevel_ = 1;
207 TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
209 TrajectoryAnalysisModule *module = impl_->module_;
211 if (impl_->bPrintCopyright_)
213 CopyRight(stderr, argv[0]);
216 SelectionCollection selections;
217 selections.setDebugLevel(impl_->debugLevel_);
219 TrajectoryAnalysisSettings settings;
220 TrajectoryAnalysisRunnerCommon common(&settings);
222 if (!impl_->parseOptions(&settings, &common, &selections, &argc, argv))
227 common.initTopology(&selections);
228 selections.compile();
230 const TopologyInformation &topology = common.topologyInformation();
231 module->initAnalysis(settings, topology);
234 common.initFirstFrame();
235 module->initAfterFirstFrame(common.frame());
238 t_pbc *ppbc = settings.hasPBC() ? &pbc : NULL;
241 AnalysisDataParallelOptions dataOptions;
242 TrajectoryAnalysisModuleDataPointer pdata(
243 module->startFrames(dataOptions, selections));
247 t_trxframe &frame = common.frame();
250 set_pbc(ppbc, topology.ePBC(), frame.box);
253 selections.evaluate(&frame, ppbc);
254 module->analyzeFrame(nframes, frame, ppbc, pdata.get());
258 while (common.readNextFrame());
259 module->finishFrames(pdata.get());
260 if (pdata.get() != NULL)
266 if (common.hasTrajectory())
268 fprintf(stderr, "Analyzed %d frames, last time %.3f\n",
269 nframes, common.frame().time);
273 fprintf(stderr, "Analyzed topology coordinates\n");
276 // Restore the maximal groups for dynamic selections.
277 selections.evaluateFinal(nframes);
279 module->finishAnalysis(nframes);
280 module->writeOutput();
287 TrajectoryAnalysisCommandLineRunner::writeHelp(const HelpWriterContext &context)
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);
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");
300 impl_->module_->initOptions(&moduleOptions, &settings);
301 common.initOptions(&commonOptions);
302 selections.initOptions(&selectionOptions);
304 options.addSubSection(&commonOptions);
305 options.addSubSection(&selectionOptions);
306 options.addSubSection(&moduleOptions);
308 SelectionOptionManager seloptManager(&selections);
309 setManagerForSelectionOptions(&options, &seloptManager);
311 CommandLineHelpWriter(options)
312 .setShowDescriptions(true)
313 .setTimeUnitString(settings.timeUnitManager().timeUnitAsString())