cmdlinerunner.cpp: use ICommandLineOptionsModule pygromacs
authorMaxim Koltsov <maks@omrb.pnpi.spb.ru>
Fri, 28 Aug 2015 19:41:05 +0000 (22:41 +0300)
committerMaxim Koltsov <maks@omrb.pnpi.spb.ru>
Fri, 28 Aug 2015 19:41:05 +0000 (22:41 +0300)
Make TrajectoryAnalysisCommandLineRunner a subclass of
ICommandLineOptionsModule for unification reasons. Resolve duplications
issues with run/writeHelp.
This should ease implementing of Python based trajectory tools later,
along with more refactoring and generalizations.

IOptionsContainer interface was extended with addGroup and addManager
methods from Options class, thus untying runner from Options itself.

Former support for batches was removed in favor of upcoming
implementation.

src/gromacs/commandline/cmdlineoptionsmodule.cpp
src/gromacs/commandline/cmdlineoptionsmodule.h
src/gromacs/options/ioptionscontainer.h
src/gromacs/options/options-impl.h
src/gromacs/options/options.h
src/gromacs/trajectoryanalysis/analysismodule.h
src/gromacs/trajectoryanalysis/cmdlinerunner.cpp
src/gromacs/trajectoryanalysis/cmdlinerunner.h
src/python/sip/trajectoryanalysis/analysismodule.sip
src/python/test.py

index 581174ffba00eb5a11f7ab4de73bbe094be03eb9..3395095bca87261257b0a43a22479120c23361ef 100644 (file)
@@ -202,6 +202,15 @@ int ICommandLineOptionsModule::runAsMain(
     return CommandLineModuleManager::runAsMainSingleModule(argc, argv, &module);
 }
 
