Merge branch 'master' into pygromacs
[alexxy/gromacs.git] / src / gromacs / trajectoryanalysis / cmdlinerunner.cpp
index b7165f94bf776076cbdf8a6f32d214f61a0a905c..912db6c9633ce7b530abc8cfa47fd645b1659da2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, 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.
  * \author Teemu Murtola <teemu.murtola@gmail.com>
  * \ingroup module_trajectoryanalysis
  */
-#include "cmdlinerunner.h"
+#include "gmxpre.h"
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "cmdlinerunner.h"
 
 #include "gromacs/analysisdata/paralleloptions.h"
 #include "gromacs/commandline/cmdlinehelpcontext.h"
 #include "gromacs/commandline/cmdlinemodulemanager.h"
 #include "gromacs/commandline/cmdlineparser.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/runnercommon.h"
 #include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/filestream.h"
 #include "gromacs/utility/gmxassert.h"
 
+#include "runnercommon.h"
+
 namespace gmx
 {
 
@@ -81,7 +81,7 @@ class TrajectoryAnalysisCommandLineRunner::Impl
         void parseOptions(TrajectoryAnalysisSettings *settings,
                           TrajectoryAnalysisRunnerCommon *common,
                           SelectionCollection *selections,
-                          int *argc, char *argv[]);
+                          int *argc, char *argv[], bool full=true);
 
         TrajectoryAnalysisModule *module_;
         bool                      bUseDefaultGroups_;
@@ -106,22 +106,28 @@ TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
         TrajectoryAnalysisSettings *settings,
         TrajectoryAnalysisRunnerCommon *common,
         SelectionCollection *selections,
-        int *argc, char *argv[])
+        int *argc, char *argv[], bool full)
 {
-    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);
-
-    options.addSubSection(&commonOptions);
+    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);
+    if (full) {
+        options.addSubSection(&commonOptions);
+    }
     options.addSubSection(&selectionOptions);
     options.addSubSection(&moduleOptions);
 
-    SelectionOptionManager seloptManager(selections);
-    setManagerForSelectionOptions(&options, &seloptManager);
+    module_->initOptions(&moduleOptions, settings);
+    if (full) {
+        common->initOptions(&commonOptions);
+    }
+    selections->initOptions(&selectionOptions);
 
     {
         CommandLineParser  parser(&options);
@@ -132,16 +138,19 @@ TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
         options.finish();
     }
 
-    common->optionsFinished(&commonOptions);
+    if (full) {
+        common->optionsFinished(&commonOptions);
+    }
     module_->optionsFinished(&moduleOptions, settings);
 
     common->initIndexGroups(selections, bUseDefaultGroups_);
 
-    const bool bInteractive = File::standardInput().isInteractive();
+    const bool bInteractive = StandardInputStream::instance().isInteractive();
     seloptManager.parseRequestedFromStdin(bInteractive);
-    common->doneIndexGroups(selections);
 
+    common->doneIndexGroups(selections);
     common->initTopology(selections);
+
     selections->compile();
 }
 
@@ -192,9 +201,23 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
     const TopologyInformation &topology = common.topologyInformation();
     module->initAnalysis(settings, topology);
 
+    TrajectoryAnalysisModule::Batch batch = module->getBatch();
+    std::vector<SelectionCollection*> batchSelections;
+    std::vector<Impl*> impls;
+    for (size_t i = 0; i < batch.size(); i++) {
+        TrajectoryAnalysisModule *bmodule = batch[i];
+        batchSelections.push_back(new SelectionCollection());
+        impls.push_back(new Impl(bmodule));
+        std::vector<char*> modArgv = module->getArgv(i);
+        int modArgc = modArgv.size();
+        impls.back()->parseOptions(&settings, &common, batchSelections.back(), &modArgc, modArgv.data(), false);
+
+        batch[i]->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;
@@ -203,6 +226,17 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
     AnalysisDataParallelOptions         dataOptions;
     TrajectoryAnalysisModuleDataPointer pdata(
             module->startFrames(dataOptions, selections));
+
+    std::vector<AnalysisDataParallelOptions> batchOptions;
+    std::vector<TrajectoryAnalysisModuleDataPointer> batchDataPointers;
+    for (size_t i = 0; i < batch.size(); i++) {
+        batch[i]->initAfterFirstFrame(settings, common.frame());
+
+        batchOptions.push_back(AnalysisDataParallelOptions());
+        batchDataPointers.push_back(batch[i]->startFrames(
+            batchOptions.back(), *batchSelections[i]));
+    }
+
     do
     {
         common.initFrame();
@@ -212,12 +246,26 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
             set_pbc(ppbc, topology.ePBC(), frame.box);
         }
 
+        for (size_t i = 0; i < batch.size(); i++) {
+            batchSelections[i]->evaluate(&frame, ppbc);
+            batch[i]->analyzeFrame(nframes, frame, ppbc, batchDataPointers[i].get());
+            batch[i]->finishFrameSerial(nframes);
+        }
         selections.evaluate(&frame, ppbc);
         module->analyzeFrame(nframes, frame, ppbc, pdata.get());
+        module->finishFrameSerial(nframes);
 
-        nframes++;
+        ++nframes;
     }
     while (common.readNextFrame());
