Fix norm calculation in gmx_spatial
[alexxy/gromacs.git] / src / gromacs / gmxana / gmx_spatial.cpp
index 44f9b2ac1631285d9c169d8779fea617bb0d76db..90eda00f9f476496105fd0c7f04c78c8f5097516 100644 (file)
@@ -1,7 +1,9 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2007,2008,2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2007,2008,2009,2010,2011 by the GROMACS development team.
+ * Copyright (c) 2012,2013,2014,2015,2017 by the GROMACS development team.
+ * Copyright (c) 2019,2020,2021, 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.
 #include "gromacs/fileio/confio.h"
 #include "gromacs/fileio/trxio.h"
 #include "gromacs/gmxana/gmx_ana.h"
-#include "gromacs/legacyheaders/macros.h"
-#include "gromacs/legacyheaders/typedefs.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pbcutil/rmpbc.h"
 #include "gromacs/topology/index.h"
+#include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/trajectoryframe.h"
+#include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/futil.h"
+#include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/smalloc.h"
 
-static const double bohr = 0.529177249;  /* conversion factor to compensate for VMD plugin conversion... */
+static const double bohr =
+        0.529177249; /* conversion factor to compensate for VMD plugin conversion... */
 
-int gmx_spatial(int argc, char *argv[])
+int gmx_spatial(int argc, charargv[])
 {
-    const char     *desc[] = {
+    const chardesc[] = {
         "[THISMODULE] calculates the spatial distribution function and",
         "outputs it in a form that can be read by VMD as Gaussian98 cube format.",
         "For a system of 32,000 atoms and a 50 ns trajectory, the SDF can be generated",
         "in about 30 minutes, with most of the time dedicated to the two runs through",
         "[TT]trjconv[tt] that are required to center everything properly.",
         "This also takes a whole bunch of space (3 copies of the trajectory file).",
-        "Still, the pictures are pretty and very informative when the fitted selection is properly made.",
+        "Still, the pictures are pretty and very informative when the fitted selection is ",
+        "properly ",
+        "made.",
         "3-4 atoms in a widely mobile group (like a free amino acid in solution) works",
         "well, or select the protein backbone in a stable folded structure to get the SDF",
         "of solvent and look at the time-averaged solvation shell.",
@@ -71,22 +78,29 @@ int gmx_spatial(int argc, char *argv[])
         "",
         "Usage:",
         "",
-        "1. Use [gmx-make_ndx] to create a group containing the atoms around which you want the SDF",
+        "1. Use [gmx-make_ndx] to create a group containing the atoms around which you want the ",
+        "SDF",
         "2. [TT]gmx trjconv -s a.tpr -f a.tng -o b.tng -boxcenter tric -ur compact -pbc none[tt]",
         "3. [TT]gmx trjconv -s a.tpr -f b.tng -o c.tng -fit rot+trans[tt]",
         "4. run [THISMODULE] on the [TT]c.tng[tt] output of step #3.",
         "5. Load [TT]grid.cube[tt] into VMD and view as an isosurface.",
         "",
-        "[BB]Note[bb] that systems such as micelles will require [TT]gmx trjconv -pbc cluster[tt] between steps 1 and 2.",
+        "[BB]Note[bb] that systems such as micelles will require [TT]gmx trjconv -pbc cluster[tt] ",
+        "between steps 1 and 2.",
         "",
         "Warnings",
         "^^^^^^^^",
         "",
-        "The SDF will be generated for a cube that contains all bins that have some non-zero occupancy.",
-        "However, the preparatory [TT]-fit rot+trans[tt] option to [gmx-trjconv] implies that your system will be rotating",
-        "and translating in space (in order that the selected group does not). Therefore the values that are",
-        "returned will only be valid for some region around your central group/coordinate that has full overlap",
-        "with system volume throughout the entire translated/rotated system over the course of the trajectory.",
+        "The SDF will be generated for a cube that contains all bins that have some non-zero ",
+        "occupancy.",
+        "However, the preparatory [TT]-fit rot+trans[tt] option to [gmx-trjconv] implies that ",
+        "your system will be rotating",
+        "and translating in space (in order that the selected group does not). Therefore the ",
+        "values that are",
+        "returned will only be valid for some region around your central group/coordinate that ",
+        "has full overlap",
+        "with system volume throughout the entire translated/rotated system over the course of ",
+        "the trajectory.",
         "It is up to the user to ensure that this is the case.",
         "",
         "Risky options",
@@ -98,80 +112,92 @@ int gmx_spatial(int argc, char *argv[])
         "memory is allocated for cube bins based on the initial coordinates and the [TT]-nab[tt]",
         "option value."
     };
-    const char     *bugs[] = {
-        "When the allocated memory is not large enough, a segmentation fault may occur. This is usually detected "
-        "and the program is halted prior to the fault while displaying a warning message suggesting the use of the [TT]-nab[tt] (Number of Additional Bins) "
-        "option. However, the program does not detect all such events. If you encounter a segmentation fault, run it again "
+    const char* bugs[] = {
+        "When the allocated memory is not large enough, a segmentation fault may occur. ",
+        "This is usually detected ",
+        "and the program is halted prior to the fault while displaying a warning message ",
+        "suggesting the use of the [TT]-nab[tt] (Number of Additional Bins) ",
+        "option. However, the program does not detect all such events. If you encounter a ",
+        "segmentation fault, run it again ",
         "with an increased [TT]-nab[tt] value."
     };
 
     static gmx_bool bPBC         = FALSE;
-    static int      iIGNOREOUTER = -1;   /*Positive values may help if the surface is spikey */
+    static int      iIGNOREOUTER = -1; /*Positive values may help if the surface is spikey */
     static gmx_bool bCUTDOWN     = TRUE;
     static real     rBINWIDTH    = 0.05; /* nm */
     static gmx_bool bCALCDIV     = TRUE;
     static int      iNAB         = 4;
 
-    t_pargs         pa[] = {
-        { "-pbc",      FALSE, etBOOL, {&bPBC},
-          "Use periodic boundary conditions for computing distances" },
-        { "-div",      FALSE, etBOOL, {&bCALCDIV},
-          "Calculate and apply the divisor for bin occupancies based on atoms/minimal cube size. Set as TRUE for visualization and as FALSE ([TT]-nodiv[tt]) to get accurate counts per frame" },
-        { "-ign",      FALSE, etINT, {&iIGNOREOUTER},
-          "Do not display this number of outer cubes (positive values may reduce boundary speckles; -1 ensures outer surface is visible)" },
-        /*    { "-cut",      bCUTDOWN, etBOOL, {&bCUTDOWN},*/
-        /*      "Display a total cube that is of minimal size" }, */
-        { "-bin",      FALSE, etREAL, {&rBINWIDTH},
-          "Width of the bins (nm)" },
-        { "-nab",      FALSE, etINT, {&iNAB},
-          "Number of additional bins to ensure proper memory allocation" }
-    };
+    t_pargs pa[] = { { "-pbc",
+                       FALSE,
+                       etBOOL,
+                       { &bPBC },
+                       "Use periodic boundary conditions for computing distances" },
+                     { "-div",
+                       FALSE,
+                       etBOOL,
+                       { &bCALCDIV },
+                       "Calculate and apply the divisor for bin occupancies based on atoms/minimal "
+                       "cube size. Set as TRUE for visualization and as FALSE ([TT]-nodiv[tt]) to "
+                       "get accurate counts per frame" },
+                     { "-ign",
+                       FALSE,
+                       etINT,
+                       { &iIGNOREOUTER },
+                       "Do not display this number of outer cubes (positive values may reduce "
+                       "boundary speckles; -1 ensures outer surface is visible)" },
+                     /*    { "-cut",      bCUTDOWN, etBOOL, {&bCUTDOWN},*/
+                     /*      "Display a total cube that is of minimal size" }, */
+                     { "-bin", FALSE, etREAL, { &rBINWIDTH }, "Width of the bins (nm)" },
+                     { "-nab",
+                       FALSE,
+                       etINT,
+                       { &iNAB },
+                       "Number of additional bins to ensure proper memory allocation" } };
 
-    double          MINBIN[3];
-    double          MAXBIN[3];
-    t_topology      top;
-    int             ePBC;
-    char            title[STRLEN];
-    t_trxframe      fr;
-    rvec           *xtop;
-    matrix          box, box_pbc;
-    t_trxstatus    *status;
-    int             flags = TRX_READ_X;
-    t_pbc           pbc;
-    t_atoms        *atoms;
-    int             natoms;
-    char           *grpnm, *grpnmp;
-    atom_id        *index, *indexp;
-    int             i, nidx, nidxp;
-    int             v;
-    int             j, k;
-    int          ***bin = NULL;
-    int             nbin[3];
-    FILE           *flp;
-    int             x, y, z, minx, miny, minz, maxx, maxy, maxz;
-    int             numfr, numcu;
-    int             tot, maxval, minval;
-    double          norm;
-    output_env_t    oenv;
-    gmx_rmpbc_t     gpbc = NULL;
+    double            MINBIN[3];
+    double            MAXBIN[3];
+    t_topology        top;
+    PbcType           pbcType;
+    t_trxframe        fr;
+    rvec*             xtop;
+    matrix            box, box_pbc;
+    t_trxstatus*      status;
+    int               flags = TRX_READ_X;
+    t_pbc             pbc;
+    t_atoms*          atoms;
+    int               natoms;
+    char *            grpnm, *grpnmp;
+    int *             index, *indexp;
+    int               i, nidx, nidxp;
+    int               v;
+    int               j, k;
+    int***            bin = nullptr;
+    int               nbin[3];
+    FILE*             flp;
+    int               x, y, z, minx, miny, minz, maxx, maxy, maxz;
+    int               numfr, numcu;
+    int               tot, maxval, minval;
+    double            norm;
+    gmx_output_env_t* oenv;
+    gmx_rmpbc_t       gpbc = nullptr;
 
-    t_filenm        fnm[] = {
-        { efTPS,  NULL,  NULL, ffREAD }, /* this is for the topology */
-        { efTRX, "-f", NULL, ffREAD },   /* and this for the trajectory */
-        { efNDX, NULL, NULL, ffOPTRD }
-    };
+    t_filenm fnm[] = { { efTPS, nullptr, nullptr, ffREAD }, /* this is for the topology */
+                       { efTRX, "-f", nullptr, ffREAD },    /* and this for the trajectory */
+                       { efNDX, nullptr, nullptr, ffOPTRD } };
 
 #define NFILE asize(fnm)
 
     /* This is the routine responsible for adding default options,
      * calling the X/motif interface, etc. */
-    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
-                           NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
+    if (!parse_common_args(
+                &argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
     {
         return 0;
     }
 
-    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xtop, NULL, box, TRUE);
+    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &pbcType, &xtop, nullptr, box, TRUE);
     sfree(xtop);
 
     atoms = &(top.atoms);
@@ -181,7 +207,8 @@ int gmx_spatial(int argc, char *argv[])
     get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nidxp, &indexp, &grpnmp);
 
     /* The first time we read data is a little special */
-    natoms = read_first_frame(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &fr, flags);
+    read_first_frame(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &fr, flags);
+    natoms = fr.natoms;
 
     /* Memory Allocation */
     MINBIN[XX] = MAXBIN[XX] = fr.x[0][XX];
@@ -216,9 +243,9 @@ int gmx_spatial(int argc, char *argv[])
     }
     for (i = ZZ; i >= XX; --i)
     {
-        MAXBIN[i]  = (std::ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH)+iNAB)*rBINWIDTH+MINBIN[i];
-        MINBIN[i] -= iNAB*rBINWIDTH;
-        nbin[i]    = static_cast<int>(std::ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH));
+        MAXBIN[i] = (std::ceil((MAXBIN[i] - MINBIN[i]) / rBINWIDTH) + iNAB) * rBINWIDTH + MINBIN[i];
+        MINBIN[i] -= iNAB * rBINWIDTH;
+        nbin[i] = static_cast<int>(std::ceil((MAXBIN[i] - MINBIN[i]) / rBINWIDTH));
     }
     snew(bin, nbin[XX]);
     for (i = 0; i < nbin[XX]; ++i)
