Convert gmx dump to module
authorMark Abraham <mark.j.abraham@gmail.com>
Sun, 24 Feb 2019 07:15:57 +0000 (08:15 +0100)
committerPaul Bauer <paul.bauer.q@gmail.com>
Mon, 25 Mar 2019 11:42:50 +0000 (12:42 +0100)
Used Options and more std::string.

Minor fixes and improvements to text. Removed the report of the known
bug, replacing it with a TODO.

Added eftRunInput to the filename option types understood by
FileNameOption machinery, so that tools that only operate on .tpr
files work properly. This is then used for gmx dump -s.

Refs #2877

Change-Id: I5bb1c73c39a4cdd820735f894d4cb55d171afd48

src/gromacs/options/filenameoption.cpp
src/gromacs/options/optionfiletype.h
src/gromacs/tools/dump.cpp
src/gromacs/tools/dump.h
src/programs/legacymodules.cpp

index f3c12b9b5dec0a94b2e8ea6520c392995c2cd700..6906029acca8ae99693ec2d1a6362a486e090498 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016,2017,2019, 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.
@@ -82,6 +82,7 @@ struct FileTypeMapping
 const FileTypeMapping c_fileTypeMapping[] =
 {
     { eftTopology,    efTPS },
+    { eftRunInput,    efTPR },
     { eftTrajectory,  efTRX },
     { eftEnergy,      efEDR },
     { eftPDB,         efPDB },
index ccdb1b4d532726f1226be1b87cc0398b63a156f7..a769ac41365098c47c003d0abd861d91e1a8025b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2015,2019, 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.
@@ -54,6 +54,7 @@ namespace gmx
 enum OptionFileType {
     eftUnknown,
     eftTopology,
+    eftRunInput,
     eftTrajectory,
     eftEnergy,
     eftPDB,
index 32a99fd5ddc4440cb72cc5c4661e8b18721d87fc..b116ff6d0549985c59836ab9a41fd4a4b45c77ea 100644 (file)
  * To help us fund GROMACS development, we humbly ask that you cite
  * the research papers on the package. Check out http://www.gromacs.org.
  */
+/*! \internal \file
+ * \brief Implements gmx dump utility.
+ *
+ * \ingroup module_tools
+ */
 #include "gmxpre.h"
 
 #include "dump.h"
 #include <cstdio>
 #include <cstring>
 
-#include "gromacs/commandline/pargs.h"
+#include "gromacs/commandline/cmdlineoptionsmodule.h"
 #include "gromacs/fileio/checkpoint.h"
 #include "gromacs/fileio/enxio.h"
+#include "gromacs/fileio/filetypes.h"
 #include "gromacs/fileio/gmxfio.h"
 #include "gromacs/fileio/mtxio.h"
 #include "gromacs/fileio/tngio.h"
 #include "gromacs/fileio/trrio.h"
 #include "gromacs/fileio/xtcio.h"
 #include "gromacs/gmxpreprocess/gmxcpp.h"
-#include "gromacs/linearalgebra/sparsematrix.h"
 #include "gromacs/math/vecdump.h"
 #include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/forcerec.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/mdtypes/state.h"
+#include "gromacs/options/basicoptions.h"
+#include "gromacs/options/filenameoption.h"
+#include "gromacs/options/ioptionscontainer.h"
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
 #include "gromacs/trajectory/energyframe.h"
@@ -80,7 +88,7 @@ namespace
 {
 
 //! Dump a TPR file
-void list_tpx(const char *fn,
+void list_tpr(const char *fn,
               gmx_bool    bShowNumbers,
               gmx_bool    bShowParameters,
               const char *mdpfn,
@@ -186,8 +194,8 @@ void list_tpx(const char *fn,
 void list_top(const char *fn)
 {
     int       status, done;
-#define BUFLEN 256
-    char      buf[BUFLEN];
+    // Legacy string length macro
+    char      buf[STRLEN];
     gmx_cpp_t handle;
     char     *cppopts[] = { nullptr };
 
@@ -198,7 +206,7 @@ void list_top(const char *fn)
     }
     do
     {
-        status = cpp_read_line(&handle, BUFLEN, buf);
+        status = cpp_read_line(&handle, STRLEN, buf);
         done   = static_cast<int>(status == eCPP_EOF);
         if (!done)
         {
@@ -618,82 +626,150 @@ void list_mtx(const char *fn)
     sfree(full);
 }
 
-}   // namespace
+class Dump : public ICommandLineOptionsModule
+{
+    public:
+        Dump()
+        {}
 
-int gmx_dump(int argc, char *argv[])
+        // From ICommandLineOptionsModule
+        void init(CommandLineModuleSettings * /*settings*/) override
+        {
+        }
+
+        void initOptions(IOptionsContainer                 *options,
+                         ICommandLineOptionsModuleSettings *settings) override;
+
+        void optionsFinished() override;
+
+        int run() override;
+
+    private:
+        //! Commandline options
+        //! \{
+        bool bShowNumbers_      = true;
+        bool bShowParams_       = false;
+        bool bSysTop_           = false;
+        bool bOriginalInputrec_ = false;
+        //! \}
+        //! Commandline file options
+        //! \{
+        std::string inputTprFilename_;
+        std::string inputTrajectoryFilename_;
+        std::string inputEnergyFilename_;
+        std::string inputCheckpointFilename_;
+        std::string inputTopologyFilename_;
+        std::string inputMatrixFilename_;
+        std::string outputMdpFilename_;
+        //! \}
+};
+
+void Dump::initOptions(IOptionsContainer                 *options,
+                       ICommandLineOptionsModuleSettings *settings)
 {
     const char *desc[] = {
         "[THISMODULE] reads a run input file ([REF].tpr[ref]),",
-        "a trajectory ([REF].trr[ref]/[REF].xtc[ref]/[TT]/tng[tt]), an energy",
-        "file ([REF].edr[ref]) or a checkpoint file ([REF].cpt[ref])",
+        "a trajectory ([REF].trr[ref]/[REF].xtc[ref]/[TT]tng[tt]), an energy",
+        "file ([REF].edr[ref]), a checkpoint file ([REF].cpt[ref])",
+        "or topology file ([REF].top[ref])",
         "and prints that to standard output in a readable format.",
         "This program is essential for checking your run input file in case of",
-        "problems.[PAR]",
-        "The program can also preprocess a topology to help finding problems.",
-        "Note that currently setting [TT]GMXLIB[tt] is the only way to customize",
-        "directories used for searching include files.",
-    };
-    const char *bugs[] = {
-        "Position restraint output from -sys -s is broken"
-    };
-    t_filenm    fnm[] = {
-        { efTPR, "-s", nullptr, ffOPTRD },
-        { efTRX, "-f", nullptr, ffOPTRD },
-        { efEDR, "-e", nullptr, ffOPTRD },
-        { efCPT, nullptr, nullptr, ffOPTRD },
-        { efTOP, "-p", nullptr, ffOPTRD },
-        { efMTX, "-mtx", "hessian", ffOPTRD },
-        { efMDP, "-om", nullptr, ffOPTWR }
+        "problems."
     };
-#define NFILE asize(fnm)
-
-    gmx_output_env_t *oenv;
-    /* Command line options */
-    gmx_bool          bShowNumbers      = TRUE;
-    gmx_bool          bShowParams       = FALSE;
-    gmx_bool          bSysTop           = FALSE;
-    gmx_bool          bOriginalInputrec = FALSE;
-    t_pargs           pa[]              = {
-        { "-nr", FALSE, etBOOL, {&bShowNumbers}, "Show index numbers in output (leaving them out makes comparison easier, but creates a useless topology)" },
-        { "-param", FALSE, etBOOL, {&bShowParams}, "Show parameters for each bonded interaction (for comparing dumps, it is useful to combine this with -nonr)" },
-        { "-sys", FALSE, etBOOL, {&bSysTop}, "List the atoms and bonded interactions for the whole system instead of for each molecule type" },
-        { "-orgir", FALSE, etBOOL, {&bOriginalInputrec}, "Show input parameters from tpr as they were written by the version that produced the file, instead of how the current version reads them" }
-    };
-
-    if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
-                           asize(desc), desc, asize(bugs), bugs, &oenv))
-    {
-        return 0;
-    }
+    settings->setHelpText(desc);
+    // TODO If this ancient note acknowledging a bug is still true,
+    // fix it or block that run path:
+    //   Position restraint output from -sys -s is broken
+
+    options->addOption(FileNameOption("s")
+                           .filetype(eftRunInput).inputFile()
+                           .store(&inputTprFilename_)
+                           .description("Run input file to dump"));
+    options->addOption(FileNameOption("f")
+                           .filetype(eftTrajectory).inputFile()
+                           .store(&inputTrajectoryFilename_)
+                           .description("Trajectory file to dump"));
+    options->addOption(FileNameOption("e")
+                           .filetype(eftEnergy).inputFile()
+                           .store(&inputEnergyFilename_)
+                           .description("Energy file to dump"));
+    options->addOption(FileNameOption("cp")
+                           .legacyType(efCPT).inputFile()
+                           .store(&inputCheckpointFilename_)
+                           .description("Checkpoint file to dump"));
+    options->addOption(FileNameOption("p")
+                           .legacyType(efTOP).inputFile()
+                           .store(&inputTopologyFilename_)
+                           .description("Topology file to dump"));
+    options->addOption(FileNameOption("mtx")
+                           .legacyType(efMTX).inputFile()
+                           .store(&inputMatrixFilename_)
+                           .description("Hessian matrix to dump"));
+    options->addOption(FileNameOption("om")
+                           .legacyType(efMDP).outputFile()
+                           .store(&outputMdpFilename_)
+                           .description("grompp input file from run input file"));
+
+    options->addOption(BooleanOption("nr")
+                           .store(&bShowNumbers_).defaultValue(true)
+                           .description("Show index numbers in output (leaving them out makes comparison easier, but creates a useless topology)"));
+    options->addOption(BooleanOption("param")
+                           .store(&bShowParams_).defaultValue(false)
+                           .description("Show parameters for each bonded interaction (for comparing dumps, it is useful to combine this with -nonr)"));
+    options->addOption(BooleanOption("sys")
+                           .store(&bShowParams_).defaultValue(false)
+                           .description("List the atoms and bonded interactions for the whole system instead of for each molecule type"));
+    options->addOption(BooleanOption("orgir")
+                           .store(&bShowParams_).defaultValue(false)
+                           .description("Show input parameters from tpr as they were written by the version that produced the file, instead of how the current version reads them"));
+}
 
+void Dump::optionsFinished()
+{
+    // TODO Currently gmx dump ignores user input that seeks to dump
+    // multiple files. Here, we could enforce that the user only asks
+    // to dump one file.
+}
 
-    if (ftp2bSet(efTPR, NFILE, fnm))
+int Dump::run()
+{
+    if (!inputTprFilename_.empty())
     {
-        list_tpx(ftp2fn(efTPR, NFILE, fnm), bShowNumbers, bShowParams,
-                 ftp2fn_null(efMDP, NFILE, fnm), bSysTop, bOriginalInputrec);
+        list_tpr(inputTprFilename_.c_str(), bShowNumbers_, bShowParams_,
+                 outputMdpFilename_.c_str(), bSysTop_, bOriginalInputrec_);
     }
-    else if (ftp2bSet(efTRX, NFILE, fnm))
+    else if (!inputTrajectoryFilename_.empty())
     {
-        list_trx(ftp2fn(efTRX, NFILE, fnm));
+        list_trx(inputTrajectoryFilename_.c_str());
     }
-    else if (ftp2bSet(efEDR, NFILE, fnm))
+    else if (!inputEnergyFilename_.empty())
     {
-        list_ene(ftp2fn(efEDR, NFILE, fnm));
+        list_ene(inputEnergyFilename_.c_str());
     }
-    else if (ftp2bSet(efCPT, NFILE, fnm))
+    else if (!inputCheckpointFilename_.empty())
     {
-        list_checkpoint(ftp2fn(efCPT, NFILE, fnm), stdout);
+        list_checkpoint(inputCheckpointFilename_.c_str(), stdout);
     }
-    else if (ftp2bSet(efTOP, NFILE, fnm))
+    else if (!inputTopologyFilename_.empty())
     {
-        list_top(ftp2fn(efTOP, NFILE, fnm));
+        list_top(inputTopologyFilename_.c_str());
     }
-    else if (ftp2bSet(efMTX, NFILE, fnm))
+    else if (!inputMatrixFilename_.empty())
     {
-        list_mtx(ftp2fn(efMTX, NFILE, fnm));
+        list_mtx(inputMatrixFilename_.c_str());
     }
 
     return 0;
 }
 
+}   // namespace
+
+const char DumpInfo::name[]             = "dump";
+const char DumpInfo::shortDescription[] =
+    "Make binary files human readable";
+ICommandLineOptionsModulePointer DumpInfo::create()
+{
+    return std::make_unique<Dump>();
+}
+
 }   // namespace gmx
index f30c7983339be1f1751509b121f42a1b04a8bf0b..f8f2f99ef988abc113d36ff3f1edc07bbf7dde41 100644 (file)
 #ifndef GMX_TOOLS_DUMP_H
 #define GMX_TOOLS_DUMP_H
 
+#include "gromacs/commandline/cmdlineoptionsmodule.h"
+
 namespace gmx
 {
 
-/*! \brief Implements gmx dump
- *
- * \param[in] argc  argc value passed to main().
- * \param[in] argv  argv array passed to main().
- */
-int gmx_dump(int argc, char *argv[]);
+class DumpInfo
+{
+
+    public:
+        static const char name[];
+        static const char shortDescription[];
+        static ICommandLineOptionsModulePointer create();
+};
 
 }   // namespace gmx
 
index 6b5179f94128345860e5309f82dd1ed5064e0628..76dc0d98ee41ff2024a9d54a82d600679c6e6173 100644 (file)
@@ -174,8 +174,10 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
 {
     registerModule(manager, &gmx_check, "check",
                    "Check and compare files");
-    registerModule(manager, &gmx::gmx_dump, "dump",
-                   "Make binary files human readable");
+    gmx::ICommandLineOptionsModule::registerModuleFactory(
+            manager, gmx::DumpInfo::name,
+            gmx::DumpInfo::shortDescription,
+            &gmx::DumpInfo::create);
     registerModule(manager, &gmx_grompp, "grompp",
                    "Make a run input file");
     registerModule(manager, &gmx_convert_tpr, "convert-tpr",