2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
47 #include "gmx_fatal.h"
61 #include "mtop_util.h"
65 static real minthird = -1.0/3.0, minsixth = -1.0/6.0;
83 gmx_large_int_t nsteps;
84 gmx_large_int_t npoints;
93 static double mypow(double x, double y)
105 static int *select_it(int nre, char *nm[], int *nset)
110 gmx_bool bVerbose = TRUE;
112 if ((getenv("VERBOSE")) != NULL)
117 fprintf(stderr, "Select the terms you want from the following list\n");
118 fprintf(stderr, "End your selection with 0\n");
122 for (k = 0; (k < nre); )
124 for (j = 0; (j < 4) && (k < nre); j++, k++)
126 fprintf(stderr, " %3d=%14s", k+1, nm[k]);
128 fprintf(stderr, "\n");
135 if (1 != scanf("%d", &n))
137 gmx_fatal(FARGS, "Error reading user input");
139 if ((n > 0) && (n <= nre))
147 for (i = (*nset) = 0; (i < nre); i++)
160 static void chomp(char *buf)
162 int len = strlen(buf);
164 while ((len > 0) && (buf[len-1] == '\n'))
171 static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset)
174 int n, k, kk, j, i, nmatch, nind, nss;
176 gmx_bool bEOF, bVerbose = TRUE, bLong = FALSE;
177 char *ptr, buf[STRLEN];
178 const char *fm4 = "%3d %-14s";
179 const char *fm2 = "%3d %-34s";
182 if ((getenv("VERBOSE")) != NULL)
187 fprintf(stderr, "\n");
188 fprintf(stderr, "Select the terms you want from the following list by\n");
189 fprintf(stderr, "selecting either (part of) the name or the number or a combination.\n");
190 fprintf(stderr, "End your selection with an empty line or a zero.\n");
191 fprintf(stderr, "-------------------------------------------------------------------\n");
195 for (k = 0; k < nre; k++)
197 newnm[k] = strdup(nm[k].name);
198 /* Insert dashes in all the names */
199 while ((ptr = strchr(newnm[k], ' ')) != NULL)
209 fprintf(stderr, "\n");
212 for (kk = k; kk < k+4; kk++)
214 if (kk < nre && strlen(nm[kk].name) > 14)
222 fprintf(stderr, " ");
226 fprintf(stderr, fm4, k+1, newnm[k]);
235 fprintf(stderr, fm2, k+1, newnm[k]);
246 fprintf(stderr, "\n\n");
252 while (!bEOF && (fgets2(buf, STRLEN-1, stdin)))
254 /* Remove newlines */
260 /* Empty line means end of input */
261 bEOF = (strlen(buf) == 0);
269 /* First try to read an integer */
270 nss = sscanf(ptr, "%d", &nind);
273 /* Zero means end of input */
278 else if ((1 <= nind) && (nind <= nre))
284 fprintf(stderr, "number %d is out of range\n", nind);
289 /* Now try to read a string */
292 for (nind = 0; nind < nre; nind++)
294 if (gmx_strcasecmp(newnm[nind], ptr) == 0)
304 for (nind = 0; nind < nre; nind++)
306 if (gmx_strncasecmp(newnm[nind], ptr, i) == 0)
314 fprintf(stderr, "String '%s' does not match anything\n", ptr);
319 /* Look for the first space, and remove spaces from there */
320 if ((ptr = strchr(ptr, ' ')) != NULL)
325 while (!bEOF && (ptr && (strlen(ptr) > 0)));
330 for (i = (*nset) = 0; (i < nre); i++)
342 gmx_fatal(FARGS, "No energy terms selected");
345 for (i = 0; (i < nre); i++)
354 static void get_dhdl_parms(const char *topnm, t_inputrec *ir)
361 /* all we need is the ir to be able to write the label */
362 read_tpx(topnm, ir, box, &natoms, NULL, NULL, NULL, &mtop);
365 static void get_orires_parms(const char *topnm,
366 int *nor, int *nex, int **label, real **obs)
377 read_tpx(topnm, &ir, box, &natoms, NULL, NULL, NULL, &mtop);
378 top = gmx_mtop_generate_local_top(&mtop, &ir);
380 ip = top->idef.iparams;
381 iatom = top->idef.il[F_ORIRES].iatoms;
383 /* Count how many distance restraint there are... */
384 nb = top->idef.il[F_ORIRES].nr;
387 gmx_fatal(FARGS, "No orientation restraints in topology!\n");
394 for (i = 0; i < nb; i += 3)
396 (*label)[i/3] = ip[iatom[i]].orires.label;
397 (*obs)[i/3] = ip[iatom[i]].orires.obs;
398 if (ip[iatom[i]].orires.ex >= *nex)
400 *nex = ip[iatom[i]].orires.ex+1;
403 fprintf(stderr, "Found %d orientation restraints with %d experiments",
407 static int get_bounds(const char *topnm,
408 real **bounds, int **index, int **dr_pair, int *npairs,
409 gmx_mtop_t *mtop, gmx_localtop_t **ltop, t_inputrec *ir)
412 t_functype *functype;
414 int natoms, i, j, k, type, ftype, natom;
422 read_tpx(topnm, ir, box, &natoms, NULL, NULL, NULL, mtop);
424 top = gmx_mtop_generate_local_top(mtop, ir);
427 functype = top->idef.functype;
428 ip = top->idef.iparams;
430 /* Count how many distance restraint there are... */
431 nb = top->idef.il[F_DISRES].nr;
434 gmx_fatal(FARGS, "No distance restraints in topology!\n");
437 /* Allocate memory */
442 /* Fill the bound array */
444 for (i = 0; (i < top->idef.ntypes); i++)
447 if (ftype == F_DISRES)
450 label1 = ip[i].disres.label;
451 b[nb] = ip[i].disres.up1;
458 /* Fill the index array */
460 disres = &(top->idef.il[F_DISRES]);
461 iatom = disres->iatoms;
462 for (i = j = k = 0; (i < disres->nr); )
465 ftype = top->idef.functype[type];
466 natom = interaction_function[ftype].nratoms+1;
467 if (label1 != top->idef.iparams[type].disres.label)
470 label1 = top->idef.iparams[type].disres.label;
480 gmx_incons("get_bounds for distance restraints");
489 static void calc_violations(real rt[], real rav3[], int nb, int index[],
490 real bounds[], real *viol, double *st, double *sa)
492 const real sixth = 1.0/6.0;
494 double rsum, rav, sumaver, sumt;
498 for (i = 0; (i < nb); i++)
502 for (j = index[i]; (j < index[i+1]); j++)
506 viol[j] += mypow(rt[j], -3.0);
509 rsum += mypow(rt[j], -6);
511 rsum = max(0.0, mypow(rsum, -sixth)-bounds[i]);
512 rav = max(0.0, mypow(rav, -sixth)-bounds[i]);
521 static void analyse_disre(const char *voutfn, int nframes,
522 real violaver[], real bounds[], int index[],
523 int pair[], int nbounds,
524 const output_env_t oenv)
527 double sum, sumt, sumaver;
530 /* Subtract bounds from distances, to calculate violations */
531 calc_violations(violaver, violaver,
532 nbounds, pair, bounds, NULL, &sumt, &sumaver);
535 fprintf(stdout, "\nSum of violations averaged over simulation: %g nm\n",
537 fprintf(stdout, "Largest violation averaged over simulation: %g nm\n\n",
540 vout = xvgropen(voutfn, "r\\S-3\\N average violations", "DR Index", "nm",
544 for (i = 0; (i < nbounds); i++)
546 /* Do ensemble averaging */
548 for (j = pair[i]; (j < pair[i+1]); j++)
550 sumaver += sqr(violaver[j]/nframes);
552 sumaver = max(0.0, mypow(sumaver, minsixth)-bounds[i]);
555 sum = max(sum, sumaver);
556 fprintf(vout, "%10d %10.5e\n", index[i], sumaver);
559 for (j = 0; (j < dr.ndr); j++)
561 fprintf(vout, "%10d %10.5e\n", j, mypow(violaver[j]/nframes, minthird));
566 fprintf(stdout, "\nSum of violations averaged over simulation: %g nm\n",
568 fprintf(stdout, "Largest violation averaged over simulation: %g nm\n\n", sum);
570 do_view(oenv, voutfn, "-graphtype bar");
573 static void einstein_visco(const char *fn, const char *fni, int nsets,
574 int nint, real **eneint,
575 real V, real T, double dt,
576 const output_env_t oenv)
579 double av[4], avold[4];
585 for (i = 0; i <= nsets; i++)
589 fp0 = xvgropen(fni, "Shear viscosity integral",
590 "Time (ps)", "(kg m\\S-1\\N s\\S-1\\N ps)", oenv);
591 fp1 = xvgropen(fn, "Shear viscosity using Einstein relation",
592 "Time (ps)", "(kg m\\S-1\\N s\\S-1\\N)", oenv);
593 for (i = 0; i < nf4; i++)
595 for (m = 0; m <= nsets; m++)
599 for (j = 0; j < nint - i; j++)
601 for (m = 0; m < nsets; m++)
603 di = sqr(eneint[m][j+i] - eneint[m][j]);
606 av[nsets] += di/nsets;
609 /* Convert to SI for the viscosity */
610 fac = (V*NANO*NANO*NANO*PICO*1e10)/(2*BOLTZMANN*T)/(nint - i);
611 fprintf(fp0, "%10g", i*dt);
612 for (m = 0; (m <= nsets); m++)
615 fprintf(fp0, " %10g", av[m]);
618 fprintf(fp1, "%10g", (i + 0.5)*dt);
619 for (m = 0; (m <= nsets); m++)
621 fprintf(fp1, " %10g", (av[m]-avold[m])/dt);
641 gmx_large_int_t nst_min;
644 static void clear_ee_sum(ee_sum_t *ees)
652 static void add_ee_sum(ee_sum_t *ees, double sum, int np)
658 static void add_ee_av(ee_sum_t *ees)
662 av = ees->sum/ees->np;
669 static double calc_ee2(int nb, ee_sum_t *ees)
671 return (ees->sav2/nb - dsqr(ees->sav/nb))/(nb - 1);
674 static void set_ee_av(ener_ee_t *eee)
678 char buf[STEPSTRSIZE];
679 fprintf(debug, "Storing average for err.est.: %s steps\n",
680 gmx_step_str(eee->nst, buf));
682 add_ee_av(&eee->sum);
684 if (eee->b == 1 || eee->nst < eee->nst_min)
686 eee->nst_min = eee->nst;
691 static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax)
694 double sum, sum2, sump, see2;
695 gmx_large_int_t steps, np, p, bound_nb;
699 double x, sx, sy, sxx, sxy;
702 /* Check if we have exact statistics over all points */
703 for (i = 0; i < nset; i++)
706 ed->bExactStat = FALSE;
709 /* All energy file sum entries 0 signals no exact sums.
710 * But if all energy values are 0, we still have exact sums.
713 for (f = 0; f < edat->nframes && !ed->bExactStat; f++)
715 if (ed->ener[i] != 0)
719 ed->bExactStat = (ed->es[f].sum != 0);
723 ed->bExactStat = TRUE;
729 for (i = 0; i < nset; i++)
740 for (nb = nbmin; nb <= nbmax; nb++)
743 clear_ee_sum(&eee[nb].sum);
747 for (f = 0; f < edat->nframes; f++)
753 /* Add the sum and the sum of variances to the totals. */
759 sum2 += dsqr(sum/np - (sum + es->sum)/(np + p))
765 /* Add a single value to the sum and sum of squares. */
771 /* sum has to be increased after sum2 */
775 /* For the linear regression use variance 1/p.
776 * Note that sump is the sum, not the average, so we don't need p*.
778 x = edat->step[f] - 0.5*(edat->steps[f] - 1);
784 for (nb = nbmin; nb <= nbmax; nb++)
786 /* Check if the current end step is closer to the desired
787 * block boundary than the next end step.
789 bound_nb = (edat->step[0]-1)*nb + edat->nsteps*(eee[nb].b+1);
790 if (eee[nb].nst > 0 &&
791 bound_nb - edat->step[f-1]*nb < edat->step[f]*nb - bound_nb)
801 eee[nb].nst += edat->step[f] - edat->step[f-1];
805 add_ee_sum(&eee[nb].sum, es->sum, edat->points[f]);
809 add_ee_sum(&eee[nb].sum, edat->s[i].ener[f], 1);
811 bound_nb = (edat->step[0]-1)*nb + edat->nsteps*(eee[nb].b+1);
812 if (edat->step[f]*nb >= bound_nb)
819 edat->s[i].av = sum/np;
822 edat->s[i].rmsd = sqrt(sum2/np);
826 edat->s[i].rmsd = sqrt(sum2/np - dsqr(edat->s[i].av));
829 if (edat->nframes > 1)
831 edat->s[i].slope = (np*sxy - sx*sy)/(np*sxx - sx*sx);
835 edat->s[i].slope = 0;
840 for (nb = nbmin; nb <= nbmax; nb++)
842 /* Check if we actually got nb blocks and if the smallest
843 * block is not shorter than 80% of the average.
847 char buf1[STEPSTRSIZE], buf2[STEPSTRSIZE];
848 fprintf(debug, "Requested %d blocks, we have %d blocks, min %s nsteps %s\n",
850 gmx_step_str(eee[nb].nst_min, buf1),
851 gmx_step_str(edat->nsteps, buf2));
853 if (eee[nb].b == nb && 5*nb*eee[nb].nst_min >= 4*edat->nsteps)
855 see2 += calc_ee2(nb, &eee[nb].sum);
861 edat->s[i].ee = sqrt(see2/nee);
871 static enerdata_t *calc_sum(int nset, enerdata_t *edat, int nbmin, int nbmax)
882 snew(s->ener, esum->nframes);
883 snew(s->es, esum->nframes);
885 s->bExactStat = TRUE;
887 for (i = 0; i < nset; i++)
889 if (!edat->s[i].bExactStat)
891 s->bExactStat = FALSE;
893 s->slope += edat->s[i].slope;
896 for (f = 0; f < edat->nframes; f++)
899 for (i = 0; i < nset; i++)
901 sum += edat->s[i].ener[f];
905 for (i = 0; i < nset; i++)
907 sum += edat->s[i].es[f].sum;
913 calc_averages(1, esum, nbmin, nbmax);
918 static char *ee_pr(double ee, char *buf)
925 sprintf(buf, "%s", "--");
929 /* Round to two decimals by printing. */
930 sprintf(tmp, "%.1e", ee);
931 sscanf(tmp, "%lf", &rnd);
932 sprintf(buf, "%g", rnd);
938 static void remove_drift(int nset, int nbmin, int nbmax, real dt, enerdata_t *edat)
940 /* Remove the drift by performing a fit to y = ax+b.
941 Uses 5 iterations. */
943 double delta, d, sd, sd2;
945 edat->npoints = edat->nframes;
946 edat->nsteps = edat->nframes;
948 for (k = 0; (k < 5); k++)
950 for (i = 0; (i < nset); i++)
952 delta = edat->s[i].slope*dt;
956 fprintf(debug, "slope for set %d is %g\n", i, edat->s[i].slope);
959 for (j = 0; (j < edat->nframes); j++)
961 edat->s[i].ener[j] -= j*delta;
962 edat->s[i].es[j].sum = 0;
963 edat->s[i].es[j].sum2 = 0;
966 calc_averages(nset, edat, nbmin, nbmax);
970 static void calc_fluctuation_props(FILE *fp,
971 gmx_bool bDriftCorr, real dt,
972 int nset, int set[], int nmol,
973 char **leg, enerdata_t *edat,
974 int nbmin, int nbmax)
977 double vv, v, h, varv, hh, varh, tt, cv, cp, alpha, kappa, dcp, et, varet;
980 eVol, eEnth, eTemp, eEtot, eNR
982 const char *my_ener[] = { "Volume", "Enthalpy", "Temperature", "Total Energy" };
985 NANO3 = NANO*NANO*NANO;
988 fprintf(fp, "\nYou may want to use the -driftcorr flag in order to correct\n"
989 "for spurious drift in the graphs. Note that this is not\n"
990 "a substitute for proper equilibration and sampling!\n");
994 remove_drift(nset, nbmin, nbmax, dt, edat);
996 for (i = 0; (i < eNR); i++)
998 for (ii[i] = 0; (ii[i] < nset &&
999 (gmx_strcasecmp(leg[ii[i]], my_ener[i]) != 0)); ii[i]++)
1003 /* if (ii[i] < nset)
1004 fprintf(fp,"Found %s data.\n",my_ener[i]);
1006 /* Compute it all! */
1007 alpha = kappa = cp = dcp = cv = NOTSET;
1011 if (ii[eTemp] < nset)
1013 tt = edat->s[ii[eTemp]].av;
1017 if ((ii[eVol] < nset) && (ii[eTemp] < nset))
1019 vv = edat->s[ii[eVol]].av*NANO3;
1020 varv = dsqr(edat->s[ii[eVol]].rmsd*NANO3);
1021 kappa = (varv/vv)/(BOLTZMANN*tt);
1025 if ((ii[eEnth] < nset) && (ii[eTemp] < nset))
1027 hh = KILO*edat->s[ii[eEnth]].av/AVOGADRO;
1028 varh = dsqr(KILO*edat->s[ii[eEnth]].rmsd/AVOGADRO);
1029 cp = AVOGADRO*((varh/nmol)/(BOLTZMANN*tt*tt));
1032 et = varet = NOTSET;
1033 if ((ii[eEtot] < nset) && (hh == NOTSET) && (tt != NOTSET))
1035 /* Only compute cv in constant volume runs, which we can test
1036 by checking whether the enthalpy was computed.
1038 et = edat->s[ii[eEtot]].av;
1039 varet = sqr(edat->s[ii[eEtot]].rmsd);
1040 cv = KILO*((varet/nmol)/(BOLTZ*tt*tt));
1043 if ((ii[eVol] < nset) && (ii[eEnth] < nset) && (ii[eTemp] < nset))
1045 double v_sum, h_sum, vh_sum, v_aver, h_aver, vh_aver;
1046 vh_sum = v_sum = h_sum = 0;
1047 for (j = 0; (j < edat->nframes); j++)
1049 v = edat->s[ii[eVol]].ener[j]*NANO3;
1050 h = KILO*edat->s[ii[eEnth]].ener[j]/AVOGADRO;
1055 vh_aver = vh_sum / edat->nframes;
1056 v_aver = v_sum / edat->nframes;
1057 h_aver = h_sum / edat->nframes;
1058 alpha = (vh_aver-v_aver*h_aver)/(v_aver*BOLTZMANN*tt*tt);
1059 dcp = (v_aver*AVOGADRO/nmol)*tt*sqr(alpha)/(kappa);
1066 fprintf(fp, "\nWARNING: nmol = %d, this may not be what you want.\n",
1069 fprintf(fp, "\nTemperature dependent fluctuation properties at T = %g.\n", tt);
1070 fprintf(fp, "\nHeat capacities obtained from fluctuations do *not* include\n");
1071 fprintf(fp, "quantum corrections. If you want to get a more accurate estimate\n");
1072 fprintf(fp, "please use the g_dos program.\n\n");
1073 fprintf(fp, "WARNING: Please verify that your simulations are converged and perform\n"
1074 "a block-averaging error analysis (not implemented in g_energy yet)\n");
1080 fprintf(fp, "varv = %10g (m^6)\n", varv*AVOGADRO/nmol);
1085 fprintf(fp, "Volume = %10g m^3/mol\n",
1090 fprintf(fp, "Enthalpy = %10g kJ/mol\n",
1091 hh*AVOGADRO/(KILO*nmol));
1093 if (alpha != NOTSET)
1095 fprintf(fp, "Coefficient of Thermal Expansion Alpha_P = %10g (1/K)\n",
1098 if (kappa != NOTSET)
1100 fprintf(fp, "Isothermal Compressibility Kappa = %10g (J/m^3)\n",
1102 fprintf(fp, "Adiabatic bulk modulus = %10g (m^3/J)\n",
1107 fprintf(fp, "Heat capacity at constant pressure Cp = %10g J/mol K\n",
1112 fprintf(fp, "Heat capacity at constant volume Cv = %10g J/mol K\n",
1117 fprintf(fp, "Cp-Cv = %10g J/mol K\n",
1120 please_cite(fp, "Allen1987a");
1124 fprintf(fp, "You should select the temperature in order to obtain fluctuation properties.\n");
1128 static void analyse_ener(gmx_bool bCorr, const char *corrfn,
1129 gmx_bool bFee, gmx_bool bSum, gmx_bool bFluct, gmx_bool bTempFluct,
1130 gmx_bool bVisco, const char *visfn, int nmol,
1131 gmx_large_int_t start_step, double start_t,
1132 gmx_large_int_t step, double t,
1133 double time[], real reftemp,
1135 int nset, int set[], gmx_bool *bIsEner,
1136 char **leg, gmx_enxnm_t *enm,
1137 real Vaver, real ezero,
1138 int nbmin, int nbmax,
1139 const output_env_t oenv)
1142 /* Check out the printed manual for equations! */
1143 double Dt, aver, stddev, errest, delta_t, totaldrift;
1144 enerdata_t *esum = NULL;
1145 real xxx, integral, intBulk, Temp = 0, Pres = 0;
1146 real sfrac, oldfrac, diffsum, diffav, fstep, pr_aver, pr_stddev, pr_errest;
1147 double beta = 0, expE, expEtot, *fee = NULL;
1148 gmx_large_int_t nsteps;
1149 int nexact, nnotexact;
1153 char buf[256], eebuf[100];
1155 nsteps = step - start_step + 1;
1158 fprintf(stdout, "Not enough steps (%s) for statistics\n",
1159 gmx_step_str(nsteps, buf));
1163 /* Calculate the time difference */
1164 delta_t = t - start_t;
1166 fprintf(stdout, "\nStatistics over %s steps [ %.4f through %.4f ps ], %d data sets\n",
1167 gmx_step_str(nsteps, buf), start_t, t, nset);
1169 calc_averages(nset, edat, nbmin, nbmax);
1173 esum = calc_sum(nset, edat, nbmin, nbmax);
1176 if (!edat->bHaveSums)
1185 for (i = 0; (i < nset); i++)
1187 if (edat->s[i].bExactStat)
1200 fprintf(stdout, "All statistics are over %s points\n",
1201 gmx_step_str(edat->npoints, buf));
1203 else if (nexact == 0 || edat->npoints == edat->nframes)
1205 fprintf(stdout, "All statistics are over %d points (frames)\n",
1210 fprintf(stdout, "The term%s", nnotexact == 1 ? "" : "s");
1211 for (i = 0; (i < nset); i++)
1213 if (!edat->s[i].bExactStat)
1215 fprintf(stdout, " '%s'", leg[i]);
1218 fprintf(stdout, " %s has statistics over %d points (frames)\n",
1219 nnotexact == 1 ? "is" : "are", edat->nframes);
1220 fprintf(stdout, "All other statistics are over %s points\n",
1221 gmx_step_str(edat->npoints, buf));
1223 fprintf(stdout, "\n");
1225 fprintf(stdout, "%-24s %10s %10s %10s %10s",
1226 "Energy", "Average", "Err.Est.", "RMSD", "Tot-Drift");
1229 fprintf(stdout, " %10s\n", "-kT ln<e^(E/kT)>");
1233 fprintf(stdout, "\n");
1235 fprintf(stdout, "-------------------------------------------------------------------------------\n");
1237 /* Initiate locals, only used with -sum */
1241 beta = 1.0/(BOLTZ*reftemp);
1244 for (i = 0; (i < nset); i++)
1246 aver = edat->s[i].av;
1247 stddev = edat->s[i].rmsd;
1248 errest = edat->s[i].ee;
1253 for (j = 0; (j < edat->nframes); j++)
1255 expE += exp(beta*(edat->s[i].ener[j] - aver)/nmol);
1259 expEtot += expE/edat->nframes;
1262 fee[i] = log(expE/edat->nframes)/beta + aver/nmol;
1264 if (strstr(leg[i], "empera") != NULL)
1268 else if (strstr(leg[i], "olum") != NULL)
1272 else if (strstr(leg[i], "essure") != NULL)
1278 pr_aver = aver/nmol-ezero;
1279 pr_stddev = stddev/nmol;
1280 pr_errest = errest/nmol;
1289 /* Multiply the slope in steps with the number of steps taken */
1290 totaldrift = (edat->nsteps - 1)*edat->s[i].slope;
1296 fprintf(stdout, "%-24s %10g %10s %10g %10g",
1297 leg[i], pr_aver, ee_pr(pr_errest, eebuf), pr_stddev, totaldrift);
1300 fprintf(stdout, " %10g", fee[i]);
1303 fprintf(stdout, " (%s)\n", enm[set[i]].unit);
1307 for (j = 0; (j < edat->nframes); j++)
1309 edat->s[i].ener[j] -= aver;
1315 totaldrift = (edat->nsteps - 1)*esum->s[0].slope;
1316 fprintf(stdout, "%-24s %10g %10s %10s %10g (%s)",
1317 "Total", esum->s[0].av/nmol, ee_pr(esum->s[0].ee/nmol, eebuf),
1318 "--", totaldrift/nmol, enm[set[0]].unit);
1319 /* pr_aver,pr_stddev,a,totaldrift */
1322 fprintf(stdout, " %10g %10g\n",
1323 log(expEtot)/beta + esum->s[0].av/nmol, log(expEtot)/beta);
1327 fprintf(stdout, "\n");
1331 /* Do correlation function */
1332 if (edat->nframes > 1)
1334 Dt = delta_t/(edat->nframes - 1);
1342 const char* leg[] = { "Shear", "Bulk" };
1347 /* Assume pressure tensor is in Pxx Pxy Pxz Pyx Pyy Pyz Pzx Pzy Pzz */
1349 /* Symmetrise tensor! (and store in first three elements)
1350 * And subtract average pressure!
1353 for (i = 0; i < 12; i++)
1355 snew(eneset[i], edat->nframes);
1357 for (i = 0; (i < edat->nframes); i++)
1359 eneset[0][i] = 0.5*(edat->s[1].ener[i]+edat->s[3].ener[i]);
1360 eneset[1][i] = 0.5*(edat->s[2].ener[i]+edat->s[6].ener[i]);
1361 eneset[2][i] = 0.5*(edat->s[5].ener[i]+edat->s[7].ener[i]);
1362 for (j = 3; j <= 11; j++)
1364 eneset[j][i] = edat->s[j].ener[i];
1366 eneset[11][i] -= Pres;
1369 /* Determine integrals of the off-diagonal pressure elements */
1371 for (i = 0; i < 3; i++)
1373 snew(eneint[i], edat->nframes + 1);
1378 for (i = 0; i < edat->nframes; i++)
1380 eneint[0][i+1] = eneint[0][i] + 0.5*(edat->s[1].es[i].sum + edat->s[3].es[i].sum)*Dt/edat->points[i];
1381 eneint[1][i+1] = eneint[1][i] + 0.5*(edat->s[2].es[i].sum + edat->s[6].es[i].sum)*Dt/edat->points[i];
1382 eneint[2][i+1] = eneint[2][i] + 0.5*(edat->s[5].es[i].sum + edat->s[7].es[i].sum)*Dt/edat->points[i];
1385 einstein_visco("evisco.xvg", "eviscoi.xvg",
1386 3, edat->nframes+1, eneint, Vaver, Temp, Dt, oenv);
1388 for (i = 0; i < 3; i++)
1394 /*do_autocorr(corrfn,buf,nenergy,3,eneset,Dt,eacNormal,TRUE);*/
1395 /* Do it for shear viscosity */
1396 strcpy(buf, "Shear Viscosity");
1397 low_do_autocorr(corrfn, oenv, buf, edat->nframes, 3,
1398 (edat->nframes+1)/2, eneset, Dt,
1399 eacNormal, 1, TRUE, FALSE, FALSE, 0.0, 0.0, 0, 1);
1401 /* Now for bulk viscosity */
1402 strcpy(buf, "Bulk Viscosity");
1403 low_do_autocorr(corrfn, oenv, buf, edat->nframes, 1,
1404 (edat->nframes+1)/2, &(eneset[11]), Dt,
1405 eacNormal, 1, TRUE, FALSE, FALSE, 0.0, 0.0, 0, 1);
1407 factor = (Vaver*1e-26/(BOLTZMANN*Temp))*Dt;
1408 fp = xvgropen(visfn, buf, "Time (ps)", "\\8h\\4 (cp)", oenv);
1409 xvgr_legend(fp, asize(leg), leg, oenv);
1411 /* Use trapezium rule for integration */
1414 nout = get_acfnout();
1415 if ((nout < 2) || (nout >= edat->nframes/2))
1417 nout = edat->nframes/2;
1419 for (i = 1; (i < nout); i++)
1421 integral += 0.5*(eneset[0][i-1] + eneset[0][i])*factor;
1422 intBulk += 0.5*(eneset[11][i-1] + eneset[11][i])*factor;
1423 fprintf(fp, "%10g %10g %10g\n", (i*Dt), integral, intBulk);
1427 for (i = 0; i < 12; i++)
1437 strcpy(buf, "Autocorrelation of Energy Fluctuations");
1441 strcpy(buf, "Energy Autocorrelation");
1444 do_autocorr(corrfn, oenv, buf, edat->nframes,
1446 bSum ? &edat->s[nset-1].ener : eneset,
1447 (delta_t/edat->nframes), eacNormal, FALSE);
1453 static void print_time(FILE *fp, double t)
1455 fprintf(fp, "%12.6f", t);
1458 static void print1(FILE *fp, gmx_bool bDp, real e)
1462 fprintf(fp, " %16.12f", e);
1466 fprintf(fp, " %10.6f", e);
1470 static void fec(const char *ene2fn, const char *runavgfn,
1471 real reftemp, int nset, int set[], char *leg[],
1472 enerdata_t *edat, double time[],
1473 const output_env_t oenv)
1475 const char * ravgleg[] = {
1476 "\\8D\\4E = E\\sB\\N-E\\sA\\N",
1477 "<e\\S-\\8D\\4E/kT\\N>\\s0..t\\N"
1481 int nre, timecheck, step, nenergy, nenergy2, maxenergy;
1487 gmx_enxnm_t *enm = NULL;
1491 /* read second energy file */
1494 enx = open_enx(ene2fn, "r");
1495 do_enxnms(enx, &(fr->nre), &enm);
1497 snew(eneset2, nset+1);
1503 /* This loop searches for the first frame (when -b option is given),
1504 * or when this has been found it reads just one energy frame
1508 bCont = do_enx(enx, fr);
1512 timecheck = check_times(fr->t);
1516 while (bCont && (timecheck < 0));
1518 /* Store energies for analysis afterwards... */
1519 if ((timecheck == 0) && bCont)
1523 if (nenergy2 >= maxenergy)
1526 for (i = 0; i <= nset; i++)
1528 srenew(eneset2[i], maxenergy);
1531 if (fr->t != time[nenergy2])
1533 fprintf(stderr, "\nWARNING time mismatch %g!=%g at frame %s\n",
1534 fr->t, time[nenergy2], gmx_step_str(fr->step, buf));
1536 for (i = 0; i < nset; i++)
1538 eneset2[i][nenergy2] = fr->ener[set[i]].e;
1544 while (bCont && (timecheck == 0));
1547 if (edat->nframes != nenergy2)
1549 fprintf(stderr, "\nWARNING file length mismatch %d!=%d\n",
1550 edat->nframes, nenergy2);
1552 nenergy = min(edat->nframes, nenergy2);
1554 /* calculate fe difference dF = -kT ln < exp(-(E_B-E_A)/kT) >_A */
1558 fp = xvgropen(runavgfn, "Running average free energy difference",
1559 "Time (" unit_time ")", "\\8D\\4E (" unit_energy ")", oenv);
1560 xvgr_legend(fp, asize(ravgleg), ravgleg, oenv);
1562 fprintf(stdout, "\n%-24s %10s\n",
1563 "Energy", "dF = -kT ln < exp(-(EB-EA)/kT) >A");
1565 beta = 1.0/(BOLTZ*reftemp);
1566 for (i = 0; i < nset; i++)
1568 if (gmx_strcasecmp(leg[i], enm[set[i]].name) != 0)
1570 fprintf(stderr, "\nWARNING energy set name mismatch %s!=%s\n",
1571 leg[i], enm[set[i]].name);
1573 for (j = 0; j < nenergy; j++)
1575 dE = eneset2[i][j] - edat->s[i].ener[j];
1576 sum += exp(-dE*beta);
1579 fprintf(fp, "%10g %10g %10g\n",
1580 time[j], dE, -BOLTZ*reftemp*log(sum/(j+1)) );
1583 aver = -BOLTZ*reftemp*log(sum/nenergy);
1584 fprintf(stdout, "%-24s %10g\n", leg[i], aver);
1594 static void do_dhdl(t_enxframe *fr, t_inputrec *ir, FILE **fp_dhdl,
1595 const char *filename, gmx_bool bDp,
1596 int *blocks, int *hists, int *samples, int *nlambdas,
1597 const output_env_t oenv)
1599 const char *dhdl = "dH/d\\lambda", *deltag = "\\DeltaH", *lambda = "\\lambda";
1600 char title[STRLEN], label_x[STRLEN], label_y[STRLEN], legend[STRLEN];
1602 gmx_bool first = FALSE;
1603 int nblock_hist = 0, nblock_dh = 0, nblock_dhcoll = 0;
1606 double temp = 0, start_time = 0, delta_time = 0, start_lambda = 0, delta_lambda = 0;
1607 static int setnr = 0;
1608 double *native_lambda_vec = NULL;
1609 const char **lambda_components = NULL;
1610 int n_lambda_vec = 0;
1611 gmx_bool changing_lambda = FALSE;
1612 int lambda_fep_state;
1614 /* now count the blocks & handle the global dh data */
1615 for (i = 0; i < fr->nblock; i++)
1617 if (fr->block[i].id == enxDHHIST)
1621 else if (fr->block[i].id == enxDH)
1625 else if (fr->block[i].id == enxDHCOLL)
1628 if ( (fr->block[i].nsub < 1) ||
1629 (fr->block[i].sub[0].type != xdr_datatype_double) ||
1630 (fr->block[i].sub[0].nr < 5))
1632 gmx_fatal(FARGS, "Unexpected block data");
1635 /* read the data from the DHCOLL block */
1636 temp = fr->block[i].sub[0].dval[0];
1637 start_time = fr->block[i].sub[0].dval[1];
1638 delta_time = fr->block[i].sub[0].dval[2];
1639 start_lambda = fr->block[i].sub[0].dval[3];
1640 delta_lambda = fr->block[i].sub[0].dval[4];
1641 changing_lambda = (delta_lambda != 0);
1642 if (fr->block[i].nsub > 1)
1644 lambda_fep_state = fr->block[i].sub[1].ival[0];
1645 if (n_lambda_vec == 0)
1647 n_lambda_vec = fr->block[i].sub[1].ival[1];
1651 if (n_lambda_vec != fr->block[i].sub[1].ival[1])
1654 "Unexpected change of basis set in lambda");
1657 if (lambda_components == NULL)
1659 snew(lambda_components, n_lambda_vec);
1661 if (native_lambda_vec == NULL)
1663 snew(native_lambda_vec, n_lambda_vec);
1665 for (j = 0; j < n_lambda_vec; j++)
1667 native_lambda_vec[j] = fr->block[i].sub[0].dval[5+j];
1668 lambda_components[j] =
1669 efpt_singular_names[fr->block[i].sub[1].ival[2+j]];
1675 if (nblock_hist == 0 && nblock_dh == 0)
1677 /* don't do anything */
1680 if (nblock_hist > 0 && nblock_dh > 0)
1682 gmx_fatal(FARGS, "This energy file contains both histogram dhdl data and non-histogram dhdl data. Don't know what to do.");
1688 /* we have standard, non-histogram data --
1689 call open_dhdl to open the file */
1690 /* TODO this is an ugly hack that needs to be fixed: this will only
1691 work if the order of data is always the same and if we're
1692 only using the g_energy compiled with the mdrun that produced
1694 *fp_dhdl = open_dhdl(filename, ir, oenv);
1698 sprintf(title, "N(%s)", deltag);
1699 sprintf(label_x, "%s (%s)", deltag, unit_energy);
1700 sprintf(label_y, "Samples");
1701 *fp_dhdl = xvgropen_type(filename, title, label_x, label_y, exvggtXNY, oenv);
1702 sprintf(buf, "T = %g (K), %s = %g", temp, lambda, start_lambda);
1703 xvgr_subtitle(*fp_dhdl, buf, oenv);
1707 (*hists) += nblock_hist;
1708 (*blocks) += nblock_dh;
1709 (*nlambdas) = nblock_hist+nblock_dh;
1711 /* write the data */
1712 if (nblock_hist > 0)
1714 gmx_large_int_t sum = 0;
1716 for (i = 0; i < fr->nblock; i++)
1718 t_enxblock *blk = &(fr->block[i]);
1719 if (blk->id == enxDHHIST)
1721 double foreign_lambda, dx;
1723 int nhist, derivative;
1725 /* check the block types etc. */
1726 if ( (blk->nsub < 2) ||
1727 (blk->sub[0].type != xdr_datatype_double) ||
1728 (blk->sub[1].type != xdr_datatype_large_int) ||
1729 (blk->sub[0].nr < 2) ||
1730 (blk->sub[1].nr < 2) )
1732 gmx_fatal(FARGS, "Unexpected block data in file");
1734 foreign_lambda = blk->sub[0].dval[0];
1735 dx = blk->sub[0].dval[1];
1736 nhist = blk->sub[1].lval[0];
1737 derivative = blk->sub[1].lval[1];
1738 for (j = 0; j < nhist; j++)
1741 x0 = blk->sub[1].lval[2+j];
1745 sprintf(legend, "N(%s(%s=%g) | %s=%g)",
1746 deltag, lambda, foreign_lambda,
1747 lambda, start_lambda);
1751 sprintf(legend, "N(%s | %s=%g)",
1752 dhdl, lambda, start_lambda);
1756 xvgr_new_dataset(*fp_dhdl, setnr, 1, lg, oenv);
1758 for (k = 0; k < blk->sub[j+2].nr; k++)
1763 hist = blk->sub[j+2].ival[k];
1766 fprintf(*fp_dhdl, "%g %d\n%g %d\n", xmin, hist,
1770 /* multiple histogram data blocks in one histogram
1771 mean that the second one is the reverse of the first one:
1772 for dhdl derivatives, it's important to know both the
1773 maximum and minimum values */
1778 (*samples) += (int)(sum/nblock_hist);
1784 char **setnames = NULL;
1785 int nnames = nblock_dh;
1787 for (i = 0; i < fr->nblock; i++)
1789 t_enxblock *blk = &(fr->block[i]);
1790 if (blk->id == enxDH)
1794 len = blk->sub[2].nr;
1798 if (len != blk->sub[2].nr)
1800 gmx_fatal(FARGS, "Length inconsistency in dhdl data");
1807 for (i = 0; i < len; i++)
1809 double time = start_time + delta_time*i;
1811 fprintf(*fp_dhdl, "%.4f ", time);
1813 for (j = 0; j < fr->nblock; j++)
1815 t_enxblock *blk = &(fr->block[j]);
1816 if (blk->id == enxDH)
1819 if (blk->sub[2].type == xdr_datatype_float)
1821 value = blk->sub[2].fval[i];
1825 value = blk->sub[2].dval[i];
1827 /* we need to decide which data type it is based on the count*/
1829 if (j == 1 && ir->bExpanded)
1831 fprintf(*fp_dhdl, "%4d", (int)value); /* if expanded ensembles and zero, this is a state value, it's an integer. We need a cleaner conditional than if j==1! */
1837 fprintf(*fp_dhdl, " %#.12g", value); /* print normal precision */
1841 fprintf(*fp_dhdl, " %#.8g", value); /* print normal precision */
1846 fprintf(*fp_dhdl, "\n");
1852 int gmx_energy(int argc, char *argv[])
1854 const char *desc[] = {
1856 "[TT]g_energy[tt] extracts energy components or distance restraint",
1857 "data from an energy file. The user is prompted to interactively",
1858 "select the desired energy terms.[PAR]",
1860 "Average, RMSD, and drift are calculated with full precision from the",
1861 "simulation (see printed manual). Drift is calculated by performing",
1862 "a least-squares fit of the data to a straight line. The reported total drift",
1863 "is the difference of the fit at the first and last point.",
1864 "An error estimate of the average is given based on a block averages",
1865 "over 5 blocks using the full-precision averages. The error estimate",
1866 "can be performed over multiple block lengths with the options",
1867 "[TT]-nbmin[tt] and [TT]-nbmax[tt].",
1868 "[BB]Note[bb] that in most cases the energy files contains averages over all",
1869 "MD steps, or over many more points than the number of frames in",
1870 "energy file. This makes the [TT]g_energy[tt] statistics output more accurate",
1871 "than the [TT].xvg[tt] output. When exact averages are not present in the energy",
1872 "file, the statistics mentioned above are simply over the single, per-frame",
1873 "energy values.[PAR]",
1875 "The term fluctuation gives the RMSD around the least-squares fit.[PAR]",
1877 "Some fluctuation-dependent properties can be calculated provided",
1878 "the correct energy terms are selected, and that the command line option",
1879 "[TT]-fluct_props[tt] is given. The following properties",
1880 "will be computed:[BR]",
1881 "Property Energy terms needed[BR]",
1882 "---------------------------------------------------[BR]",
1883 "Heat capacity C[SUB]p[sub] (NPT sims): Enthalpy, Temp [BR]",
1884 "Heat capacity C[SUB]v[sub] (NVT sims): Etot, Temp [BR]",
1885 "Thermal expansion coeff. (NPT): Enthalpy, Vol, Temp[BR]",
1886 "Isothermal compressibility: Vol, Temp [BR]",
1887 "Adiabatic bulk modulus: Vol, Temp [BR]",
1888 "---------------------------------------------------[BR]",
1889 "You always need to set the number of molecules [TT]-nmol[tt].",
1890 "The C[SUB]p[sub]/C[SUB]v[sub] computations do [BB]not[bb] include any corrections",
1891 "for quantum effects. Use the [TT]g_dos[tt] program if you need that (and you do).[PAR]"
1892 "When the [TT]-viol[tt] option is set, the time averaged",
1893 "violations are plotted and the running time-averaged and",
1894 "instantaneous sum of violations are recalculated. Additionally",
1895 "running time-averaged and instantaneous distances between",
1896 "selected pairs can be plotted with the [TT]-pairs[tt] option.[PAR]",
1898 "Options [TT]-ora[tt], [TT]-ort[tt], [TT]-oda[tt], [TT]-odr[tt] and",
1899 "[TT]-odt[tt] are used for analyzing orientation restraint data.",
1900 "The first two options plot the orientation, the last three the",
1901 "deviations of the orientations from the experimental values.",
1902 "The options that end on an 'a' plot the average over time",
1903 "as a function of restraint. The options that end on a 't'",
1904 "prompt the user for restraint label numbers and plot the data",
1905 "as a function of time. Option [TT]-odr[tt] plots the RMS",
1906 "deviation as a function of restraint.",
1907 "When the run used time or ensemble averaged orientation restraints,",
1908 "option [TT]-orinst[tt] can be used to analyse the instantaneous,",
1909 "not ensemble-averaged orientations and deviations instead of",
1910 "the time and ensemble averages.[PAR]",
1912 "Option [TT]-oten[tt] plots the eigenvalues of the molecular order",
1913 "tensor for each orientation restraint experiment. With option",
1914 "[TT]-ovec[tt] also the eigenvectors are plotted.[PAR]",
1916 "Option [TT]-odh[tt] extracts and plots the free energy data",
1917 "(Hamiltoian differences and/or the Hamiltonian derivative dhdl)",
1918 "from the [TT]ener.edr[tt] file.[PAR]",
1920 "With [TT]-fee[tt] an estimate is calculated for the free-energy",
1921 "difference with an ideal gas state: [BR]",
1922 " [GRK]Delta[grk] A = A(N,V,T) - A[SUB]idealgas[sub](N,V,T) = kT [LN][CHEVRON][EXP]U[SUB]pot[sub]/kT[exp][chevron][ln][BR]",
1923 " [GRK]Delta[grk] G = G(N,p,T) - G[SUB]idealgas[sub](N,p,T) = kT [LN][CHEVRON][EXP]U[SUB]pot[sub]/kT[exp][chevron][ln][BR]",
1924 "where k is Boltzmann's constant, T is set by [TT]-fetemp[tt] and",
1925 "the average is over the ensemble (or time in a trajectory).",
1926 "Note that this is in principle",
1927 "only correct when averaging over the whole (Boltzmann) ensemble",
1928 "and using the potential energy. This also allows for an entropy",
1929 "estimate using:[BR]",
1930 " [GRK]Delta[grk] S(N,V,T) = S(N,V,T) - S[SUB]idealgas[sub](N,V,T) = ([CHEVRON]U[SUB]pot[sub][chevron] - [GRK]Delta[grk] A)/T[BR]",
1931 " [GRK]Delta[grk] S(N,p,T) = S(N,p,T) - S[SUB]idealgas[sub](N,p,T) = ([CHEVRON]U[SUB]pot[sub][chevron] + pV - [GRK]Delta[grk] G)/T",
1934 "When a second energy file is specified ([TT]-f2[tt]), a free energy",
1935 "difference is calculated [BR] dF = -kT [LN][CHEVRON][EXP]-(E[SUB]B[sub]-E[SUB]A[sub])/kT[exp][chevron][SUB]A[sub][ln] ,",
1936 "where E[SUB]A[sub] and E[SUB]B[sub] are the energies from the first and second energy",
1937 "files, and the average is over the ensemble A. The running average",
1938 "of the free energy difference is printed to a file specified by [TT]-ravg[tt].",
1939 "[BB]Note[bb] that the energies must both be calculated from the same trajectory."
1942 static gmx_bool bSum = FALSE, bFee = FALSE, bPrAll = FALSE, bFluct = FALSE, bDriftCorr = FALSE;
1943 static gmx_bool bDp = FALSE, bMutot = FALSE, bOrinst = FALSE, bOvec = FALSE, bFluctProps = FALSE;
1944 static int skip = 0, nmol = 1, nbmin = 5, nbmax = 5;
1945 static real reftemp = 300.0, ezero = 0;
1947 { "-fee", FALSE, etBOOL, {&bFee},
1948 "Do a free energy estimate" },
1949 { "-fetemp", FALSE, etREAL, {&reftemp},
1950 "Reference temperature for free energy calculation" },
1951 { "-zero", FALSE, etREAL, {&ezero},
1952 "Subtract a zero-point energy" },
1953 { "-sum", FALSE, etBOOL, {&bSum},
1954 "Sum the energy terms selected rather than display them all" },
1955 { "-dp", FALSE, etBOOL, {&bDp},
1956 "Print energies in high precision" },
1957 { "-nbmin", FALSE, etINT, {&nbmin},
1958 "Minimum number of blocks for error estimate" },
1959 { "-nbmax", FALSE, etINT, {&nbmax},
1960 "Maximum number of blocks for error estimate" },
1961 { "-mutot", FALSE, etBOOL, {&bMutot},
1962 "Compute the total dipole moment from the components" },
1963 { "-skip", FALSE, etINT, {&skip},
1964 "Skip number of frames between data points" },
1965 { "-aver", FALSE, etBOOL, {&bPrAll},
1966 "Also print the exact average and rmsd stored in the energy frames (only when 1 term is requested)" },
1967 { "-nmol", FALSE, etINT, {&nmol},
1968 "Number of molecules in your sample: the energies are divided by this number" },
1969 { "-fluct_props", FALSE, etBOOL, {&bFluctProps},
1970 "Compute properties based on energy fluctuations, like heat capacity" },
1971 { "-driftcorr", FALSE, etBOOL, {&bDriftCorr},
1972 "Useful only for calculations of fluctuation properties. The drift in the observables will be subtracted before computing the fluctuation properties."},
1973 { "-fluc", FALSE, etBOOL, {&bFluct},
1974 "Calculate autocorrelation of energy fluctuations rather than energy itself" },
1975 { "-orinst", FALSE, etBOOL, {&bOrinst},
1976 "Analyse instantaneous orientation data" },
1977 { "-ovec", FALSE, etBOOL, {&bOvec},
1978 "Also plot the eigenvectors with [TT]-oten[tt]" }
1980 const char * drleg[] = {
1984 static const char *setnm[] = {
1985 "Pres-XX", "Pres-XY", "Pres-XZ", "Pres-YX", "Pres-YY",
1986 "Pres-YZ", "Pres-ZX", "Pres-ZY", "Pres-ZZ", "Temperature",
1987 "Volume", "Pressure"
1990 FILE *out = NULL, *fp_pairs = NULL, *fort = NULL, *fodt = NULL, *foten = NULL;
1991 FILE *fp_dhdl = NULL;
1996 gmx_localtop_t *top = NULL;
2000 gmx_enxnm_t *enm = NULL;
2001 t_enxframe *frame, *fr = NULL;
2003 #define NEXT (1-cur)
2004 int nre, teller, teller_disre, nfr;
2005 gmx_large_int_t start_step;
2006 int nor = 0, nex = 0, norfr = 0, enx_i = 0;
2008 real *bounds = NULL, *violaver = NULL, *oobs = NULL, *orient = NULL, *odrms = NULL;
2009 int *index = NULL, *pair = NULL, norsel = 0, *orsel = NULL, *or_label = NULL;
2010 int nbounds = 0, npairs;
2011 gmx_bool bDisRe, bDRAll, bORA, bORT, bODA, bODR, bODT, bORIRE, bOTEN, bDHDL;
2012 gmx_bool bFoundStart, bCont, bEDR, bVisco;
2013 double sum, sumaver, sumt, ener, dbl;
2014 double *time = NULL;
2016 int *set = NULL, i, j, k, nset, sss;
2017 gmx_bool *bIsEner = NULL;
2018 char **pairleg, **odtleg, **otenleg;
2021 char *anm_j, *anm_k, *resnm_j, *resnm_k;
2022 int resnr_j, resnr_k;
2023 const char *orinst_sub = "@ subtitle \"instantaneous\"\n";
2026 t_enxblock *blk = NULL;
2027 t_enxblock *blk_disre = NULL;
2029 int dh_blocks = 0, dh_hists = 0, dh_samples = 0, dh_lambdas = 0;
2032 { efEDR, "-f", NULL, ffREAD },
2033 { efEDR, "-f2", NULL, ffOPTRD },
2034 { efTPX, "-s", NULL, ffOPTRD },
2035 { efXVG, "-o", "energy", ffWRITE },
2036 { efXVG, "-viol", "violaver", ffOPTWR },
2037 { efXVG, "-pairs", "pairs", ffOPTWR },
2038 { efXVG, "-ora", "orienta", ffOPTWR },
2039 { efXVG, "-ort", "orientt", ffOPTWR },
2040 { efXVG, "-oda", "orideva", ffOPTWR },
2041 { efXVG, "-odr", "oridevr", ffOPTWR },
2042 { efXVG, "-odt", "oridevt", ffOPTWR },
2043 { efXVG, "-oten", "oriten", ffOPTWR },
2044 { efXVG, "-corr", "enecorr", ffOPTWR },
2045 { efXVG, "-vis", "visco", ffOPTWR },
2046 { efXVG, "-ravg", "runavgdf", ffOPTWR },
2047 { efXVG, "-odh", "dhdl", ffOPTWR }
2049 #define NFILE asize(fnm)
2053 CopyRight(stderr, argv[0]);
2055 ppa = add_acf_pargs(&npargs, pa);
2056 parse_common_args(&argc, argv,
2057 PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END | PCA_BE_NICE,
2058 NFILE, fnm, npargs, ppa, asize(desc), desc, 0, NULL, &oenv);
2060 bDRAll = opt2bSet("-pairs", NFILE, fnm);
2061 bDisRe = opt2bSet("-viol", NFILE, fnm) || bDRAll;
2062 bORA = opt2bSet("-ora", NFILE, fnm);
2063 bORT = opt2bSet("-ort", NFILE, fnm);
2064 bODA = opt2bSet("-oda", NFILE, fnm);
2065 bODR = opt2bSet("-odr", NFILE, fnm);
2066 bODT = opt2bSet("-odt", NFILE, fnm);
2067 bORIRE = bORA || bORT || bODA || bODR || bODT;
2068 bOTEN = opt2bSet("-oten", NFILE, fnm);
2069 bDHDL = opt2bSet("-odh", NFILE, fnm);
2074 fp = open_enx(ftp2fn(efEDR, NFILE, fnm), "r");
2075 do_enxnms(fp, &nre, &enm);
2079 bVisco = opt2bSet("-vis", NFILE, fnm);
2081 if ((!bDisRe) && (!bDHDL))
2085 nset = asize(setnm);
2087 /* This is nasty code... To extract Pres tensor, Volume and Temperature */
2088 for (j = 0; j < nset; j++)
2090 for (i = 0; i < nre; i++)
2092 if (strstr(enm[i].name, setnm[j]))
2100 if (gmx_strcasecmp(setnm[j], "Volume") == 0)
2102 printf("Enter the box volume (" unit_volume "): ");
2103 if (1 != scanf("%lf", &dbl))
2105 gmx_fatal(FARGS, "Error reading user input");
2111 gmx_fatal(FARGS, "Could not find term %s for viscosity calculation",
2119 set = select_by_name(nre, enm, &nset);
2121 /* Print all the different units once */
2122 sprintf(buf, "(%s)", enm[set[0]].unit);
2123 for (i = 1; i < nset; i++)
2125 for (j = 0; j < i; j++)
2127 if (strcmp(enm[set[i]].unit, enm[set[j]].unit) == 0)
2135 strcat(buf, enm[set[i]].unit);
2139 out = xvgropen(opt2fn("-o", NFILE, fnm), "Gromacs Energies", "Time (ps)", buf,
2143 for (i = 0; (i < nset); i++)
2145 leg[i] = enm[set[i]].name;
2149 leg[nset] = strdup("Sum");
2150 xvgr_legend(out, nset+1, (const char**)leg, oenv);
2154 xvgr_legend(out, nset, (const char**)leg, oenv);
2157 snew(bIsEner, nset);
2158 for (i = 0; (i < nset); i++)
2161 for (j = 0; (j <= F_ETOT); j++)
2163 bIsEner[i] = bIsEner[i] ||
2164 (gmx_strcasecmp(interaction_function[j].longname, leg[i]) == 0);
2168 if (bPrAll && nset > 1)
2170 gmx_fatal(FARGS, "Printing averages can only be done when a single set is selected");
2175 if (bORIRE || bOTEN)
2177 get_orires_parms(ftp2fn(efTPX, NFILE, fnm), &nor, &nex, &or_label, &oobs);
2201 fprintf(stderr, "Select the orientation restraint labels you want (-1 is all)\n");
2202 fprintf(stderr, "End your selection with 0\n");
2209 if (1 != scanf("%d", &(orsel[j])))
2211 gmx_fatal(FARGS, "Error reading user input");
2214 while (orsel[j] > 0);
2217 fprintf(stderr, "Selecting all %d orientation restraints\n", nor);
2220 for (i = 0; i < nor; i++)
2227 /* Build the selection */
2229 for (i = 0; i < j; i++)
2231 for (k = 0; k < nor; k++)
2233 if (or_label[k] == orsel[i])
2242 fprintf(stderr, "Orientation restraint label %d not found\n",
2247 snew(odtleg, norsel);
2248 for (i = 0; i < norsel; i++)
2250 snew(odtleg[i], 256);
2251 sprintf(odtleg[i], "%d", or_label[orsel[i]]);
2255 fort = xvgropen(opt2fn("-ort", NFILE, fnm), "Calculated orientations",
2256 "Time (ps)", "", oenv);
2257 if (bOrinst && output_env_get_print_xvgr_codes(oenv))
2259 fprintf(fort, "%s", orinst_sub);
2261 xvgr_legend(fort, norsel, (const char**)odtleg, oenv);
2265 fodt = xvgropen(opt2fn("-odt", NFILE, fnm),
2266 "Orientation restraint deviation",
2267 "Time (ps)", "", oenv);
2268 if (bOrinst && output_env_get_print_xvgr_codes(oenv))
2270 fprintf(fodt, "%s", orinst_sub);
2272 xvgr_legend(fodt, norsel, (const char**)odtleg, oenv);
2278 foten = xvgropen(opt2fn("-oten", NFILE, fnm),
2279 "Order tensor", "Time (ps)", "", oenv);
2280 snew(otenleg, bOvec ? nex*12 : nex*3);
2281 for (i = 0; i < nex; i++)
2283 for (j = 0; j < 3; j++)
2285 sprintf(buf, "eig%d", j+1);
2286 otenleg[(bOvec ? 12 : 3)*i+j] = strdup(buf);
2290 for (j = 0; j < 9; j++)
2292 sprintf(buf, "vec%d%s", j/3+1, j%3 == 0 ? "x" : (j%3 == 1 ? "y" : "z"));
2293 otenleg[12*i+3+j] = strdup(buf);
2297 xvgr_legend(foten, bOvec ? nex*12 : nex*3, (const char**)otenleg, oenv);
2302 nbounds = get_bounds(ftp2fn(efTPX, NFILE, fnm), &bounds, &index, &pair, &npairs,
2304 snew(violaver, npairs);
2305 out = xvgropen(opt2fn("-o", NFILE, fnm), "Sum of Violations",
2306 "Time (ps)", "nm", oenv);
2307 xvgr_legend(out, 2, drleg, oenv);
2310 fp_pairs = xvgropen(opt2fn("-pairs", NFILE, fnm), "Pair Distances",
2311 "Time (ps)", "Distance (nm)", oenv);
2312 if (output_env_get_print_xvgr_codes(oenv))
2314 fprintf(fp_pairs, "@ subtitle \"averaged (tau=%g) and instantaneous\"\n",
2321 get_dhdl_parms(ftp2fn(efTPX, NFILE, fnm), &ir);
2324 /* Initiate energies and set them to zero */
2331 edat.bHaveSums = TRUE;
2334 /* Initiate counters */
2337 bFoundStart = FALSE;
2342 /* This loop searches for the first frame (when -b option is given),
2343 * or when this has been found it reads just one energy frame
2347 bCont = do_enx(fp, &(frame[NEXT]));
2350 timecheck = check_times(frame[NEXT].t);
2353 while (bCont && (timecheck < 0));
2355 if ((timecheck == 0) && bCont)
2357 /* We read a valid frame, so we can use it */
2358 fr = &(frame[NEXT]);
2362 /* The frame contains energies, so update cur */
2365 if (edat.nframes % 1000 == 0)
2367 srenew(edat.step, edat.nframes+1000);
2368 memset(&(edat.step[edat.nframes]), 0, 1000*sizeof(edat.step[0]));
2369 srenew(edat.steps, edat.nframes+1000);
2370 memset(&(edat.steps[edat.nframes]), 0, 1000*sizeof(edat.steps[0]));
2371 srenew(edat.points, edat.nframes+1000);
2372 memset(&(edat.points[edat.nframes]), 0, 1000*sizeof(edat.points[0]));
2374 for (i = 0; i < nset; i++)
2376 srenew(edat.s[i].ener, edat.nframes+1000);
2377 memset(&(edat.s[i].ener[edat.nframes]), 0,
2378 1000*sizeof(edat.s[i].ener[0]));
2379 srenew(edat.s[i].es, edat.nframes+1000);
2380 memset(&(edat.s[i].es[edat.nframes]), 0,
2381 1000*sizeof(edat.s[i].es[0]));
2386 edat.step[nfr] = fr->step;
2391 /* Initiate the previous step data */
2392 start_step = fr->step;
2394 /* Initiate the energy sums */
2395 edat.steps[nfr] = 1;
2396 edat.points[nfr] = 1;
2397 for (i = 0; i < nset; i++)
2400 edat.s[i].es[nfr].sum = fr->ener[sss].e;
2401 edat.s[i].es[nfr].sum2 = 0;
2408 edat.steps[nfr] = fr->nsteps;
2412 /* mdrun only calculated the energy at energy output
2413 * steps. We don't need to check step intervals.
2415 edat.points[nfr] = 1;
2416 for (i = 0; i < nset; i++)
2419 edat.s[i].es[nfr].sum = fr->ener[sss].e;
2420 edat.s[i].es[nfr].sum2 = 0;
2423 edat.bHaveSums = FALSE;
2425 else if (fr->step - start_step + 1 == edat.nsteps + fr->nsteps)
2427 /* We have statistics to the previous frame */
2428 edat.points[nfr] = fr->nsum;
2429 for (i = 0; i < nset; i++)
2432 edat.s[i].es[nfr].sum = fr->ener[sss].esum;
2433 edat.s[i].es[nfr].sum2 = fr->ener[sss].eav;
2435 edat.npoints += fr->nsum;
2439 /* The interval does not match fr->nsteps:
2440 * can not do exact averages.
2442 edat.bHaveSums = FALSE;
2445 edat.nsteps = fr->step - start_step + 1;
2447 for (i = 0; i < nset; i++)
2449 edat.s[i].ener[nfr] = fr->ener[set[i]].e;
2453 * Define distance restraint legends. Can only be done after
2454 * the first frame has been read... (Then we know how many there are)
2456 blk_disre = find_block_id_enxframe(fr, enxDISRE, NULL);
2457 if (bDisRe && bDRAll && !leg && blk_disre)
2462 fa = top->idef.il[F_DISRES].iatoms;
2463 ip = top->idef.iparams;
2464 if (blk_disre->nsub != 2 ||
2465 (blk_disre->sub[0].nr != blk_disre->sub[1].nr) )
2467 gmx_incons("Number of disre sub-blocks not equal to 2");
2470 ndisre = blk_disre->sub[0].nr;
2471 if (ndisre != top->idef.il[F_DISRES].nr/3)
2473 gmx_fatal(FARGS, "Number of disre pairs in the energy file (%d) does not match the number in the run input file (%d)\n",
2474 ndisre, top->idef.il[F_DISRES].nr/3);
2476 snew(pairleg, ndisre);
2477 for (i = 0; i < ndisre; i++)
2479 snew(pairleg[i], 30);
2482 gmx_mtop_atominfo_global(&mtop, j, &anm_j, &resnr_j, &resnm_j);
2483 gmx_mtop_atominfo_global(&mtop, k, &anm_k, &resnr_k, &resnm_k);
2484 sprintf(pairleg[i], "%d %s %d %s (%d)",
2485 resnr_j, anm_j, resnr_k, anm_k,
2486 ip[fa[3*i]].disres.label);
2488 set = select_it(ndisre, pairleg, &nset);
2490 for (i = 0; (i < nset); i++)
2493 sprintf(leg[2*i], "a %s", pairleg[set[i]]);
2494 snew(leg[2*i+1], 32);
2495 sprintf(leg[2*i+1], "i %s", pairleg[set[i]]);
2497 xvgr_legend(fp_pairs, 2*nset, (const char**)leg, oenv);
2501 * Store energies for analysis afterwards...
2503 if (!bDisRe && !bDHDL && (fr->nre > 0))
2505 if (edat.nframes % 1000 == 0)
2507 srenew(time, edat.nframes+1000);
2509 time[edat.nframes] = fr->t;
2513 * Printing time, only when we do not want to skip frames
2515 if (!skip || teller % skip == 0)
2519 /*******************************************
2520 * D I S T A N C E R E S T R A I N T S
2521 *******************************************/
2525 float *disre_rt = blk_disre->sub[0].fval;
2526 float *disre_rm3tav = blk_disre->sub[1].fval;
2528 double *disre_rt = blk_disre->sub[0].dval;
2529 double *disre_rm3tav = blk_disre->sub[1].dval;
2532 print_time(out, fr->t);
2533 if (violaver == NULL)
2535 snew(violaver, ndisre);
2538 /* Subtract bounds from distances, to calculate violations */
2539 calc_violations(disre_rt, disre_rm3tav,
2540 nbounds, pair, bounds, violaver, &sumt, &sumaver);
2542 fprintf(out, " %8.4f %8.4f\n", sumaver, sumt);
2545 print_time(fp_pairs, fr->t);
2546 for (i = 0; (i < nset); i++)
2549 fprintf(fp_pairs, " %8.4f", mypow(disre_rm3tav[sss], minthird));
2550 fprintf(fp_pairs, " %8.4f", disre_rt[sss]);
2552 fprintf(fp_pairs, "\n");
2559 do_dhdl(fr, &ir, &fp_dhdl, opt2fn("-odh", NFILE, fnm), bDp, &dh_blocks, &dh_hists, &dh_samples, &dh_lambdas, oenv);
2562 /*******************************************
2564 *******************************************/
2571 /* We skip frames with single points (usually only the first frame),
2572 * since they would result in an average plot with outliers.
2576 print_time(out, fr->t);
2577 print1(out, bDp, fr->ener[set[0]].e);
2578 print1(out, bDp, fr->ener[set[0]].esum/fr->nsum);
2579 print1(out, bDp, sqrt(fr->ener[set[0]].eav/fr->nsum));
2585 print_time(out, fr->t);
2589 for (i = 0; i < nset; i++)
2591 sum += fr->ener[set[i]].e;
2593 print1(out, bDp, sum/nmol-ezero);
2597 for (i = 0; (i < nset); i++)
2601 print1(out, bDp, (fr->ener[set[i]].e)/nmol-ezero);
2605 print1(out, bDp, fr->ener[set[i]].e);
2612 blk = find_block_id_enxframe(fr, enx_i, NULL);
2616 xdr_datatype dt = xdr_datatype_float;
2618 xdr_datatype dt = xdr_datatype_double;
2622 if ( (blk->nsub != 1) || (blk->sub[0].type != dt) )
2624 gmx_fatal(FARGS, "Orientational restraints read in incorrectly");
2627 vals = blk->sub[0].fval;
2629 vals = blk->sub[0].dval;
2632 if (blk->sub[0].nr != (size_t)nor)
2634 gmx_fatal(FARGS, "Number of orientation restraints in energy file (%d) does not match with the topology (%d)", blk->sub[0].nr);
2638 for (i = 0; i < nor; i++)
2640 orient[i] += vals[i];
2645 for (i = 0; i < nor; i++)
2647 odrms[i] += sqr(vals[i]-oobs[i]);
2652 fprintf(fort, " %10f", fr->t);
2653 for (i = 0; i < norsel; i++)
2655 fprintf(fort, " %g", vals[orsel[i]]);
2657 fprintf(fort, "\n");
2661 fprintf(fodt, " %10f", fr->t);
2662 for (i = 0; i < norsel; i++)
2664 fprintf(fodt, " %g", vals[orsel[i]]-oobs[orsel[i]]);
2666 fprintf(fodt, "\n");
2670 blk = find_block_id_enxframe(fr, enxORT, NULL);
2674 xdr_datatype dt = xdr_datatype_float;
2676 xdr_datatype dt = xdr_datatype_double;
2680 if ( (blk->nsub != 1) || (blk->sub[0].type != dt) )
2682 gmx_fatal(FARGS, "Orientational restraints read in incorrectly");
2685 vals = blk->sub[0].fval;
2687 vals = blk->sub[0].dval;
2690 if (blk->sub[0].nr != (size_t)(nex*12))
2692 gmx_fatal(FARGS, "Number of orientation experiments in energy file (%g) does not match with the topology (%d)",
2693 blk->sub[0].nr/12, nex);
2695 fprintf(foten, " %10f", fr->t);
2696 for (i = 0; i < nex; i++)
2698 for (j = 0; j < (bOvec ? 12 : 3); j++)
2700 fprintf(foten, " %g", vals[i*12+j]);
2703 fprintf(foten, "\n");
2710 while (bCont && (timecheck == 0));
2712 fprintf(stderr, "\n");
2734 out = xvgropen(opt2fn("-ora", NFILE, fnm),
2735 "Average calculated orientations",
2736 "Restraint label", "", oenv);
2737 if (bOrinst && output_env_get_print_xvgr_codes(oenv))
2739 fprintf(out, "%s", orinst_sub);
2741 for (i = 0; i < nor; i++)
2743 fprintf(out, "%5d %g\n", or_label[i], orient[i]/norfr);
2749 out = xvgropen(opt2fn("-oda", NFILE, fnm),
2750 "Average restraint deviation",
2751 "Restraint label", "", oenv);
2752 if (bOrinst && output_env_get_print_xvgr_codes(oenv))
2754 fprintf(out, "%s", orinst_sub);
2756 for (i = 0; i < nor; i++)
2758 fprintf(out, "%5d %g\n", or_label[i], orient[i]/norfr-oobs[i]);
2764 out = xvgropen(opt2fn("-odr", NFILE, fnm),
2765 "RMS orientation restraint deviations",
2766 "Restraint label", "", oenv);
2767 if (bOrinst && output_env_get_print_xvgr_codes(oenv))
2769 fprintf(out, "%s", orinst_sub);
2771 for (i = 0; i < nor; i++)
2773 fprintf(out, "%5d %g\n", or_label[i], sqrt(odrms[i]/norfr));
2784 analyse_disre(opt2fn("-viol", NFILE, fnm),
2785 teller_disre, violaver, bounds, index, pair, nbounds, oenv);
2792 printf("\n\nWrote %d lambda values with %d samples as ",
2793 dh_lambdas, dh_samples);
2796 printf("%d dH histograms ", dh_hists);
2800 printf("%d dH data blocks ", dh_blocks);
2802 printf("to %s\n", opt2fn("-odh", NFILE, fnm));
2807 gmx_fatal(FARGS, "No dH data in %s\n", opt2fn("-f", NFILE, fnm));
2813 double dt = (frame[cur].t-start_t)/(edat.nframes-1);
2814 analyse_ener(opt2bSet("-corr", NFILE, fnm), opt2fn("-corr", NFILE, fnm),
2815 bFee, bSum, bFluct, opt2parg_bSet("-nmol", npargs, ppa),
2816 bVisco, opt2fn("-vis", NFILE, fnm),
2818 start_step, start_t, frame[cur].step, frame[cur].t,
2819 time, reftemp, &edat,
2820 nset, set, bIsEner, leg, enm, Vaver, ezero, nbmin, nbmax,
2824 calc_fluctuation_props(stdout, bDriftCorr, dt, nset, set, nmol, leg, &edat,
2828 if (opt2bSet("-f2", NFILE, fnm))
2830 fec(opt2fn("-f2", NFILE, fnm), opt2fn("-ravg", NFILE, fnm),
2831 reftemp, nset, set, leg, &edat, time, oenv);
2835 const char *nxy = "-nxy";
2837 do_view(oenv, opt2fn("-o", NFILE, fnm), nxy);
2838 do_view(oenv, opt2fn_null("-ravg", NFILE, fnm), nxy);
2839 do_view(oenv, opt2fn_null("-ora", NFILE, fnm), nxy);
2840 do_view(oenv, opt2fn_null("-ort", NFILE, fnm), nxy);
2841 do_view(oenv, opt2fn_null("-oda", NFILE, fnm), nxy);
2842 do_view(oenv, opt2fn_null("-odr", NFILE, fnm), nxy);
2843 do_view(oenv, opt2fn_null("-odt", NFILE, fnm), nxy);
2844 do_view(oenv, opt2fn_null("-oten", NFILE, fnm), nxy);
2845 do_view(oenv, opt2fn_null("-odh", NFILE, fnm), nxy);