@@ -231,12 +258,12 @@ int gmx_spatial(int argc, char *argv[])
     }
     copy_mat(box, box_pbc);
     numfr = 0;
-    minx  = miny = minz = 999;
-    maxx  = maxy = maxz = 0;
+    minx = miny = minz = 999;
+    maxx = maxy = maxz = 0;
 
     if (bPBC)
     {
-        gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
+        gpbc = gmx_rmpbc_init(&top.idef, pbcType, natoms);
     }
     /* This is the main loop over frames */
     do
@@ -247,23 +274,33 @@ int gmx_spatial(int argc, char *argv[])
         if (bPBC)
         {
             gmx_rmpbc_trxfr(gpbc, &fr);
-            set_pbc(&pbc, ePBC, box_pbc);
+            set_pbc(&pbc, pbcType, box_pbc);
         }
 
         for (i = 0; i < nidx; i++)
         {
-            if (fr.x[index[i]][XX] < MINBIN[XX] || fr.x[index[i]][XX] > MAXBIN[XX] ||
-                fr.x[index[i]][YY] < MINBIN[YY] || fr.x[index[i]][YY] > MAXBIN[YY] ||
-                fr.x[index[i]][ZZ] < MINBIN[ZZ] || fr.x[index[i]][ZZ] > MAXBIN[ZZ])
+            if (fr.x[index[i]][XX] < MINBIN[XX] || fr.x[index[i]][XX] > MAXBIN[XX]
+                || fr.x[index[i]][YY] < MINBIN[YY] || fr.x[index[i]][YY] > MAXBIN[YY]
+                || fr.x[index[i]][ZZ] < MINBIN[ZZ] || fr.x[index[i]][ZZ] > MAXBIN[ZZ])
             {
-                printf("There was an item outside of the allocated memory. Increase the value given with the -nab option.\n");
-                printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n", MINBIN[XX], MINBIN[YY], MINBIN[ZZ], MAXBIN[XX], MAXBIN[YY], MAXBIN[ZZ]);
-                printf("Memory was required for [%f,%f,%f]\n", fr.x[index[i]][XX], fr.x[index[i]][YY], fr.x[index[i]][ZZ]);
+                printf("There was an item outside of the allocated memory. Increase the value "
+                       "given with the -nab option.\n");
+                printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n",
+                       MINBIN[XX],
+                       MINBIN[YY],
+                       MINBIN[ZZ],
+                       MAXBIN[XX],
+                       MAXBIN[YY],
+                       MAXBIN[ZZ]);
+                printf("Memory was required for [%f,%f,%f]\n",
+                       fr.x[index[i]][XX],
+                       fr.x[index[i]][YY],
+                       fr.x[index[i]][ZZ]);
                 exit(1);
             }