+// static
+int ICommandLineOptionsModule::runAsMain(
+        int argc, char *argv[],
+        ICommandLineOptionsModule *module)
+{
+    CommandLineOptionsModule cmdmodule("", "", module);
+    return CommandLineModuleManager::runAsMainSingleModule(argc, argv, &cmdmodule);
+}
+
 // static
 void ICommandLineOptionsModule::registerModule(
         CommandLineModuleManager *manager, const char *name,
index 2aa8dbebdcb08dc2b43fb4df8e20c95100b19608..bb3ef1787b0ef8a36dffcb3dddede0d8ea8a5ca9 100644 (file)
@@ -172,6 +172,9 @@ class ICommandLineOptionsModule
         static int
         runAsMain(int argc, char *argv[], const char *name,
                   const char *description, FactoryMethod factory);
+
+        static int
+        runAsMain(int argc, char *argv[], ICommandLineOptionsModule *module);
         /*! \brief
          * Registers a module of a certain type to this manager.
          *
index 1e8eddb2c97749a7f4065f470b7e3317f8528f5e..a2b687a27f27c2c834803914be6deae513c06506 100644 (file)
 namespace gmx
 {
 
+/*! \brief
+ * Base class for option managers.
+ *
+ * This class is used as a marker for all classes that are used with
+ * Options::addManager().  It doesn't provide any methods, but only supports
+ * transporting these classes through the Options collection into the
+ * individual option implementation classes.
+ *
+ * The virtual destructor is present to make this class polymorphic, such that
+ * `dynamic_cast` can be used when retrieving a manager of a certain type for
+ * the individual options.
+ *
+ * \inlibraryapi
+ * \ingroup module_options
+ */
+class IOptionManager
+{
+    protected:
+        virtual ~IOptionManager();
+};
+
 /*! \brief
  * Interface for adding input options.
  *
@@ -124,6 +145,40 @@ class IOptionsContainer
             return info->toType<typename OptionType::InfoType>();
         }
 
+        /*! \brief
+         * Adds an option manager.
+         *
+         * \param    manager Manager to add.
+         * \throws   std::bad_alloc if out of memory.
+         *
+         * Option managers are used by some types of options that require
+         * interaction between different option instances (e.g., selection
+         * options), or need to support globally set properties (e.g., a global
+         * default file prefix).  Option objects can retrieve the pointer to
+         * their manager when they are created, and the caller can alter the
+         * behavior of the options through the manager.
+         * See the individual managers for details.
+         *
+         * Caller is responsible for memory management of \p manager.
+         * The Options object (and its contained options) only stores a
+         * reference to the object.
+         *
+         * This method cannot be called after adding options or subsections.
+         */
+        virtual void addManager(IOptionManager *manager) = 0;
+
+        /*! \brief
+         * Creates a subgroup of options within the current options.
+         *
+         * To add options to the group, use the returned interface.
+         *
+         * Currently, this is only used to influence the order of options:
+         * all options in a group appear before options in a group added after
+         * it, no matter in which order the options are added to the groups.
+         * In the future, the groups could also be used to influence the help
+         * output.
+         */
+        virtual IOptionsContainer &addGroup() = 0;
     protected:
         // Disallow deletion through the interface.
         // (no need for the virtual, but some compilers warn otherwise)
index aaf61fb4d822ecfb3b6be2152b04b35f546a3a9a..a49225e17013638017eae29c8915d196f4ef0315 100644 (file)
@@ -88,11 +88,13 @@ class OptionsImpl
                 //! Creates a group within the given Options.
                 explicit Group(OptionsImpl *parent) : parent_(parent) {}
 
-                //! Adds an option subgroup.
-                IOptionsContainer &addGroup();
                 // From IOptionsContainer
+                virtual IOptionsContainer &addGroup();
                 virtual OptionInfo *addOption(const AbstractOption &settings);
 
+                virtual void addManager(IOptionManager * /*manager*/) {
+                    // TODO: raise error?
+                }
                 //! Containing options object.
                 OptionsImpl  *parent_;
                 /*! \brief
index 43afe21d40482f1ed79fc6a0c994ea1c01835227..f2df6ddb09b1f753f775302c0145aab0065e8b8e 100644 (file)
@@ -63,26 +63,6 @@ namespace internal
 class OptionsImpl;
 }
 
-/*! \brief
- * Base class for option managers.
- *
- * This class is used as a marker for all classes that are used with
- * Options::addManager().  It doesn't provide any methods, but only supports
- * transporting these classes through the Options collection into the
- * individual option implementation classes.
- *
- * The virtual destructor is present to make this class polymorphic, such that
- * `dynamic_cast` can be used when retrieving a manager of a certain type for
- * the individual options.
- *
- * \inlibraryapi
- * \ingroup module_options
- */
-class IOptionManager
-{
-    protected:
-        virtual ~IOptionManager();
-};
 
 /*! \brief
  * Collection of options.
@@ -115,27 +95,6 @@ class Options : public IOptionsContainer
         //! Returns the short name of the option collection.
         const std::string &name() const;
 
-        /*! \brief
-         * Adds an option manager.
-         *
-         * \param    manager Manager to add.
-         * \throws   std::bad_alloc if out of memory.
-         *
-         * Option managers are used by some types of options that require
-         * interaction between different option instances (e.g., selection
-         * options), or need to support globally set properties (e.g., a global
-         * default file prefix).  Option objects can retrieve the pointer to
-         * their manager when they are created, and the caller can alter the
-         * behavior of the options through the manager.
-         * See the individual managers for details.
-         *
-         * Caller is responsible for memory management of \p manager.
-         * The Options object (and its contained options) only stores a
-         * reference to the object.
-         *
-         * This method cannot be called after adding options or subsections.
-         */
-        void addManager(IOptionManager *manager);
 
         /*! \brief
          * Adds an option collection as a subsection of this collection.
@@ -158,22 +117,11 @@ class Options : public IOptionsContainer
          */
         void addSubSection(Options *section);
 
-        /*! \brief
-         * Creates a subgroup of options within the current options.
-         *
-         * To add options to the group, use the returned interface.
-         *
-         * Currently, this is only used to influence the order of options:
-         * all options in a group appear before options in a group added after
-         * it, no matter in which order the options are added to the groups.
-         * In the future, the groups could also be used to influence the help
-         * output.
-         */
-        IOptionsContainer &addGroup();
-
         // From IOptionsContainer
         virtual OptionInfo *addOption(const AbstractOption &settings);
         using IOptionsContainer::addOption;
+        void addManager(IOptionManager *manager);
+        IOptionsContainer &addGroup();
 
         /*! \brief
          * Notifies the collection that all option values are assigned.
index d91b0daa3ca53926c5d72a2173c07164a2ef53f5..8553342b4c8f0b22a0bef92de628d33975ae70b4 100644 (file)
@@ -388,11 +388,6 @@ class TrajectoryAnalysisModule
          */
         virtual void writeOutput() = 0;
 
-        typedef std::vector<TrajectoryAnalysisModule*> Batch;
-        virtual const Batch getBatch() { return Batch(); }
-
-        virtual const std::vector<char*> getArgv(int) { return std::vector<char*>(); }
-
         /*! \brief
          * Returns the name of the analysis module.
          *
index 0bc78ce8fad84fe6e0cb640461ad6505fce4b14c..6e58a2323d85d963f94932a8fdb139eade54e846 100644 (file)
@@ -46,7 +46,7 @@
 #include "gromacs/analysisdata/paralleloptions.h"
 #include "gromacs/commandline/cmdlinehelpcontext.h"
 #include "gromacs/commandline/cmdlinehelpwriter.h"
-#include "gromacs/commandline/cmdlinemodule.h"
+#include "gromacs/commandline/cmdlineoptionsmodule.h"
 #include "gromacs/commandline/cmdlinemodulemanager.h"
 #include "gromacs/commandline/cmdlineparser.h"
 #include "gromacs/fileio/trx.h"
@@ -73,81 +73,30 @@ namespace gmx
 class TrajectoryAnalysisCommandLineRunner::Impl
 {
     public:
-        class RunnerCommandLineModule;
-
-        Impl(TrajectoryAnalysisModule *module);
+        Impl(TrajectoryAnalysisModulePointer module);
         ~Impl();
 
-        void parseOptions(TrajectoryAnalysisSettings *settings,
-                          TrajectoryAnalysisRunnerCommon *common,
-                          SelectionCollection *selections,
-                          int *argc, char *argv[], bool full = true);
-
-        TrajectoryAnalysisModule *module_;
-        bool                      bUseDefaultGroups_;
-        int                       debugLevel_;
+        TrajectoryAnalysisModulePointer module_;
+        bool                            bUseDefaultGroups_;
+        int                             debugLevel_;
+        SelectionCollection             selections_;
+        SelectionOptionManager          selOptManager_;
+        TrajectoryAnalysisSettings      settings_;
+        TrajectoryAnalysisRunnerCommon  common_;
 };
 
 
 TrajectoryAnalysisCommandLineRunner::Impl::Impl(
-        TrajectoryAnalysisModule *module)
-    : module_(module), bUseDefaultGroups_(true), debugLevel_(0)
+        TrajectoryAnalysisModulePointer module)
+    : module_(module), bUseDefaultGroups_(true), debugLevel_(0),
+      selOptManager_(&selections_), common_(&settings_)
 {
 }
 
 
 TrajectoryAnalysisCommandLineRunner::Impl::~Impl()
 {
-}
-
-
-void
-TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
-        TrajectoryAnalysisSettings *settings,
-        TrajectoryAnalysisRunnerCommon *common,
-        SelectionCollection *selections,
-        int *argc, char *argv[], bool full)
-{
-    FileNameOptionManager  fileoptManager;
-    SelectionOptionManager seloptManager(selections);
-    Options                options(NULL, NULL);
-    IOptionsContainer     &commonOptions = options.addGroup();
-    IOptionsContainer     &moduleOptions = options.addGroup();
-
-    options.addManager(&fileoptManager);
-    options.addManager(&seloptManager);
-
-    module_->initOptions(&moduleOptions, settings);
-    if (full)
-    {
-        common->initOptions(&commonOptions);
-    }
-    selections->initOptions(&commonOptions);
-
-    {
-        CommandLineParser  parser(&options);
-        // 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 (full)
-    {
-        common->optionsFinished();
-    }
-    module_->optionsFinished(settings);
-
-    common->initIndexGroups(selections, bUseDefaultGroups_);
-
-    const bool bInteractive = StandardInputStream::instance().isInteractive();
-    seloptManager.parseRequestedFromStdin(bInteractive);
-
-    common->doneIndexGroups(selections);
-    common->initTopology(selections);
-
-    selections->compile();
+    module_.reset();
 }
 
 
@@ -156,11 +105,16 @@ TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
  */
 
 TrajectoryAnalysisCommandLineRunner::TrajectoryAnalysisCommandLineRunner(
-        TrajectoryAnalysisModule *module)
-    : impl_(new Impl(module))
+        TrajectoryAnalysisCommandLineRunner::ModuleFactoryMethod factory)
+    : impl_(new Impl(factory()))
 {
 }
 
