Remove unnecessary config.h includes
[alexxy/gromacs.git] / src / gromacs / trajectoryanalysis / cmdlinerunner.cpp
index fd5288ffb861d1ec6c6e5a617b2485769675a452..d826b870a8db22340e25068acf4f639bad65de39 100644 (file)
@@ -1,59 +1,62 @@
 /*
+ * This file is part of the GROMACS molecular simulation package.
  *
- *                This source code is part of
+ * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
  *
- *                 G   R   O   M   A   C   S
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
  *
- *          GROningen MAchine for Chemical Simulations
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
  *
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
  *
  * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- *
- * For more info, check our website at http://www.gromacs.org
+ * the research papers on the package. Check out http://www.gromacs.org.
  */
 /*! \internal \file
  * \brief
  * Implements gmx::TrajectoryAnalysisCommandLineRunner.
  *
- * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
  * \ingroup module_trajectoryanalysis
  */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "gmxpre.h"
 
-#include "copyrite.h"
-#include "pbc.h"
-#include "rmpbc.h"
-#include "statutil.h"
+#include "cmdlinerunner.h"
 
 #include "gromacs/analysisdata/paralleloptions.h"
+#include "gromacs/commandline/cmdlinehelpcontext.h"
 #include "gromacs/commandline/cmdlinehelpwriter.h"
+#include "gromacs/commandline/cmdlinemodule.h"
+#include "gromacs/commandline/cmdlinemodulemanager.h"
 #include "gromacs/commandline/cmdlineparser.h"
-#include "gromacs/onlinehelp/helpwritercontext.h"
+#include "gromacs/fileio/trx.h"
+#include "gromacs/options/filenameoptionmanager.h"
 #include "gromacs/options/options.h"
+#include "gromacs/pbcutil/pbc.h"
 #include "gromacs/selection/selectioncollection.h"
 #include "gromacs/selection/selectionoptionmanager.h"
 #include "gromacs/trajectoryanalysis/analysismodule.h"
 #include "gromacs/trajectoryanalysis/analysissettings.h"
-#include "gromacs/trajectoryanalysis/cmdlinerunner.h"
 #include "gromacs/trajectoryanalysis/runnercommon.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/file.h"
@@ -69,26 +72,25 @@ namespace gmx
 class TrajectoryAnalysisCommandLineRunner::Impl
 {
     public:
+        class RunnerCommandLineModule;
+
         Impl(TrajectoryAnalysisModule *module);
         ~Impl();
 
-        void printHelp(const Options &options,
-                       const TrajectoryAnalysisSettings &settings,
-                       const TrajectoryAnalysisRunnerCommon &common);
-        bool parseOptions(TrajectoryAnalysisSettings *settings,
+        void parseOptions(TrajectoryAnalysisSettings *settings,
                           TrajectoryAnalysisRunnerCommon *common,
                           SelectionCollection *selections,
                           int *argc, char *argv[]);
 
         TrajectoryAnalysisModule *module_;
-        int                     debugLevel_;
-        bool                    bPrintCopyright_;
+        bool                      bUseDefaultGroups_;
+        int                       debugLevel_;
 };
 
 
 TrajectoryAnalysisCommandLineRunner::Impl::Impl(
         TrajectoryAnalysisModule *module)
-    : module_(module), debugLevel_(0), bPrintCopyright_(true)
+    : module_(module), bUseDefaultGroups_(true), debugLevel_(0)
 {
 }
 
@@ -99,77 +101,49 @@ TrajectoryAnalysisCommandLineRunner::Impl::~Impl()
 
 
 void
-TrajectoryAnalysisCommandLineRunner::Impl::printHelp(
-        const Options &options,
-        const TrajectoryAnalysisSettings &settings,
-        const TrajectoryAnalysisRunnerCommon &common)
-{
-    TrajectoryAnalysisRunnerCommon::HelpFlags flags = common.helpFlags();
-    if (flags != 0)
-    {
-        HelpWriterContext context(&File::standardError(),
-                                  eHelpOutputFormat_Console);
-        CommandLineHelpWriter(options)
-            .setShowDescriptions(flags & TrajectoryAnalysisRunnerCommon::efHelpShowDescriptions)
-            .setShowHidden(flags & TrajectoryAnalysisRunnerCommon::efHelpShowHidden)
-            .setTimeUnitString(settings.timeUnitManager().timeUnitAsString())
-            .writeHelp(context);
-    }
-}
-
-
-bool
 TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
         TrajectoryAnalysisSettings *settings,
         TrajectoryAnalysisRunnerCommon *common,
         SelectionCollection *selections,
         int *argc, char *argv[])
 {
-    Options options(NULL, NULL);
-    Options moduleOptions(module_->name(), module_->description());
-    Options commonOptions("common", "Common analysis control");
-    Options selectionOptions("selection", "Common selection control");
-    module_->initOptions(&moduleOptions, settings);
-    common->initOptions(&commonOptions);
-    selections->initOptions(&selectionOptions);
+    FileNameOptionManager  fileoptManager;
+    SelectionOptionManager seloptManager(selections);
+    Options                options(NULL, NULL);
+    Options                moduleOptions(module_->name(), module_->description());
+    Options                commonOptions("common", "Common analysis control");
+    Options                selectionOptions("selection", "Common selection control");
 
+    options.addManager(&fileoptManager);
+    options.addManager(&seloptManager);
     options.addSubSection(&commonOptions);
     options.addSubSection(&selectionOptions);
     options.addSubSection(&moduleOptions);
 
-    SelectionOptionManager seloptManager(selections);
-    setManagerForSelectionOptions(&options, &seloptManager);
+    module_->initOptions(&moduleOptions, settings);
+    common->initOptions(&commonOptions);
+    selections->initOptions(&selectionOptions);
 
     {
         CommandLineParser  parser(&options);
-        try
-        {
-            parser.parse(argc, argv);
-        }
-        catch (const UserInputError &ex)
-        {
-            printHelp(options, *settings, *common);
-            throw;
-        }
-        printHelp(options, *settings, *common);
+        // TODO: Print the help if user provides an invalid option?
+        // Or just add a message advising the user to invoke the help?
+        parser.parse(argc, argv);
         common->scaleTimeOptions(&options);
         options.finish();
     }
 
-    if (!common->optionsFinished(&commonOptions))
-    {
-        return false;
-    }
+    common->optionsFinished(&commonOptions);
     module_->optionsFinished(&moduleOptions, settings);
 
-    common->initIndexGroups(selections);
+    common->initIndexGroups(selections, bUseDefaultGroups_);
 
-    // TODO: Check whether the input is a pipe.
-    bool bInteractive = true;
+    const bool bInteractive = File::standardInput().isInteractive();
     seloptManager.parseRequestedFromStdin(bInteractive);
     common->doneIndexGroups(selections);
 
-    return true;
+    common->initTopology(selections);
+    selections->compile();
 }
 
 