-            x = static_cast<int>(std::ceil((fr.x[index[i]][XX]-MINBIN[XX])/rBINWIDTH));
-            y = static_cast<int>(std::ceil((fr.x[index[i]][YY]-MINBIN[YY])/rBINWIDTH));
-            z = static_cast<int>(std::ceil((fr.x[index[i]][ZZ]-MINBIN[ZZ])/rBINWIDTH));
+            x = static_cast<int>(std::ceil((fr.x[index[i]][XX] - MINBIN[XX]) / rBINWIDTH));
+            y = static_cast<int>(std::ceil((fr.x[index[i]][YY] - MINBIN[YY]) / rBINWIDTH));
+            z = static_cast<int>(std::ceil((fr.x[index[i]][ZZ] - MINBIN[ZZ]) / rBINWIDTH));
             ++bin[x][y][z];
             if (x < minx)
             {
@@ -293,8 +330,7 @@ int gmx_spatial(int argc, char *argv[])
         numfr++;
         /* printf("%f\t%f\t%f\n",box[XX][XX],box[YY][YY],box[ZZ][ZZ]); */
 
-    }
-    while (read_next_frame(oenv, status, &fr));
+    } while (read_next_frame(oenv, status, &fr));
 
     if (bPBC)
     {
@@ -304,19 +340,24 @@ int gmx_spatial(int argc, char *argv[])
     if (!bCUTDOWN)
     {
         minx = miny = minz = 0;
-        maxx = nbin[XX];
-        maxy = nbin[YY];
-        maxz = nbin[ZZ];
+        maxx               = nbin[XX];
+        maxy               = nbin[YY];
+        maxz               = nbin[ZZ];
     }
 
     /* OUTPUT */
     flp = gmx_ffopen("grid.cube", "w");
     fprintf(flp, "Spatial Distribution Function\n");
     fprintf(flp, "test\n");
-    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", nidxp, (MINBIN[XX]+(minx+iIGNOREOUTER)*rBINWIDTH)*10./bohr, (MINBIN[YY]+(miny+iIGNOREOUTER)*rBINWIDTH)*10./bohr, (MINBIN[ZZ]+(minz+iIGNOREOUTER)*rBINWIDTH)*10./bohr);
-    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxx-minx+1-(2*iIGNOREOUTER), rBINWIDTH*10./bohr, 0., 0.);
-    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxy-miny+1-(2*iIGNOREOUTER), 0., rBINWIDTH*10./bohr, 0.);
-    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxz-minz+1-(2*iIGNOREOUTER), 0., 0., rBINWIDTH*10./bohr);
+    fprintf(flp,
+            "%5d%12.6f%12.6f%12.6f\n",
+            nidxp,
+            (MINBIN[XX] + (minx + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr,
+            (MINBIN[YY] + (miny + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr,
+            (MINBIN[ZZ] + (minz + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr);
+    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxx - minx + 1 - (2 * iIGNOREOUTER), rBINWIDTH * 10. / bohr, 0., 0.);
+    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxy - miny + 1 - (2 * iIGNOREOUTER), 0., rBINWIDTH * 10. / bohr, 0.);
+    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxz - minz + 1 - (2 * iIGNOREOUTER), 0., 0., rBINWIDTH * 10. / bohr);
     for (i = 0; i < nidxp; i++)
     {
         v = 2;
@@ -340,7 +381,13 @@ int gmx_spatial(int argc, char *argv[])
         {
             v = 16;
         }
-        fprintf(flp, "%5d%12.6f%12.6f%12.6f%12.6f\n", v, 0., fr.x[indexp[i]][XX]*10.0/bohr, fr.x[indexp[i]][YY]*10.0/bohr, fr.x[indexp[i]][ZZ]*10.0/bohr);
+        fprintf(flp,
+                "%5d%12.6f%12.6f%12.6f%12.6f\n",
+                v,
+                0.,
+                fr.x[indexp[i]][XX] * 10.0 / bohr,
+                fr.x[indexp[i]][YY] * 10.0 / bohr,
+                fr.x[indexp[i]][ZZ] * 10.0 / bohr);
     }
 
     tot = 0;
@@ -364,7 +411,8 @@ int gmx_spatial(int argc, char *argv[])
                 }
                 if (bin[k][j][i] != 0)
                 {
-                    printf("A bin was not empty when it should have been empty. Programming error.\n");
+                    printf("A bin was not empty when it should have been empty. Programming "
+                           "error.\n");
                     printf("bin[%d][%d][%d] was = %d\n", k, j, i, bin[k][j][i]);
                     exit(1);
                 }
@@ -376,19 +424,19 @@ int gmx_spatial(int argc, char *argv[])
     maxval = 0;
     for (k = 0; k < nbin[XX]; k++)
     {
-        if (k < minx+iIGNOREOUTER || k > maxx-iIGNOREOUTER)
+        if (k < minx + iIGNOREOUTER || k > maxx - iIGNOREOUTER)
         {
             continue;
         }
         for (j = 0; j < nbin[YY]; j++)
         {
-            if (j < miny+iIGNOREOUTER || j > maxy-iIGNOREOUTER)
+            if (j < miny + iIGNOREOUTER || j > maxy - iIGNOREOUTER)
             {
                 continue;
             }
             for (i = 0; i < nbin[ZZ]; i++)
             {
-                if (i < minz+iIGNOREOUTER || i > maxz-iIGNOREOUTER)
+                if (i < minz + iIGNOREOUTER || i > maxz - iIGNOREOUTER)
                 {
                     continue;
                 }
@@ -405,10 +453,12 @@ int gmx_spatial(int argc, char *argv[])
         }
     }
 
-    numcu = (maxx-minx+1-(2*iIGNOREOUTER))*(maxy-miny+1-(2*iIGNOREOUTER))*(maxz-minz+1-(2*iIGNOREOUTER));
+    numcu = (maxx - minx + 1 - (2 * iIGNOREOUTER)) * (maxy - miny + 1 - (2 * iIGNOREOUTER))
+            * (maxz - minz + 1 - (2 * iIGNOREOUTER));
     if (bCALCDIV)
     {
-        norm = static_cast<double>(numcu*numfr)/tot;
+        norm = double(numcu) * numfr / tot;
+        GMX_ASSERT(norm >= 0, "The norm should be non-negative.");
     }
     else
     {
@@ -417,23 +467,23 @@ int gmx_spatial(int argc, char *argv[])
 
     for (k = 0; k < nbin[XX]; k++)
     {
-        if (k < minx+iIGNOREOUTER || k > maxx-iIGNOREOUTER)
+        if (k < minx + iIGNOREOUTER || k > maxx - iIGNOREOUTER)
         {
             continue;
         }
         for (j = 0; j < nbin[YY]; j++)
         {
-            if (j < miny+iIGNOREOUTER || j > maxy-iIGNOREOUTER)
+            if (j < miny + iIGNOREOUTER || j > maxy - iIGNOREOUTER)
             {
                 continue;
             }
             for (i = 0; i < nbin[ZZ]; i++)
             {
-                if (i < minz+iIGNOREOUTER || i > maxz-iIGNOREOUTER)
+                if (i < minz + iIGNOREOUTER || i > maxz - iIGNOREOUTER)
                 {
                     continue;
                 }
-                fprintf(flp, "%12.6f ", static_cast<double>(norm*bin[k][j][i])/numfr);
+                fprintf(flp, "%12.6f ", static_cast<double>(norm * bin[k][j][i]) / numfr);
             }
             fprintf(flp, "\n");
         }
@@ -443,13 +493,19 @@ int gmx_spatial(int argc, char *argv[])
 
     if (bCALCDIV)
     {
-        printf("Counts per frame in all %d cubes divided by %le\n", numcu, 1.0/norm);
-        printf("Normalized data: average %le, min %le, max %le\n", 1.0, minval*norm/numfr, maxval*norm/numfr);
+        printf("Counts per frame in all %d cubes divided by %le\n", numcu, 1.0 / norm);
+        printf("Normalized data: average %le, min %le, max %le\n",
+               1.0,
+               minval * norm / numfr,
+               maxval * norm / numfr);
     }
     else
     {
         printf("grid.cube contains counts per frame in all %d cubes\n", numcu);
-        printf("Raw data: average %le, min %le, max %le\n", 1.0/norm, static_cast<double>(minval)/numfr, static_cast<double>(maxval)/numfr);
+        printf("Raw data: average %le, min %le, max %le\n",
+               1.0 / norm,
+               static_cast<double>(minval) / numfr,
+               static_cast<double>(maxval) / numfr);
     }
 
     return 0;