+TrajectoryAnalysisCommandLineRunner::TrajectoryAnalysisCommandLineRunner(
+        TrajectoryAnalysisCommandLineRunner::ModuleFactoryFunctor *functor)
+    : impl_(new Impl((*functor)()))
+{
+}
 
 TrajectoryAnalysisCommandLineRunner::~TrajectoryAnalysisCommandLineRunner()
 {
@@ -180,104 +134,91 @@ TrajectoryAnalysisCommandLineRunner::setSelectionDebugLevel(int debuglevel)
     impl_->debugLevel_ = debuglevel;
 }
 
+void TrajectoryAnalysisCommandLineRunner::init(CommandLineModuleSettings * /*settings*/)
+{
+}
 
-int
-TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
+void
+TrajectoryAnalysisCommandLineRunner::initOptions(IOptionsContainer                 *options,
+                                                 ICommandLineOptionsModuleSettings *settings)
 {
-    TrajectoryAnalysisModule *module = impl_->module_;
+    impl_->selections_.setDebugLevel(impl_->debugLevel_);
 
-    SelectionCollection       selections;
-    selections.setDebugLevel(impl_->debugLevel_);
+    options->addManager(&impl_->selOptManager_);
 
-    TrajectoryAnalysisSettings      settings;
-    TrajectoryAnalysisRunnerCommon  common(&settings);
+    IOptionsContainer &commonOptions = options->addGroup();
+    IOptionsContainer &moduleOptions = options->addGroup();
 
-    impl_->parseOptions(&settings, &common, &selections, &argc, argv);
+    impl_->module_->initOptions(&moduleOptions, &impl_->settings_);
+    impl_->common_.initOptions(&commonOptions);
+    impl_->selections_.initOptions(&commonOptions);
 
-    const TopologyInformation &topology = common.topologyInformation();
-    module->initAnalysis(settings, topology);
+    const char *help[] = { impl_->settings_.helpText().data() };
+    settings->setHelpText(help);
+}
 