+    for (size_t i = 0; i < batch.size(); i++) {
+        batch[i]->finishFrames(batchDataPointers[i].get());
+        if (batchDataPointers[i].get() != NULL) {
+            batchDataPointers[i]->finish();
+        }
+        batchDataPointers[i].reset();
+    }
+
     module->finishFrames(pdata.get());
     if (pdata.get() != NULL)
     {
@@ -236,6 +284,15 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
     }
 
     // Restore the maximal groups for dynamic selections.
+    for (size_t i = 0; i < batch.size(); i++) {
+        batchSelections[i]->evaluateFinal(nframes);
+        batch[i]->finishAnalysis(nframes);
+        batch[i]->writeOutput();
+
+        delete batchSelections[i];
+        delete impls[i];
+    }
+
     selections.evaluateFinal(nframes);
 
     module->finishAnalysis(nframes);
@@ -254,24 +311,23 @@ TrajectoryAnalysisCommandLineRunner::writeHelp(const CommandLineHelpContext &con
     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)
+        .setHelpText(settings.helpText())
         .setTimeUnitString(settings.timeUnitManager().timeUnitAsString())
         .writeHelp(context);
 }
@@ -283,7 +339,7 @@ TrajectoryAnalysisCommandLineRunner::writeHelp(const CommandLineHelpContext &con
  * \ingroup module_trajectoryanalysis
  */
 class TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule
-    : public CommandLineModuleInterface
+    : public ICommandLineModule
 {
     public:
         /*! \brief
@@ -298,28 +354,45 @@ class TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule
          */
         RunnerCommandLineModule(const char *name, const char *description,
                                 ModuleFactoryMethod factory)
-            : name_(name), description_(description), factory_(factory)
+            : name_(name), description_(description), hasFunction_(true), factory_(factory), functor_(NULL)
+        {
+        }
+
+        /*! \brief
+         * Overloaded constructor accepting a functor instead of function pointer.
+         */
+        RunnerCommandLineModule(const char *name, const char *description,
+                                ModuleFactoryFunctor *factory)
+            : name_(name), description_(description), hasFunction_(false), factory_(NULL), functor_(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_;
+        const char            *name_;
+        const char            *description_;
+        bool                   hasFunction_;
+        ModuleFactoryMethod    factory_;
+        ModuleFactoryFunctor   *functor_;
 
         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_());
+    TrajectoryAnalysisModulePointer     module(hasFunction_? factory_() : (*functor_)());
     TrajectoryAnalysisCommandLineRunner runner(module.get());
     return runner.run(argc, argv);
 }
@@ -327,7 +400,7 @@ int TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule::run(
 void TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule::writeHelp(
         const CommandLineHelpContext &context) const
 {
-    TrajectoryAnalysisModulePointer     module(factory_());
+    TrajectoryAnalysisModulePointer     module(hasFunction_? factory_() : (*functor_)());
     TrajectoryAnalysisCommandLineRunner runner(module.get());
     runner.writeHelp(context);
 }
@@ -341,6 +414,15 @@ TrajectoryAnalysisCommandLineRunner::runAsMain(
     return CommandLineModuleManager::runAsMainSingleModule(argc, argv, &module);
 }
 
+// static
+int
+TrajectoryAnalysisCommandLineRunner::runAsMain(
+        int argc, char *argv[], ModuleFactoryFunctor *factory)
+{
+    Impl::RunnerCommandLineModule module(NULL, NULL, factory);
+    return CommandLineModuleManager::runAsMainSingleModule(argc, argv, &module);
+}
+
 // static
 void
 TrajectoryAnalysisCommandLineRunner::registerModule(