3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * Green Red Orange Magenta Azure Cyan Skyblue
40 #include "gromacs/commandline/pargs.h"
45 #include "gmx_fatal.h"
47 #include "gromacs/fileio/futil.h"
53 #include "gromacs/fileio/pdbio.h"
54 #include "gromacs/fileio/matio.h"
58 static int index2(int *ibox, int x, int y)
63 static int index3(int *ibox, int x, int y, int z)
65 return (ibox[2]*(ibox[1]*x+y)+z);
68 static gmx_int64_t indexn(int ndim, const int *ibox, const int *nxyz)
73 /* Compute index in 1-D array */
75 for (k = 0; (k < ndim); k++)
78 for (kk = k+1; (kk < ndim); kk++)
88 int Nx; /* x grid points in unit cell */
89 int Ny; /* y grid points in unit cell */
90 int Nz; /* z grid points in unit cell */
91 int dmin[3]; /* starting point x,y,z*/
92 int dmax[3]; /* ending point x,y,z */
93 real cell[6]; /* usual cell parameters */
97 static void lo_write_xplor(XplorMap * map, const char * file)
102 fp = ffopen(file, "w");
103 /* The REMARKS part is the worst part of the XPLOR format
104 * and may cause problems with some programs
106 fprintf(fp, "\n 2 !NTITLE\n");
107 fprintf(fp, " REMARKS Energy Landscape from GROMACS\n");
108 fprintf(fp, " REMARKS DATE: 2004-12-21 \n");
109 fprintf(fp, " %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
110 map->Nx, map->dmin[0], map->dmax[0],
111 map->Ny, map->dmin[1], map->dmax[1],
112 map->Nz, map->dmin[2], map->dmax[2]);
113 fprintf(fp, "%12.5E%12.5E%12.5E%12.5E%12.5E%12.5E\n",
114 map->cell[0], map->cell[1], map->cell[2],
115 map->cell[3], map->cell[4], map->cell[5]);
116 fprintf(fp, "ZYX\n");
119 for (n = 0; n < map->Nz; n++, z++)
121 fprintf(fp, "%8d\n", z);
122 for (i = 0; i < map->Nx*map->Ny; i += 6)
124 for (j = 0; j < 6; j++)
126 if (i+j < map->Nx*map->Ny)
128 fprintf(fp, "%12.5E", map->ed[n*map->Nx*map->Ny+i+j]);
134 fprintf(fp, " -9999\n");
138 static void write_xplor(const char *file, real *data, int *ibox, real dmin[], real dmax[])
147 snew(xm->ed, xm->Nx*xm->Ny*xm->Nz);
149 for (k = 0; (k < xm->Nz); k++)
151 for (j = 0; (j < xm->Ny); j++)
153 for (i = 0; (i < xm->Nx); i++)
155 xm->ed[n++] = data[index3(ibox, i, j, k)];
159 xm->cell[0] = dmax[XX]-dmin[XX];
160 xm->cell[1] = dmax[YY]-dmin[YY];
161 xm->cell[2] = dmax[ZZ]-dmin[ZZ];
162 xm->cell[3] = xm->cell[4] = xm->cell[5] = 90;
164 clear_ivec(xm->dmin);
165 xm->dmax[XX] = ibox[XX]-1;
166 xm->dmax[YY] = ibox[YY]-1;
167 xm->dmax[ZZ] = ibox[ZZ]-1;
169 lo_write_xplor(xm, file);
175 static void normalize_p_e(int len, double *P, int *nbin, real *E, real pmin)
180 for (i = 0; (i < len); i++)
188 printf("Ptot = %g\n", Ptot);
189 for (i = 0; (i < len); i++)
192 /* Have to check for pmin after normalizing to prevent "stretching"
207 static int comp_minima(const void *a, const void *b)
209 t_minimum *ma = (t_minimum *) a;
210 t_minimum *mb = (t_minimum *) b;
212 if (ma->ener < mb->ener)
216 else if (ma->ener > mb->ener)
227 void print_minimum(FILE *fp, int num, const t_minimum *min)
230 "Minimum %d at index " "%"GMX_PRId64 " energy %10.3f\n",
231 num, min->index, min->ener);
235 void add_minimum(FILE *fp, int num, const t_minimum *min, t_minimum *mm)
237 print_minimum(fp, num, min);
238 mm[num].index = min->index;
239 mm[num].ener = min->ener;
243 gmx_bool is_local_minimum_from_below(const t_minimum *this_min,
249 return ((dimension_index == dimension_min) ||
250 ((dimension_index > dimension_min) &&
251 (this_min->ener < W[neighbour_index])));
252 /* Note over/underflow within W cannot occur. */
256 gmx_bool is_local_minimum_from_above(const t_minimum *this_min,
262 return ((dimension_index == dimension_max) ||
263 ((dimension_index < dimension_max) &&
264 (this_min->ener < W[neighbour_index])));
265 /* Note over/underflow within W cannot occur. */
268 static void pick_minima(const char *logfile, int *ibox, int ndim, int len, real W[])
272 t_minimum *mm, this_min;
274 int loopmax, loopcounter;
278 fp = ffopen(logfile, "w");
279 /* Loop over each element in the array of dimenion ndim seeking
280 * minima with respect to every dimension. Specialized loops for
281 * speed with ndim == 2 and ndim == 3. */
285 /* This is probably impossible to reach anyway. */
288 for (i = 0; (i < ibox[0]); i++)
290 for (j = 0; (j < ibox[1]); j++)
292 /* Get the index of this point in the flat array */
293 this_min.index = index2(ibox, i, j);
294 this_min.ener = W[this_min.index];
295 if (is_local_minimum_from_below(&this_min, i, 0, index2(ibox, i-1, j ), W) &&
296 is_local_minimum_from_above(&this_min, i, ibox[0]-1, index2(ibox, i+1, j ), W) &&
297 is_local_minimum_from_below(&this_min, j, 0, index2(ibox, i, j-1), W) &&
298 is_local_minimum_from_above(&this_min, j, ibox[1]-1, index2(ibox, i, j+1), W))
300 add_minimum(fp, nmin, &this_min, mm);
307 for (i = 0; (i < ibox[0]); i++)
309 for (j = 0; (j < ibox[1]); j++)
311 for (k = 0; (k < ibox[2]); k++)
313 /* Get the index of this point in the flat array */
314 this_min.index = index3(ibox, i, j, k);
315 this_min.ener = W[this_min.index];
316 if (is_local_minimum_from_below(&this_min, i, 0, index3(ibox, i-1, j, k ), W) &&
317 is_local_minimum_from_above(&this_min, i, ibox[0]-1, index3(ibox, i+1, j, k ), W) &&
318 is_local_minimum_from_below(&this_min, j, 0, index3(ibox, i, j-1, k ), W) &&
319 is_local_minimum_from_above(&this_min, j, ibox[1]-1, index3(ibox, i, j+1, k ), W) &&
320 is_local_minimum_from_below(&this_min, k, 0, index3(ibox, i, j, k-1), W) &&
321 is_local_minimum_from_above(&this_min, k, ibox[2]-1, index3(ibox, i, j, k+1), W))
323 add_minimum(fp, nmin, &this_min, mm);
331 /* Note this treats ndim == 1 and ndim > 3 */
333 /* Set up an ndim-dimensional vector to loop over the points
334 * on the grid. (0,0,0, ... 0) is an acceptable place to
336 snew(this_point, ndim);
338 /* Determine the number of points of the ndim-dimensional
341 for (i = 1; i < ndim; i++)
347 while (loopmax > loopcounter)
349 gmx_bool bMin = TRUE;
351 /* Get the index of this_point in the flat array */
352 this_min.index = indexn(ndim, ibox, this_point);
353 this_min.ener = W[this_min.index];
355 /* Is this_point a minimum from above and below in each
357 for (i = 0; bMin && (i < ndim); i++)
359 /* Save the index of this_point within the curent
360 * dimension so we can change that index in the
361 * this_point array for use with indexn(). */
362 int index = this_point[i];
365 is_local_minimum_from_below(&this_min, index, 0, indexn(ndim, ibox, this_point), W);
368 is_local_minimum_from_above(&this_min, index, ibox[i]-1, indexn(ndim, ibox, this_point), W);
373 add_minimum(fp, nmin, &this_min, mm);
377 /* update global loop counter */
380 /* Avoid underflow of this_point[i] */
381 if (loopmax > loopcounter)
383 /* update this_point non-recursively */
386 while (ibox[i] == this_point[i])
390 /* this_point[i] cannot underflow because
391 * loopmax > loopcounter. */
400 qsort(mm, nmin, sizeof(mm[0]), comp_minima);
401 fprintf(fp, "Minima sorted after energy\n");
402 for (i = 0; (i < nmin); i++)
404 print_minimum(fp, i, &mm[i]);
410 static void do_sham(const char *fn, const char *ndx,
411 const char *xpmP, const char *xpm, const char *xpm2,
412 const char *xpm3, const char *xpm4, const char *pdb,
414 int n, int neig, real **eig,
415 gmx_bool bGE, int nenerT, real **enerT,
416 int nmap, real *mapindex, real **map,
418 real pmax, real gmax,
419 real *emin, real *emax, int nlevels, real pmin,
420 const char *mname, int *idim, int *ibox,
421 gmx_bool bXmin, real *xmin, gmx_bool bXmax, real *xmax)
424 real *min_eig, *max_eig;
425 real *axis_x, *axis_y, *axis_z, *axis = NULL;
427 real **PP, *W, *E, **WW, **EE, *S, **SS, *M, **MM, *bE;
430 double *bfac, efac, bref, Pmax, Wmin, Wmax, Winf, Emin, Emax, Einf, Smin, Smax, Sinf, Mmin, Mmax, Minf;
432 int i, j, k, imin, len, index, d, *nbin, *bindex, bi;
437 t_rgb rlo = { 0, 0, 0 };
438 t_rgb rhi = { 1, 1, 1 };
440 /* Determine extremes for the eigenvectors */
447 for (i = 0; (i < neig); i++)
449 /* Check for input constraints */
450 min_eig[i] = max_eig[i] = eig[i][0];
451 for (j = 0; (j < n); j++)
453 min_eig[i] = min(min_eig[i], eig[i][j]);
454 max_eig[i] = max(max_eig[i], eig[i][j]);
455 delta[i] = (max_eig[i]-min_eig[i])/(2.0*ibox[i]);
457 /* Add some extra space, half a bin on each side, unless the
458 * user has set the limits.
462 if (max_eig[i] > xmax[i])
464 gmx_warning("Your xmax[%d] value %f is smaller than the largest data point %f", i, xmax[i], max_eig[i]);
466 max_eig[i] = xmax[i];
470 max_eig[i] += delta[i];
475 if (min_eig[i] < xmin[i])
477 gmx_warning("Your xmin[%d] value %f is larger than the smallest data point %f", i, xmin[i], min_eig[i]);
479 min_eig[i] = xmin[i];
483 min_eig[i] -= delta[i];
485 bfac[i] = ibox[i]/(max_eig[i]-min_eig[i]);
488 bref = 1/(BOLTZ*Tref);
490 if (bGE || nenerT == 2)
493 for (j = 0; (j < n); j++)
497 bE[j] = bref*enerT[0][j];
501 bE[j] = (bref - 1/(BOLTZ*enerT[1][j]))*enerT[0][j];
503 Emin = min(Emin, bE[j]);
511 for (i = 0; (i < neig); i++)
515 printf("There are %d bins in the %d-dimensional histogram. Beta-Emin = %g\n",
526 /* Loop over projections */
527 for (j = 0; (j < n); j++)
529 /* Loop over dimensions */
531 for (i = 0; (i < neig); i++)
533 nxyz[i] = bfac[i]*(eig[i][j]-min_eig[i]);
534 if (nxyz[i] < 0 || nxyz[i] >= ibox[i])
541 index = indexn(neig, ibox, nxyz);
542 range_check(index, 0, len);
543 /* Compute the exponential factor */
546 efac = exp(-bE[j]+Emin);
552 /* Apply the bin volume correction for a multi-dimensional distance */
553 for (i = 0; i < neig; i++)
559 else if (idim[i] == 3)
561 efac /= sqr(eig[i][j]);
563 else if (idim[i] == -1)
565 efac /= sin(DEG2RAD*eig[i][j]);
568 /* Update the probability */
570 /* Update the energy */
573 E[index] += enerT[0][j];
575 /* Statistics: which "structure" in which bin */
580 /* Normalize probability */
581 normalize_p_e(len, P, nbin, E, pmin);
583 /* Compute boundaries for the Free energy */
587 /* Recompute Emin: it may have changed due to averaging */
590 for (i = 0; (i < len); i++)
594 Pmax = max(P[i], Pmax);
595 W[i] = -BOLTZ*Tref*log(P[i]);
601 Emin = min(E[i], Emin);
602 Emax = max(E[i], Emax);
603 Wmax = max(W[i], Wmax);
623 /* Write out the free energy as a function of bin index */
624 fp = ffopen(fn, "w");
625 for (i = 0; (i < len); i++)
630 S[i] = E[i]-W[i]-Smin;
631 fprintf(fp, "%5d %10.5e %10.5e %10.5e\n", i, W[i], E[i], S[i]);
641 /* Organize the structures in the bins */
643 snew(b->index, len+1);
646 for (i = 0; (i < len); i++)
648 b->index[i+1] = b->index[i]+nbin[i];
651 for (i = 0; (i < n); i++)
654 b->a[b->index[bi]+nbin[bi]] = i;
657 /* Consistency check */
658 /* This no longer applies when we allow the plot to be smaller
659 than the sampled space.
660 for(i=0; (i<len); i++) {
661 if (nbin[i] != (b->index[i+1] - b->index[i]))
662 gmx_fatal(FARGS,"nbin[%d] = %d, should be %d",i,nbin[i],
663 b->index[i+1] - b->index[i]);
666 /* Write the index file */
667 fp = ffopen(ndx, "w");
668 for (i = 0; (i < len); i++)
672 fprintf(fp, "[ %d ]\n", i);
673 for (j = b->index[i]; (j < b->index[i+1]); j++)
675 fprintf(fp, "%d\n", b->a[j]+1);
680 snew(axis_x, ibox[0]+1);
681 snew(axis_y, ibox[1]+1);
682 snew(axis_z, ibox[2]+1);
683 maxbox = max(ibox[0], max(ibox[1], ibox[2]));
684 snew(PP, maxbox*maxbox);
685 snew(WW, maxbox*maxbox);
686 snew(EE, maxbox*maxbox);
687 snew(SS, maxbox*maxbox);
688 for (i = 0; (i < min(neig, 3)); i++)
692 case 0: axis = axis_x; break;
693 case 1: axis = axis_y; break;
694 case 2: axis = axis_z; break;
697 for (j = 0; j <= ibox[i]; j++)
699 axis[j] = min_eig[i] + j/bfac[i];
705 snew(MM, maxbox*maxbox);
706 for (i = 0; (i < ibox[0]); i++)
708 MM[i] = &(M[i*ibox[1]]);
712 for (i = 0; (i < nmap); i++)
714 Mmin = min(Mmin, map[0][i]);
715 Mmax = max(Mmax, map[0][i]);
718 for (i = 0; (i < len); i++)
722 for (i = 0; (i < nmap); i++)
724 index = gmx_nint(mapindex[i]);
727 gmx_fatal(FARGS, "Number of bins in file from -mdata option does not correspond to current analysis");
732 M[index] = map[0][i];
741 pick_minima(logf, ibox, neig, len, W);
746 flags = MAT_SPATIAL_X | MAT_SPATIAL_Y;
749 /* Dump to XPM file */
751 for (i = 0; (i < ibox[0]); i++)
753 snew(PP[i], ibox[1]);
754 for (j = 0; j < ibox[1]; j++)
756 PP[i][j] = P[i*ibox[1]+j];
758 WW[i] = &(W[i*ibox[1]]);
759 EE[i] = &(E[i*ibox[1]]);
760 SS[i] = &(S[i*ibox[1]]);
762 fp = ffopen(xpmP, "w");
763 write_xpm(fp, flags, "Probability Distribution", "", "PC1", "PC2",
764 ibox[0], ibox[1], axis_x, axis_y, PP, 0, Pmax, rlo, rhi, &nlevels);
766 fp = ffopen(xpm, "w");
767 write_xpm(fp, flags, "Gibbs Energy Landscape", "G (kJ/mol)", "PC1", "PC2",
768 ibox[0], ibox[1], axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels);
770 fp = ffopen(xpm2, "w");
771 write_xpm(fp, flags, "Enthalpy Landscape", "H (kJ/mol)", "PC1", "PC2",
772 ibox[0], ibox[1], axis_x, axis_y, EE,
773 emin ? *emin : Emin, emax ? *emax : Einf, rlo, rhi, &nlevels);
775 fp = ffopen(xpm3, "w");
776 write_xpm(fp, flags, "Entropy Landscape", "TDS (kJ/mol)", "PC1", "PC2",
777 ibox[0], ibox[1], axis_x, axis_y, SS, 0, Sinf, rlo, rhi, &nlevels);
781 fp = ffopen(xpm4, "w");
782 write_xpm(fp, flags, "Custom Landscape", mname, "PC1", "PC2",
783 ibox[0], ibox[1], axis_x, axis_y, MM, 0, Minf, rlo, rhi, &nlevels);
789 /* Dump to PDB file */
790 fp = ffopen(pdb, "w");
791 for (i = 0; (i < ibox[0]); i++)
793 xxx[XX] = 3*(i+0.5-ibox[0]/2);
794 for (j = 0; (j < ibox[1]); j++)
796 xxx[YY] = 3*(j+0.5-ibox[1]/2);
797 for (k = 0; (k < ibox[2]); k++)
799 xxx[ZZ] = 3*(k+0.5-ibox[2]/2);
800 index = index3(ibox, i, j, k);
803 fprintf(fp, "%-6s%5u %-4.4s%3.3s %4d %8.3f%8.3f%8.3f%6.2f%6.2f\n",
804 "ATOM", (index+1) %10000, "H", "H", (index+1)%10000,
805 xxx[XX], xxx[YY], xxx[ZZ], 1.0, W[index]);
811 write_xplor("out.xplor", W, ibox, min_eig, max_eig);
814 write_xplor("user.xplor", M, ibox, min_eig, max_eig);
816 nxyz[XX] = imin/(ibox[1]*ibox[2]);
817 nxyz[YY] = (imin-nxyz[XX]*ibox[1]*ibox[2])/ibox[2];
818 nxyz[ZZ] = imin % ibox[2];
819 for (i = 0; (i < ibox[0]); i++)
822 for (j = 0; (j < ibox[1]); j++)
824 WW[i][j] = W[index3(ibox, i, j, nxyz[ZZ])];
827 snew(buf, strlen(xpm)+4);
828 sprintf(buf, "%s", xpm);
829 sprintf(&buf[strlen(xpm)-4], "12.xpm");
830 fp = ffopen(buf, "w");
831 write_xpm(fp, flags, "Gibbs Energy Landscape", "W (kJ/mol)", "PC1", "PC2",
832 ibox[0], ibox[1], axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels);
834 for (i = 0; (i < ibox[0]); i++)
836 for (j = 0; (j < ibox[2]); j++)
838 WW[i][j] = W[index3(ibox, i, nxyz[YY], j)];
841 sprintf(&buf[strlen(xpm)-4], "13.xpm");
842 fp = ffopen(buf, "w");
843 write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC1", "PC3",
844 ibox[0], ibox[2], axis_x, axis_z, WW, 0, gmax, rlo, rhi, &nlevels);
846 for (i = 0; (i < ibox[1]); i++)
848 for (j = 0; (j < ibox[2]); j++)
850 WW[i][j] = W[index3(ibox, nxyz[XX], i, j)];
853 sprintf(&buf[strlen(xpm)-4], "23.xpm");
854 fp = ffopen(buf, "w");
855 write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC2", "PC3",
856 ibox[1], ibox[2], axis_y, axis_z, WW, 0, gmax, rlo, rhi, &nlevels);
867 static void ehisto(const char *fh, int n, real **enerT, const output_env_t oenv)
870 int i, j, k, nbin, blength;
872 real *T, bmin, bmax, bwidth;
880 for (j = 1; (j < n); j++)
882 for (k = 0; (k < nbin); k++)
884 if (T[k] == enerT[1][j])
893 T[nbin] = enerT[1][j];
896 bmin = min(enerT[0][j], bmin);
897 bmax = max(enerT[0][j], bmax);
900 blength = (bmax - bmin)/bwidth + 2;
902 for (i = 0; (i < nbin); i++)
904 snew(histo[i], blength);
906 for (j = 0; (j < n); j++)
908 k = (enerT[0][j]-bmin)/bwidth;
909 histo[bindex[j]][k]++;
911 fp = xvgropen(fh, "Energy distribution", "E (kJ/mol)", "", oenv);
912 for (j = 0; (j < blength); j++)
914 fprintf(fp, "%8.3f", bmin+j*bwidth);
915 for (k = 0; (k < nbin); k++)
917 fprintf(fp, " %6d", histo[k][j]);
924 int gmx_sham(int argc, char *argv[])
926 const char *desc[] = {
927 "[THISMODULE] makes multi-dimensional free-energy, enthalpy and entropy plots.",
928 "[THISMODULE] reads one or more [TT].xvg[tt] files and analyzes data sets.",
929 "The basic purpose of [THISMODULE] is to plot Gibbs free energy landscapes",
930 "(option [TT]-ls[tt])",
931 "by Bolzmann inverting multi-dimensional histograms (option [TT]-lp[tt]),",
933 "make enthalpy (option [TT]-lsh[tt]) and entropy (option [TT]-lss[tt])",
934 "plots. The histograms can be made for any quantities the user supplies.",
935 "A line in the input file may start with a time",
936 "(see option [TT]-time[tt]) and any number of [IT]y[it]-values may follow.",
937 "Multiple sets can also be",
938 "read when they are separated by & (option [TT]-n[tt]),",
939 "in this case only one [IT]y[it]-value is read from each line.",
940 "All lines starting with # and @ are skipped.",
942 "Option [TT]-ge[tt] can be used to supply a file with free energies",
943 "when the ensemble is not a Boltzmann ensemble, but needs to be biased",
944 "by this free energy. One free energy value is required for each",
945 "(multi-dimensional) data point in the [TT]-f[tt] input.",
947 "Option [TT]-ene[tt] can be used to supply a file with energies.",
948 "These energies are used as a weighting function in the single",
949 "histogram analysis method by Kumar et al. When temperatures",
950 "are supplied (as a second column in the file), an experimental",
951 "weighting scheme is applied. In addition the vales",
952 "are used for making enthalpy and entropy plots.",
954 "With option [TT]-dim[tt], dimensions can be gives for distances.",
955 "When a distance is 2- or 3-dimensional, the circumference or surface",
956 "sampled by two particles increases with increasing distance.",
957 "Depending on what one would like to show, one can choose to correct",
958 "the histogram and free-energy for this volume effect.",
959 "The probability is normalized by r and r^2 for dimensions of 2 and 3, ",
961 "A value of -1 is used to indicate an angle in degrees between two",
962 "vectors: a sin(angle) normalization will be applied.",
963 "[BB]Note[bb] that for angles between vectors the inner-product or cosine",
964 "is the natural quantity to use, as it will produce bins of the same",
967 static real tb = -1, te = -1, frac = 0.5, filtlen = 0;
968 static gmx_bool bHaveT = TRUE, bDer = FALSE, bSubAv = TRUE, bAverCorr = FALSE, bXYdy = FALSE;
969 static gmx_bool bEESEF = FALSE, bEENLC = FALSE, bEeFitAc = FALSE, bPower = FALSE;
970 static gmx_bool bShamEner = TRUE, bSham = TRUE;
971 static real Tref = 298.15, pmin = 0, ttol = 0, pmax = 0, gmax = 0, emin = 0, emax = 0;
972 static rvec nrdim = {1, 1, 1};
973 static rvec nrbox = {32, 32, 32};
974 static rvec xmin = {0, 0, 0}, xmax = {1, 1, 1};
975 static int nsets_in = 1, nb_min = 4, resol = 10, nlevels = 25;
976 static const char *mname = "";
978 { "-time", FALSE, etBOOL, {&bHaveT},
979 "Expect a time in the input" },
980 { "-b", FALSE, etREAL, {&tb},
981 "First time to read from set" },
982 { "-e", FALSE, etREAL, {&te},
983 "Last time to read from set" },
984 { "-ttol", FALSE, etREAL, {&ttol},
985 "Tolerance on time in appropriate units (usually ps)" },
986 { "-n", FALSE, etINT, {&nsets_in},
987 "Read this number of sets separated by lines containing only an ampersand" },
988 { "-d", FALSE, etBOOL, {&bDer},
989 "Use the derivative" },
990 { "-sham", FALSE, etBOOL, {&bSham},
991 "Turn off energy weighting even if energies are given" },
992 { "-tsham", FALSE, etREAL, {&Tref},
993 "Temperature for single histogram analysis" },
994 { "-pmin", FALSE, etREAL, {&pmin},
995 "Minimum probability. Anything lower than this will be set to zero" },
996 { "-dim", FALSE, etRVEC, {nrdim},
997 "Dimensions for distances, used for volume correction (max 3 values, dimensions > 3 will get the same value as the last)" },
998 { "-ngrid", FALSE, etRVEC, {nrbox},
999 "Number of bins for energy landscapes (max 3 values, dimensions > 3 will get the same value as the last)" },
1000 { "-xmin", FALSE, etRVEC, {xmin},
1001 "Minimum for the axes in energy landscape (see above for > 3 dimensions)" },
1002 { "-xmax", FALSE, etRVEC, {xmax},
1003 "Maximum for the axes in energy landscape (see above for > 3 dimensions)" },
1004 { "-pmax", FALSE, etREAL, {&pmax},
1005 "Maximum probability in output, default is calculate" },
1006 { "-gmax", FALSE, etREAL, {&gmax},
1007 "Maximum free energy in output, default is calculate" },
1008 { "-emin", FALSE, etREAL, {&emin},
1009 "Minimum enthalpy in output, default is calculate" },
1010 { "-emax", FALSE, etREAL, {&emax},
1011 "Maximum enthalpy in output, default is calculate" },
1012 { "-nlevels", FALSE, etINT, {&nlevels},
1013 "Number of levels for energy landscape" },
1014 { "-mname", FALSE, etSTR, {&mname},
1015 "Legend label for the custom landscape" },
1017 #define NPA asize(pa)
1020 int n, e_n, d_n, nlast, s, nset, e_nset, d_nset, i, j = 0, *idim, *ibox;
1021 real **val, **et_val, **dt_val, *t, *e_t, e_dt, d_dt, *d_t, dt, tot, error;
1023 double *av, *sig, cum1, cum2, cum3, cum4, db;
1024 const char *fn_ge, *fn_ene;
1026 gmx_int64_t num_grid_points;
1029 { efXVG, "-f", "graph", ffREAD },
1030 { efXVG, "-ge", "gibbs", ffOPTRD },
1031 { efXVG, "-ene", "esham", ffOPTRD },
1032 { efXVG, "-dist", "ener", ffOPTWR },
1033 { efXVG, "-histo", "edist", ffOPTWR },
1034 { efNDX, "-bin", "bindex", ffOPTWR },
1035 { efXPM, "-lp", "prob", ffOPTWR },
1036 { efXPM, "-ls", "gibbs", ffOPTWR },
1037 { efXPM, "-lsh", "enthalpy", ffOPTWR },
1038 { efXPM, "-lss", "entropy", ffOPTWR },
1039 { efXPM, "-map", "map", ffOPTWR },
1040 { efPDB, "-ls3", "gibbs3", ffOPTWR },
1041 { efXVG, "-mdata", "mapdata", ffOPTRD },
1042 { efLOG, "-g", "shamlog", ffOPTWR }
1044 #define NFILE asize(fnm)
1049 if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_BE_NICE,
1050 NFILE, fnm, npargs, pa, asize(desc), desc, 0, NULL, &oenv))
1055 val = read_xvg_time(opt2fn("-f", NFILE, fnm), bHaveT,
1056 opt2parg_bSet("-b", npargs, pa), tb-ttol,
1057 opt2parg_bSet("-e", npargs, pa), te+ttol,
1058 nsets_in, &nset, &n, &dt, &t);
1059 printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt);
1061 fn_ge = opt2fn_null("-ge", NFILE, fnm);
1062 fn_ene = opt2fn_null("-ene", NFILE, fnm);
1064 if (fn_ge && fn_ene)
1066 gmx_fatal(FARGS, "Can not do free energy and energy corrections at the same time");
1069 if (fn_ge || fn_ene)
1071 et_val = read_xvg_time(fn_ge ? fn_ge : fn_ene, bHaveT,
1072 opt2parg_bSet("-b", npargs, pa), tb-ttol,
1073 opt2parg_bSet("-e", npargs, pa), te+ttol,
1074 1, &e_nset, &e_n, &e_dt, &e_t);
1079 gmx_fatal(FARGS, "Can only handle one free energy component in %s",
1085 if (e_nset != 1 && e_nset != 2)
1087 gmx_fatal(FARGS, "Can only handle one energy component or one energy and one T in %s",
1093 gmx_fatal(FARGS, "Number of energies (%d) does not match number of entries (%d) in %s", e_n, n, opt2fn("-f", NFILE, fnm));
1101 if (opt2fn_null("-mdata", NFILE, fnm) != NULL)
1103 dt_val = read_xvg_time(opt2fn("-mdata", NFILE, fnm), bHaveT,
1104 FALSE, tb, FALSE, te,
1105 nsets_in, &d_nset, &d_n, &d_dt, &d_t);
1108 gmx_fatal(FARGS, "Can only handle one mapping data column in %s",
1109 opt2fn("-mdata", NFILE, fnm));
1117 if (fn_ene && et_val)
1119 ehisto(opt2fn("-histo", NFILE, fnm), e_n, et_val, oenv);
1122 snew(idim, max(3, nset));
1123 snew(ibox, max(3, nset));
1124 snew(rmin, max(3, nset));
1125 snew(rmax, max(3, nset));
1126 for (i = 0; (i < min(3, nset)); i++)
1133 for (; (i < nset); i++)
1141 /* Check that the grid size is manageable. */
1142 num_grid_points = ibox[0];
1143 for (i = 1; i < nset; i++)
1146 if (!check_int_multiply_for_overflow(num_grid_points, ibox[i], &result))
1149 "The number of dimensions and grid points is too large for this tool.\n");
1151 num_grid_points = result;
1153 /* The number of grid points fits in a gmx_int64_t. */
1155 do_sham(opt2fn("-dist", NFILE, fnm), opt2fn("-bin", NFILE, fnm),
1156 opt2fn("-lp", NFILE, fnm),
1157 opt2fn("-ls", NFILE, fnm), opt2fn("-lsh", NFILE, fnm),
1158 opt2fn("-lss", NFILE, fnm), opt2fn("-map", NFILE, fnm),
1159 opt2fn("-ls3", NFILE, fnm), opt2fn("-g", NFILE, fnm),
1160 n, nset, val, fn_ge != NULL, e_nset, et_val, d_n, d_t, dt_val, Tref,
1162 opt2parg_bSet("-emin", NPA, pa) ? &emin : NULL,
1163 opt2parg_bSet("-emax", NPA, pa) ? &emax : NULL,
1166 opt2parg_bSet("-xmin", NPA, pa), rmin,
1167 opt2parg_bSet("-xmax", NPA, pa), rmax);