-    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);
-    }
+void
+TrajectoryAnalysisCommandLineRunner::optionsFinished()
+{
+    // TODO: scaleTimeOptions? (maybe pass options here too, with default arg)
+    impl_->common_.optionsFinished();
+    impl_->module_->optionsFinished(&impl_->settings_);
+
+    impl_->common_.initIndexGroups(&impl_->selections_, impl_->bUseDefaultGroups_);
+
+    const bool bInteractive = StandardInputStream::instance().isInteractive();
+    impl_->selOptManager_.parseRequestedFromStdin(bInteractive);
+    impl_->common_.doneIndexGroups(&impl_->selections_);
+
+    impl_->common_.initTopology(&impl_->selections_);
+    impl_->selections_.compile();
+}
+
+
+int
+TrajectoryAnalysisCommandLineRunner::run()
+{
+    const TopologyInformation &topology = impl_->common_.topologyInformation();
+    impl_->module_->initAnalysis(impl_->settings_, topology);
 
     // Load first frame.
-    common.initFirstFrame();
-    module->initAfterFirstFrame(settings, common.frame());
+    impl_->common_.initFirstFrame();
+    impl_->module_->initAfterFirstFrame(impl_->settings_, impl_->common_.frame());
 
     t_pbc  pbc;
-    t_pbc *ppbc = settings.hasPBC() ? &pbc : NULL;
+    t_pbc *ppbc = impl_->settings_.hasPBC() ? &pbc : NULL;
 
     int    nframes = 0;
     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]));
-    }
-
+            impl_->module_->startFrames(dataOptions, impl_->selections_));
     do
     {
-        common.initFrame();
-        t_trxframe &frame = common.frame();
+        impl_->common_.initFrame();
+        t_trxframe &frame = impl_->common_.frame();
         if (ppbc != NULL)
         {
             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);
+        impl_->selections_.evaluate(&frame, ppbc);
+        impl_->module_->analyzeFrame(nframes, frame, ppbc, pdata.get());
+        impl_->module_->finishFrameSerial(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());
+    while (impl_->common_.readNextFrame());
+    impl_->module_->finishFrames(pdata.get());
     if (pdata.get() != NULL)
     {
         pdata->finish();
     }
     pdata.reset();
 
-    if (common.hasTrajectory())
+    if (impl_->common_.hasTrajectory())
     {
         fprintf(stderr, "Analyzed %d frames, last time %.3f\n",
-                nframes, common.frame().time);
+                nframes, impl_->common_.frame().time);
     }
     else
     {
@@ -285,131 +226,20 @@ 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);
-    module->writeOutput();
+    impl_->selections_.evaluateFinal(nframes);
 
