Fix formatting of fatal errors in g_bar
authorErik Lindahl <erik@kth.se>
Mon, 28 Jul 2014 18:49:22 +0000 (20:49 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Tue, 2 Sep 2014 20:42:37 +0000 (22:42 +0200)
The lambda value has changed from a floating
point number into a complicated vector, so we
now have a small routine that formats the contents
of this vector for the fatal error routines.

Fixes #1531.

Change-Id: I41f7d27c16a76879d6f1f7dc669655d755c1ce3d

src/gromacs/gmxana/gmx_bar.c

index b692574685521ae180bb371b745bac9f53bb77d4..4f7ad985a90a5817353d2cea2d65845c85ac9114 100644 (file)
@@ -1132,6 +1132,31 @@ void sim_data_histogram(sim_data_t *sd, const char *filename,
     xvgrclose(fp);
 }
 
+static int
+snprint_lambda_vec(char *str, int sz, const char *label, lambda_vec_t *lambda)
+{
+    int n = 0;
+
+    n += snprintf(str+n, sz-n, "lambda vector [%s]: ", label);
+    if (lambda->index >= 0)
+    {
+        n += snprintf(str+n, sz-n, " init-lambda-state=%d", lambda->index);
+    }
+    if (lambda->dhdl >= 0)
+    {
+        n += snprintf(str+n, sz-n, " dhdl index=%d", lambda->dhdl);
+    }
+    else
+    {
+        int i;
+        for (i = 0; i < lambda->lc->N; i++)
+        {
+            n += snprintf(str+n, sz-n, " (%s) l=%g", lambda->lc->names[i], lambda->val[i]);
+        }
+    }
+    return n;
+}
+
 /* create a collection (array) of barres_t object given a ordered linked list
    of barlamda_t sample collections */
 static barres_t *barres_list_create(sim_data_t *sd, int *nres,
@@ -1187,17 +1212,27 @@ static barres_t *barres_list_create(sim_data_t *sd, int *nres,
         }
         else if (!scprev && !sc)
         {
-            gmx_fatal(FARGS, "There is no path from lambda=%f -> %f that is covered by foreign lambdas:\ncannot proceed with BAR.\nUse thermodynamic integration of dH/dl by calculating the averages of dH/dl\nwith g_analyze and integrating them.\nAlternatively, use the -extp option if (and only if) the Hamiltonian\ndepends linearly on lambda, which is NOT normally the case.\n", bl->prev->lambda, bl->lambda);
+            char descX[STRLEN], descY[STRLEN];
+            snprint_lambda_vec(descX, STRLEN, "X", bl->prev->lambda);
+            snprint_lambda_vec(descY, STRLEN, "Y", bl->lambda);
+
+            gmx_fatal(FARGS, "There is no path between the states X & Y below that is covered by foreign lambdas:\ncannot proceed with BAR.\nUse thermodynamic integration of dH/dl by calculating the averages of dH/dl\nwith g_analyze and integrating them.\nAlternatively, use the -extp option if (and only if) the Hamiltonian\ndepends linearly on lambda, which is NOT normally the case.\n\n%s\n%s\n", descX, descY);
         }
 
         /* normal delta H */
         if (!scprev)
         {
-            gmx_fatal(FARGS, "Could not find a set for foreign lambda = %f\nin the files for lambda = %f", bl->lambda, bl->prev->lambda);
+            char descX[STRLEN], descY[STRLEN];
+            snprint_lambda_vec(descX, STRLEN, "X", bl->lambda);
+            snprint_lambda_vec(descY, STRLEN, "Y", bl->prev->lambda);
+            gmx_fatal(FARGS, "Could not find a set for foreign lambda (state X below)\nin the files for main lambda (state Y below)\n\n%s\n%s\n", descX, descY);
         }
         if (!sc)
         {
-            gmx_fatal(FARGS, "Could not find a set for foreign lambda = %f\nin the files for lambda = %f", bl->prev->lambda, bl->lambda);
+            char descX[STRLEN], descY[STRLEN];
+            snprint_lambda_vec(descX, STRLEN, "X", bl->prev->lambda);
+            snprint_lambda_vec(descY, STRLEN, "Y", bl->lambda);
+            gmx_fatal(FARGS, "Could not find a set for foreign lambda (state X below)\nin the files for main lambda (state Y below)\n\n%s\n%s\n", descX, descY);
         }
         br->a = scprev;
         br->b = sc;