1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*- */
3 * This file is part of the GROMACS molecular simulation package.
5 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
6 * Copyright (c) 2001-2004, The GROMACS development team,
7 * check out http://www.gromacs.org for more information.
8 * Copyright (c) 2012, by the GROMACS development team, led by
9 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
10 * others, as listed in the AUTHORS file in the top-level source
11 * directory and at http://www.gromacs.org.
13 * GROMACS is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public License
15 * as published by the Free Software Foundation; either version 2.1
16 * of the License, or (at your option) any later version.
18 * GROMACS is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with GROMACS; if not, see
25 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
26 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 * If you want to redistribute modifications to GROMACS, please
29 * consider that scientific software is very special. Version
30 * control is crucial - bugs must be traceable. We will be happy to
31 * consider code for inclusion in the official distribution, but
32 * derived work must not be called official GROMACS. Details are found
33 * in the README & COPYING files - if they are missing, get the
34 * official version at http://www.gromacs.org.
36 * To help us fund GROMACS development, we humbly ask that you cite
37 * the research papers on the package. Check out http://www.gromacs.org.
53 #include "gmx_random.h"
63 #define WHAM_MAXFILELEN 2048
65 /* enum for energy units */
66 enum { enSel
, en_kJ
, en_kCal
, en_kT
, enNr
};
67 /* enum for type of input files (pdos, tpr, or pullf) */
68 enum { whamin_unknown
, whamin_tpr
, whamin_pullxf
, whamin_pdo
};
69 /* enum for bootstrapping method (
70 - bootstrap complete histograms with continuous weights (Bayesian bootstrap)
71 - bootstrap complete histograms
72 - bootstrap trajectories from given umbrella histograms
73 - bootstrap trajectories from Gaussian with mu/sigam computed from
74 the respective histogram
76 ********************************************************************
77 FOR MORE DETAILS ON THE BOOTSTRAP METHODS (INCLUDING EXAMPLES), SEE
78 JS Hub, BL de Groot, D van der Spoel
79 [TT]g_wham[tt] - A free weighted histogram analysis implementation including
80 robust error and autocorrelation estimates,
81 J Chem Theory Comput, accepted (2010)
82 ********************************************************************
84 enum { bsMethod_unknown
, bsMethod_BayesianHist
, bsMethod_hist
,
85 bsMethod_traj
, bsMethod_trajGauss
};
90 /* umbrella with pull code of gromacs 4.x */
91 int npullgrps
; /* nr of pull groups in tpr file */
92 int pull_geometry
; /* such as distance, position */
93 ivec pull_dim
; /* pull dimension with geometry distance */
94 int pull_ndim
; /* nr of pull_dim != 0 */
95 real
*k
; /* force constants in tpr file */
96 rvec
*init_dist
; /* reference displacements */
97 real
*umbInitDist
; /* reference displacement in umbrella direction */
99 /* From here, old pdo stuff */
105 char PullName
[4][256];
107 double UmbCons
[4][3];
112 int nPull
; /* nr of pull groups in this pdo or pullf/x file */
113 double **Histo
,**cum
; /* nPull histograms and nPull cumulative distr. funct */
114 int nBin
; /* nr of bins. identical to opt->bins */
115 double *k
; /* force constants for the nPull groups */
116 double *pos
; /* umbrella positions for the nPull groups */
117 double *z
; /* z=(-Fi/kT) for the nPull groups. These values are
118 iteratively computed during wham */
119 double *N
, *Ntot
; /* nr of data points in nPull histograms. N and Ntot
120 only differ if bHistEq==TRUE */
122 double *g
,*tau
,*tausmooth
; /* g = 1 + 2*tau[int]/dt where tau is the integrated
123 autocorrelation time. Compare, e.g.
124 Ferrenberg/Swendsen, PRL 63:1195 (1989)
125 Kumar et al, J Comp Chem 13, 1011-1021 (1992), eq. 28 */
127 double dt
; /* timestep in the input data. Can be adapted with
129 gmx_bool
**bContrib
; /* TRUE, if any data point of the histogram is within min
130 and max, otherwise FALSE. */
131 real
**ztime
; /* input data z(t) as a function of time. Required to
133 real
*forceAv
; /* average force estimated from average displacement, fAv=dzAv*k
134 Used for integration to guess the potential. */
135 real
*aver
,*sigma
; /* average and stddev of histograms */
136 double *bsWeight
; /* for bootstrapping complete histograms with continuous weights */
143 const char *fnTpr
,*fnPullf
;
144 const char *fnPdo
,*fnPullx
; /* file names of input */
145 gmx_bool bTpr
,bPullf
,bPdo
,bPullx
;/* input file types given? */
146 real tmin
, tmax
, dt
; /* only read input within tmin and tmax with dt */
148 gmx_bool bInitPotByIntegration
; /* before WHAM, guess potential by force integration. Yields
149 1.5 to 2 times faster convergence */
150 int stepUpdateContrib
; /* update contribution table every ... iterations. Accelerates
153 /* BASIC WHAM OPTIONS */
154 int bins
; /* nr of bins, min, max, and dz of profile */
156 real Temperature
,Tolerance
; /* temperature, converged when probability changes less
158 gmx_bool bCycl
; /* generate cyclic (periodic) PMF */
161 gmx_bool bLog
; /* energy output (instead of probability) for profile */
162 int unit
; /* unit for PMF output kJ/mol or kT or kCal/mol */
163 gmx_bool bSym
; /* symmetrize PMF around z=0 after WHAM, useful for
165 real zProf0
; /* after wham, set prof to zero at this z-position
166 When bootstrapping, set zProf0 to a "stable" reference
168 gmx_bool bProf0Set
; /* setting profile to 0 at zProf0? */
170 gmx_bool bBoundsOnly
,bHistOnly
; /* determine min and max, or write histograms and exit */
171 gmx_bool bAuto
; /* determine min and max automatically but do not exit */
173 gmx_bool verbose
; /* more noisy wham mode */
174 int stepchange
; /* print maximum change in prof after how many interations */
175 output_env_t oenv
; /* xvgr options */
177 /* AUTOCORRELATION STUFF */
178 gmx_bool bTauIntGiven
,bCalcTauInt
;/* IACT given or should be calculated? */
179 real sigSmoothIact
; /* sigma of Gaussian to smooth ACTs */
180 gmx_bool bAllowReduceIact
; /* Allow to reduce ACTs during smoothing. Otherwise
181 ACT are only increased during smoothing */
182 real acTrestart
; /* when computing ACT, time between restarting points */
183 gmx_bool bHistEq
; /* Enforce the same weight for each umbella window, that is
184 calculate with the same number of data points for
185 each window. That can be reasonable, if the histograms
186 have different length, but due to autocorrelation,
187 a longer simulation should not have larger weightin wham. */
189 /* BOOTSTRAPPING STUFF */
190 int nBootStrap
; /* nr of bootstraps (50 is usually enough) */
191 int bsMethod
; /* if == bsMethod_hist, consider complete histograms as independent
192 data points and, hence, only mix complete histograms.
193 if == bsMethod_BayesianHist, consider complete histograms
194 as independent data points, but assign random weights
195 to the histograms during the bootstrapping ("Bayesian bootstrap")
196 In case of long correlations (e.g., inside a channel), these
197 will yield a more realistic error.
198 if == bsMethod_traj(Gauss), generate synthetic histograms
200 histogram by generating an autocorrelated random sequence
201 that is distributed according to the respective given
202 histogram. With bsMethod_trajGauss, bootstrap from a Gaussian
203 (instead of from the umbrella histogram) to generate a new
206 real tauBootStrap
; /* autocorrelation time (ACT) used to generate synthetic
207 histograms. If ==0, use calculated ACF */
208 int histBootStrapBlockLength
; /* when mixing histograms, mix only histograms withing blocks
209 long the reaction coordinate xi. Avoids gaps along xi. */
210 int bsSeed
; /* random seed for bootstrapping */
211 gmx_bool bs_verbose
; /* Write cumulative distribution functions (CDFs) of histograms
212 and write the generated histograms for each bootstrap */
214 /* tabulated umbrella potential stuff */
216 double *tabX
,*tabY
,tabMin
,tabMax
,tabDz
;
219 gmx_rng_t rng
; /* gromacs random number generator */
223 t_UmbrellaWindow
* initUmbrellaWindows(int nwin
)
225 t_UmbrellaWindow
*win
;
228 for (i
=0; i
<nwin
; i
++)
230 win
[i
].Histo
= win
[i
].cum
= 0;
231 win
[i
].k
= win
[i
].pos
= win
[i
].z
=0;
232 win
[i
].N
= win
[i
].Ntot
= 0;
233 win
[i
].g
= win
[i
].tau
= win
[i
].tausmooth
= 0;
237 win
[i
].aver
= win
[i
].sigma
= 0;
243 void freeUmbrellaWindows(t_UmbrellaWindow
*win
, int nwin
)
246 for (i
=0; i
<nwin
; i
++)
249 for (j
=0;j
<win
[i
].nPull
;j
++)
250 sfree(win
[i
].Histo
[j
]);
252 for (j
=0;j
<win
[i
].nPull
;j
++)
253 sfree(win
[i
].cum
[j
]);
255 for (j
=0;j
<win
[i
].nPull
;j
++)
256 sfree(win
[i
].bContrib
[j
]);
266 sfree(win
[i
].tausmooth
);
267 sfree(win
[i
].bContrib
);
269 sfree(win
[i
].forceAv
);
272 sfree(win
[i
].bsWeight
);
277 /* Read and setup tabulated umbrella potential */
278 void setup_tab(const char *fn
,t_UmbrellaOptions
*opt
)
283 printf("Setting up tabulated potential from file %s\n",fn
);
284 nl
=read_xvg(fn
,&y
,&ny
);
287 gmx_fatal(FARGS
,"Found %d columns in %s. Expected 2.\n",ny
,fn
);
289 opt
->tabMax
=y
[0][nl
-1];
290 opt
->tabDz
=(opt
->tabMax
-opt
->tabMin
)/(nl
-1);
292 gmx_fatal(FARGS
,"The tabulated potential in %s must be provided in \n"
293 "ascending z-direction",fn
);
295 if (fabs(y
[0][i
+1]-y
[0][i
]-opt
->tabDz
) > opt
->tabDz
/1e6
)
296 gmx_fatal(FARGS
,"z-values in %s are not equally spaced.\n",ny
,fn
);
301 opt
->tabX
[i
]=y
[0][i
];
302 opt
->tabY
[i
]=y
[1][i
];
304 printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n",
305 opt
->tabMin
,opt
->tabMax
,opt
->tabDz
);
308 void read_pdo_header(FILE * file
,t_UmbrellaHeader
* header
, t_UmbrellaOptions
*opt
)
311 char Buffer0
[256], Buffer1
[256], Buffer2
[256], Buffer3
[256], Buffer4
[256];
315 if (fgets(line
,2048,file
) == NULL
)
316 gmx_fatal(FARGS
,"Error reading header from pdo file\n");
317 sscanf(line
,"%s%s%s",Buffer0
,Buffer1
,Buffer2
);
318 if(strcmp(Buffer1
,"UMBRELLA"))
319 gmx_fatal(FARGS
,"This does not appear to be a valid pdo file. Found %s, expected %s\n"
320 "(Found in first line: `%s')\n",
321 Buffer1
, "UMBRELLA",line
);
322 if(strcmp(Buffer2
,"3.0"))
323 gmx_fatal(FARGS
,"This does not appear to be a version 3.0 pdo file");
326 if (fgets(line
,2048,file
) == NULL
)
327 gmx_fatal(FARGS
,"Error reading header from pdo file\n");
328 sscanf(line
,"%s%s%s%d%d%d",Buffer0
,Buffer1
,Buffer2
,
329 &(header
->Dims
[0]),&(header
->Dims
[1]),&(header
->Dims
[2]));
331 /* printf("%d %d %d\n", header->Dims[0],header->Dims[1],header->Dims[2]); */
333 header
->nDim
= header
->Dims
[0] + header
->Dims
[1] + header
->Dims
[2];
335 gmx_fatal(FARGS
,"Currently only supports one dimension");
338 if (fgets(line
,2048,file
) == NULL
)
339 gmx_fatal(FARGS
,"Error reading header from pdo file\n");
340 sscanf(line
,"%s%s%d",Buffer0
,Buffer1
,&(header
->nSkip
));
343 if (fgets(line
,2048,file
) == NULL
)
344 gmx_fatal(FARGS
,"Error reading header from pdo file\n");
345 sscanf(line
,"%s%s%s%s",Buffer0
,Buffer1
,Buffer2
,header
->Reference
);
348 if (fgets(line
,2048,file
) == NULL
)
349 gmx_fatal(FARGS
,"Error reading header from pdo file\n");
350 sscanf(line
,"%s%s%s%s%s%d",Buffer0
,Buffer1
,Buffer2
,Buffer3
,Buffer4
,&(header
->nPull
));
353 printf("\tFound nPull=%d , nSkip=%d, ref=%s\n",header
->nPull
,header
->nSkip
,
356 for(i
=0;i
<header
->nPull
;++i
)
358 if (fgets(line
,2048,file
) == NULL
)
359 gmx_fatal(FARGS
,"Error reading header from pdo file\n");
360 sscanf(line
,"%*s%*s%*s%s%*s%*s%lf%*s%*s%lf",header
->PullName
[i
]
361 ,&(header
->UmbPos
[i
][0]),&(header
->UmbCons
[i
][0]));
363 printf("\tpullgroup %d, pullname = %s, UmbPos = %g, UmbConst = %g\n",
364 i
,header
->PullName
[i
],header
->UmbPos
[i
][0],header
->UmbCons
[i
][0]);
367 if (fgets(line
,2048,file
) == NULL
)
368 gmx_fatal(FARGS
,"Cannot read from file\n");
369 sscanf(line
,"%s",Buffer3
);
370 if (strcmp(Buffer3
,"#####") != 0)
371 gmx_fatal(FARGS
,"Expected '#####', found %s. Hick.\n",Buffer3
);
375 static char *fgets3(FILE *fp
,char ptr
[],int *len
)
380 if (fgets(ptr
,*len
-1,fp
) == NULL
)
383 while ((strchr(ptr
,'\n') == NULL
) && (!feof(fp
)))
385 /* This line is longer than len characters, let's increase len! */
389 if (fgets(p
-1,STRLEN
,fp
) == NULL
)
393 if (ptr
[slen
-1] == '\n')
399 void read_pdo_data(FILE * file
, t_UmbrellaHeader
* header
,
400 int fileno
, t_UmbrellaWindow
* win
,
401 t_UmbrellaOptions
*opt
,
402 gmx_bool bGetMinMax
,real
*mintmp
,real
*maxtmp
)
404 int i
,inttemp
,bins
,count
,ntot
;
405 real min
,max
,minfound
=1e20
,maxfound
=-1e20
;
406 double temp
,time
,time0
=0,dt
;
408 t_UmbrellaWindow
* window
=0;
409 gmx_bool timeok
,dt_ok
=1;
410 char *tmpbuf
=0,fmt
[256],fmtign
[256];
411 int len
=STRLEN
,dstep
=1;
412 const int blocklen
=4096;
422 /* Need to alocate memory and set up structure */
423 window
->nPull
=header
->nPull
;
426 snew(window
->Histo
,window
->nPull
);
427 snew(window
->z
,window
->nPull
);
428 snew(window
->k
,window
->nPull
);
429 snew(window
->pos
,window
->nPull
);
430 snew(window
->N
, window
->nPull
);
431 snew(window
->Ntot
, window
->nPull
);
432 snew(window
->g
, window
->nPull
);
433 snew(window
->bsWeight
, window
->nPull
);
437 if (opt
->bCalcTauInt
)
438 snew(window
->ztime
, window
->nPull
);
441 snew(lennow
,window
->nPull
);
443 for(i
=0;i
<window
->nPull
;++i
)
446 window
->bsWeight
[i
]=1.;
447 snew(window
->Histo
[i
],bins
);
448 window
->k
[i
]=header
->UmbCons
[i
][0];
449 window
->pos
[i
]=header
->UmbPos
[i
][0];
453 if (opt
->bCalcTauInt
)
457 /* Done with setup */
463 min
=max
=bins
=0; /* Get rid of warnings */
468 while ( (ptr
=fgets3(file
,tmpbuf
,&len
)) != NULL
)
472 if (ptr
[0] == '#' || strlen(ptr
)<2)
475 /* Initiate format string */
477 strcat(fmtign
,"%*s");
479 sscanf(ptr
,"%lf",&time
); /* printf("Time %f\n",time); */
480 /* Round time to fs */
481 time
=1.0/1000*( (int) (time
*1000+0.5) );
483 /* get time step of pdo file */
491 dstep
=(int)(opt
->dt
/dt
+0.5);
500 dt_ok
=((count
-1)%dstep
== 0);
501 timeok
=(dt_ok
&& time
>= opt
->tmin
&& time
<= opt
->tmax
);
503 printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
504 time,opt->tmin, opt->tmax, dt_ok,timeok); */
508 for(i
=0;i
<header
->nPull
;++i
)
511 strcat(fmt
,"%lf"); /* Creating a format stings such as "%*s...%*s%lf" */
512 strcat(fmtign
,"%*s"); /* ignoring one more entry in the next loop */
513 if(sscanf(ptr
,fmt
,&temp
))
515 temp
+=header
->UmbPos
[i
][0];
524 if (opt
->bCalcTauInt
)
526 /* save time series for autocorrelation analysis */
527 ntot
=window
->Ntot
[i
];
531 srenew(window
->ztime
[i
],lennow
[i
]);
533 window
->ztime
[i
][ntot
]=temp
;
546 else if (inttemp
>= bins
)
550 if(inttemp
>= 0 && inttemp
< bins
)
552 window
->Histo
[i
][inttemp
]+=1.;
563 printf("time %f larger than tmax %f, stop reading pdo file\n",time
,opt
->tmax
);
578 void enforceEqualWeights(t_UmbrellaWindow
* window
,int nWindows
)
583 NEnforced
=window
[0].Ntot
[0];
584 printf("\nFound -hist-eq. Enforcing equal weights for all histograms, \ni.e. doing a "
585 "non-weighted histogram analysis method. Ndata = %d\n",NEnforced
);
586 /* enforce all histograms to have the same weight as the very first histogram */
588 for(j
=0;j
<nWindows
;++j
)
590 for(k
=0;k
<window
[j
].nPull
;++k
)
592 ratio
=1.0*NEnforced
/window
[j
].Ntot
[k
];
593 for(i
=0;i
<window
[0].nBin
;++i
)
595 window
[j
].Histo
[k
][i
]*=ratio
;
597 window
[j
].N
[k
]=(int)(ratio
*window
[j
].N
[k
] + 0.5);
602 /* Simple linear interpolation between two given tabulated points */
603 double tabulated_pot(double dist
, t_UmbrellaOptions
*opt
)
608 jl
=floor((dist
-opt
->tabMin
)/opt
->tabDz
);
610 if (jl
<0 || ju
>=opt
->tabNbins
)
612 gmx_fatal(FARGS
,"Distance %f out of bounds of tabulated potential (jl=%d, ju=%d).\n"
613 "Provide an extended table.",dist
,jl
,ju
);
617 dz
=dist
-opt
->tabX
[jl
];
618 dp
=(pu
-pl
)*dz
/opt
->tabDz
;
623 /* Don't worry, that routine does not mean we compute the PMF in limited precision.
624 After rapid convergence (using only substiantal contributions), we always switch to
626 void setup_acc_wham(double *profile
,t_UmbrellaWindow
* window
,int nWindows
,
627 t_UmbrellaOptions
*opt
)
629 int i
,j
,k
,nGrptot
=0,nContrib
=0,nTot
=0;
630 double U
,min
=opt
->min
,dz
=opt
->dz
,temp
,ztot_half
,distance
,ztot
,contrib1
,contrib2
;
631 gmx_bool bAnyContrib
;
633 static double wham_contrib_lim
;
637 for(i
=0;i
<nWindows
;++i
)
639 nGrptot
+=window
[i
].nPull
;
641 wham_contrib_lim
=opt
->Tolerance
/nGrptot
;
644 ztot
=opt
->max
-opt
->min
;
647 for(i
=0;i
<nWindows
;++i
)
649 if ( ! window
[i
].bContrib
)
651 snew(window
[i
].bContrib
,window
[i
].nPull
);
653 for(j
=0;j
<window
[i
].nPull
;++j
)
655 if ( ! window
[i
].bContrib
[j
])
656 snew(window
[i
].bContrib
[j
],opt
->bins
);
658 for(k
=0;k
<opt
->bins
;++k
)
660 temp
=(1.0*k
+0.5)*dz
+min
;
661 distance
= temp
- window
[i
].pos
[j
]; /* distance to umbrella center */
663 { /* in cyclic wham: */
664 if (distance
> ztot_half
) /* |distance| < ztot_half */
666 else if (distance
< -ztot_half
)
669 /* Note: there are two contributions to bin k in the wham equations:
670 i) N[j]*exp(- U/(8.314e-3*opt->Temperature) + window[i].z[j])
671 ii) exp(- U/(8.314e-3*opt->Temperature))
672 where U is the umbrella potential
673 If any of these number is larger wham_contrib_lim, I set contrib=TRUE
677 U
=0.5*window
[i
].k
[j
]*sqr(distance
); /* harmonic potential assumed. */
679 U
=tabulated_pot(distance
,opt
); /* Use tabulated potential */
681 contrib1
=profile
[k
]*exp(- U
/(8.314e-3*opt
->Temperature
));
682 contrib2
=window
[i
].N
[j
]*exp(- U
/(8.314e-3*opt
->Temperature
) + window
[i
].z
[j
]);
683 window
[i
].bContrib
[j
][k
] = (contrib1
> wham_contrib_lim
|| contrib2
> wham_contrib_lim
);
684 bAnyContrib
= (bAnyContrib
| window
[i
].bContrib
[j
][k
]);
685 if (window
[i
].bContrib
[j
][k
])
689 /* If this histo is far outside min and max all bContrib may be FALSE,
690 causing a floating point exception later on. To avoid that, switch
693 for(k
=0;k
<opt
->bins
;++k
)
694 window
[i
].bContrib
[j
][k
]=TRUE
;
698 printf("Initialized rapid wham stuff (contrib tolerance %g)\n"
699 "Evaluating only %d of %d expressions.\n\n",wham_contrib_lim
,nContrib
, nTot
);
702 printf("Updated rapid wham stuff. (evaluating only %d of %d contributions)\n",
708 void calc_profile(double *profile
,t_UmbrellaWindow
* window
, int nWindows
,
709 t_UmbrellaOptions
*opt
, gmx_bool bExact
)
712 double num
,ztot_half
,ztot
,distance
,min
=opt
->min
,dz
=opt
->dz
;
713 double denom
,U
=0,temp
=0,invg
;
715 ztot
=opt
->max
-opt
->min
;
718 for(i
=0;i
<opt
->bins
;++i
)
721 for(j
=0;j
<nWindows
;++j
)
723 for(k
=0;k
<window
[j
].nPull
;++k
)
725 invg
= 1.0/window
[j
].g
[k
] * window
[j
].bsWeight
[k
];
726 temp
= (1.0*i
+0.5)*dz
+min
;
727 num
+= invg
*window
[j
].Histo
[k
][i
];
729 if (! (bExact
|| window
[j
].bContrib
[k
][i
]))
731 distance
= temp
- window
[j
].pos
[k
]; /* distance to umbrella center */
733 { /* in cyclic wham: */
734 if (distance
> ztot_half
) /* |distance| < ztot_half */
736 else if (distance
< -ztot_half
)
741 U
=0.5*window
[j
].k
[k
]*sqr(distance
); /* harmonic potential assumed. */
743 U
=tabulated_pot(distance
,opt
); /* Use tabulated potential */
744 denom
+=invg
*window
[j
].N
[k
]*exp(- U
/(8.314e-3*opt
->Temperature
) + window
[j
].z
[k
]);
747 profile
[i
]=num
/denom
;
752 double calc_z(double * profile
,t_UmbrellaWindow
* window
, int nWindows
,
753 t_UmbrellaOptions
*opt
, gmx_bool bExact
)
756 double U
=0,min
=opt
->min
,dz
=opt
->dz
,temp
,ztot_half
,distance
,ztot
,totalMax
;
757 double MAX
=-1e20
, total
=0;
759 ztot
=opt
->max
-opt
->min
;
762 for(i
=0;i
<nWindows
;++i
)
764 for(j
=0;j
<window
[i
].nPull
;++j
)
767 for(k
=0;k
<window
[i
].nBin
;++k
)
769 if (! (bExact
|| window
[i
].bContrib
[j
][k
]))
771 temp
=(1.0*k
+0.5)*dz
+min
;
772 distance
= temp
- window
[i
].pos
[j
]; /* distance to umbrella center */
774 { /* in cyclic wham: */
775 if (distance
> ztot_half
) /* |distance| < ztot_half */
777 else if (distance
< -ztot_half
)
782 U
=0.5*window
[i
].k
[j
]*sqr(distance
); /* harmonic potential assumed. */
784 U
=tabulated_pot(distance
,opt
); /* Use tabulated potential */
786 total
+=profile
[k
]*exp(-U
/(8.314e-3*opt
->Temperature
));
788 /* Avoid floating point exception if window is far outside min and max */
793 temp
= fabs(total
- window
[i
].z
[j
]);
799 window
[i
].z
[j
] = total
;
805 void symmetrizeProfile(double* profile
,t_UmbrellaOptions
*opt
)
808 double *prof2
,bins
=opt
->bins
,min
=opt
->min
,max
=opt
->max
,dz
=opt
->dz
,zsym
,deltaz
,profsym
;
811 if (min
>0. || max
<0.)
812 gmx_fatal(FARGS
,"Cannot symmetrize profile around z=0 with min=%f and max=%f\n",
821 /* bin left of zsym */
822 j
=floor((zsym
-min
)/dz
-0.5);
823 if (j
>=0 && (j
+1)<bins
)
825 /* interpolate profile linearly between bins j and j+1 */
828 profsym
=profile
[j
] + (profile
[j
+1]-profile
[j
])/dz
*deltaz
;
829 /* average between left and right */
830 prof2
[i
]=0.5*(profsym
+profile
[i
]);
838 memcpy(profile
,prof2
,bins
*sizeof(double));
842 void prof_normalization_and_unit(double * profile
, t_UmbrellaOptions
*opt
)
845 double unit_factor
=1., R_MolarGasConst
, diff
;
847 R_MolarGasConst
=8.314472e-3; /* in kJ/(mol*K) */
850 /* Not log? Nothing to do! */
854 /* Get profile in units of kT, kJ/mol, or kCal/mol */
855 if (opt
->unit
== en_kT
)
857 else if (opt
->unit
== en_kJ
)
858 unit_factor
=R_MolarGasConst
*opt
->Temperature
;
859 else if (opt
->unit
== en_kCal
)
860 unit_factor
=R_MolarGasConst
*opt
->Temperature
/4.1868;
862 gmx_fatal(FARGS
,"Sorry, I don't know this energy unit.");
866 profile
[i
]=-log(profile
[i
])*unit_factor
;
868 /* shift to zero at z=opt->zProf0 */
875 /* Get bin with shortest distance to opt->zProf0
876 (-0.5 from bin position and +0.5 from rounding cancel) */
877 imin
=(int)((opt
->zProf0
-opt
->min
)/opt
->dz
);
890 void getRandomIntArray(int nPull
,int blockLength
,int* randomArray
,gmx_rng_t rng
)
892 int ipull
,blockBase
,nr
,ipullRandom
;
897 for (ipull
=0; ipull
<nPull
; ipull
++)
899 blockBase
=(ipull
/blockLength
)*blockLength
;
901 { /* make sure nothing bad happens in the last block */
902 nr
=(int)(gmx_rng_uniform_real(rng
)*blockLength
);
903 ipullRandom
= blockBase
+ nr
;
904 } while (ipullRandom
>= nPull
);
905 if (ipullRandom
<0 || ipullRandom
>=nPull
)
906 gmx_fatal(FARGS
,"Ups, random iWin = %d, nPull = %d, nr = %d, "
907 "blockLength = %d, blockBase = %d\n",
908 ipullRandom
,nPull
,nr
,blockLength
,blockBase
);
909 randomArray
[ipull
]=ipullRandom
;
911 /*for (ipull=0; ipull<nPull; ipull++)
912 printf("%d ",randomArray[ipull]); printf("\n"); */
915 void copy_pullgrp_to_synthwindow(t_UmbrellaWindow
*synthWindow
,
916 t_UmbrellaWindow
*thisWindow
,int pullid
)
918 synthWindow
->N
[0]=thisWindow
->N
[pullid
];
919 synthWindow
->Histo
[0]=thisWindow
->Histo
[pullid
];
920 synthWindow
->pos
[0]=thisWindow
->pos
[pullid
];
921 synthWindow
->z
[0]=thisWindow
->z
[pullid
];
922 synthWindow
->k
[0]=thisWindow
->k
[pullid
];
923 synthWindow
->bContrib
[0]=thisWindow
->bContrib
[pullid
];
924 synthWindow
->g
[0]=thisWindow
->g
[pullid
];
925 synthWindow
->bsWeight
[0]=thisWindow
->bsWeight
[pullid
];
928 /* Calculate cumulative distribution function of of all histograms. They
929 allow to create random number sequences
930 which are distributed according to the histograms. Required to generate
931 the "synthetic" histograms for the Bootstrap method */
932 void calc_cumulatives(t_UmbrellaWindow
*window
,int nWindows
,
933 t_UmbrellaOptions
*opt
,const char *fnhist
)
942 snew(fn
,strlen(fnhist
)+10);
943 snew(buf
,strlen(fnhist
)+10);
944 sprintf(fn
,"%s_cumul.xvg",strncpy(buf
,fnhist
,strlen(fnhist
)-4));
945 fp
=xvgropen(fn
,"CDFs of umbrella windows","z","CDF",opt
->oenv
);
949 for (i
=0; i
<nWindows
; i
++)
951 snew(window
[i
].cum
,window
[i
].nPull
);
952 for (j
=0; j
<window
[i
].nPull
; j
++)
954 snew(window
[i
].cum
[j
],nbin
+1);
955 window
[i
].cum
[j
][0]=0.;
956 for (k
=1; k
<=nbin
; k
++)
957 window
[i
].cum
[j
][k
] = window
[i
].cum
[j
][k
-1]+window
[i
].Histo
[j
][k
-1];
959 /* normalize CDFs. Ensure cum[nbin]==1 */
960 last
= window
[i
].cum
[j
][nbin
];
961 for (k
=0; k
<=nbin
; k
++)
962 window
[i
].cum
[j
][k
] /= last
;
966 printf("Cumulative distriubtion functions of all histograms created.\n");
969 for (k
=0; k
<=nbin
; k
++)
971 fprintf(fp
,"%g\t",opt
->min
+k
*opt
->dz
);
972 for (i
=0; i
<nWindows
; i
++)
973 for (j
=0; j
<window
[i
].nPull
; j
++)
974 fprintf(fp
,"%g\t",window
[i
].cum
[j
][k
]);
977 printf("Wrote cumulative distribution functions to %s\n",fn
);
985 /* Return j such that xx[j] <= x < xx[j+1] */
986 void searchCumulative(double xx
[], int n
, double x
, int *j
)
1002 else if (x
==xx
[n
-1])
1008 void create_synthetic_histo(t_UmbrellaWindow
*synthWindow
, t_UmbrellaWindow
*thisWindow
,
1009 int pullid
,t_UmbrellaOptions
*opt
)
1011 int N
,i
,nbins
,r_index
,ibin
;
1012 double r
,tausteps
=0.0,a
,ap
,dt
,x
,invsqrt2
,g
,y
,sig
=0.,z
,mu
=0.;
1015 N
=thisWindow
->N
[pullid
];
1017 nbins
=thisWindow
->nBin
;
1019 /* tau = autocorrelation time */
1020 if (opt
->tauBootStrap
>0.0)
1021 tausteps
=opt
->tauBootStrap
/dt
;
1022 else if (opt
->bTauIntGiven
|| opt
->bCalcTauInt
)
1024 /* calc tausteps from g=1+2tausteps */
1025 g
=thisWindow
->g
[pullid
];
1031 "When generating hypothetical trajctories from given umbrella histograms,\n"
1032 "autocorrelation times (ACTs) are required. Otherwise the statistical error\n"
1033 "cannot be predicted. You have 3 options:\n"
1034 "1) Make g_wham estimate the ACTs (options -ac and -acsig).\n"
1035 "2) Calculate the ACTs by yourself (e.g. with g_analyze) and provide them\n");
1037 " with option -iiact for all umbrella windows.\n"
1038 "3) If all ACTs are identical and know, you can define them with -bs-tau.\n"
1039 " Use option (3) only if you are sure what you're doing, you may severely\n"
1040 " underestimate the error if a too small ACT is given.\n");
1041 gmx_fatal(FARGS
,errstr
);
1044 synthWindow
->N
[0]=N
;
1045 synthWindow
->pos
[0]=thisWindow
->pos
[pullid
];
1046 synthWindow
->z
[0]=thisWindow
->z
[pullid
];
1047 synthWindow
->k
[0]=thisWindow
->k
[pullid
];
1048 synthWindow
->bContrib
[0]=thisWindow
->bContrib
[pullid
];
1049 synthWindow
->g
[0]=thisWindow
->g
[pullid
];
1050 synthWindow
->bsWeight
[0]=thisWindow
->bsWeight
[pullid
];
1052 for (i
=0;i
<nbins
;i
++)
1053 synthWindow
->Histo
[0][i
]=0.;
1055 if (opt
->bsMethod
==bsMethod_trajGauss
)
1057 sig
= thisWindow
->sigma
[pullid
];
1058 mu
= thisWindow
->aver
[pullid
];
1061 /* Genrate autocorrelated Gaussian random variable with autocorrelation time tau
1063 If x and y are random numbers from N(0,1) (Gaussian with average 0 and sigma=1),
1065 z = a*x + sqrt(1-a^2)*y
1066 is also from N(0,1), and cov(z,x) = a. Thus, by gerenating a sequence
1067 x' = a*x + sqrt(1-a^2)*y, the sequnce x(t) is from N(0,1) and has an autocorrelation
1069 C(t) = exp(-t/tau) with tau=-1/ln(a)
1071 Then, use error function to turn the Gaussian random variable into a uniformly
1072 distributed one in [0,1]. Eventually, use cumulative distribution function of
1073 histogram to get random variables distributed according to histogram.
1074 Note: The ACT of the flat distribution and of the generated histogram is not
1075 100% exactly tau, but near tau (my test was 3.8 instead of 4).
1077 a
=exp(-1.0/tausteps
);
1079 invsqrt2
=1./sqrt(2.0);
1081 /* init random sequence */
1082 x
=gmx_rng_gaussian_table(opt
->rng
);
1084 if (opt
->bsMethod
==bsMethod_traj
)
1086 /* bootstrap points from the umbrella histograms */
1089 y
=gmx_rng_gaussian_table(opt
->rng
);
1091 /* get flat distribution in [0,1] using cumulative distribution function of Gauusian
1092 Note: CDF(Gaussian) = 0.5*{1+erf[x/sqrt(2)]}
1094 r
=0.5*(1+gmx_erf(x
*invsqrt2
));
1095 searchCumulative(thisWindow
->cum
[pullid
],nbins
+1 ,r
,&r_index
);
1096 synthWindow
->Histo
[0][r_index
]+=1.;
1099 else if (opt
->bsMethod
==bsMethod_trajGauss
)
1101 /* bootstrap points from a Gaussian with the same average and sigma
1102 as the respective umbrella histogram. The idea was, that -given
1103 limited sampling- the bootstrapped histograms are otherwise biased
1104 from the limited sampling of the US histos. However, bootstrapping from
1105 the Gaussian seems to yield a similar estimate. */
1109 y
=gmx_rng_gaussian_table(opt
->rng
);
1112 ibin
=floor((z
-opt
->min
)/opt
->dz
);
1116 while ( (ibin
+=nbins
) < 0);
1117 else if (ibin
>=nbins
)
1118 while ( (ibin
-=nbins
) >= nbins
);
1121 if (ibin
>=0 && ibin
<nbins
)
1123 synthWindow
->Histo
[0][ibin
]+=1.;
1130 gmx_fatal(FARGS
,"Unknown bsMethod (id %d). That should not happen.\n",opt
->bsMethod
);
1135 void print_histograms(const char *fnhist
, t_UmbrellaWindow
* window
, int nWindows
,
1136 int bs_index
,t_UmbrellaOptions
*opt
)
1138 char *fn
=0,*buf
=0,title
[256];
1145 strcpy(title
,"Umbrella histograms");
1149 snew(fn
,strlen(fnhist
)+10);
1150 snew(buf
,strlen(fnhist
)+1);
1151 sprintf(fn
,"%s_bs%d.xvg",strncpy(buf
,fnhist
,strlen(fnhist
)-4),bs_index
);
1152 sprintf(title
,"Umbrella histograms. Bootstrap #%d",bs_index
);
1155 fp
=xvgropen(fn
,title
,"z","count",opt
->oenv
);
1158 /* Write histograms */
1161 fprintf(fp
,"%e\t",(double)(l
+0.5)*opt
->dz
+opt
->min
);
1162 for(i
=0;i
<nWindows
;++i
)
1164 for(j
=0;j
<window
[i
].nPull
;++j
)
1166 fprintf(fp
,"%e\t",window
[i
].Histo
[j
][l
]);
1173 printf("Wrote %s\n",fn
);
1181 int func_wham_is_larger(const void *a
, const void *b
)
1195 void setRandomBsWeights(t_UmbrellaWindow
*synthwin
,int nAllPull
, t_UmbrellaOptions
*opt
)
1202 /* generate ordered random numbers between 0 and nAllPull */
1203 for (i
=0; i
<nAllPull
-1; i
++)
1205 r
[i
] = gmx_rng_uniform_real(opt
->rng
) * nAllPull
;
1207 qsort((void *)r
,nAllPull
-1, sizeof(double), &func_wham_is_larger
);
1208 r
[nAllPull
-1]=1.0*nAllPull
;
1210 synthwin
[0].bsWeight
[0]=r
[0];
1211 for (i
=1; i
<nAllPull
; i
++)
1213 synthwin
[i
].bsWeight
[0]=r
[i
]-r
[i
-1];
1216 /* avoid to have zero weight by adding a tiny value */
1217 for (i
=0; i
<nAllPull
; i
++)
1218 if (synthwin
[i
].bsWeight
[0] < 1e-5)
1219 synthwin
[i
].bsWeight
[0] = 1e-5;
1224 void do_bootstrapping(const char *fnres
, const char* fnprof
, const char *fnhist
,
1225 char* ylabel
, double *profile
,
1226 t_UmbrellaWindow
* window
, int nWindows
, t_UmbrellaOptions
*opt
)
1228 t_UmbrellaWindow
* synthWindow
;
1229 double *bsProfile
,*bsProfiles_av
, *bsProfiles_av2
,maxchange
=1e20
,tmp
,stddev
;
1230 int i
,j
,*randomArray
=0,winid
,pullid
,ib
;
1231 int iAllPull
,nAllPull
,*allPull_winId
,*allPull_pullId
;
1233 gmx_bool bExact
=FALSE
;
1235 /* init random generator */
1236 if (opt
->bsSeed
==-1)
1237 opt
->rng
=gmx_rng_init(gmx_rng_make_seed());
1239 opt
->rng
=gmx_rng_init(opt
->bsSeed
);
1241 snew(bsProfile
, opt
->bins
);
1242 snew(bsProfiles_av
, opt
->bins
);
1243 snew(bsProfiles_av2
,opt
->bins
);
1245 /* Create array of all pull groups. Note that different windows
1246 may have different nr of pull groups
1247 First: Get total nr of pull groups */
1249 for (i
=0;i
<nWindows
;i
++)
1250 nAllPull
+=window
[i
].nPull
;
1251 snew(allPull_winId
,nAllPull
);
1252 snew(allPull_pullId
,nAllPull
);
1254 /* Setup one array of all pull groups */
1255 for (i
=0;i
<nWindows
;i
++)
1257 for (j
=0;j
<window
[i
].nPull
;j
++)
1259 allPull_winId
[iAllPull
]=i
;
1260 allPull_pullId
[iAllPull
]=j
;
1265 /* setup stuff for synthetic windows */
1266 snew(synthWindow
,nAllPull
);
1267 for (i
=0;i
<nAllPull
;i
++)
1269 synthWindow
[i
].nPull
=1;
1270 synthWindow
[i
].nBin
=opt
->bins
;
1271 snew(synthWindow
[i
].Histo
,1);
1272 if (opt
->bsMethod
== bsMethod_traj
|| opt
->bsMethod
== bsMethod_trajGauss
)
1273 snew(synthWindow
[i
].Histo
[0],opt
->bins
);
1274 snew(synthWindow
[i
].N
,1);
1275 snew(synthWindow
[i
].pos
,1);
1276 snew(synthWindow
[i
].z
,1);
1277 snew(synthWindow
[i
].k
,1);
1278 snew(synthWindow
[i
].bContrib
,1);
1279 snew(synthWindow
[i
].g
,1);
1280 snew(synthWindow
[i
].bsWeight
,1);
1283 switch(opt
->bsMethod
)
1286 snew(randomArray
,nAllPull
);
1287 printf("\n\nWhen computing statistical errors by bootstrapping entire histograms:\n");
1288 please_cite(stdout
,"Hub2006");
1290 case bsMethod_BayesianHist
:
1291 /* just copy all histogams into synthWindow array */
1292 for (i
=0;i
<nAllPull
;i
++)
1294 winid
=allPull_winId
[i
];
1295 pullid
=allPull_pullId
[i
];
1296 copy_pullgrp_to_synthwindow(synthWindow
+i
,window
+winid
,pullid
);
1300 case bsMethod_trajGauss
:
1301 calc_cumulatives(window
,nWindows
,opt
,fnhist
);
1304 gmx_fatal(FARGS
,"Unknown bootstrap method. That should not have happened.\n");
1307 /* do bootstrapping */
1308 fp
=xvgropen(fnprof
,"Boot strap profiles","z",ylabel
,opt
->oenv
);
1309 for (ib
=0;ib
<opt
->nBootStrap
;ib
++)
1311 printf(" *******************************************\n"
1312 " ******** Start bootstrap nr %d ************\n"
1313 " *******************************************\n",ib
+1);
1315 switch(opt
->bsMethod
)
1318 /* bootstrap complete histograms from given histograms */
1319 getRandomIntArray(nAllPull
,opt
->histBootStrapBlockLength
,randomArray
,opt
->rng
);
1320 for (i
=0;i
<nAllPull
;i
++){
1321 winid
=allPull_winId
[randomArray
[i
]];
1322 pullid
=allPull_pullId
[randomArray
[i
]];
1323 copy_pullgrp_to_synthwindow(synthWindow
+i
,window
+winid
,pullid
);
1326 case bsMethod_BayesianHist
:
1327 /* keep histos, but assign random weights ("Bayesian bootstrap") */
1328 setRandomBsWeights(synthWindow
,nAllPull
,opt
);
1331 case bsMethod_trajGauss
:
1332 /* create new histos from given histos, that is generate new hypothetical
1334 for (i
=0;i
<nAllPull
;i
++)
1336 winid
=allPull_winId
[i
];
1337 pullid
=allPull_pullId
[i
];
1338 create_synthetic_histo(synthWindow
+i
,window
+winid
,pullid
,opt
);
1343 /* write histos in case of verbose output */
1344 if (opt
->bs_verbose
)
1345 print_histograms(fnhist
,synthWindow
,nAllPull
,ib
,opt
);
1351 memcpy(bsProfile
,profile
,opt
->bins
*sizeof(double)); /* use profile as guess */
1354 if ( (i
%opt
->stepUpdateContrib
) == 0)
1355 setup_acc_wham(bsProfile
,synthWindow
,nAllPull
,opt
);
1356 if (maxchange
<opt
->Tolerance
)
1358 if (((i
%opt
->stepchange
) == 0 || i
==1) && !i
==0)
1359 printf("\t%4d) Maximum change %e\n",i
,maxchange
);
1360 calc_profile(bsProfile
,synthWindow
,nAllPull
,opt
,bExact
);
1362 } while( (maxchange
=calc_z(bsProfile
, synthWindow
, nAllPull
, opt
,bExact
)) > opt
->Tolerance
|| !bExact
);
1363 printf("\tConverged in %d iterations. Final maximum change %g\n",i
,maxchange
);
1366 prof_normalization_and_unit(bsProfile
,opt
);
1368 /* symmetrize profile around z=0 */
1370 symmetrizeProfile(bsProfile
,opt
);
1372 /* save stuff to get average and stddev */
1373 for (i
=0;i
<opt
->bins
;i
++)
1376 bsProfiles_av
[i
]+=tmp
;
1377 bsProfiles_av2
[i
]+=tmp
*tmp
;
1378 fprintf(fp
,"%e\t%e\n",(i
+0.5)*opt
->dz
+opt
->min
,tmp
);
1384 /* write average and stddev */
1385 fp
=xvgropen(fnres
,"Average and stddev from bootstrapping","z",ylabel
,opt
->oenv
);
1386 fprintf(fp
,"@TYPE xydy\n");
1387 for (i
=0;i
<opt
->bins
;i
++)
1389 bsProfiles_av
[i
]/=opt
->nBootStrap
;
1390 bsProfiles_av2
[i
]/=opt
->nBootStrap
;
1391 tmp
=bsProfiles_av2
[i
]-sqr(bsProfiles_av
[i
]);
1392 stddev
=(tmp
>=0.) ? sqrt(tmp
) : 0.; /* Catch rouding errors */
1393 fprintf(fp
,"%e\t%e\t%e\n",(i
+0.5)*opt
->dz
+opt
->min
,bsProfiles_av
[i
],stddev
);
1396 printf("Wrote boot strap result to %s\n",fnres
);
1399 int whaminFileType(char *fn
)
1403 if (strcmp(fn
+len
-3,"tpr")==0)
1405 else if (strcmp(fn
+len
-3,"xvg")==0 || strcmp(fn
+len
-6,"xvg.gz")==0)
1406 return whamin_pullxf
;
1407 else if (strcmp(fn
+len
-3,"pdo")==0 || strcmp(fn
+len
-6,"pdo.gz")==0)
1410 gmx_fatal(FARGS
,"Unknown file type of %s. Should be tpr, xvg, or pdo.\n",fn
);
1411 return whamin_unknown
;
1414 void read_wham_in(const char *fn
,char ***filenamesRet
, int *nfilesRet
,
1415 t_UmbrellaOptions
*opt
)
1417 char **filename
=0,tmp
[STRLEN
];
1418 int nread
,sizenow
,i
,block
=1;
1424 while (fscanf(fp
,"%s",tmp
) != EOF
)
1426 if (strlen(tmp
)>=WHAM_MAXFILELEN
)
1427 gmx_fatal(FARGS
,"Filename too long. Only %d characters allowed\n",WHAM_MAXFILELEN
);
1431 srenew(filename
,sizenow
);
1432 for (i
=sizenow
-block
;i
<sizenow
;i
++)
1433 snew(filename
[i
],WHAM_MAXFILELEN
);
1435 strcpy(filename
[nread
],tmp
);
1437 printf("Found file %s in %s\n",filename
[nread
],fn
);
1440 *filenamesRet
=filename
;
1445 FILE *open_pdo_pipe(const char *fn
, t_UmbrellaOptions
*opt
,gmx_bool
*bPipeOpen
)
1447 char Buffer
[1024],gunzip
[1024],*Path
=0;
1449 static gmx_bool bFirst
=1;
1451 /* gzipped pdo file? */
1452 if ((strcmp(fn
+strlen(fn
)-3,".gz")==0))
1454 /* search gunzip executable */
1455 if(!(Path
=getenv("GMX_PATH_GZIP")))
1457 if (gmx_fexist("/bin/gunzip"))
1458 sprintf(gunzip
,"%s","/bin/gunzip");
1459 else if (gmx_fexist("/usr/bin/gunzip"))
1460 sprintf(gunzip
,"%s","/usr/bin/gunzip");
1462 gmx_fatal(FARGS
,"Cannot find executable gunzip in /bin or /usr/bin.\n"
1463 "You may want to define the path to gunzip "
1464 "with the environment variable GMX_PATH_GZIP.",gunzip
);
1468 sprintf(gunzip
,"%s/gunzip",Path
);
1469 if (!gmx_fexist(gunzip
))
1470 gmx_fatal(FARGS
,"Cannot find executable %s. Please define the path to gunzip"
1471 " in the environmental varialbe GMX_PATH_GZIP.",gunzip
);
1475 printf("Using gunzig executable %s\n",gunzip
);
1478 if (!gmx_fexist(fn
))
1480 gmx_fatal(FARGS
,"File %s does not exist.\n",fn
);
1482 sprintf(Buffer
,"%s -c < %s",gunzip
,fn
);
1484 printf("Executing command '%s'\n",Buffer
);
1486 if((pipe
=popen(Buffer
,"r"))==NULL
)
1488 gmx_fatal(FARGS
,"Unable to open pipe to `%s'\n",Buffer
);
1491 gmx_fatal(FARGS
,"Cannot open a compressed file on platform without pipe support");
1496 pipe
=ffopen(fn
,"r");
1503 void pdo_close_file(FILE *fp
)
1512 /* Reading pdo files */
1513 void read_pdo_files(char **fn
, int nfiles
, t_UmbrellaHeader
* header
,
1514 t_UmbrellaWindow
*window
, t_UmbrellaOptions
*opt
)
1517 real mintmp
,maxtmp
,done
=0.;
1520 /* char Buffer0[1000]; */
1523 gmx_fatal(FARGS
,"No files found. Hick.");
1525 /* if min and max are not given, get min and max from the input files */
1528 printf("Automatic determination of boundaries from %d pdo files...\n",nfiles
);
1531 for(i
=0;i
<nfiles
;++i
)
1533 file
=open_pdo_pipe(fn
[i
],opt
,&bPipeOpen
);
1534 /*fgets(Buffer0,999,file);
1535 fprintf(stderr,"First line '%s'\n",Buffer0); */
1536 done
=100.0*(i
+1)/nfiles
;
1537 printf("\rOpening %s ... [%2.0f%%]",fn
[i
],done
); fflush(stdout
);
1540 read_pdo_header(file
,header
,opt
);
1541 /* here only determine min and max of this window */
1542 read_pdo_data(file
,header
,i
,NULL
,opt
,TRUE
,&mintmp
,&maxtmp
);
1543 if (maxtmp
>opt
->max
)
1545 if (mintmp
<opt
->min
)
1548 pdo_close_file(file
);
1553 printf("\nDetermined boundaries to %f and %f\n\n",opt
->min
,opt
->max
);
1554 if (opt
->bBoundsOnly
)
1556 printf("Found option -boundsonly, now exiting.\n");
1560 /* store stepsize in profile */
1561 opt
->dz
=(opt
->max
-opt
->min
)/opt
->bins
;
1563 /* Having min and max, we read in all files */
1564 /* Loop over all files */
1565 for(i
=0;i
<nfiles
;++i
)
1567 done
=100.0*(i
+1)/nfiles
;
1568 printf("\rOpening %s ... [%2.0f%%]",fn
[i
],done
); fflush(stdout
);
1571 file
=open_pdo_pipe(fn
[i
],opt
,&bPipeOpen
);
1572 read_pdo_header(file
,header
,opt
);
1573 /* load data into window */
1574 read_pdo_data(file
,header
,i
,window
,opt
,FALSE
,NULL
,NULL
);
1575 if ((window
+i
)->Ntot
[0] == 0.0)
1576 fprintf(stderr
,"\nWARNING, no data points read from file %s (check -b option)\n", fn
[i
]);
1578 pdo_close_file(file
);
1583 for(i
=0;i
<nfiles
;++i
)
1588 #define int2YN(a) (((a)==0)?("N"):("Y"))
1590 void read_tpr_header(const char *fn
,t_UmbrellaHeader
* header
,t_UmbrellaOptions
*opt
)
1597 /* printf("Reading %s \n",fn); */
1598 read_tpx_state(fn
,&ir
,&state
,NULL
,NULL
);
1600 if (ir
.ePull
!= epullUMBRELLA
)
1601 gmx_fatal(FARGS
,"This is not a tpr of an umbrella simulation. Found pull type \"%s\" "
1602 " (ir.ePull = %d)\n", epull_names
[ir
.ePull
],ir
.ePull
);
1604 /* nr of pull groups */
1607 gmx_fatal(FARGS
,"This is not a tpr of umbrella simulation. Found only %d pull groups\n",ngrp
);
1609 header
->npullgrps
=ir
.pull
->ngrp
;
1610 header
->pull_geometry
=ir
.pull
->eGeom
;
1611 copy_ivec(ir
.pull
->dim
,header
->pull_dim
);
1612 header
->pull_ndim
=header
->pull_dim
[0]+header
->pull_dim
[1]+header
->pull_dim
[2];
1613 if (header
->pull_geometry
==epullgPOS
&& header
->pull_ndim
>1)
1615 gmx_fatal(FARGS
,"Found pull geometry 'position' and more than 1 pull dimension (%d).\n"
1616 "Hence, the pull potential does not correspond to a one-dimensional umbrella potential.\n"
1617 "If you have some special umbrella setup you may want to write your own pdo files\n"
1618 "and feed them into g_wham. Check g_wham -h !\n",header
->pull_ndim
);
1620 snew(header
->k
,ngrp
);
1621 snew(header
->init_dist
,ngrp
);
1622 snew(header
->umbInitDist
,ngrp
);
1624 /* only z-direction with epullgCYL? */
1625 if (header
->pull_geometry
== epullgCYL
)
1627 if (header
->pull_dim
[XX
] || header
->pull_dim
[YY
] || (!header
->pull_dim
[ZZ
]))
1628 gmx_fatal(FARGS
,"With pull geometry 'cylinder', expected pulling in Z direction only.\n"
1629 "However, found dimensions [%s %s %s]\n",
1630 int2YN(header
->pull_dim
[XX
]),int2YN(header
->pull_dim
[YY
]),
1631 int2YN(header
->pull_dim
[ZZ
]));
1634 for (i
=0;i
<ngrp
;i
++)
1636 header
->k
[i
]=ir
.pull
->grp
[i
+1].k
;
1637 if (header
->k
[i
]==0.0)
1638 gmx_fatal(FARGS
,"Pull group %d has force constant of of 0.0 in %s.\n"
1639 "That doesn't seem to be an Umbrella tpr.\n",
1641 copy_rvec(ir
.pull
->grp
[i
+1].init
,header
->init_dist
[i
]);
1643 /* initial distance to reference */
1644 switch(header
->pull_geometry
)
1648 if (header
->pull_dim
[d
])
1649 header
->umbInitDist
[i
]=header
->init_dist
[i
][d
];
1652 /* umbrella distance stored in init_dist[i][0] for geometry cylinder (not in ...[i][ZZ]) */
1656 header
->umbInitDist
[i
]=header
->init_dist
[i
][0];
1659 gmx_fatal(FARGS
,"Pull geometry %s not supported\n",epullg_names
[header
->pull_geometry
]);
1663 if (opt
->verbose
|| first
)
1665 printf("File %s, %d groups, geometry \"%s\", dimensions [%s %s %s], (%d dimensions)\n",
1666 fn
,header
->npullgrps
,epullg_names
[header
->pull_geometry
],
1667 int2YN(header
->pull_dim
[0]),int2YN(header
->pull_dim
[1]),int2YN(header
->pull_dim
[2]),
1669 for (i
=0;i
<ngrp
;i
++)
1670 printf("\tgrp %d) k = %-5g position = %g\n",i
,header
->k
[i
],header
->umbInitDist
[i
]);
1672 if (!opt
->verbose
&& first
)
1673 printf("\tUse option -v to see this output for all input tpr files\n");
1679 double dist_ndim(double **dx
,int ndim
,int line
)
1683 for (i
=0;i
<ndim
;i
++)
1684 r2
+=sqr(dx
[i
][line
]);
1688 void read_pull_xf(const char *fn
, const char *fntpr
, t_UmbrellaHeader
* header
,
1689 t_UmbrellaWindow
* window
,
1690 t_UmbrellaOptions
*opt
,
1691 gmx_bool bGetMinMax
,real
*mintmp
,real
*maxtmp
)
1693 double **y
=0,pos
=0.,t
,force
,time0
=0.,dt
;
1694 int ny
,nt
,bins
,ibin
,i
,g
,dstep
=1,nColPerGrp
,nColRefOnce
,nColRefEachGrp
,nColExpect
,ntot
;
1695 real min
,max
,minfound
=1e20
,maxfound
=-1e20
;
1696 gmx_bool dt_ok
,timeok
,bHaveForce
;
1697 const char *quantity
;
1698 const int blocklen
=4096;
1702 in force output pullf.xvg:
1703 No reference, one column per pull group
1704 in position output pullx.xvg (not cylinder)
1705 ndim reference, ndim columns per pull group
1706 in position output pullx.xvg (in geometry cylinder):
1707 ndim*2 columns per pull group (ndim for ref, ndim for group)
1710 nColPerGrp
= opt
->bPullx
? header
->pull_ndim
: 1;
1711 quantity
= opt
->bPullx
? "position" : "force";
1715 if (header
->pull_geometry
== epullgCYL
)
1717 /* Geometry cylinder -> reference group before each pull group */
1718 nColRefEachGrp
=header
->pull_ndim
;
1723 /* Geometry NOT cylinder -> reference group only once after time column */
1725 nColRefOnce
=header
->pull_ndim
;
1728 else /* read forces, no reference groups */
1734 nColExpect
= 1 + nColRefOnce
+ header
->npullgrps
*(nColRefEachGrp
+nColPerGrp
);
1735 bHaveForce
= opt
->bPullf
;
1737 /* With geometry "distance" or "distance_periodic", only force reading is supported so far.
1738 That avoids the somewhat tedious extraction of the right columns from the pullx files
1739 to compute the distances projection on the vector. Sorry for the laziness. */
1740 if ( (header
->pull_geometry
==epullgDIR
|| header
->pull_geometry
==epullgDIRPBC
)
1743 gmx_fatal(FARGS
,"With pull geometries \"direction\" and \"direction_periodic\", only pull force "
1744 "reading \n(option -if) is supported at present, "
1745 "not pull position reading (options -ix).\nMake sure mdrun writes the pull "
1746 "forces (pullf.xvg files)\nand provide them to g_wham with option -if.",
1747 epullg_names
[header
->pull_geometry
]);
1750 nt
=read_xvg(fn
,&y
,&ny
);
1752 /* Check consistency */
1755 gmx_fatal(FARGS
,"Empty pull %s file %s\n",quantity
,fn
);
1757 if (ny
!= nColExpect
)
1759 gmx_fatal(FARGS
,"Found %d pull groups in %s,\n but %d data columns in %s (expected %d)\n"
1760 "\nMaybe you confused options -ix and -if ?\n",
1761 header
->npullgrps
,fntpr
,ny
-1,fn
,nColExpect
-1);
1765 printf("Found %d times and %d %s sets %s\n",nt
,(ny
-1)/nColPerGrp
,quantity
,fn
);
1774 window
->dt
=y
[0][1]-y
[0][0];
1776 else if (opt
->nBootStrap
&& opt
->tauBootStrap
!=0.0)
1778 fprintf(stderr
,"\n *** WARNING, Could not determine time step in %s\n",fn
);
1781 /* Need to alocate memory and set up structure */
1782 window
->nPull
=header
->npullgrps
;
1785 snew(window
->Histo
,window
->nPull
);
1786 snew(window
->z
,window
->nPull
);
1787 snew(window
->k
,window
->nPull
);
1788 snew(window
->pos
,window
->nPull
);
1789 snew(window
->N
, window
->nPull
);
1790 snew(window
->Ntot
, window
->nPull
);
1791 snew(window
->g
, window
->nPull
);
1792 snew(window
->bsWeight
, window
->nPull
);
1795 if (opt
->bCalcTauInt
)
1796 snew(window
->ztime
,window
->nPull
);
1799 snew(lennow
,window
->nPull
);
1801 for(g
=0;g
<window
->nPull
;++g
)
1804 window
->bsWeight
[g
]=1.;
1805 snew(window
->Histo
[g
],bins
);
1806 window
->k
[g
]=header
->k
[g
];
1810 window
->pos
[g
]=header
->umbInitDist
[g
];
1811 if (opt
->bCalcTauInt
)
1812 window
->ztime
[g
]=NULL
;
1817 { /* only determine min and max */
1820 min
=max
=bins
=0; /* Get rid of warnings */
1825 /* Do you want that time frame? */
1826 t
=1.0/1000*( (int) ((y
[0][i
]*1000) + 0.5)); /* round time to fs */
1828 /* get time step of pdo file and get dstep from opt->dt */
1838 dstep
=(int)(opt
->dt
/dt
+0.5);
1843 window
->dt
=dt
*dstep
;
1846 dt_ok
=(i
%dstep
== 0);
1847 timeok
=(dt_ok
&& t
>= opt
->tmin
&& t
<= opt
->tmax
);
1849 printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
1850 t,opt->tmin, opt->tmax, dt_ok,timeok); */
1854 for(g
=0;g
<header
->npullgrps
;++g
)
1858 /* y has 1 time column y[0] and one column per force y[1],...,y[nGrps] */
1860 pos
= -force
/header
->k
[g
] + header
->umbInitDist
[g
];
1864 switch (header
->pull_geometry
)
1867 /* y has 1 time column y[0] and nColPerGrps columns per pull group;
1868 Distance to reference: */
1869 /* pos=dist_ndim(y+1+nColRef+g*nColPerGrp,header->pull_ndim,i); gmx 4.0 */
1870 pos
=dist_ndim(y
+ 1 + nColRefOnce
+ g
*nColPerGrp
,header
->pull_ndim
,i
);
1874 Time ref[ndim] group1[ndim] group2[ndim] ... */
1877 Time ref1[ndim] group1[ndim] ref2[ndim] group2[ndim] ... */
1879 /* * with geometry==position, we have the reference once (nColRefOnce==ndim), but
1880 no extra reference group columns before each group (nColRefEachGrp==0)
1882 * with geometry==cylinder, we have no initial ref group column (nColRefOnce==0),
1883 but ndim ref group colums before every group (nColRefEachGrp==ndim)
1884 Distance to reference: */
1885 pos
=y
[1 + nColRefOnce
+ nColRefEachGrp
+ g
*(nColRefEachGrp
+nColPerGrp
)][i
];
1888 gmx_fatal(FARGS
,"Bad error, this error should have been catched before. Ups.\n");
1892 /* printf("grp %d dpos %f poseq %f pos %f \n",g,dpos,poseq,pos); */
1902 if (opt
->bCalcTauInt
&& !bGetMinMax
)
1904 /* save time series for autocorrelation analysis */
1905 ntot
=window
->Ntot
[g
];
1906 /* printf("i %d, ntot %d, lennow[g] = %d\n",i,ntot,lennow[g]); */
1907 if (ntot
>=lennow
[g
])
1909 lennow
[g
]+=blocklen
;
1910 srenew(window
->ztime
[g
],lennow
[g
]);
1912 window
->ztime
[g
][ntot
]=pos
;
1915 ibin
=(int) floor((pos
-min
)/(max
-min
)*bins
);
1919 while ( (ibin
+=bins
) < 0);
1920 else if (ibin
>=bins
)
1921 while ( (ibin
-=bins
) >= bins
);
1923 if(ibin
>= 0 && ibin
< bins
)
1925 window
->Histo
[g
][ibin
]+=1.;
1932 else if (t
>opt
->tmax
)
1935 printf("time %f larger than tmax %f, stop reading this pullx/pullf file\n",t
,opt
->tmax
);
1950 void read_tpr_pullxf_files(char **fnTprs
,char **fnPull
,int nfiles
,
1951 t_UmbrellaHeader
* header
,
1952 t_UmbrellaWindow
*window
, t_UmbrellaOptions
*opt
)
1957 printf("Reading %d tpr and pullf files\n",nfiles
/2);
1959 /* min and max not given? */
1962 printf("Automatic determination of boundaries...\n");
1965 for (i
=0;i
<nfiles
; i
++)
1967 if (whaminFileType(fnTprs
[i
]) != whamin_tpr
)
1968 gmx_fatal(FARGS
,"Expected the %d'th file in input file to be a tpr file\n",i
);
1969 read_tpr_header(fnTprs
[i
],header
,opt
);
1970 if (whaminFileType(fnPull
[i
]) != whamin_pullxf
)
1971 gmx_fatal(FARGS
,"Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n",i
);
1972 read_pull_xf(fnPull
[i
],fnTprs
[i
],header
,NULL
,opt
,TRUE
,&mintmp
,&maxtmp
);
1973 if (maxtmp
>opt
->max
)
1975 if (mintmp
<opt
->min
)
1978 printf("\nDetermined boundaries to %f and %f\n\n",opt
->min
,opt
->max
);
1979 if (opt
->bBoundsOnly
)
1981 printf("Found option -boundsonly, now exiting.\n");
1985 /* store stepsize in profile */
1986 opt
->dz
=(opt
->max
-opt
->min
)/opt
->bins
;
1988 for (i
=0;i
<nfiles
; i
++)
1990 if (whaminFileType(fnTprs
[i
]) != whamin_tpr
)
1991 gmx_fatal(FARGS
,"Expected the %d'th file in input file to be a tpr file\n",i
);
1992 read_tpr_header(fnTprs
[i
],header
,opt
);
1993 if (whaminFileType(fnPull
[i
]) != whamin_pullxf
)
1994 gmx_fatal(FARGS
,"Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n",i
);
1995 read_pull_xf(fnPull
[i
],fnTprs
[i
],header
,window
+i
,opt
,FALSE
,NULL
,NULL
);
1996 if (window
[i
].Ntot
[0] == 0.0)
1997 fprintf(stderr
,"\nWARNING, no data points read from file %s (check -b option)\n", fnPull
[i
]);
2000 for (i
=0;i
<nfiles
; i
++)
2009 /* Note: Here we consider tau[int] := int_0^inf ACF(t) as the integrated autocorrelation time.
2010 The factor `g := 1 + 2*tau[int]` subsequently enters the uncertainty.
2012 void readIntegratedAutocorrelationTimes(t_UmbrellaWindow
*window
,int nwins
,t_UmbrellaOptions
*opt
,
2018 printf("Readging Integrated autocorrelation times from %s ...\n",fn
);
2019 nlines
=read_xvg(fn
,&iact
,&ny
);
2021 gmx_fatal(FARGS
,"Found %d lines with integrated autocorrelation times in %s.\nExpected %d",
2023 for (i
=0;i
<nlines
;i
++){
2024 if (window
[i
].nPull
!= ny
)
2025 gmx_fatal(FARGS
,"You are providing autocorrelation times with option -iiact and the\n"
2026 "number of pull groups is different in different simulations. That is not\n"
2027 "supported yet. Sorry.\n");
2028 for (ig
=0;ig
<window
[i
].nPull
;ig
++){
2029 /* compare Kumar et al, J Comp Chem 13, 1011-1021 (1992) */
2030 window
[i
].g
[ig
]=1+2*iact
[ig
][i
]/window
[i
].dt
;
2032 if (iact
[ig
][i
] <= 0.0)
2033 fprintf(stderr
,"\nWARNING, IACT = %f (window %d, group %d)\n", iact
[ig
][i
],i
,ig
);
2039 /* Smooth autocorreltion times along the reaction coordinate. This is useful
2040 if the ACT is subject to high uncertainty in case if limited sampling. Note
2041 that -in case of limited sampling- the ACT may be severely underestimated.
2042 Note: the g=1+2tau are overwritten.
2043 if opt->bAllowReduceIact==FALSE, the ACTs are never reduced, only increased
2046 void smoothIact(t_UmbrellaWindow
*window
,int nwins
,t_UmbrellaOptions
*opt
)
2049 double pos
,dpos2
,siglim
,siglim2
,gaufact
,invtwosig2
,w
,weight
,tausm
;
2051 /* only evaluate within +- 3sigma of the Gausian */
2052 siglim
=3.0*opt
->sigSmoothIact
;
2053 siglim2
=dsqr(siglim
);
2054 /* pre-factor of Gaussian */
2055 gaufact
=1.0/(sqrt(2*M_PI
)*opt
->sigSmoothIact
);
2056 invtwosig2
=0.5/dsqr(opt
->sigSmoothIact
);
2058 for (i
=0;i
<nwins
;i
++)
2060 snew(window
[i
].tausmooth
,window
[i
].nPull
);
2061 for (ig
=0;ig
<window
[i
].nPull
;ig
++)
2065 pos
=window
[i
].pos
[ig
];
2066 for (j
=0;j
<nwins
;j
++)
2068 for (jg
=0;jg
<window
[j
].nPull
;jg
++)
2070 dpos2
=dsqr(window
[j
].pos
[jg
]-pos
);
2072 w
=gaufact
*exp(-dpos2
*invtwosig2
);
2074 tausm
+=w
*window
[j
].tau
[jg
];
2075 /*printf("Weight %g dpos2=%g pos=%g gaufact=%g invtwosig2=%g\n",
2076 w,dpos2,pos,gaufact,invtwosig2); */
2081 if (opt
->bAllowReduceIact
|| tausm
>window
[i
].tau
[ig
])
2082 window
[i
].tausmooth
[ig
]=tausm
;
2084 window
[i
].tausmooth
[ig
]=window
[i
].tau
[ig
];
2085 window
[i
].g
[ig
] = 1+2*tausm
/window
[i
].dt
;
2090 /* try to compute the autocorrelation time for each umbrealla window */
2091 #define WHAM_AC_ZERO_LIMIT 0.05
2092 void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow
*window
,int nwins
,
2093 t_UmbrellaOptions
*opt
, const char *fn
)
2095 int i
,ig
,ncorr
,ntot
,j
,k
,*count
,restart
;
2096 real
*corr
,c0
,dt
,timemax
,tmp
;
2097 real
*ztime
,av
,tausteps
;
2101 fpcorr
=xvgropen("hist_autocorr.xvg","Autocorrelation functions of umbrella windows",
2102 "time [ps]","autocorrelation function",opt
->oenv
);
2105 for (i
=0;i
<nwins
;i
++)
2107 printf("\rEstimating integrated autocorreltion times ... [%2.0f%%] ...",100.*(i
+1)/nwins
);
2109 ntot
=window
[i
].Ntot
[0];
2111 /* using half the maximum time as length of autocorrelation function */
2114 gmx_fatal(FARGS
,"Tryig to estimtate autocorrelation time from only %d"
2115 " points. Provide more pull data!",ntot
);
2117 /* snew(corrSq,ncorr); */
2121 snew(window
[i
].tau
,window
[i
].nPull
);
2122 restart
=(int)(opt
->acTrestart
/dt
+0.5);
2126 for (ig
=0;ig
<window
[i
].nPull
;ig
++)
2128 if (ntot
!= window
[i
].Ntot
[ig
])
2129 gmx_fatal(FARGS
,"Encountered different nr of frames in different pull groups.\n"
2130 "That should not happen. (%d and %d)\n", ntot
,window
[i
].Ntot
[ig
]);
2131 ztime
=window
[i
].ztime
[ig
];
2133 /* calc autocorrelation function C(t) = < [z(tau)-<z>]*[z(tau+t)-<z>]> */
2134 for(j
=0, av
=0; (j
<ntot
); j
++)
2137 for(k
=0; (k
<ncorr
); k
++)
2142 for(j
=0; (j
<ntot
); j
+=restart
)
2143 for(k
=0; (k
<ncorr
) && (j
+k
< ntot
); k
++)
2145 tmp
=(ztime
[j
]-av
)*(ztime
[j
+k
]-av
);
2147 /* corrSq[k] += tmp*tmp; */
2150 /* divide by nr of frames for each time displacement */
2151 for(k
=0; (k
<ncorr
); k
++)
2153 /* count probably = (ncorr-k+(restart-1))/restart; */
2154 corr
[k
] = corr
[k
]/count
[k
];
2155 /* variance of autocorrelation function */
2156 /* corrSq[k]=corrSq[k]/count[k]; */
2158 /* normalize such that corr[0] == 0 */
2160 for(k
=0; (k
<ncorr
); k
++)
2163 /* corrSq[k]*=c0*c0; */
2166 /* write ACFs in verbose mode */
2169 for(k
=0; (k
<ncorr
); k
++)
2170 fprintf(fpcorr
,"%g %g\n",k
*dt
,corr
[k
]);
2171 fprintf(fpcorr
,"&\n");
2174 /* esimate integrated correlation time, fitting is too unstable */
2175 tausteps
= 0.5*corr
[0];
2176 /* consider corr below WHAM_AC_ZERO_LIMIT as noise */
2177 for(j
=1; (j
<ncorr
) && (corr
[j
]>WHAM_AC_ZERO_LIMIT
); j
++)
2178 tausteps
+= corr
[j
];
2180 /* g = 1+2*tau, see. Ferrenberg/Swendsen, PRL 63:1195 (1989) or
2181 Kumar et al, eq. 28 ff. */
2182 window
[i
].tau
[ig
] = tausteps
*dt
;
2183 window
[i
].g
[ig
] = 1+2*tausteps
;
2184 /* printf("win %d, group %d, estimated correlation time = %g ps\n",i,ig,window[i].tau[ig]); */
2193 /* plot IACT along reaction coordinate */
2194 fp
=xvgropen(fn
,"Integrated autocorrelation times","z","IACT [ps]",opt
->oenv
);
2195 fprintf(fp
,"@ s0 symbol 1\n@ s0 symbol size 0.5\n@ s0 line linestyle 0\n");
2196 fprintf(fp
,"# WIN tau(gr1) tau(gr2) ...\n");
2197 for (i
=0;i
<nwins
;i
++)
2199 fprintf(fp
,"# %3d ",i
);
2200 for (ig
=0;ig
<window
[i
].nPull
;ig
++)
2201 fprintf(fp
," %11g",window
[i
].tau
[ig
]);
2204 for (i
=0;i
<nwins
;i
++)
2205 for (ig
=0;ig
<window
[i
].nPull
;ig
++)
2206 fprintf(fp
,"%8g %8g\n",window
[i
].pos
[ig
],window
[i
].tau
[ig
]);
2207 if (opt
->sigSmoothIact
> 0.0)
2209 printf("Smoothing autocorrelation times along reaction coordinate with Gaussian of sig = %g\n",
2210 opt
->sigSmoothIact
);
2211 /* smooth IACT along reaction coordinate and overwrite g=1+2tau */
2212 smoothIact(window
,nwins
,opt
);
2213 fprintf(fp
,"&\n@ s1 symbol 1\n@ s1 symbol size 0.5\n@ s1 line linestyle 0\n");
2214 fprintf(fp
,"@ s1 symbol color 2\n");
2215 for (i
=0;i
<nwins
;i
++)
2216 for (ig
=0;ig
<window
[i
].nPull
;ig
++)
2217 fprintf(fp
,"%8g %8g\n",window
[i
].pos
[ig
],window
[i
].tausmooth
[ig
]);
2220 printf("Wrote %s\n",fn
);
2223 /* compute average and sigma of each umbrella window */
2224 void averageSigma(t_UmbrellaWindow
*window
,int nwins
,t_UmbrellaOptions
*opt
)
2227 real av
,sum2
,sig
,diff
,*ztime
,nSamplesIndep
;
2229 for (i
=0;i
<nwins
;i
++)
2231 snew(window
[i
].aver
, window
[i
].nPull
);
2232 snew(window
[i
].sigma
,window
[i
].nPull
);
2234 ntot
=window
[i
].Ntot
[0];
2235 for (ig
=0;ig
<window
[i
].nPull
;ig
++)
2237 ztime
=window
[i
].ztime
[ig
];
2238 for (k
=0, av
=0.; k
<ntot
; k
++)
2241 for (k
=0, sum2
=0.; k
<ntot
; k
++)
2246 sig
=sqrt(sum2
/ntot
);
2247 window
[i
].aver
[ig
]=av
;
2249 /* Note: This estimate for sigma is biased from the limited sampling.
2250 Correct sigma by n/(n-1) where n = number of independent
2251 samples. Only possible if IACT is known.
2255 nSamplesIndep
=window
[i
].N
[ig
]/(window
[i
].tau
[ig
]/window
[i
].dt
);
2256 window
[i
].sigma
[ig
]=sig
* nSamplesIndep
/(nSamplesIndep
-1);
2259 window
[i
].sigma
[ig
]=sig
;
2260 printf("win %d, aver = %f sig = %f\n",i
,av
,window
[i
].sigma
[ig
]);
2266 /* Use histograms to compute average force on pull group.
2267 In addition, compute the sigma of the histogram.
2269 void computeAverageForce(t_UmbrellaWindow
*window
,int nWindows
,t_UmbrellaOptions
*opt
)
2271 int i
,j
,bins
=opt
->bins
,k
;
2272 double dz
,min
=opt
->min
,max
=opt
->max
,displAv
,displAv2
,temp
,distance
,ztot
,ztot_half
,w
,weight
;
2279 /* Compute average displacement from histograms */
2280 for(j
=0;j
<nWindows
;++j
)
2282 snew(window
[j
].forceAv
,window
[j
].nPull
);
2283 for(k
=0;k
<window
[j
].nPull
;++k
)
2288 for(i
=0;i
<opt
->bins
;++i
)
2290 temp
=(1.0*i
+0.5)*dz
+min
;
2291 distance
= temp
- window
[j
].pos
[k
];
2293 { /* in cyclic wham: */
2294 if (distance
> ztot_half
) /* |distance| < ztot_half */
2296 else if (distance
< -ztot_half
)
2299 w
=window
[j
].Histo
[k
][i
]/window
[j
].g
[k
];
2300 displAv
+= w
*distance
;
2301 displAv2
+= w
*sqr(distance
);
2303 /* Are we near min or max? We are getting wron forces from the histgrams since
2304 the histigrams are zero outside [min,max). Therefore, assume that the position
2305 on the other side of the histomgram center is equally likely. */
2308 posmirrored
=window
[j
].pos
[k
]-distance
;
2309 if (posmirrored
>=max
|| posmirrored
<min
)
2311 displAv
+= -w
*distance
;
2312 displAv2
+= w
*sqr(-distance
);
2320 /* average force from average displacement */
2321 window
[j
].forceAv
[k
] = displAv
*window
[j
].k
[k
];
2322 /* sigma from average square displacement */
2323 /* window[j].sigma [k] = sqrt(displAv2); */
2324 /* printf("Win %d, sigma = %f\n",j,sqrt(displAv2)); */
2329 /* Check if the complete reaction coordinate is covered by the histograms */
2330 void checkReactionCoordinateCovered(t_UmbrellaWindow
*window
,int nwins
,
2331 t_UmbrellaOptions
*opt
)
2333 int i
,ig
,j
,bins
=opt
->bins
,bBoundary
;
2334 real avcount
=0,z
,relcount
,*count
;
2335 snew(count
,opt
->bins
);
2337 for(j
=0;j
<opt
->bins
;++j
)
2339 for (i
=0;i
<nwins
;i
++){
2340 for (ig
=0;ig
<window
[i
].nPull
;ig
++)
2341 count
[j
]+=window
[i
].Histo
[ig
][j
];
2343 avcount
+=1.0*count
[j
];
2348 relcount
=count
[j
]/avcount
;
2349 z
=(j
+0.5)*opt
->dz
+opt
->min
;
2350 bBoundary
=( j
<bins
/20 || (bins
-j
)>bins
/20 );
2351 /* check for bins with no data */
2353 fprintf(stderr
, "\nWARNING, no data point in bin %d (z=%g) !\n"
2354 "You may not get a reasonable profile. Check your histograms!\n",j
,z
);
2355 /* and check for poor sampling */
2356 else if (relcount
<0.005 && !bBoundary
)
2357 fprintf(stderr
, "Warning, poor sampling bin %d (z=%g). Check your histograms!\n",j
,z
);
2363 void guessPotByIntegration(t_UmbrellaWindow
*window
,int nWindows
,t_UmbrellaOptions
*opt
,
2366 int i
,j
,ig
,bins
=opt
->bins
,nHist
,winmin
,groupmin
;
2367 double dz
,min
=opt
->min
,*pot
,pos
,hispos
,dist
,diff
,fAv
,distmin
,*f
;
2370 dz
=(opt
->max
-min
)/bins
;
2372 printf("Getting initial potential by integration.\n");
2374 /* Compute average displacement from histograms */
2375 computeAverageForce(window
,nWindows
,opt
);
2377 /* Get force for each bin from all histograms in this bin, or, alternatively,
2378 if no histograms are inside this bin, from the closest histogram */
2381 for(j
=0;j
<opt
->bins
;++j
)
2383 pos
=(1.0*j
+0.5)*dz
+min
;
2388 for (i
=0;i
<nWindows
;i
++)
2390 for (ig
=0;ig
<window
[i
].nPull
;ig
++)
2392 hispos
=window
[i
].pos
[ig
];
2393 dist
=fabs(hispos
-pos
);
2394 /* average force within bin */
2398 fAv
+=window
[i
].forceAv
[ig
];
2400 /* at the same time, rememer closest histogram */
2408 /* if no histogram found in this bin, use closest histogram */
2412 fAv
=window
[winmin
].forceAv
[groupmin
];
2416 for(j
=1;j
<opt
->bins
;++j
)
2417 pot
[j
] = pot
[j
-1] - 0.5*dz
*(f
[j
-1]+f
[j
]);
2419 /* cyclic wham: linearly correct possible offset */
2422 diff
=(pot
[bins
-1]-pot
[0])/(bins
-1);
2423 for(j
=1;j
<opt
->bins
;++j
)
2428 fp
=xvgropen("pmfintegrated.xvg","PMF from force integration","z","PMF [kJ/mol]",opt
->oenv
);
2429 for(j
=0;j
<opt
->bins
;++j
)
2430 fprintf(fp
,"%g %g\n",(j
+0.5)*dz
+opt
->min
,pot
[j
]);
2432 printf("verbose mode: wrote %s with PMF from interated forces\n","pmfintegrated.xvg");
2435 /* get initial z=exp(-F[i]/kT) from integrated potential, where F[i] denote the free
2436 energy offsets which are usually determined by wham
2437 First: turn pot into probabilities:
2439 for(j
=0;j
<opt
->bins
;++j
)
2440 pot
[j
]=exp(-pot
[j
]/(8.314e-3*opt
->Temperature
));
2441 calc_z(pot
,window
,nWindows
,opt
,TRUE
);
2448 int gmx_wham(int argc
,char *argv
[])
2450 const char *desc
[] = {
2451 "This is an analysis program that implements the Weighted",
2452 "Histogram Analysis Method (WHAM). It is intended to analyze",
2453 "output files generated by umbrella sampling simulations to ",
2454 "compute a potential of mean force (PMF). [PAR] ",
2455 "At present, three input modes are supported.[BR]",
2456 "[TT]*[tt] With option [TT]-it[tt], the user provides a file which contains the",
2457 " file names of the umbrella simulation run-input files ([TT].tpr[tt] files),",
2458 " AND, with option [TT]-ix[tt], a file which contains file names of",
2459 " the pullx [TT]mdrun[tt] output files. The [TT].tpr[tt] and pullx files must",
2460 " be in corresponding order, i.e. the first [TT].tpr[tt] created the",
2461 " first pullx, etc.[BR]",
2462 "[TT]*[tt] Same as the previous input mode, except that the the user",
2463 " provides the pull force output file names ([TT]pullf.xvg[tt]) with option [TT]-if[tt].",
2464 " From the pull force the position in the umbrella potential is",
2465 " computed. This does not work with tabulated umbrella potentials.[BR]"
2466 "[TT]*[tt] With option [TT]-ip[tt], the user provides file names of (gzipped) [TT].pdo[tt] files, i.e.",
2467 " the GROMACS 3.3 umbrella output files. If you have some unusual"
2468 " reaction coordinate you may also generate your own [TT].pdo[tt] files and",
2469 " feed them with the [TT]-ip[tt] option into to [TT]g_wham[tt]. The [TT].pdo[tt] file header",
2470 " must be similar to the following:[PAR]",
2471 "[TT]# UMBRELLA 3.0[BR]",
2472 "# Component selection: 0 0 1[BR]",
2474 "# Ref. Group 'TestAtom'[BR]",
2475 "# Nr. of pull groups 2[BR]",
2476 "# Group 1 'GR1' Umb. Pos. 5.0 Umb. Cons. 1000.0[BR]",
2477 "# Group 2 'GR2' Umb. Pos. 2.0 Umb. Cons. 500.0[BR]",
2479 "The number of pull groups, umbrella positions, force constants, and names ",
2480 "may (of course) differ. Following the header, a time column and ",
2481 "a data column for each pull group follows (i.e. the displacement",
2482 "with respect to the umbrella center). Up to four pull groups are possible ",
2483 "per [TT].pdo[tt] file at present.[PAR]",
2484 "By default, the output files are[BR]",
2485 " [TT]-o[tt] PMF output file[BR]",
2486 " [TT]-hist[tt] Histograms output file[BR]",
2487 "Always check whether the histograms sufficiently overlap.[PAR]",
2488 "The umbrella potential is assumed to be harmonic and the force constants are ",
2489 "read from the [TT].tpr[tt] or [TT].pdo[tt] files. If a non-harmonic umbrella force was applied ",
2490 "a tabulated potential can be provided with [TT]-tab[tt].[PAR]",
2491 "WHAM OPTIONS[BR]------------[BR]",
2492 " [TT]-bins[tt] Number of bins used in analysis[BR]",
2493 " [TT]-temp[tt] Temperature in the simulations[BR]",
2494 " [TT]-tol[tt] Stop iteration if profile (probability) changed less than tolerance[BR]",
2495 " [TT]-auto[tt] Automatic determination of boundaries[BR]",
2496 " [TT]-min,-max[tt] Boundaries of the profile [BR]",
2497 "The data points that are used to compute the profile",
2498 "can be restricted with options [TT]-b[tt], [TT]-e[tt], and [TT]-dt[tt]. ",
2499 "Adjust [TT]-b[tt] to ensure sufficient equilibration in each ",
2500 "umbrella window.[PAR]",
2501 "With [TT]-log[tt] (default) the profile is written in energy units, otherwise ",
2502 "(with [TT]-nolog[tt]) as probability. The unit can be specified with [TT]-unit[tt]. ",
2503 "With energy output, the energy in the first bin is defined to be zero. ",
2504 "If you want the free energy at a different ",
2505 "position to be zero, set [TT]-zprof0[tt] (useful with bootstrapping, see below).[PAR]",
2506 "For cyclic or periodic reaction coordinates (dihedral angle, channel PMF",
2507 "without osmotic gradient), the option [TT]-cycl[tt] is useful. [TT]g_wham[tt] will make use of the ",
2508 "periodicity of the system and generate a periodic PMF. The first and the last bin of the",
2509 "reaction coordinate will assumed be be neighbors.[PAR]",
2510 "Option [TT]-sym[tt] symmetrizes the profile around z=0 before output, ",
2511 "which may be useful for, e.g. membranes.[PAR]",
2512 "AUTOCORRELATIONS[BR]----------------[BR]",
2513 "With [TT]-ac[tt], [TT]g_wham[tt] estimates the integrated autocorrelation ",
2514 "time (IACT) [GRK]tau[grk] for each umbrella window and weights the respective ",
2515 "window with 1/[1+2*[GRK]tau[grk]/dt]. The IACTs are written ",
2516 "to the file defined with [TT]-oiact[tt]. In verbose mode, all ",
2517 "autocorrelation functions (ACFs) are written to [TT]hist_autocorr.xvg[tt]. ",
2518 "Because the IACTs can be severely underestimated in case of limited ",
2519 "sampling, option [TT]-acsig[tt] allows one to smooth the IACTs along the ",
2520 "reaction coordinate with a Gaussian ([GRK]sigma[grk] provided with [TT]-acsig[tt], ",
2521 "see output in [TT]iact.xvg[tt]). Note that the IACTs are estimated by simple ",
2522 "integration of the ACFs while the ACFs are larger 0.05.",
2523 "If you prefer to compute the IACTs by a more sophisticated (but possibly ",
2524 "less robust) method such as fitting to a double exponential, you can ",
2525 "compute the IACTs with [TT]g_analyze[tt] and provide them to [TT]g_wham[tt] with the file ",
2526 "[TT]iact-in.dat[tt] (option [TT]-iiact[tt]), which should contain one line per ",
2527 "input file ([TT].pdo[tt] or pullx/f file) and one column per pull group in the respective file.[PAR]",
2528 "ERROR ANALYSIS[BR]--------------[BR]",
2529 "Statistical errors may be estimated with bootstrap analysis. Use it with care, ",
2530 "otherwise the statistical error may be substantially underestimated. ",
2531 "More background and examples for the bootstrap technique can be found in ",
2532 "Hub, de Groot and Van der Spoel, JCTC (2010) 6: 3713-3720.[BR]",
2533 "[TT]-nBootstrap[tt] defines the number of bootstraps (use, e.g., 100). ",
2534 "Four bootstrapping methods are supported and ",
2535 "selected with [TT]-bs-method[tt].[BR]",
2536 " (1) [TT]b-hist[tt] Default: complete histograms are considered as independent ",
2537 "data points, and the bootstrap is carried out by assigning random weights to the ",
2538 "histograms (\"Bayesian bootstrap\"). Note that each point along the reaction coordinate",
2539 "must be covered by multiple independent histograms (e.g. 10 histograms), otherwise the ",
2540 "statistical error is underestimated.[BR]",
2541 " (2) [TT]hist[tt] Complete histograms are considered as independent data points. ",
2542 "For each bootstrap, N histograms are randomly chosen from the N given histograms ",
2543 "(allowing duplication, i.e. sampling with replacement).",
2544 "To avoid gaps without data along the reaction coordinate blocks of histograms ",
2545 "([TT]-histbs-block[tt]) may be defined. In that case, the given histograms are ",
2546 "divided into blocks and only histograms within each block are mixed. Note that ",
2547 "the histograms within each block must be representative for all possible histograms, ",
2548 "otherwise the statistical error is underestimated.[BR]",
2549 " (3) [TT]traj[tt] The given histograms are used to generate new random trajectories,",
2550 "such that the generated data points are distributed according the given histograms ",
2551 "and properly autocorrelated. The autocorrelation time (ACT) for each window must be ",
2552 "known, so use [TT]-ac[tt] or provide the ACT with [TT]-iiact[tt]. If the ACT of all ",
2553 "windows are identical (and known), you can also provide them with [TT]-bs-tau[tt]. ",
2554 "Note that this method may severely underestimate the error in case of limited sampling, ",
2555 "that is if individual histograms do not represent the complete phase space at ",
2556 "the respective positions.[BR]",
2557 " (4) [TT]traj-gauss[tt] The same as method [TT]traj[tt], but the trajectories are ",
2558 "not bootstrapped from the umbrella histograms but from Gaussians with the average ",
2559 "and width of the umbrella histograms. That method yields similar error estimates ",
2560 "like method [TT]traj[tt].[PAR]"
2561 "Bootstrapping output:[BR]",
2562 " [TT]-bsres[tt] Average profile and standard deviations[BR]",
2563 " [TT]-bsprof[tt] All bootstrapping profiles[BR]",
2564 "With [TT]-vbs[tt] (verbose bootstrapping), the histograms of each bootstrap are written, ",
2565 "and, with bootstrap method [TT]traj[tt], the cumulative distribution functions of ",
2569 const char *en_unit
[]={NULL
,"kJ","kCal","kT",NULL
};
2570 const char *en_unit_label
[]={"","E (kJ mol\\S-1\\N)","E (kcal mol\\S-1\\N)","E (kT)",NULL
};
2571 const char *en_bsMethod
[]={ NULL
,"b-hist", "hist", "traj", "traj-gauss", NULL
};
2573 static t_UmbrellaOptions opt
;
2576 { "-min", FALSE
, etREAL
, {&opt
.min
},
2577 "Minimum coordinate in profile"},
2578 { "-max", FALSE
, etREAL
, {&opt
.max
},
2579 "Maximum coordinate in profile"},
2580 { "-auto", FALSE
, etBOOL
, {&opt
.bAuto
},
2581 "Determine min and max automatically"},
2582 { "-bins",FALSE
, etINT
, {&opt
.bins
},
2583 "Number of bins in profile"},
2584 { "-temp", FALSE
, etREAL
, {&opt
.Temperature
},
2586 { "-tol", FALSE
, etREAL
, {&opt
.Tolerance
},
2588 { "-v", FALSE
, etBOOL
, {&opt
.verbose
},
2590 { "-b", FALSE
, etREAL
, {&opt
.tmin
},
2591 "First time to analyse (ps)"},
2592 { "-e", FALSE
, etREAL
, {&opt
.tmax
},
2593 "Last time to analyse (ps)"},
2594 { "-dt", FALSE
, etREAL
, {&opt
.dt
},
2595 "Analyse only every dt ps"},
2596 { "-histonly", FALSE
, etBOOL
, {&opt
.bHistOnly
},
2597 "Write histograms and exit"},
2598 { "-boundsonly", FALSE
, etBOOL
, {&opt
.bBoundsOnly
},
2599 "Determine min and max and exit (with [TT]-auto[tt])"},
2600 { "-log", FALSE
, etBOOL
, {&opt
.bLog
},
2601 "Calculate the log of the profile before printing"},
2602 { "-unit", FALSE
, etENUM
, {en_unit
},
2603 "Energy unit in case of log output" },
2604 { "-zprof0", FALSE
, etREAL
, {&opt
.zProf0
},
2605 "Define profile to 0.0 at this position (with [TT]-log[tt])"},
2606 { "-cycl", FALSE
, etBOOL
, {&opt
.bCycl
},
2607 "Create cyclic/periodic profile. Assumes min and max are the same point."},
2608 { "-sym", FALSE
, etBOOL
, {&opt
.bSym
},
2609 "Symmetrize profile around z=0"},
2610 { "-hist-eq", FALSE
, etBOOL
, {&opt
.bHistEq
},
2611 "HIDDENEnforce equal weight for all histograms. (Non-Weighed-HAM)"},
2612 { "-ac", FALSE
, etBOOL
, {&opt
.bCalcTauInt
},
2613 "Calculate integrated autocorrelation times and use in wham"},
2614 { "-acsig", FALSE
, etREAL
, {&opt
.sigSmoothIact
},
2615 "Smooth autocorrelation times along reaction coordinate with Gaussian of this [GRK]sigma[grk]"},
2616 { "-ac-trestart", FALSE
, etREAL
, {&opt
.acTrestart
},
2617 "When computing autocorrelation functions, restart computing every .. (ps)"},
2618 { "-acred", FALSE
, etBOOL
, {&opt
.bAllowReduceIact
},
2619 "HIDDENWhen smoothing the ACTs, allow to reduce ACTs. Otherwise, only increase ACTs "
2620 "during smoothing"},
2621 { "-nBootstrap", FALSE
, etINT
, {&opt
.nBootStrap
},
2622 "nr of bootstraps to estimate statistical uncertainty (e.g., 200)" },
2623 { "-bs-method", FALSE
, etENUM
, {en_bsMethod
},
2624 "Bootstrap method" },
2625 { "-bs-tau", FALSE
, etREAL
, {&opt
.tauBootStrap
},
2626 "Autocorrelation time (ACT) assumed for all histograms. Use option [TT]-ac[tt] if ACT is unknown."},
2627 { "-bs-seed", FALSE
, etINT
, {&opt
.bsSeed
},
2628 "Seed for bootstrapping. (-1 = use time)"},
2629 { "-histbs-block", FALSE
, etINT
, {&opt
.histBootStrapBlockLength
},
2630 "When mixing histograms only mix within blocks of [TT]-histbs-block[tt]."},
2631 { "-vbs", FALSE
, etBOOL
, {&opt
.bs_verbose
},
2632 "Verbose bootstrapping. Print the CDFs and a histogram file for each bootstrap."},
2633 { "-stepout", FALSE
, etINT
, {&opt
.stepchange
},
2634 "HIDDENWrite maximum change every ... (set to 1 with [TT]-v[tt])"},
2635 { "-updateContr", FALSE
, etINT
, {&opt
.stepUpdateContrib
},
2636 "HIDDENUpdate table with significan contributions to WHAM every ... iterations"},
2640 { efDAT
, "-ix","pullx-files",ffOPTRD
}, /* wham input: pullf.xvg's and tprs */
2641 { efDAT
, "-if","pullf-files",ffOPTRD
}, /* wham input: pullf.xvg's and tprs */
2642 { efDAT
, "-it","tpr-files",ffOPTRD
}, /* wham input: tprs */
2643 { efDAT
, "-ip","pdo-files",ffOPTRD
}, /* wham input: pdo files (gmx3 style) */
2644 { efXVG
, "-o", "profile", ffWRITE
}, /* output file for profile */
2645 { efXVG
, "-hist","histo", ffWRITE
}, /* output file for histograms */
2646 { efXVG
, "-oiact","iact",ffOPTWR
}, /* writing integrated autocorrelation times */
2647 { efDAT
, "-iiact","iact-in",ffOPTRD
}, /* reading integrated autocorrelation times */
2648 { efXVG
, "-bsres","bsResult", ffOPTWR
}, /* average and errors of bootstrap analysis */
2649 { efXVG
, "-bsprof","bsProfs", ffOPTWR
}, /* output file for bootstrap profiles */
2650 { efDAT
, "-tab","umb-pot",ffOPTRD
}, /* Tabulated umbrella potential (if not harmonic) */
2653 int i
,j
,l
,nfiles
,nwins
,nfiles2
;
2654 t_UmbrellaHeader header
;
2655 t_UmbrellaWindow
* window
=NULL
;
2656 double *profile
,maxchange
=1e20
;
2657 gmx_bool bMinSet
,bMaxSet
,bAutoSet
,bExact
=FALSE
;
2658 char **fninTpr
,**fninPull
,**fninPdo
;
2660 FILE *histout
,*profout
;
2661 char ylabel
[256],title
[256];
2663 #define NFILE asize(fnm)
2665 CopyRight(stderr
,argv
[0]);
2669 opt
.bHistOnly
=FALSE
;
2678 /* bootstrapping stuff */
2680 opt
.bsMethod
=bsMethod_hist
;
2681 opt
.tauBootStrap
=0.0;
2683 opt
.histBootStrapBlockLength
=8;
2684 opt
.bs_verbose
=FALSE
;
2689 opt
.Temperature
=298;
2691 opt
.bBoundsOnly
=FALSE
;
2693 opt
.bCalcTauInt
=FALSE
;
2694 opt
.sigSmoothIact
=0.0;
2695 opt
.bAllowReduceIact
=TRUE
;
2696 opt
.bInitPotByIntegration
=TRUE
;
2699 opt
.stepUpdateContrib
=100;
2701 parse_common_args(&argc
,argv
,PCA_BE_NICE
,
2702 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,0,NULL
,&opt
.oenv
);
2704 opt
.unit
=nenum(en_unit
);
2705 opt
.bsMethod
=nenum(en_bsMethod
);
2707 opt
.bProf0Set
=opt2parg_bSet("-zprof0", asize(pa
), pa
);
2709 opt
.bTab
=opt2bSet("-tab",NFILE
,fnm
);
2710 opt
.bPdo
=opt2bSet("-ip",NFILE
,fnm
);
2711 opt
.bTpr
=opt2bSet("-it",NFILE
,fnm
);
2712 opt
.bPullx
=opt2bSet("-ix",NFILE
,fnm
);
2713 opt
.bPullf
=opt2bSet("-if",NFILE
,fnm
);
2714 opt
.bTauIntGiven
=opt2bSet("-iiact",NFILE
,fnm
);
2715 if (opt
.bTab
&& opt
.bPullf
)
2716 gmx_fatal(FARGS
,"Force input does not work with tabulated potentials. "
2717 "Provide pullx.xvg or pdo files!");
2719 #define WHAMBOOLXOR(a,b) ( ((!(a))&&(b)) || ((a)&&(!(b))))
2720 if (!opt
.bPdo
&& !WHAMBOOLXOR(opt
.bPullx
,opt
.bPullf
))
2721 gmx_fatal(FARGS
,"Give either pullx (-ix) OR pullf (-if) data. Not both.");
2722 if ( !opt
.bPdo
&& !(opt
.bTpr
|| opt
.bPullf
|| opt
.bPullx
))
2723 gmx_fatal(FARGS
,"g_wham supports three input modes, pullx, pullf, or pdo file input."
2724 "\n\n Check g_wham -h !");
2726 opt
.fnPdo
=opt2fn("-ip",NFILE
,fnm
);
2727 opt
.fnTpr
=opt2fn("-it",NFILE
,fnm
);
2728 opt
.fnPullf
=opt2fn("-if",NFILE
,fnm
);
2729 opt
.fnPullx
=opt2fn("-ix",NFILE
,fnm
);
2731 bMinSet
= opt2parg_bSet("-min", asize(pa
), pa
);
2732 bMaxSet
= opt2parg_bSet("-max", asize(pa
), pa
);
2733 bAutoSet
= opt2parg_bSet("-auto", asize(pa
), pa
);
2734 if ( (bMinSet
|| bMaxSet
) && bAutoSet
)
2735 gmx_fatal(FARGS
,"With -auto, do not give -min or -max\n");
2737 if ( (bMinSet
&& !bMaxSet
) || (!bMinSet
&& bMaxSet
))
2738 gmx_fatal(FARGS
,"When giving -min, you must give -max (and vice versa), too\n");
2740 if (bMinSet
&& opt
.bAuto
)
2742 printf("Note: min and max given, switching off -auto.\n");
2746 if (opt
.bTauIntGiven
&& opt
.bCalcTauInt
)
2747 gmx_fatal(FARGS
,"Either read (option -iiact) or calculate (option -ac) the\n"
2748 "the autocorrelation times. Not both.");
2750 if (opt
.tauBootStrap
>0.0 && opt2parg_bSet("-ac",asize(pa
), pa
))
2751 gmx_fatal(FARGS
,"Either compute autocorrelation times (ACTs) (option -ac) or "
2752 "provide it with -bs-tau for bootstrapping. Not Both.\n");
2753 if (opt
.tauBootStrap
>0.0 && opt2bSet("-iiact",NFILE
,fnm
))
2754 gmx_fatal(FARGS
,"Either provide autocorrelation times (ACTs) with file iact-in.dat "
2755 "(option -iiact) or define all ACTs with -bs-tau for bootstrapping\n. Not Both.");
2758 /* Reading gmx4 pull output and tpr files */
2759 if (opt
.bTpr
|| opt
.bPullf
|| opt
.bPullx
)
2761 read_wham_in(opt
.fnTpr
,&fninTpr
,&nfiles
,&opt
);
2763 fnPull
=opt
.bPullf
? opt
.fnPullf
: opt
.fnPullx
;
2764 read_wham_in(fnPull
,&fninPull
,&nfiles2
,&opt
);
2765 printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n",
2766 nfiles
,nfiles2
,opt
.bPullf
? "force" : "position",opt
.fnTpr
,fnPull
);
2767 if (nfiles
!=nfiles2
)
2768 gmx_fatal(FARGS
,"Found %d file names in %s, but %d in %s\n",nfiles
,
2769 opt
.fnTpr
,nfiles2
,fnPull
);
2770 window
=initUmbrellaWindows(nfiles
);
2771 read_tpr_pullxf_files(fninTpr
,fninPull
,nfiles
, &header
, window
, &opt
);
2774 { /* reading pdo files */
2775 read_wham_in(opt
.fnPdo
,&fninPdo
,&nfiles
,&opt
);
2776 printf("Found %d pdo files in %s\n",nfiles
,opt
.fnPdo
);
2777 window
=initUmbrellaWindows(nfiles
);
2778 read_pdo_files(fninPdo
,nfiles
, &header
, window
, &opt
);
2782 /* enforce equal weight for all histograms? */
2784 enforceEqualWeights(window
,nwins
);
2786 /* write histograms */
2787 histout
=xvgropen(opt2fn("-hist",NFILE
,fnm
),"Umbrella histograms",
2788 "z","count",opt
.oenv
);
2789 for(l
=0;l
<opt
.bins
;++l
)
2791 fprintf(histout
,"%e\t",(double)(l
+0.5)/opt
.bins
*(opt
.max
-opt
.min
)+opt
.min
);
2792 for(i
=0;i
<nwins
;++i
)
2794 for(j
=0;j
<window
[i
].nPull
;++j
)
2796 fprintf(histout
,"%e\t",window
[i
].Histo
[j
][l
]);
2799 fprintf(histout
,"\n");
2802 printf("Wrote %s\n",opt2fn("-hist",NFILE
,fnm
));
2805 printf("Wrote histograms to %s, now exiting.\n",opt2fn("-hist",NFILE
,fnm
));
2809 /* Using tabulated umbrella potential */
2811 setup_tab(opt2fn("-tab",NFILE
,fnm
),&opt
);
2813 /* Integrated autocorrelation times provided ? */
2814 if (opt
.bTauIntGiven
)
2815 readIntegratedAutocorrelationTimes(window
,nwins
,&opt
,opt2fn("-iiact",NFILE
,fnm
));
2817 /* Compute integrated autocorrelation times */
2818 if (opt
.bCalcTauInt
)
2819 calcIntegratedAutocorrelationTimes(window
,nwins
,&opt
,opt2fn("-oiact",NFILE
,fnm
));
2821 /* calc average and sigma for each histogram
2822 (maybe required for bootstrapping. If not, this is fast anyhow) */
2823 if (opt
.nBootStrap
&& opt
.bsMethod
==bsMethod_trajGauss
)
2824 averageSigma(window
,nwins
,&opt
);
2826 /* Get initial potential by simple integration */
2827 if (opt
.bInitPotByIntegration
)
2828 guessPotByIntegration(window
,nwins
,&opt
,0);
2830 /* Check if complete reaction coordinate is covered */
2831 checkReactionCoordinateCovered(window
,nwins
,&opt
);
2833 /* Calculate profile */
2834 snew(profile
,opt
.bins
);
2840 if ( (i
%opt
.stepUpdateContrib
) == 0)
2841 setup_acc_wham(profile
,window
,nwins
,&opt
);
2842 if (maxchange
<opt
.Tolerance
)
2845 /* if (opt.verbose) */
2846 printf("Switched to exact iteration in iteration %d\n",i
);
2848 calc_profile(profile
,window
,nwins
,&opt
,bExact
);
2849 if (((i
%opt
.stepchange
) == 0 || i
==1) && !i
==0)
2850 printf("\t%4d) Maximum change %e\n",i
,maxchange
);
2852 } while ( (maxchange
=calc_z(profile
, window
, nwins
, &opt
,bExact
)) > opt
.Tolerance
|| !bExact
);
2853 printf("Converged in %d iterations. Final maximum change %g\n",i
,maxchange
);
2855 /* calc error from Kumar's formula */
2856 /* Unclear how the error propagates along reaction coordinate, therefore
2858 /* calc_error_kumar(profile,window, nwins,&opt); */
2860 /* Write profile in energy units? */
2863 prof_normalization_and_unit(profile
,&opt
);
2864 strcpy(ylabel
,en_unit_label
[opt
.unit
]);
2865 strcpy(title
,"Umbrella potential");
2869 strcpy(ylabel
,"Density of states");
2870 strcpy(title
,"Density of states");
2873 /* symmetrize profile around z=0? */
2875 symmetrizeProfile(profile
,&opt
);
2877 /* write profile or density of states */
2878 profout
=xvgropen(opt2fn("-o",NFILE
,fnm
),title
,"z",ylabel
,opt
.oenv
);
2879 for(i
=0;i
<opt
.bins
;++i
)
2880 fprintf(profout
,"%e\t%e\n",(double)(i
+0.5)/opt
.bins
*(opt
.max
-opt
.min
)+opt
.min
,profile
[i
]);
2882 printf("Wrote %s\n",opt2fn("-o",NFILE
,fnm
));
2884 /* Bootstrap Method */
2886 do_bootstrapping(opt2fn("-bsres",NFILE
,fnm
),opt2fn("-bsprof",NFILE
,fnm
),
2887 opt2fn("-hist",NFILE
,fnm
),
2888 ylabel
, profile
, window
, nwins
, &opt
);
2891 freeUmbrellaWindows(window
,nfiles
);
2893 printf("\nIn case you use results from g_wham for a publication, please cite:\n");
2894 please_cite(stdout
,"Hub2010");