+    impl_->module_->finishAnalysis(nframes);
+    impl_->module_->writeOutput();
     return 0;
 }
 
-
-void
-TrajectoryAnalysisCommandLineRunner::writeHelp(const CommandLineHelpContext &context)
-{
-    // 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);
-
-    SelectionOptionManager          seloptManager(&selections);
-    Options                         options(NULL, NULL);
-
-    options.addManager(&seloptManager);
-    IOptionsContainer &commonOptions = options.addGroup();
-    IOptionsContainer &moduleOptions = options.addGroup();
-
-    impl_->module_->initOptions(&moduleOptions, &settings);
-    common.initOptions(&commonOptions);
-    selections.initOptions(&commonOptions);
-
-    CommandLineHelpWriter(options)
-        .setHelpText(settings.helpText())
-        .setTimeUnitString(settings.timeUnitManager().timeUnitAsString())
-        .writeHelp(context);
-}
-
-
-/*! \internal \brief
- * Command line module for a trajectory analysis module.
- *
- * \ingroup module_trajectoryanalysis
- */
-class TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule
-    : public ICommandLineModule
-{
-    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), 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_;
-        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(hasFunction_ ? factory_() : (*functor_)());
-    TrajectoryAnalysisCommandLineRunner runner(module.get());
-    return runner.run(argc, argv);
-}
-
-void TrajectoryAnalysisCommandLineRunner::Impl::RunnerCommandLineModule::writeHelp(
-        const CommandLineHelpContext &context) const
-{
-    TrajectoryAnalysisModulePointer     module(hasFunction_ ? factory_() : (*functor_)());
-    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);
+    TrajectoryAnalysisCommandLineRunner *module = new TrajectoryAnalysisCommandLineRunner(factory);
+    return ICommandLineOptionsModule::runAsMain(argc, argv, module);
 }
 
 // static
@@ -417,8 +247,8 @@ int
 TrajectoryAnalysisCommandLineRunner::runAsMain(
         int argc, char *argv[], ModuleFactoryFunctor *factory)
 {
-    Impl::RunnerCommandLineModule module(NULL, NULL, factory);
-    return CommandLineModuleManager::runAsMainSingleModule(argc, argv, &module);
+    TrajectoryAnalysisCommandLineRunner *module = new TrajectoryAnalysisCommandLineRunner(factory);
+    return ICommandLineOptionsModule::runAsMain(argc, argv, module);
 }
 
 // static
@@ -427,9 +257,8 @@ TrajectoryAnalysisCommandLineRunner::registerModule(
         CommandLineModuleManager *manager, const char *name,
         const char *description, ModuleFactoryMethod factory)
 {
-    CommandLineModulePointer module(
-            new Impl::RunnerCommandLineModule(name, description, factory));
-    manager->addModule(move(module));
+    ICommandLineOptionsModule::registerModule(manager, name, description,
+        new TrajectoryAnalysisCommandLineRunner(factory));
 }
 
 } // namespace gmx
index 0b703ea268485300ab0d70954064217634a8870d..54f945560c6034b5ea375c007f7b138e4bcb0218 100644 (file)
@@ -43,6 +43,7 @@
 #ifndef GMX_TRAJECTORYANALYSIS_CMDLINERUNNER_H
 #define GMX_TRAJECTORYANALYSIS_CMDLINERUNNER_H
 
+#include "gromacs/commandline/cmdlineoptionsmodule.h"
 #include "gromacs/trajectoryanalysis/analysismodule.h"
 #include "gromacs/utility/classhelpers.h"
 
@@ -64,7 +65,7 @@ class CommandLineHelpContext;
  * \inpublicapi
  * \ingroup module_trajectoryanalysis
  */
