Append _pullx_ and _pullf to pull files when -deffnm used.
authorPeter Kasson <kasson@gmail.com>
Mon, 22 Jun 2015 21:32:26 +0000 (17:32 -0400)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Sun, 28 Jun 2015 12:22:40 +0000 (14:22 +0200)
Changes -deffnm behavior for pulling so that the pullx and pullf
files don't collide. Previously, this resulted in one being
backed up and checkpoint restarts failing when -deffnm was used.
(Technically this applies to anything where -px and -pf are identical
 and not explicitly set, but that only happens with -deffnm.)

Additionally return fatal error if -px or -pf set and output files
collide.

Fix is now localized to the pull code.

Fixes #942 except for log file collision with pull-rotation.

Change-Id: I27b8b4ced0f307905e2c2ea4fb260376dd25dc32

src/gromacs/pulling/pull.cpp

index 5a4f8e0150ea849cd41d7326574c810a2fb14c88..b48558e869c40b67a12f84644937cf8e2b6ad2a4 100644 (file)
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pulling/pull_internal.h"
 #include "gromacs/topology/mtop_util.h"
+#include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/futil.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/smalloc.h"
 
+static std::string append_before_extension(std::string pathname,
+                                           std::string to_append)
+{
+    /* Appends to_append before last '.' in pathname */
+    size_t extPos = pathname.find_last_of('.');
+    if (extPos == std::string::npos)
+    {
+        return pathname + to_append;
+    }
+    else
+    {
+        return pathname.substr(0, extPos) + to_append +
+               pathname.substr(extPos, std::string::npos);
+    }
+}
+
 static void pull_print_group_x(FILE *out, ivec dim,
                                const pull_group_work_t *pgrp)
 {
@@ -1867,12 +1884,50 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir,
     pull->out_f = NULL;
     if (bOutFile)
     {
-        if (pull->params.nstxout > 0)
+        /* Check for px and pf filename collision, if we are writing
+           both files */
+        std::string px_filename, pf_filename;
+        std::string px_appended, pf_appended;
+        try
+        {
+            px_filename  = std::string(opt2fn("-px", nfile, fnm));
+            pf_filename  = std::string(opt2fn("-pf", nfile, fnm));
+        }
+        GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
+
+
+        if ((pull->params.nstxout != 0) &&
+            (pull->params.nstfout != 0) &&
+            (px_filename == pf_filename))
+        {
+            if (!opt2bSet("-px", nfile, fnm) && !opt2bSet("-pf", nfile, fnm))
+            {
+                /* We are writing both pull files but neither set directly. */
+                try
+                {
+                    px_appended   = append_before_extension(px_filename, "_pullx");
+                    pf_appended   = append_before_extension(pf_filename, "_pullf");
+                }
+                GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
+                pull->out_x   = open_pull_out(px_appended.c_str(), pull, oenv,
+                                              TRUE, Flags);
+                pull->out_f = open_pull_out(pf_appended.c_str(), pull, oenv,
+                                            FALSE, Flags);
+                return pull;
+            }
+            else
+            {
+                /* If one of -px and -pf is set but the filenames are identical: */
+                gmx_fatal(FARGS, "Identical pull_x and pull_f output filenames %s",
+                          px_filename.c_str());
+            }
+        }
+        if (pull->params.nstxout != 0)
         {
             pull->out_x = open_pull_out(opt2fn("-px", nfile, fnm), pull, oenv,
                                         TRUE, Flags);
         }
-        if (pull->params.nstfout > 0)
+        if (pull->params.nstfout != 0)
         {
             pull->out_f = open_pull_out(opt2fn("-pf", nfile, fnm), pull, oenv,
                                         FALSE, Flags);