@@ -190,16 +164,16 @@ TrajectoryAnalysisCommandLineRunner::~TrajectoryAnalysisCommandLineRunner()
 
 
 void
-TrajectoryAnalysisCommandLineRunner::setPrintCopyright(bool bPrint)
+TrajectoryAnalysisCommandLineRunner::setUseDefaultGroups(bool bUseDefaults)
 {
-    impl_->bPrintCopyright_ = bPrint;
+    impl_->bUseDefaultGroups_ = bUseDefaults;
 }
 
 
 void
 TrajectoryAnalysisCommandLineRunner::setSelectionDebugLevel(int debuglevel)
 {
-    impl_->debugLevel_ = 1;
+    impl_->debugLevel_ = debuglevel;
 }
 
 
@@ -208,37 +182,26 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
 {
     TrajectoryAnalysisModule *module = impl_->module_;
 
-    if (impl_->bPrintCopyright_)
-    {
-        CopyRight(stderr, argv[0]);
-    }
-
-    SelectionCollection  selections;
+    SelectionCollection       selections;
     selections.setDebugLevel(impl_->debugLevel_);
 
-    TrajectoryAnalysisSettings  settings;
+    TrajectoryAnalysisSettings      settings;
     TrajectoryAnalysisRunnerCommon  common(&settings);
 
-    if (!impl_->parseOptions(&settings, &common, &selections, &argc, argv))
-    {
-        return 0;
-    }
-
-    common.initTopology(&selections);
-    selections.compile();
+    impl_->parseOptions(&settings, &common, &selections, &argc, argv);
 
     const TopologyInformation &topology = common.topologyInformation();
     module->initAnalysis(settings, topology);
 
     // Load first frame.
     common.initFirstFrame();
-    module->initAfterFirstFrame(common.frame());
+    module->initAfterFirstFrame(settings, common.frame());
 
     t_pbc  pbc;
     t_pbc *ppbc = settings.hasPBC() ? &pbc : NULL;
 
-    int nframes = 0;
-    AnalysisDataParallelOptions dataOptions;
+    int    nframes = 0;
+    AnalysisDataParallelOptions         dataOptions;
     TrajectoryAnalysisModuleDataPointer pdata(
             module->startFrames(dataOptions, selections));
     do
@@ -284,29 +247,28 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
 
 
 void
-TrajectoryAnalysisCommandLineRunner::writeHelp(const HelpWriterContext &context)
+TrajectoryAnalysisCommandLineRunner::writeHelp(const CommandLineHelpContext &context)
 {
-    // TODO: This method duplicates some code from run() and Impl::printHelp().
+    // TODO: This method duplicates some code from run().
     // See how to best refactor it to share the common code.
     SelectionCollection             selections;
     TrajectoryAnalysisSettings      settings;
     TrajectoryAnalysisRunnerCommon  common(&settings);
 
-    Options options(NULL, NULL);
-    Options moduleOptions(impl_->module_->name(), impl_->module_->description());
-    Options commonOptions("common", "Common analysis control");
-    Options selectionOptions("selection", "Common selection control");
-
-    impl_->module_->initOptions(&moduleOptions, &settings);
-    common.initOptions(&commonOptions);
-    selections.initOptions(&selectionOptions);
+    SelectionOptionManager          seloptManager(&selections);
+    Options                         options(NULL, NULL);
+    Options                         moduleOptions(impl_->module_->name(), impl_->module_->description());
+    Options                         commonOptions("common", "Common analysis control");
+    Options                         selectionOptions("selection", "Common selection control");
 
+    options.addManager(&seloptManager);
     options.addSubSection(&commonOptions);
     options.addSubSection(&selectionOptions);
     options.addSubSection(&moduleOptions);
 
-    SelectionOptionManager seloptManager(&selections);
-    setManagerForSelectionOptions(&options, &seloptManager);
+    impl_->module_->initOptions(&moduleOptions, &settings);
+    common.initOptions(&commonOptions);
+    selections.initOptions(&selectionOptions);
 
     CommandLineHelpWriter(options)
         .setShowDescriptions(true)
@@ -314,4 +276,86 @@ TrajectoryAnalysisCommandLineRunner::writeHelp(const HelpWriterContext &context)
         .writeHelp(context);
 }
 
+
+/*! \internal \brief
+ * Command line module for a trajectory analysis module.
+ *
+ * \ingroup module_trajectoryanalysis
+ */
+class TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule
+    : public CommandLineModuleInterface
+{
+    public:
+        /*! \brief
+         * Constructs a module.
+         *
+         * \param[in] name         Name for the module.
+         * \param[in] description  One-line description for the module.
+         * \param[in] factory      Factory method to create the analysis module.
+         *
+         * Does not throw.  This is important for correct implementation of
+         * runAsMain().
+         */
+        RunnerCommandLineModule(const char *name, const char *description,
+                                ModuleFactoryMethod factory)
+            : name_(name), description_(description), factory_(factory)
+        {
+        }
+
+        virtual const char *name() const { return name_; }
+        virtual const char *shortDescription() const { return description_; };
+
+        virtual void init(CommandLineModuleSettings *settings);
+        virtual int run(int argc, char *argv[]);
+        virtual void writeHelp(const CommandLineHelpContext &context) const;
+
+    private:
+        const char             *name_;
+        const char             *description_;
+        ModuleFactoryMethod     factory_;
+
+        GMX_DISALLOW_COPY_AND_ASSIGN(RunnerCommandLineModule);
+};
+
+void TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule::init(
+        CommandLineModuleSettings * /*settings*/)
+{
+}
+
+int TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule::run(
+        int argc, char *argv[])
+{
+    TrajectoryAnalysisModulePointer     module(factory_());
+    TrajectoryAnalysisCommandLineRunner runner(module.get());
+    return runner.run(argc, argv);
+}
+
+void TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule::writeHelp(
+        const CommandLineHelpContext &context) const
+{
+    TrajectoryAnalysisModulePointer     module(factory_());
+    TrajectoryAnalysisCommandLineRunner runner(module.get());
+    runner.writeHelp(context);
+}
+
+// static
+int
+TrajectoryAnalysisCommandLineRunner::runAsMain(
+        int argc, char *argv[], ModuleFactoryMethod factory)
+{
+    Impl::RunnerCommandLineModule module(NULL, NULL, factory);
+    return CommandLineModuleManager::runAsMainSingleModule(argc, argv, &module);
+}
+
+// static
+void
+TrajectoryAnalysisCommandLineRunner::registerModule(
+        CommandLineModuleManager *manager, const char *name,
+        const char *description, ModuleFactoryMethod factory)
+{
+    CommandLineModulePointer module(
+            new Impl::RunnerCommandLineModule(name, description, factory));
+    manager->addModule(move(module));
+}
+
 } // namespace gmx