-class TrajectoryAnalysisCommandLineRunner
+class TrajectoryAnalysisCommandLineRunner : public ICommandLineOptionsModule
 {
     public:
         /*! \brief
@@ -158,15 +159,19 @@ class TrajectoryAnalysisCommandLineRunner
                                    ModuleFactoryMethod factory);
 
         /*! \brief
-         * Create a new runner with the provided module.
+         * Constructs a module.
          *
-         * \param  module  Analysis module to run using the runner.
-         * \throws std::bad_alloc if out of memory.
+         * \param[in] factory      Factory method to create the analysis module.
          *
-         * The caller should ensure that the provided module is not destroyed
-         * while the runner exists.
+         * Does not throw.  This is important for correct implementation of
+         * runAsMain().
          */
-        TrajectoryAnalysisCommandLineRunner(TrajectoryAnalysisModule *module);
+        TrajectoryAnalysisCommandLineRunner(ModuleFactoryMethod factory);
+
+        /*! \brief
+         * Overloaded constructor accepting a functor instead of function pointer.
+         */
+        TrajectoryAnalysisCommandLineRunner(ModuleFactoryFunctor *factory);
         ~TrajectoryAnalysisCommandLineRunner();
 
         /*! \brief
@@ -191,21 +196,13 @@ class TrajectoryAnalysisCommandLineRunner
          * \see SelectionCollection::setDebugLevel()
          */
         void setSelectionDebugLevel(int debuglevel);
-        /*! \brief
-         * Parses options from the given command line and runs the analysis.
-         *
-         * \throws  multiple  Exceptions are used to indicate errors.
-         * \returns Zero on success.
-         */
-        int run(int argc, char *argv[]);
-        /*! \brief
-         * Prints help for the module, including common options from the runner.
-         *
-         * \param[in] context  Context object for writing the help.
-         * \throws    std::bad_alloc if out of memory.
-         * \throws    FileIOError on any I/O error.
-         */
-        void writeHelp(const CommandLineHelpContext &context);
+
+        // From ICommandLineOptionsModule
+        virtual void init(CommandLineModuleSettings *settings);
+        void initOptions(IOptionsContainer                 *options,
+                         ICommandLineOptionsModuleSettings *settings);
+        void optionsFinished();
+        int run();
 
         //! Implements the template runAsMain() method.
         static int runAsMain(int argc, char *argv[],
index cd5c65628d586318e104bfd68010ba3c260ad501..1334f34e2af7dc06018649333cb63c1a208824eb 100644 (file)
@@ -173,8 +173,6 @@ public:
     virtual void finishFrames(TrajectoryAnalysisModuleData *pdata);
     virtual void finishAnalysis(int nframes) = 0;
     virtual void writeOutput() = 0;
-    virtual const std::vector<TrajectoryAnalysisModule*> getBatch();
-    virtual const std::vector<char*> getArgv(int);
     const char* name() const;
     const char* description() const;
     int datasetCount() const;
index ac91337f085c25e3f99b6ad2e1c82c6c96495f6a..a700a0361c85e06314c92a25749e56fb6d70f44a 100644 (file)
@@ -51,34 +51,16 @@ class M(TrajectoryAnalysis.TrajectoryAnalysisModule):
         options.addOption(self.optionsHolder.fileNameOption('file').defaultBasename('test').description('filename from python to rule them all').outputFile().required().filetype(Options.eftGenericData))
         settings.setFlag(TrajectoryAnalysis.TrajectoryAnalysisSettings.efRequireTop)
 
-        self.angle = TrajectoryAnalysis.AngleInfo.create()
-
         print('python: inited')
 
-    def getBatch(self):
-        print('python: getBatch')
-        return [self.angle]
-
-    def getArgv(self, i):
-        print('python: getArgv')
-        if i == 0:
-            #First element of list should be module name -- gets discarded by parser anyway
-            return ["gangle", "-group1", "Backbone", "-oav", "angles.xvg"]
-
     def initAnalysis(self, settings, top):
         print('python: initAnalysis')
         print('There are {} atoms'.format(top.topology().atoms.nr))
         print('Topology name: {}'.format(top.topology().name))
 
-        #Tell GROMACS to keep last frame in storage, required in analyzeFrame()
-        self.angle.datasetFromIndex(1).requestStorage(1)
-
     def analyzeFrame(self, frnr, frame, pbc, data):
         sel = self.optionsHolder['sel']
-
-        dataset = self.angle.datasetFromIndex(1)
-
-        print('frame =', frnr, ', columnCount =', dataset.columnCount(), ', y =', dataset.getDataFrame(frnr).y(0))
+        print('frame =', frnr)
 
     def finishAnalysis(self, nframes):
         print('python: Analyzed {} frames'.format(nframes))