Actually disable GPU when compiling in double
[gromacs.git] / src / tools / gmx_bar.c
blob6a49d389d7df6963591dcc268ae928348026bf9e
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.2.0
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
33 * And Hey:
34 * Green Red Orange Magenta Azure Cyan Skyblue
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39 #include "gmx_header_config.h"
40 #include <math.h>
41 #include <string.h>
42 #include <ctype.h>
43 #include <math.h>
44 #include <float.h>
46 #include "sysstuff.h"
47 #include "typedefs.h"
48 #include "smalloc.h"
49 #include "futil.h"
50 #include "statutil.h"
51 #include "copyrite.h"
52 #include "macros.h"
53 #include "enxio.h"
54 #include "physics.h"
55 #include "gmx_fatal.h"
56 #include "xvgr.h"
57 #include "gmx_ana.h"
58 #include "maths.h"
60 /* Suppress Cygwin compiler warnings from using newlib version of
61 * ctype.h */
62 #ifdef GMX_CYGWIN
63 #undef isdigit
64 #endif
66 /* the dhdl.xvg data from a simulation (actually obsolete, but still
67 here for reading the dhdl.xvg file*/
68 typedef struct xvg_t
70 char *filename;
71 int ftp; /* file type */
72 int nset; /* number of lambdas, including dhdl */
73 int *np; /* number of data points (du or hists) per lambda */
74 int np_alloc; /* number of points (du or hists) allocated */
75 double temp; /* temperature */
76 double *lambda; /* the lambdas (of first index for y). */
77 double *t; /* the times (of second index for y) */
78 double **y; /* the dU values. y[0] holds the derivative, while
79 further ones contain the energy differences between
80 the native lambda and the 'foreign' lambdas. */
82 double native_lambda; /* the native lambda */
84 struct xvg_t *next, *prev; /*location in the global linked list of xvg_ts*/
85 } xvg_t;
89 typedef struct hist_t
91 unsigned int *bin[2]; /* the (forward + reverse) histogram values */
92 double dx[2]; /* the histogram spacing. The reverse
93 dx is the negative of the forward dx.*/
94 gmx_large_int_t x0[2]; /* the (forward + reverse) histogram start
95 point(s) as int */
97 int nbin[2]; /* the (forward+reverse) number of bins */
98 gmx_large_int_t sum; /* the total number of counts. Must be
99 the same for forward + reverse. */
100 int nhist; /* number of hist datas (forward or reverse) */
102 double start_time, delta_time; /* start time, end time of histogram */
103 } hist_t;
106 /* an aggregate of samples for partial free energy calculation */
107 typedef struct samples_t
109 double native_lambda;
110 double foreign_lambda;
111 double temp; /* the temperature */
112 gmx_bool derivative; /* whether this sample is a derivative */
114 /* The samples come either as either delta U lists: */
115 int ndu; /* the number of delta U samples */
116 double *du; /* the delta u's */
117 double *t; /* the times associated with those samples, or: */
118 double start_time,delta_time;/*start time and delta time for linear time*/
120 /* or as histograms: */
121 hist_t *hist; /* a histogram */
123 /* allocation data: (not NULL for data 'owned' by this struct) */
124 double *du_alloc, *t_alloc; /* allocated delta u arrays */
125 size_t ndu_alloc, nt_alloc; /* pre-allocated sizes */
126 hist_t *hist_alloc; /* allocated hist */
128 gmx_large_int_t ntot; /* total number of samples */
129 const char *filename; /* the file name this sample comes from */
130 } samples_t;
132 /* a sample range (start to end for du-style data, or boolean
133 for both du-style data and histograms */
134 typedef struct sample_range_t
136 int start, end; /* start and end index for du style data */
137 gmx_bool use; /* whether to use this sample */
139 samples_t *s; /* the samples this range belongs to */
140 } sample_range_t;
143 /* a collection of samples for a partial free energy calculation
144 (i.e. the collection of samples from one native lambda to one
145 foreign lambda) */
146 typedef struct sample_coll_t
148 double native_lambda; /* these should be the same for all samples in the histogram?*/
149 double foreign_lambda; /* collection */
150 double temp; /* the temperature */
152 int nsamples; /* the number of samples */
153 samples_t **s; /* the samples themselves */
154 sample_range_t *r; /* the sample ranges */
155 int nsamples_alloc; /* number of allocated samples */
157 gmx_large_int_t ntot; /* total number of samples in the ranges of
158 this collection */
160 struct sample_coll_t *next, *prev; /* next and previous in the list */
161 } sample_coll_t;
163 /* all the samples associated with a lambda point */
164 typedef struct lambda_t
166 double lambda; /* the native lambda (at start time if dynamic) */
167 double temp; /* temperature */
169 sample_coll_t *sc; /* the samples */
171 sample_coll_t sc_head; /*the pre-allocated list head for the linked list.*/
173 struct lambda_t *next, *prev; /* the next and prev in the list */
174 } lambda_t;
177 /* calculated values. */
178 typedef struct {
179 sample_coll_t *a, *b; /* the simulation data */
181 double dg; /* the free energy difference */
182 double dg_err; /* the free energy difference */
184 double dg_disc_err; /* discretization error */
185 double dg_histrange_err; /* histogram range error */
187 double sa; /* relative entropy of b in state a */
188 double sa_err; /* error in sa */
189 double sb; /* relative entropy of a in state b */
190 double sb_err; /* error in sb */
192 double dg_stddev; /* expected dg stddev per sample */
193 double dg_stddev_err; /* error in dg_stddev */
194 } barres_t;
199 static void hist_init(hist_t *h, int nhist, int *nbin)
201 int i;
202 if (nhist>2)
204 gmx_fatal(FARGS, "histogram with more than two sets of data!");
206 for(i=0;i<nhist;i++)
208 snew(h->bin[i], nbin[i]);
209 h->x0[i]=0;
210 h->nbin[i]=nbin[i];
211 h->start_time=h->delta_time=0;
212 h->dx[i]=0;
214 h->sum=0;
215 h->nhist=nhist;
218 static void hist_destroy(hist_t *h)
220 sfree(h->bin);
224 static void xvg_init(xvg_t *ba)
226 ba->filename=NULL;
227 ba->nset=0;
228 ba->np_alloc=0;
229 ba->np=NULL;
230 ba->y=NULL;
233 static void samples_init(samples_t *s, double native_lambda,
234 double foreign_lambda, double temp,
235 gmx_bool derivative, const char *filename)
237 s->native_lambda=native_lambda;
238 s->foreign_lambda=foreign_lambda;
239 s->temp=temp;
240 s->derivative=derivative;
242 s->ndu=0;
243 s->du=NULL;
244 s->t=NULL;
245 s->start_time = s->delta_time = 0;
246 s->hist=NULL;
247 s->du_alloc=NULL;
248 s->t_alloc=NULL;
249 s->hist_alloc=NULL;
250 s->ndu_alloc=0;
251 s->nt_alloc=0;
253 s->ntot=0;
254 s->filename=filename;
257 static void sample_range_init(sample_range_t *r, samples_t *s)
259 r->start=0;
260 r->end=s->ndu;
261 r->use=TRUE;
262 r->s=NULL;
265 static void sample_coll_init(sample_coll_t *sc, double native_lambda,
266 double foreign_lambda, double temp)
268 sc->native_lambda = native_lambda;
269 sc->foreign_lambda = foreign_lambda;
270 sc->temp = temp;
272 sc->nsamples=0;
273 sc->s=NULL;
274 sc->r=NULL;
275 sc->nsamples_alloc=0;
277 sc->ntot=0;
278 sc->next=sc->prev=NULL;
281 static void sample_coll_destroy(sample_coll_t *sc)
283 /* don't free the samples themselves */
284 sfree(sc->r);
285 sfree(sc->s);
289 static void lambda_init(lambda_t *l, double native_lambda, double temp)
291 l->lambda=native_lambda;
292 l->temp=temp;
294 l->next=NULL;
295 l->prev=NULL;
297 l->sc=&(l->sc_head);
299 sample_coll_init(l->sc, native_lambda, 0., 0.);
300 l->sc->next=l->sc;
301 l->sc->prev=l->sc;
304 static void barres_init(barres_t *br)
306 br->dg=0;
307 br->dg_err=0;
308 br->sa=0;
309 br->sa_err=0;
310 br->sb=0;
311 br->sb_err=0;
312 br->dg_stddev=0;
313 br->dg_stddev_err=0;
315 br->a=NULL;
316 br->b=NULL;
322 static gmx_bool lambda_same(double lambda1, double lambda2)
324 return gmx_within_tol(lambda1, lambda2, 10*GMX_REAL_EPS);
327 /* calculate the total number of samples in a sample collection */
328 static void sample_coll_calc_ntot(sample_coll_t *sc)
330 int i;
332 sc->ntot=0;
333 for(i=0;i<sc->nsamples;i++)
335 if (sc->r[i].use)
337 if (sc->s[i]->hist)
339 sc->ntot += sc->s[i]->ntot;
341 else
343 sc->ntot += sc->r[i].end - sc->r[i].start;
350 /* find the barsamples_t associated with a lambda that corresponds to
351 a specific foreign lambda */
352 static sample_coll_t *lambda_find_sample_coll(lambda_t *l,
353 double foreign_lambda)
355 sample_coll_t *sc=l->sc->next;
357 while(sc != l->sc)
359 if (lambda_same(sc->foreign_lambda,foreign_lambda))
361 return sc;
363 sc=sc->next;
366 return NULL;
369 /* insert li into an ordered list of lambda_colls */
370 static void lambda_insert_sample_coll(lambda_t *l, sample_coll_t *sc)
372 sample_coll_t *scn=l->sc->next;
373 while ( (scn!=l->sc) )
375 if (scn->foreign_lambda > sc->foreign_lambda)
376 break;
377 scn=scn->next;
379 /* now insert it before the found scn */
380 sc->next=scn;
381 sc->prev=scn->prev;
382 scn->prev->next=sc;
383 scn->prev=sc;
386 /* insert li into an ordered list of lambdas */
387 static void lambda_insert_lambda(lambda_t *head, lambda_t *li)
389 lambda_t *lc=head->next;
390 while (lc!=head)
392 if (lc->lambda > li->lambda)
393 break;
394 lc=lc->next;
396 /* now insert ourselves before the found lc */
397 li->next=lc;
398 li->prev=lc->prev;
399 lc->prev->next=li;
400 lc->prev=li;
403 /* insert a sample and a sample_range into a sample_coll. The
404 samples are stored as a pointer, the range is copied. */
405 static void sample_coll_insert_sample(sample_coll_t *sc, samples_t *s,
406 sample_range_t *r)
408 /* first check if it belongs here */
409 if (sc->temp != s->temp)
411 gmx_fatal(FARGS, "Temperatures in files %s and %s are not the same!",
412 s->filename, sc->next->s[0]->filename);
414 if (sc->native_lambda != s->native_lambda)
416 gmx_fatal(FARGS, "Native lambda in files %s and %s are not the same (and they should be)!",
417 s->filename, sc->next->s[0]->filename);
419 if (sc->foreign_lambda != s->foreign_lambda)
421 gmx_fatal(FARGS, "Foreign lambda in files %s and %s are not the same (and they should be)!",
422 s->filename, sc->next->s[0]->filename);
425 /* check if there's room */
426 if ( (sc->nsamples + 1) > sc->nsamples_alloc)
428 sc->nsamples_alloc = max(2*sc->nsamples_alloc, 2);
429 srenew(sc->s, sc->nsamples_alloc);
430 srenew(sc->r, sc->nsamples_alloc);
432 sc->s[sc->nsamples]=s;
433 sc->r[sc->nsamples]=*r;
434 sc->nsamples++;
436 sample_coll_calc_ntot(sc);
439 /* insert a sample into a lambda_list, creating the right sample_coll if
440 neccesary */
441 static void lambda_list_insert_sample(lambda_t *head, samples_t *s)
443 gmx_bool found=FALSE;
444 sample_coll_t *sc;
445 sample_range_t r;
447 lambda_t *l=head->next;
449 /* first search for the right lambda_t */
450 while(l != head)
452 if (lambda_same(l->lambda, s->native_lambda) )
454 found=TRUE;
455 break;
457 l=l->next;
460 if (!found)
462 snew(l, 1); /* allocate a new one */
463 lambda_init(l, s->native_lambda, s->temp); /* initialize it */
464 lambda_insert_lambda(head, l); /* add it to the list */
467 /* now look for a sample collection */
468 sc=lambda_find_sample_coll(l, s->foreign_lambda);
469 if (!sc)
471 snew(sc, 1); /* allocate a new one */
472 sample_coll_init(sc, s->native_lambda, s->foreign_lambda, s->temp);
473 lambda_insert_sample_coll(l, sc);
476 /* now insert the samples into the sample coll */
477 sample_range_init(&r, s);
478 sample_coll_insert_sample(sc, s, &r);
482 /* make a histogram out of a sample collection */
483 static void sample_coll_make_hist(sample_coll_t *sc, int **bin,
484 int *nbin_alloc, int *nbin,
485 double *dx, double *xmin, int nbin_default)
487 int i,j,k;
488 gmx_bool dx_set=FALSE;
489 gmx_bool xmin_set=FALSE;
491 gmx_bool xmax_set=FALSE;
492 gmx_bool xmax_set_hard=FALSE; /* whether the xmax is bounded by the
493 limits of a histogram */
494 double xmax=-1;
496 /* first determine dx and xmin; try the histograms */
497 for(i=0;i<sc->nsamples;i++)
499 if (sc->s[i]->hist)
501 hist_t *hist=sc->s[i]->hist;
502 for(k=0;k<hist->nhist;k++)
504 double hdx=hist->dx[k];
505 double xmax_now=(hist->x0[k]+hist->nbin[k])*hdx;
507 /* we use the biggest dx*/
508 if ( (!dx_set) || hist->dx[0] > *dx)
510 dx_set=TRUE;
511 *dx = hist->dx[0];
513 if ( (!xmin_set) || (hist->x0[k]*hdx) < *xmin)
515 xmin_set=TRUE;
516 *xmin = (hist->x0[k]*hdx);
519 if ( (!xmax_set) || (xmax_now>xmax && !xmax_set_hard) )
521 xmax_set=TRUE;
522 xmax = xmax_now;
523 if (hist->bin[k][hist->nbin[k]-1] != 0)
524 xmax_set_hard=TRUE;
526 if ( hist->bin[k][hist->nbin[k]-1]!=0 && (xmax_now < xmax) )
528 xmax_set_hard=TRUE;
529 xmax = xmax_now;
534 /* and the delta us */
535 for(i=0;i<sc->nsamples;i++)
537 if (sc->s[i]->ndu > 0)
539 /* determine min and max */
540 int starti=sc->r[i].start;
541 int endi=sc->r[i].end;
542 double du_xmin=sc->s[i]->du[starti];
543 double du_xmax=sc->s[i]->du[starti];
544 for(j=starti+1;j<endi;j++)
546 if (sc->s[i]->du[j] < du_xmin)
547 du_xmin = sc->s[i]->du[j];
548 if (sc->s[i]->du[j] > du_xmax)
549 du_xmax = sc->s[i]->du[j];
552 /* and now change the limits */
553 if ( (!xmin_set) || (du_xmin < *xmin) )
555 xmin_set=TRUE;
556 *xmin=du_xmin;
558 if ( (!xmax_set) || ((du_xmax > xmax) && !xmax_set_hard) )
560 xmax_set=TRUE;
561 xmax=du_xmax;
566 if (!xmax_set || !xmin_set)
568 *nbin=0;
569 return;
573 if (!dx_set)
575 *nbin=nbin_default;
576 *dx=(xmax-(*xmin))/((*nbin)-2); /* -2 because we want the last bin to
577 be 0, and we count from 0 */
579 else
581 *nbin=(xmax-(*xmin))/(*dx);
584 if (*nbin > *nbin_alloc)
586 *nbin_alloc=*nbin;
587 srenew(*bin, *nbin_alloc);
590 /* reset the histogram */
591 for(i=0;i<(*nbin);i++)
593 (*bin)[i] = 0;
596 /* now add the actual data */
597 for(i=0;i<sc->nsamples;i++)
599 if (sc->s[i]->hist)
601 hist_t *hist=sc->s[i]->hist;
602 for(k=0;k<hist->nhist;k++)
604 double hdx = hist->dx[k];
605 double xmin_hist=hist->x0[k]*hdx;
606 for(j=0;j<hist->nbin[k];j++)
608 /* calculate the bin corresponding to the middle of the
609 original bin */
610 double x=hdx*(j+0.5) + xmin_hist;
611 int binnr=(int)((x-(*xmin))/(*dx));
613 if (binnr >= *nbin || binnr<0)
614 binnr = (*nbin)-1;
616 (*bin)[binnr] += hist->bin[k][j];
620 else
622 int starti=sc->r[i].start;
623 int endi=sc->r[i].end;
624 for(j=starti;j<endi;j++)
626 int binnr=(int)((sc->s[i]->du[j]-(*xmin))/(*dx));
627 if (binnr >= *nbin || binnr<0)
628 binnr = (*nbin)-1;
630 (*bin)[binnr] ++;
636 /* write a collection of histograms to a file */
637 void lambdas_histogram(lambda_t *bl_head, const char *filename,
638 int nbin_default, const output_env_t oenv)
640 char label_x[STRLEN];
641 const char *dhdl="dH/d\\lambda",*deltag="\\DeltaH",*lambda="\\lambda";
642 const char *title="N(\\DeltaH)";
643 const char *label_y="Samples";
644 FILE *fp;
645 lambda_t *bl;
646 int nsets=0;
647 char **setnames=NULL;
648 gmx_bool first_set=FALSE;
649 /* histogram data: */
650 int *hist=NULL;
651 int nbin=0;
652 int nbin_alloc=0;
653 double dx=0;
654 double min=0;
655 int i;
657 printf("\nWriting histogram to %s\n", filename);
658 sprintf(label_x, "\\DeltaH (%s)", unit_energy);
660 fp=xvgropen_type(filename, title, label_x, label_y, exvggtXNY, oenv);
662 /* first get all the set names */
663 bl=bl_head->next;
664 /* iterate over all lambdas */
665 while(bl!=bl_head)
667 sample_coll_t *sc=bl->sc->next;
669 /* iterate over all samples */
670 while(sc!=bl->sc)
672 nsets++;
673 srenew(setnames, nsets);
674 snew(setnames[nsets-1], STRLEN);
675 if (!lambda_same(sc->foreign_lambda, sc->native_lambda))
677 sprintf(setnames[nsets-1], "N(%s(%s=%g) | %s=%g)",
678 deltag, lambda, sc->foreign_lambda, lambda,
679 sc->native_lambda);
681 else
683 sprintf(setnames[nsets-1], "N(%s | %s=%g)",
684 dhdl, lambda, sc->native_lambda);
686 sc=sc->next;
689 bl=bl->next;
691 xvgr_legend(fp, nsets, (const char**)setnames, oenv);
694 /* now make the histograms */
695 bl=bl_head->next;
696 /* iterate over all lambdas */
697 while(bl!=bl_head)
699 sample_coll_t *sc=bl->sc->next;
701 /* iterate over all samples */
702 while(sc!=bl->sc)
704 if (!first_set)
706 xvgr_new_dataset(fp, 0, 0, NULL, oenv);
709 sample_coll_make_hist(sc, &hist, &nbin_alloc, &nbin, &dx, &min,
710 nbin_default);
712 for(i=0;i<nbin;i++)
714 double xmin=i*dx + min;
715 double xmax=(i+1)*dx + min;
717 fprintf(fp, "%g %d\n%g %d\n", xmin, hist[i], xmax, hist[i]);
720 first_set=FALSE;
721 sc=sc->next;
724 bl=bl->next;
727 if(hist)
728 sfree(hist);
730 xvgrclose(fp);
733 /* create a collection (array) of barres_t object given a ordered linked list
734 of barlamda_t sample collections */
735 static barres_t *barres_list_create(lambda_t *bl_head, int *nres)
737 lambda_t *bl;
738 int nlambda=0;
739 barres_t *res;
740 int i;
741 gmx_bool dhdl=FALSE;
742 gmx_bool first=TRUE;
744 /* first count the lambdas */
745 bl=bl_head->next;
746 while(bl!=bl_head)
748 nlambda++;
749 bl=bl->next;
751 snew(res, nlambda-1);
753 /* next put the right samples in the res */
754 *nres=0;
755 bl=bl_head->next->next; /* we start with the second one. */
756 while(bl!=bl_head)
758 sample_coll_t *sc, *scprev;
759 barres_t *br=&(res[*nres]);
760 /* there is always a previous one. we search for that as a foreign
761 lambda: */
762 scprev=lambda_find_sample_coll(bl->prev, bl->lambda);
763 sc=lambda_find_sample_coll(bl, bl->prev->lambda);
765 barres_init(br);
767 if (!scprev && !sc)
769 /* we use dhdl */
771 scprev=lambda_find_sample_coll(bl->prev, bl->prev->lambda);
772 sc=lambda_find_sample_coll(bl, bl->lambda);
774 if (first)
776 printf("\nWARNING: Using the derivative data (dH/dlambda) to extrapolate delta H values.\nThis will only work if the Hamiltonian is linear in lambda.\n");
777 dhdl=TRUE;
779 if (!dhdl)
781 gmx_fatal(FARGS,"Some dhdl files contain only one value (dH/dl), while others \ncontain multiple values (dH/dl and/or Delta H), will not proceed \nbecause of possible inconsistencies.\n");
785 /* normal delta H */
786 if (!scprev)
788 gmx_fatal(FARGS,"Could not find a set for lambda = %g in the files for lambda = %g",bl->lambda,bl->prev->lambda);
790 if (!sc)
792 gmx_fatal(FARGS,"Could not find a set for lambda = %g in the files for lambda = %g",bl->prev->lambda,bl->lambda);
794 br->a = scprev;
795 br->b = sc;
797 first=FALSE;
798 (*nres)++;
799 bl=bl->next;
801 return res;
804 /* estimate the maximum discretization error */
805 static double barres_list_max_disc_err(barres_t *res, int nres)
807 int i,j;
808 double disc_err=0.;
809 double delta_lambda;
811 for(i=0;i<nres;i++)
813 barres_t *br=&(res[i]);
815 delta_lambda=fabs(br->b->native_lambda-br->a->native_lambda);
817 for(j=0;j<br->a->nsamples;j++)
819 if (br->a->s[j]->hist)
821 double Wfac=1.;
822 if (br->a->s[j]->derivative)
823 Wfac = delta_lambda;
825 disc_err=max(disc_err, Wfac*br->a->s[j]->hist->dx[0]);
828 for(j=0;j<br->b->nsamples;j++)
830 if (br->b->s[j]->hist)
832 double Wfac=1.;
833 if (br->b->s[j]->derivative)
834 Wfac = delta_lambda;
835 disc_err=max(disc_err, Wfac*br->b->s[j]->hist->dx[0]);
839 return disc_err;
843 /* impose start and end times on a sample collection, updating sample_ranges */
844 static void sample_coll_impose_times(sample_coll_t *sc, double begin_t,
845 double end_t)
847 int i;
848 for(i=0;i<sc->nsamples;i++)
850 samples_t *s=sc->s[i];
851 sample_range_t *r=&(sc->r[i]);
852 if (s->hist)
854 double end_time=s->hist->delta_time*s->hist->sum +
855 s->hist->start_time;
856 if (s->hist->start_time < begin_t || end_time > end_t)
858 r->use=FALSE;
861 else
863 if (!s->t)
865 double end_time;
866 if (s->start_time < begin_t)
868 r->start=(int)((begin_t - s->start_time)/s->delta_time);
870 end_time=s->delta_time*s->ndu + s->start_time;
871 if (end_time > end_t)
873 r->end=(int)((end_t - s->start_time)/s->delta_time);
876 else
878 int j;
879 for(j=0;j<s->ndu;j++)
881 if (s->t[j] <begin_t)
883 r->start = j;
886 if (s->t[j] >= end_t)
888 r->end = j;
889 break;
893 if (r->start > r->end)
895 r->use=FALSE;
899 sample_coll_calc_ntot(sc);
902 static void lambdas_impose_times(lambda_t *head, double begin, double end)
904 double first_t, last_t;
905 double begin_t, end_t;
906 lambda_t *lc;
907 int j;
909 if (begin<=0 && end<0)
911 return;
914 /* first determine the global start and end times */
915 first_t = -1;
916 last_t = -1;
917 lc=head->next;
918 while(lc!=head)
920 sample_coll_t *sc=lc->sc->next;
921 while(sc != lc->sc)
923 for(j=0;j<sc->nsamples;j++)
925 double start_t,end_t;
927 start_t = sc->s[j]->start_time;
928 end_t = sc->s[j]->start_time;
929 if (sc->s[j]->hist)
931 end_t += sc->s[j]->delta_time*sc->s[j]->hist->sum;
933 else
935 if (sc->s[j]->t)
937 end_t = sc->s[j]->t[sc->s[j]->ndu-1];
939 else
941 end_t += sc->s[j]->delta_time*sc->s[j]->ndu;
945 if (start_t < first_t || first_t<0)
947 first_t=start_t;
949 if (end_t > last_t)
951 last_t=end_t;
954 sc=sc->next;
956 lc=lc->next;
959 /* calculate the actual times */
960 if (begin > 0 )
962 begin_t = begin;
964 else
966 begin_t = first_t;
969 if (end >0 )
971 end_t = end;
973 else
975 end_t = last_t;
977 printf("\n Samples in time interval: %.3f - %.3f\n", first_t, last_t);
979 if (begin_t > end_t)
981 return;
983 printf("Removing samples outside of: %.3f - %.3f\n", begin_t, end_t);
985 /* then impose them */
986 lc=head->next;
987 while(lc!=head)
989 sample_coll_t *sc=lc->sc->next;
990 while(sc != lc->sc)
992 sample_coll_impose_times(sc, begin_t, end_t);
993 sc=sc->next;
995 lc=lc->next;
1000 /* create subsample i out of ni from an existing sample_coll */
1001 static gmx_bool sample_coll_create_subsample(sample_coll_t *sc,
1002 sample_coll_t *sc_orig,
1003 int i, int ni)
1005 int j;
1006 int hist_start, hist_end;
1008 gmx_large_int_t ntot_start;
1009 gmx_large_int_t ntot_end;
1010 gmx_large_int_t ntot_so_far;
1012 *sc = *sc_orig; /* just copy all fields */
1014 /* allocate proprietary memory */
1015 snew(sc->s, sc_orig->nsamples);
1016 snew(sc->r, sc_orig->nsamples);
1018 /* copy the samples */
1019 for(j=0;j<sc_orig->nsamples;j++)
1021 sc->s[j] = sc_orig->s[j];
1022 sc->r[j] = sc_orig->r[j]; /* copy the ranges too */
1025 /* now fix start and end fields */
1026 /* the casts avoid possible overflows */
1027 ntot_start=(gmx_large_int_t)(sc_orig->ntot*(double)i/(double)ni);
1028 ntot_end =(gmx_large_int_t)(sc_orig->ntot*(double)(i+1)/(double)ni);
1029 ntot_so_far = 0;
1030 for(j=0;j<sc->nsamples;j++)
1032 gmx_large_int_t ntot_add;
1033 gmx_large_int_t new_start, new_end;
1035 if (sc->r[j].use)
1037 if (sc->s[j]->hist)
1039 ntot_add = sc->s[j]->hist->sum;
1041 else
1043 ntot_add = sc->r[j].end - sc->r[j].start;
1046 else
1048 ntot_add = 0;
1051 if (!sc->s[j]->hist)
1053 if (ntot_so_far < ntot_start)
1055 /* adjust starting point */
1056 new_start = sc->r[j].start + (ntot_start - ntot_so_far);
1058 else
1060 new_start = sc->r[j].start;
1062 /* adjust end point */
1063 new_end = sc->r[j].start + (ntot_end - ntot_so_far);
1064 if (new_end > sc->r[j].end)
1066 new_end=sc->r[j].end;
1069 /* check if we're in range at all */
1070 if ( (new_end < new_start) || (new_start > sc->r[j].end) )
1072 new_start=0;
1073 new_end=0;
1075 /* and write the new range */
1076 sc->r[j].start=(int)new_start;
1077 sc->r[j].end=(int)new_end;
1079 else
1081 if (sc->r[j].use)
1083 double overlap;
1084 double ntot_start_norm, ntot_end_norm;
1085 /* calculate the amount of overlap of the
1086 desired range (ntot_start -- ntot_end) onto
1087 the histogram range (ntot_so_far -- ntot_so_far+ntot_add)*/
1089 /* first calculate normalized bounds
1090 (where 0 is the start of the hist range, and 1 the end) */
1091 ntot_start_norm = (ntot_start-ntot_so_far)/(double)ntot_add;
1092 ntot_end_norm = (ntot_end-ntot_so_far)/(double)ntot_add;
1094 /* now fix the boundaries */
1095 ntot_start_norm = min(1, max(0., ntot_start_norm));
1096 ntot_end_norm = max(0, min(1., ntot_end_norm));
1098 /* and calculate the overlap */
1099 overlap = ntot_end_norm - ntot_start_norm;
1101 if (overlap > 0.95) /* we allow for 5% slack */
1103 sc->r[j].use = TRUE;
1105 else if (overlap < 0.05)
1107 sc->r[j].use = FALSE;
1109 else
1111 return FALSE;
1115 ntot_so_far += ntot_add;
1117 sample_coll_calc_ntot(sc);
1119 return TRUE;
1122 /* calculate minimum and maximum work values in sample collection */
1123 static void sample_coll_min_max(sample_coll_t *sc, double Wfac,
1124 double *Wmin, double *Wmax)
1126 int i,j;
1128 *Wmin=FLT_MAX;
1129 *Wmax=-FLT_MAX;
1131 for(i=0;i<sc->nsamples;i++)
1133 samples_t *s=sc->s[i];
1134 sample_range_t *r=&(sc->r[i]);
1135 if (r->use)
1137 if (!s->hist)
1139 for(j=r->start; j<r->end; j++)
1141 *Wmin = min(*Wmin,s->du[j]*Wfac);
1142 *Wmax = max(*Wmax,s->du[j]*Wfac);
1145 else
1147 int hd=0; /* determine the histogram direction: */
1148 double dx;
1149 if ( (s->hist->nhist>1) && (Wfac<0) )
1151 hd=1;
1153 dx=s->hist->dx[hd];
1155 for(j=s->hist->nbin[hd]-1;j>=0;j--)
1157 *Wmin=min(*Wmin,Wfac*(s->hist->x0[hd])*dx);
1158 *Wmax=max(*Wmax,Wfac*(s->hist->x0[hd])*dx);
1159 /* look for the highest value bin with values */
1160 if (s->hist->bin[hd][j]>0)
1162 *Wmin=min(*Wmin,Wfac*(j+s->hist->x0[hd]+1)*dx);
1163 *Wmax=max(*Wmax,Wfac*(j+s->hist->x0[hd]+1)*dx);
1164 break;
1173 static double calc_bar_sum(int n,const double *W,double Wfac,double sbMmDG)
1175 int i;
1176 double sum;
1178 sum = 0;
1180 for(i=0; i<n; i++)
1182 sum += 1./(1. + exp(Wfac*W[i] + sbMmDG));
1185 return sum;
1188 /* calculate the BAR average given a histogram
1190 if type== 0, calculate the best estimate for the average,
1191 if type==-1, calculate the minimum possible value given the histogram
1192 if type== 1, calculate the maximum possible value given the histogram */
1193 static double calc_bar_sum_hist(const hist_t *hist, double Wfac, double sbMmDG,
1194 int type)
1196 double sum=0.;
1197 int i;
1198 int max;
1199 /* normalization factor multiplied with bin width and
1200 number of samples (we normalize through M): */
1201 double normdx = 1.;
1202 int hd=0; /* determine the histogram direction: */
1203 double dx;
1205 if ( (hist->nhist>1) && (Wfac<0) )
1207 hd=1;
1209 dx=hist->dx[hd];
1210 max=hist->nbin[hd]-1;
1211 if (type==1)
1213 max=hist->nbin[hd]; /* we also add whatever was out of range */
1216 for(i=0;i<max;i++)
1218 double x=Wfac*((i+hist->x0[hd])+0.5)*dx; /* bin middle */
1219 double pxdx=hist->bin[0][i]*normdx; /* p(x)dx */
1221 sum += pxdx/(1. + exp(x + sbMmDG));
1224 return sum;
1227 static double calc_bar_lowlevel(sample_coll_t *ca, sample_coll_t *cb,
1228 double temp, double tol, int type)
1230 double kT,beta,M;
1231 double DG;
1232 int i,j;
1233 double Wfac1,Wfac2,Wmin,Wmax;
1234 double DG0,DG1,DG2,dDG1;
1235 double sum1,sum2;
1236 double n1, n2; /* numbers of samples as doubles */
1238 kT = BOLTZ*temp;
1239 beta = 1/kT;
1241 /* count the numbers of samples */
1242 n1 = ca->ntot;
1243 n2 = cb->ntot;
1245 M = log(n1/n2);
1247 if (!lambda_same(ca->native_lambda, ca->foreign_lambda))
1249 /* this is the case when the delta U were calculated directly
1250 (i.e. we're not scaling dhdl) */
1251 Wfac1 = beta;
1252 Wfac2 = beta;
1254 else
1256 /* we're using dhdl, so delta_lambda needs to be a
1257 multiplication factor. */
1258 double delta_lambda=cb->native_lambda-ca->native_lambda;
1259 Wfac1 = beta*delta_lambda;
1260 Wfac2 = -beta*delta_lambda;
1263 if (beta < 1)
1265 /* We print the output both in kT and kJ/mol.
1266 * Here we determine DG in kT, so when beta < 1
1267 * the precision has to be increased.
1269 tol *= beta;
1272 /* Calculate minimum and maximum work to give an initial estimate of
1273 * delta G as their average.
1276 double Wmin1, Wmin2, Wmax1, Wmax2;
1277 sample_coll_min_max(ca, Wfac1, &Wmin1, &Wmax1);
1278 sample_coll_min_max(cb, Wfac2, &Wmin2, &Wmax2);
1280 Wmin=min(Wmin1, Wmin2);
1281 Wmax=max(Wmax1, Wmax2);
1284 DG0 = Wmin;
1285 DG2 = Wmax;
1287 if (debug)
1289 fprintf(debug,"DG %9.5f %9.5f\n",DG0,DG2);
1291 /* We approximate by bisection: given our initial estimates
1292 we keep checking whether the halfway point is greater or
1293 smaller than what we get out of the BAR averages.
1295 For the comparison we can use twice the tolerance. */
1296 while (DG2 - DG0 > 2*tol)
1298 DG1 = 0.5*(DG0 + DG2);
1300 /*printf("Wfac1=%g, Wfac2=%g, beta=%g, DG1=%g\n",Wfac1,Wfac2,beta,
1301 DG1);*/
1303 /* calculate the BAR averages */
1304 dDG1=0.;
1306 for(i=0;i<ca->nsamples;i++)
1308 samples_t *s=ca->s[i];
1309 sample_range_t *r=&(ca->r[i]);
1310 if (r->use)
1312 if (s->hist)
1314 dDG1 += calc_bar_sum_hist(s->hist, Wfac1, (M-DG1), type);
1316 else
1318 dDG1 += calc_bar_sum(r->end - r->start, s->du + r->start,
1319 Wfac1, (M-DG1));
1323 for(i=0;i<cb->nsamples;i++)
1325 samples_t *s=cb->s[i];
1326 sample_range_t *r=&(cb->r[i]);
1327 if (r->use)
1329 if (s->hist)
1331 dDG1 -= calc_bar_sum_hist(s->hist, Wfac2, -(M-DG1), type);
1333 else
1335 dDG1 -= calc_bar_sum(r->end - r->start, s->du + r->start,
1336 Wfac2, -(M-DG1));
1341 if (dDG1 < 0)
1343 DG0 = DG1;
1345 else
1347 DG2 = DG1;
1349 if (debug)
1351 fprintf(debug,"DG %9.5f %9.5f\n",DG0,DG2);
1355 return 0.5*(DG0 + DG2);
1358 static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb,
1359 double temp, double dg, double *sa, double *sb)
1361 int i,j;
1362 double W_ab=0.;
1363 double W_ba=0.;
1364 double kT, beta;
1365 double Wfac1, Wfac2;
1366 double n1,n2;
1368 kT = BOLTZ*temp;
1369 beta = 1/kT;
1371 /* count the numbers of samples */
1372 n1 = ca->ntot;
1373 n2 = cb->ntot;
1375 /* to ensure the work values are the same as during the delta_G */
1376 if (!lambda_same(ca->native_lambda, ca->foreign_lambda))
1378 /* this is the case when the delta U were calculated directly
1379 (i.e. we're not scaling dhdl) */
1380 Wfac1 = beta;
1381 Wfac2 = beta;
1383 else
1385 /* we're using dhdl, so delta_lambda needs to be a
1386 multiplication factor. */
1387 double delta_lambda=cb->native_lambda-ca->native_lambda;
1388 Wfac1 = beta*delta_lambda;
1389 Wfac2 = -beta*delta_lambda;
1392 /* first calculate the average work in both directions */
1393 for(i=0;i<ca->nsamples;i++)
1395 samples_t *s=ca->s[i];
1396 sample_range_t *r=&(ca->r[i]);
1397 if (r->use)
1399 if (!s->hist)
1401 for(j=r->start;j<r->end;j++)
1402 W_ab += Wfac1*s->du[j];
1404 else
1406 /* normalization factor multiplied with bin width and
1407 number of samples (we normalize through M): */
1408 double normdx = 1.;
1409 double dx;
1410 int hd=0; /* histogram direction */
1411 if ( (s->hist->nhist>1) && (Wfac1<0) )
1413 hd=1;
1415 dx=s->hist->dx[hd];
1417 for(j=0;j<s->hist->nbin[0];j++)
1419 double x=Wfac1*((j+s->hist->x0[0])+0.5)*dx; /*bin ctr*/
1420 double pxdx=s->hist->bin[0][j]*normdx; /* p(x)dx */
1421 W_ab += pxdx*x;
1426 W_ab/=n1;
1428 for(i=0;i<cb->nsamples;i++)
1430 samples_t *s=cb->s[i];
1431 sample_range_t *r=&(cb->r[i]);
1432 if (r->use)
1434 if (!s->hist)
1436 for(j=r->start;j<r->end;j++)
1437 W_ba += Wfac1*s->du[j];
1439 else
1441 /* normalization factor multiplied with bin width and
1442 number of samples (we normalize through M): */
1443 double normdx = 1.;
1444 double dx;
1445 int hd=0; /* histogram direction */
1446 if ( (s->hist->nhist>1) && (Wfac2<0) )
1448 hd=1;
1450 dx=s->hist->dx[hd];
1452 for(j=0;j<s->hist->nbin[0];j++)
1454 double x=Wfac1*((j+s->hist->x0[0])+0.5)*dx;/*bin ctr*/
1455 double pxdx=s->hist->bin[0][j]*normdx; /* p(x)dx */
1456 W_ba += pxdx*x;
1461 W_ba/=n2;
1463 /* then calculate the relative entropies */
1464 *sa = (W_ab - dg);
1465 *sb = (W_ba + dg);
1468 static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb,
1469 double temp, double dg, double *stddev)
1471 int i,j;
1472 double M;
1473 double sigmafact=0.;
1474 double kT, beta;
1475 double Wfac1, Wfac2;
1476 double n1, n2;
1478 kT = BOLTZ*temp;
1479 beta = 1/kT;
1481 /* count the numbers of samples */
1482 n1 = ca->ntot;
1483 n2 = cb->ntot;
1485 /* to ensure the work values are the same as during the delta_G */
1486 if (!lambda_same(ca->native_lambda, ca->foreign_lambda))
1488 /* this is the case when the delta U were calculated directly
1489 (i.e. we're not scaling dhdl) */
1490 Wfac1 = beta;
1491 Wfac2 = beta;
1493 else
1495 /* we're using dhdl, so delta_lambda needs to be a
1496 multiplication factor. */
1497 double delta_lambda=cb->native_lambda-ca->native_lambda;
1498 Wfac1 = beta*delta_lambda;
1499 Wfac2 = -beta*delta_lambda;
1502 M = log(n1/n2);
1505 /* calculate average in both directions */
1506 for(i=0;i<ca->nsamples;i++)
1508 samples_t *s=ca->s[i];
1509 sample_range_t *r=&(ca->r[i]);
1510 if (r->use)
1512 if (!s->hist)
1514 for(j=r->start;j<r->end;j++)
1516 sigmafact += 1./(2. + 2.*cosh((M + Wfac1*s->du[j] - dg)));
1519 else
1521 /* normalization factor multiplied with bin width and
1522 number of samples (we normalize through M): */
1523 double normdx = 1.;
1524 double dx;
1525 int hd=0; /* histogram direction */
1526 if ( (s->hist->nhist>1) && (Wfac1<0) )
1528 hd=1;
1530 dx=s->hist->dx[hd];
1532 for(j=0;j<s->hist->nbin[0];j++)
1534 double x=Wfac1*((j+s->hist->x0[0])+0.5)*dx; /*bin ctr*/
1535 double pxdx=s->hist->bin[0][j]*normdx; /* p(x)dx */
1537 sigmafact += pxdx/(2. + 2.*cosh((M + x - dg)));
1542 for(i=0;i<cb->nsamples;i++)
1544 samples_t *s=cb->s[i];
1545 sample_range_t *r=&(cb->r[i]);
1546 if (r->use)
1548 if (!s->hist)
1550 for(j=r->start;j<r->end;j++)
1552 sigmafact += 1./(2. + 2.*cosh((M - Wfac2*s->du[j] - dg)));
1555 else
1557 /* normalization factor multiplied with bin width and
1558 number of samples (we normalize through M): */
1559 double normdx = 1.;
1560 double dx;
1561 int hd=0; /* histogram direction */
1562 if ( (s->hist->nhist>1) && (Wfac2<0) )
1564 hd=1;
1566 dx=s->hist->dx[hd];
1568 for(j=0;j<s->hist->nbin[0];j++)
1570 double x=Wfac2*((j+s->hist->x0[0])+0.5)*dx;/*bin ctr*/
1571 double pxdx=s->hist->bin[0][j]*normdx; /* p(x)dx */
1573 sigmafact += pxdx/(2. + 2.*cosh((M - x - dg)));
1579 sigmafact /= (n1 + n2);
1582 /* Eq. 10 from
1583 Shirts, Bair, Hooker & Pande, Phys. Rev. Lett 91, 140601 (2003): */
1584 *stddev = sqrt(((1./sigmafact) - ( (n1+n2)/n1 + (n1+n2)/n2 )));
1589 static void calc_bar(barres_t *br, double tol,
1590 int npee_min, int npee_max, gmx_bool *bEE,
1591 double *partsum)
1593 int npee,p;
1594 double dg_sig2,sa_sig2,sb_sig2,stddev_sig2; /* intermediate variance values
1595 for calculated quantities */
1596 int nsample1, nsample2;
1597 double temp=br->a->temp;
1598 int i,j;
1599 double dg_min, dg_max;
1600 gmx_bool have_hist=FALSE;
1602 br->dg=calc_bar_lowlevel(br->a, br->b, temp, tol, 0);
1604 br->dg_disc_err = 0.;
1605 br->dg_histrange_err = 0.;
1607 /* check if there are histograms */
1608 for(i=0;i<br->a->nsamples;i++)
1610 if (br->a->r[i].use && br->a->s[i]->hist)
1612 have_hist=TRUE;
1613 break;
1616 if (!have_hist)
1618 for(i=0;i<br->b->nsamples;i++)
1620 if (br->b->r[i].use && br->b->s[i]->hist)
1622 have_hist=TRUE;
1623 break;
1628 /* calculate histogram-specific errors */
1629 if (have_hist)
1631 dg_min=calc_bar_lowlevel(br->a, br->b, temp, tol, -1);
1632 dg_max=calc_bar_lowlevel(br->a, br->b, temp, tol, 1);
1634 if (fabs(dg_max - dg_min) > GMX_REAL_EPS*10)
1636 /* the histogram range error is the biggest of the differences
1637 between the best estimate and the extremes */
1638 br->dg_histrange_err = fabs(dg_max - dg_min);
1640 br->dg_disc_err = 0.;
1641 for(i=0;i<br->a->nsamples;i++)
1643 if (br->a->s[i]->hist)
1644 br->dg_disc_err=max(br->dg_disc_err, br->a->s[i]->hist->dx[0]);
1646 for(i=0;i<br->b->nsamples;i++)
1648 if (br->b->s[i]->hist)
1649 br->dg_disc_err=max(br->dg_disc_err, br->b->s[i]->hist->dx[0]);
1652 calc_rel_entropy(br->a, br->b, temp, br->dg, &(br->sa), &(br->sb));
1654 calc_dg_stddev(br->a, br->b, temp, br->dg, &(br->dg_stddev) );
1656 dg_sig2 = 0;
1657 sa_sig2 = 0;
1658 sb_sig2 = 0;
1659 stddev_sig2 = 0;
1661 *bEE=TRUE;
1663 sample_coll_t ca, cb;
1665 /* initialize the samples */
1666 sample_coll_init(&ca, br->a->native_lambda, br->a->foreign_lambda,
1667 br->a->temp);
1668 sample_coll_init(&cb, br->b->native_lambda, br->b->foreign_lambda,
1669 br->b->temp);
1671 for(npee=npee_min; npee<=npee_max; npee++)
1673 double dgs = 0;
1674 double dgs2 = 0;
1675 double dsa = 0;
1676 double dsb = 0;
1677 double dsa2 = 0;
1678 double dsb2 = 0;
1679 double dstddev = 0;
1680 double dstddev2 = 0;
1683 for(p=0; p<npee; p++)
1685 double dgp;
1686 double stddevc;
1687 double sac, sbc;
1688 gmx_bool cac, cbc;
1690 cac=sample_coll_create_subsample(&ca, br->a, p, npee);
1691 cbc=sample_coll_create_subsample(&cb, br->b, p, npee);
1693 if (!cac || !cbc)
1695 printf("WARNING: histogram number incompatible with block number for averaging: can't do error estimate\n");
1696 *bEE=FALSE;
1697 if (cac)
1698 sample_coll_destroy(&ca);
1699 if (cbc)
1700 sample_coll_destroy(&cb);
1701 return;
1704 dgp=calc_bar_lowlevel(&ca, &cb, temp, tol, 0);
1705 dgs += dgp;
1706 dgs2 += dgp*dgp;
1708 partsum[npee*(npee_max+1)+p] += dgp;
1710 calc_rel_entropy(&ca, &cb, temp, dgp, &sac, &sbc);
1711 dsa += sac;
1712 dsa2 += sac*sac;
1713 dsb += sbc;
1714 dsb2 += sbc*sbc;
1715 calc_dg_stddev(&ca, &cb, temp, dgp, &stddevc );
1717 dstddev += stddevc;
1718 dstddev2 += stddevc*stddevc;
1720 sample_coll_destroy(&ca);
1721 sample_coll_destroy(&cb);
1723 dgs /= npee;
1724 dgs2 /= npee;
1725 dg_sig2 += (dgs2-dgs*dgs)/(npee-1);
1727 dsa /= npee;
1728 dsa2 /= npee;
1729 dsb /= npee;
1730 dsb2 /= npee;
1731 sa_sig2 += (dsa2-dsa*dsa)/(npee-1);
1732 sb_sig2 += (dsb2-dsb*dsb)/(npee-1);
1734 dstddev /= npee;
1735 dstddev2 /= npee;
1736 stddev_sig2 += (dstddev2-dstddev*dstddev)/(npee-1);
1738 br->dg_err = sqrt(dg_sig2/(npee_max - npee_min + 1));
1739 br->sa_err = sqrt(sa_sig2/(npee_max - npee_min + 1));
1740 br->sb_err = sqrt(sb_sig2/(npee_max - npee_min + 1));
1741 br->dg_stddev_err = sqrt(stddev_sig2/(npee_max - npee_min + 1));
1746 static double bar_err(int nbmin, int nbmax, const double *partsum)
1748 int nb,b;
1749 double svar,s,s2,dg;
1751 svar = 0;
1752 for(nb=nbmin; nb<=nbmax; nb++)
1754 s = 0;
1755 s2 = 0;
1756 for(b=0; b<nb; b++)
1758 dg = partsum[nb*(nbmax+1)+b];
1759 s += dg;
1760 s2 += dg*dg;
1762 s /= nb;
1763 s2 /= nb;
1764 svar += (s2 - s*s)/(nb - 1);
1767 return sqrt(svar/(nbmax + 1 - nbmin));
1770 /* deduce lambda value from legend.
1771 input:
1772 bdhdl = if true, value may be a derivative.
1773 output:
1774 bdhdl = whether the legend was for a derivative.
1776 static double legend2lambda(char *fn,const char *legend,gmx_bool *bdhdl)
1778 double lambda=0;
1779 const char *ptr;
1780 gmx_bool ok=FALSE;
1782 if (legend == NULL)
1784 gmx_fatal(FARGS,"There is no legend in file '%s', can not deduce lambda",fn);
1786 ptr = strrchr(legend,' ');
1788 if (strstr(legend,"dH"))
1790 if (! (*bdhdl))
1792 ok=FALSE;
1794 else
1796 ok=TRUE;
1799 else
1801 if (strchr(legend,'D') != NULL && strchr(legend,'H') != NULL)
1803 ok=TRUE;
1804 *bdhdl=FALSE;
1807 if (!ptr)
1809 ok=FALSE;
1812 if (!ok)
1814 printf("%s\n", legend);
1815 gmx_fatal(FARGS,"There is no proper lambda legend in file '%s', can not deduce lambda",fn);
1817 if (sscanf(ptr,"%lf",&lambda) != 1)
1819 gmx_fatal(FARGS,"There is no proper lambda legend in file '%s', can not deduce lambda",fn);
1822 return lambda;
1825 static gmx_bool subtitle2lambda(const char *subtitle,double *lambda)
1827 gmx_bool bFound;
1828 char *ptr;
1830 bFound = FALSE;
1832 /* plain text lambda string */
1833 ptr = strstr(subtitle,"lambda");
1834 if (ptr == NULL)
1836 /* xmgrace formatted lambda string */
1837 ptr = strstr(subtitle,"\\xl\\f{}");
1839 if (ptr == NULL)
1841 /* xmgr formatted lambda string */
1842 ptr = strstr(subtitle,"\\8l\\4");
1844 if (ptr != NULL)
1846 ptr = strstr(ptr,"=");
1848 if (ptr != NULL)
1850 bFound = (sscanf(ptr+1,"%lf",lambda) == 1);
1853 return bFound;
1856 static double filename2lambda(char *fn)
1858 double lambda;
1859 char *ptr,*endptr,*digitptr;
1860 int dirsep;
1861 ptr = fn;
1862 /* go to the end of the path string and search backward to find the last
1863 directory in the path which has to contain the value of lambda
1865 while (ptr[1] != '\0')
1867 ptr++;
1869 /* searching backward to find the second directory separator */
1870 dirsep = 0;
1871 digitptr = NULL;
1872 while (ptr >= fn)
1874 if (ptr[0] != DIR_SEPARATOR && ptr[1] == DIR_SEPARATOR)
1876 if (dirsep == 1) break;
1877 dirsep++;
1879 /* save the last position of a digit between the last two
1880 separators = in the last dirname */
1881 if (dirsep > 0 && isdigit(*ptr))
1883 digitptr = ptr;
1885 ptr--;
1887 if (!digitptr)
1889 gmx_fatal(FARGS,"While trying to read the lambda value from the file path:"
1890 " last directory in the path '%s' does not contain a number",fn);
1892 if (digitptr[-1] == '-')
1894 digitptr--;
1896 lambda = strtod(digitptr,&endptr);
1897 if (endptr == digitptr)
1899 gmx_fatal(FARGS,"Malformed number in file path '%s'",fn);
1902 return lambda;
1905 static void read_bar_xvg_lowlevel(char *fn, real *temp, xvg_t *ba)
1907 int i;
1908 char *subtitle,**legend,*ptr;
1909 int np;
1910 gmx_bool native_lambda_read=FALSE;
1912 xvg_init(ba);
1914 ba->filename = fn;
1916 np = read_xvg_legend(fn,&ba->y,&ba->nset,&subtitle,&legend);
1917 if (!ba->y)
1919 gmx_fatal(FARGS,"File %s contains no usable data.",fn);
1921 ba->t = ba->y[0];
1923 snew(ba->np,ba->nset);
1924 for(i=0;i<ba->nset;i++)
1925 ba->np[i]=np;
1928 ba->temp = -1;
1929 if (subtitle != NULL)
1931 ptr = strstr(subtitle,"T =");
1932 if (ptr != NULL)
1934 ptr += 3;
1935 if (sscanf(ptr,"%lf",&ba->temp) == 1)
1937 if (ba->temp <= 0)
1939 gmx_fatal(FARGS,"Found temperature of %g in file '%s'",
1940 ba->temp,fn);
1945 if (ba->temp < 0)
1947 if (*temp <= 0)
1949 gmx_fatal(FARGS,"Did not find a temperature in the subtitle in file '%s', use the -temp option of [TT]g_bar[tt]",fn);
1951 ba->temp = *temp;
1954 /* Try to deduce lambda from the subtitle */
1955 if (subtitle)
1957 if (subtitle2lambda(subtitle,&(ba->native_lambda)))
1959 native_lambda_read=TRUE;
1962 snew(ba->lambda,ba->nset-1);
1963 if (legend == NULL)
1965 /* Check if we have a single set, no legend, nset=2 means t and dH/dl */
1966 if (ba->nset == 2)
1968 if (!native_lambda_read)
1970 /* Deduce lambda from the file name */
1971 ba->native_lambda = filename2lambda(fn);
1972 native_lambda_read=TRUE;
1974 ba->lambda[0] = ba->native_lambda;
1976 else
1978 gmx_fatal(FARGS,"File %s contains multiple sets but no legends, can not determine the lambda values",fn);
1981 else
1983 for(i=0; i<ba->nset-1; i++)
1985 gmx_bool is_dhdl=(i==0);
1986 /* Read lambda from the legend */
1987 ba->lambda[i] = legend2lambda(fn,legend[i], &is_dhdl);
1989 if (is_dhdl && !native_lambda_read)
1991 ba->native_lambda = ba->lambda[i];
1992 native_lambda_read=TRUE;
1997 if (!native_lambda_read)
1999 gmx_fatal(FARGS,"File %s contains multiple sets but no indication of the native lambda",fn);
2002 /* Reorder the data */
2003 for(i=1; i<ba->nset; i++)
2005 ba->y[i-1] = ba->y[i];
2007 if (legend != NULL)
2009 for(i=0; i<ba->nset-1; i++)
2011 sfree(legend[i]);
2013 sfree(legend);
2015 ba->nset--;
2018 static void read_bar_xvg(char *fn, real *temp, lambda_t *lambda_head)
2020 xvg_t *barsim;
2021 samples_t *s;
2022 int i;
2023 double *lambda;
2025 snew(barsim,1);
2027 read_bar_xvg_lowlevel(fn, temp, barsim);
2029 if (barsim->nset <1 )
2031 gmx_fatal(FARGS,"File '%s' contains fewer than two columns", fn);
2034 if ( !gmx_within_tol(*temp,barsim->temp,GMX_FLOAT_EPS) && (*temp > 0) )
2036 gmx_fatal(FARGS,"Temperature in file %s different from earlier files or setting\n", fn);
2038 *temp=barsim->temp;
2040 /* now create a series of samples_t */
2041 snew(s, barsim->nset);
2042 for(i=0;i<barsim->nset;i++)
2044 samples_init(s+i, barsim->native_lambda, barsim->lambda[i],
2045 barsim->temp, lambda_same(barsim->native_lambda,
2046 barsim->lambda[i]),
2047 fn);
2048 s[i].du=barsim->y[i];
2049 s[i].ndu=barsim->np[i];
2050 s[i].t=barsim->t;
2052 lambda_list_insert_sample(lambda_head, s+i);
2054 printf("%s: %.1f - %.1f; lambda = %.3f\n foreign lambdas:",
2055 fn, s[0].t[0], s[0].t[s[0].ndu-1], s[0].native_lambda);
2056 for(i=0;i<barsim->nset;i++)
2058 printf(" %.3f (%d pts)", s[i].foreign_lambda, s[i].ndu);
2060 printf("\n\n");
2063 static void read_edr_rawdh_block(samples_t **smp, int *ndu, t_enxblock *blk,
2064 double start_time, double delta_time,
2065 double native_lambda, double temp,
2066 double *last_t, const char *filename)
2068 int j;
2069 gmx_bool allocated;
2070 double foreign_lambda;
2071 int derivative;
2072 samples_t *s; /* convenience pointer */
2073 int startj;
2075 /* check the block types etc. */
2076 if ( (blk->nsub < 3) ||
2077 (blk->sub[0].type != xdr_datatype_int) ||
2078 (blk->sub[1].type != xdr_datatype_double) ||
2080 (blk->sub[2].type != xdr_datatype_float) &&
2081 (blk->sub[2].type != xdr_datatype_double)
2082 ) ||
2083 (blk->sub[0].nr < 1) ||
2084 (blk->sub[1].nr < 1) )
2086 gmx_fatal(FARGS,
2087 "Unexpected/corrupted block data in file %s around time %g.",
2088 filename, start_time);
2091 derivative = blk->sub[0].ival[0];
2092 foreign_lambda = blk->sub[1].dval[0];
2094 if (! *smp)
2096 /* initialize the samples structure if it's empty. */
2097 snew(*smp, 1);
2098 samples_init(*smp, native_lambda, foreign_lambda, temp,
2099 derivative!=0, filename);
2100 (*smp)->start_time=start_time;
2101 (*smp)->delta_time=delta_time;
2104 /* set convenience pointer */
2105 s=*smp;
2107 /* now double check */
2108 if ( ! lambda_same(s->foreign_lambda, foreign_lambda) ||
2109 ( (derivative!=0) != (s->derivative!=0) ) )
2111 fprintf(stderr, "Got foreign lambda=%g, expected: %g\n",
2112 foreign_lambda, s->foreign_lambda);
2113 fprintf(stderr, "Got derivative=%d, expected: %d\n",
2114 derivative, s->derivative);
2115 gmx_fatal(FARGS, "Corrupted data in file %s around t=%g.",
2116 filename, start_time);
2119 /* make room for the data */
2120 if (s->ndu_alloc < (size_t)(s->ndu + blk->sub[2].nr) )
2122 s->ndu_alloc += (s->ndu_alloc < (size_t)blk->sub[2].nr) ?
2123 blk->sub[2].nr*2 : s->ndu_alloc;
2124 srenew(s->du_alloc, s->ndu_alloc);
2125 s->du=s->du_alloc;
2127 startj = s->ndu;
2128 s->ndu += blk->sub[2].nr;
2129 s->ntot += blk->sub[2].nr;
2130 *ndu = blk->sub[2].nr;
2132 /* and copy the data*/
2133 for(j=0;j<blk->sub[2].nr;j++)
2135 if (blk->sub[2].type == xdr_datatype_float)
2137 s->du[startj+j] = blk->sub[2].fval[j];
2139 else
2141 s->du[startj+j] = blk->sub[2].dval[j];
2144 if (start_time + blk->sub[2].nr*delta_time > *last_t)
2146 *last_t = start_time + blk->sub[2].nr*delta_time;
2150 static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk,
2151 double start_time, double delta_time,
2152 double native_lambda, double temp,
2153 double *last_t, const char *filename)
2155 int i,j;
2156 samples_t *s;
2157 int nhist;
2158 double foreign_lambda;
2159 int derivative;
2160 int nbins[2];
2162 /* check the block types etc. */
2163 if ( (blk->nsub < 2) ||
2164 (blk->sub[0].type != xdr_datatype_double) ||
2165 (blk->sub[1].type != xdr_datatype_large_int) ||
2166 (blk->sub[0].nr < 2) ||
2167 (blk->sub[1].nr < 2) )
2169 gmx_fatal(FARGS,
2170 "Unexpected/corrupted block data in file %s around time %g",
2171 filename, start_time);
2174 nhist=blk->nsub-2;
2175 if (nhist == 0)
2177 return NULL;
2179 if (nhist > 2)
2181 gmx_fatal(FARGS,
2182 "Unexpected/corrupted block data in file %s around time %g",
2183 filename, start_time);
2186 snew(s, 1);
2187 *nsamples=1;
2189 foreign_lambda=blk->sub[0].dval[0];
2190 derivative=(int)(blk->sub[1].lval[1]);
2191 if (derivative)
2192 foreign_lambda=native_lambda;
2194 samples_init(s, native_lambda, foreign_lambda, temp,
2195 derivative!=0, filename);
2196 snew(s->hist, 1);
2198 for(i=0;i<nhist;i++)
2200 nbins[i] = blk->sub[i+2].nr;
2203 hist_init(s->hist, nhist, nbins);
2205 for(i=0;i<nhist;i++)
2207 s->hist->x0[i]=blk->sub[1].lval[2+i];
2208 s->hist->dx[i] = blk->sub[0].dval[1];
2209 if (i==1)
2210 s->hist->dx[i] = - s->hist->dx[i];
2213 s->hist->start_time = start_time;
2214 s->hist->delta_time = delta_time;
2215 s->start_time = start_time;
2216 s->delta_time = delta_time;
2218 for(i=0;i<nhist;i++)
2220 int nbin;
2221 gmx_large_int_t sum=0;
2223 for(j=0;j<s->hist->nbin[i];j++)
2225 int binv=(int)(blk->sub[i+2].ival[j]);
2227 s->hist->bin[i][j] = binv;
2228 sum += binv;
2231 if (i==0)
2233 s->ntot = sum;
2234 s->hist->sum = sum;
2236 else
2238 if (s->ntot != sum)
2240 gmx_fatal(FARGS, "Histogram counts don't match in %s",
2241 filename);
2246 if (start_time + s->hist->sum*delta_time > *last_t)
2248 *last_t = start_time + s->hist->sum*delta_time;
2250 return s;
2254 static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
2256 int i;
2257 ener_file_t fp;
2258 t_enxframe *fr;
2259 int nre;
2260 gmx_enxnm_t *enm=NULL;
2261 double first_t=-1;
2262 double last_t=-1;
2263 samples_t **samples_rawdh=NULL; /* contains samples for raw delta_h */
2264 int *nhists=NULL; /* array to keep count & print at end */
2265 int *npts=NULL; /* array to keep count & print at end */
2266 double *lambdas=NULL; /* array to keep count & print at end */
2267 double native_lambda=-1;
2268 double end_time; /* the end time of the last batch of samples */
2269 int nsamples=0;
2271 fp = open_enx(fn,"r");
2272 do_enxnms(fp,&nre,&enm);
2273 snew(fr, 1);
2275 while(do_enx(fp, fr))
2277 /* count the data blocks */
2278 int nblocks_raw=0;
2279 int nblocks_hist=0;
2280 int nlam=0;
2281 int k;
2282 /* DHCOLL block information: */
2283 double start_time=0, delta_time=0, start_lambda=0, delta_lambda=0;
2284 double rtemp=0;
2286 /* count the blocks and handle collection information: */
2287 for(i=0;i<fr->nblock;i++)
2289 if (fr->block[i].id == enxDHHIST )
2290 nblocks_hist++;
2291 if ( fr->block[i].id == enxDH )
2292 nblocks_raw++;
2293 if (fr->block[i].id == enxDHCOLL )
2295 nlam++;
2296 if ( (fr->block[i].nsub < 1) ||
2297 (fr->block[i].sub[0].type != xdr_datatype_double) ||
2298 (fr->block[i].sub[0].nr < 5))
2300 gmx_fatal(FARGS, "Unexpected block data in file %s", fn);
2303 /* read the data from the DHCOLL block */
2304 rtemp = fr->block[i].sub[0].dval[0];
2305 start_time = fr->block[i].sub[0].dval[1];
2306 delta_time = fr->block[i].sub[0].dval[2];
2307 start_lambda = fr->block[i].sub[0].dval[3];
2308 delta_lambda = fr->block[i].sub[0].dval[4];
2310 if (delta_lambda>0)
2312 gmx_fatal(FARGS, "Lambda values not constant in %s: can't apply BAR method", fn);
2314 if ( ( *temp != rtemp) && (*temp > 0) )
2316 gmx_fatal(FARGS,"Temperature in file %s different from earlier files or setting\n", fn);
2318 *temp=rtemp;
2320 if (first_t < 0)
2321 first_t=start_time;
2325 if (nlam != 1)
2327 gmx_fatal(FARGS, "Did not find a delta h information in file %s" , fn);
2329 if (nblocks_raw > 0 && nblocks_hist > 0 )
2331 gmx_fatal(FARGS, "Can't handle both raw delta U data and histograms in the same file %s", fn);
2334 if (nsamples > 0)
2336 /* check the native lambda */
2337 if (!lambda_same(start_lambda, native_lambda) )
2339 gmx_fatal(FARGS, "Native lambda not constant in file %s: started at %g, and becomes %g at time %g",
2340 fn, native_lambda, start_lambda, start_time);
2342 /* check the number of samples against the previous number */
2343 if ( ((nblocks_raw+nblocks_hist)!=nsamples) || (nlam!=1 ) )
2345 gmx_fatal(FARGS, "Unexpected block count in %s: was %d, now %d\n",
2346 fn, nsamples+1, nblocks_raw+nblocks_hist+nlam);
2348 /* check whether last iterations's end time matches with
2349 the currrent start time */
2350 if ( (fabs(last_t - start_time) > 2*delta_time) && last_t>=0)
2352 /* it didn't. We need to store our samples and reallocate */
2353 for(i=0;i<nsamples;i++)
2355 if (samples_rawdh[i])
2357 /* insert it into the existing list */
2358 lambda_list_insert_sample(lambda_head,
2359 samples_rawdh[i]);
2360 /* and make sure we'll allocate a new one this time
2361 around */
2362 samples_rawdh[i]=NULL;
2367 else
2369 /* this is the first round; allocate the associated data
2370 structures */
2371 native_lambda=start_lambda;
2372 nsamples=nblocks_raw+nblocks_hist;
2373 snew(nhists, nsamples);
2374 snew(npts, nsamples);
2375 snew(lambdas, nsamples);
2376 snew(samples_rawdh, nsamples);
2377 for(i=0;i<nsamples;i++)
2379 nhists[i]=0;
2380 npts[i]=0;
2381 lambdas[i]=-1;
2382 samples_rawdh[i]=NULL; /* init to NULL so we know which
2383 ones contain values */
2387 /* and read them */
2388 k=0; /* counter for the lambdas, etc. arrays */
2389 for(i=0;i<fr->nblock;i++)
2391 if (fr->block[i].id == enxDH)
2393 int ndu;
2394 read_edr_rawdh_block(&(samples_rawdh[k]),
2395 &ndu,
2396 &(fr->block[i]),
2397 start_time, delta_time,
2398 start_lambda, rtemp,
2399 &last_t, fn);
2400 npts[k] += ndu;
2401 if (samples_rawdh[k])
2403 lambdas[k]=samples_rawdh[k]->foreign_lambda;
2405 k++;
2407 else if (fr->block[i].id == enxDHHIST)
2409 int j;
2410 int nb=0;
2411 samples_t *s; /* this is where the data will go */
2412 s=read_edr_hist_block(&nb, &(fr->block[i]),
2413 start_time, delta_time,
2414 start_lambda, rtemp,
2415 &last_t, fn);
2416 nhists[k] += nb;
2417 if (nb>0)
2419 lambdas[k]= s->foreign_lambda;
2421 k++;
2422 /* and insert the new sample immediately */
2423 for(j=0;j<nb;j++)
2425 lambda_list_insert_sample(lambda_head, s+j);
2430 /* Now store all our extant sample collections */
2431 for(i=0;i<nsamples;i++)
2433 if (samples_rawdh[i])
2435 /* insert it into the existing list */
2436 lambda_list_insert_sample(lambda_head, samples_rawdh[i]);
2441 fprintf(stderr, "\n");
2442 printf("%s: %.1f - %.1f; lambda = %.3f\n foreign lambdas:",
2443 fn, first_t, last_t, native_lambda);
2444 for(i=0;i<nsamples;i++)
2446 if (nhists[i] > 0)
2448 printf(" %.3f (%d hists)", lambdas[i], nhists[i]);
2450 else
2452 printf(" %.3f (%d pts)", lambdas[i], npts[i]);
2455 printf("\n\n");
2456 sfree(npts);
2457 sfree(nhists);
2458 sfree(lambdas);
2462 int gmx_bar(int argc,char *argv[])
2464 static const char *desc[] = {
2465 "[TT]g_bar[tt] calculates free energy difference estimates through ",
2466 "Bennett's acceptance ratio method (BAR). It also automatically",
2467 "adds series of individual free energies obtained with BAR into",
2468 "a combined free energy estimate.[PAR]",
2470 "Every individual BAR free energy difference relies on two ",
2471 "simulations at different states: say state A and state B, as",
2472 "controlled by a parameter, [GRK]lambda[grk] (see the [TT].mdp[tt] parameter",
2473 "[TT]init_lambda[tt]). The BAR method calculates a ratio of weighted",
2474 "average of the Hamiltonian difference of state B given state A and",
2475 "vice versa. If the Hamiltonian does not depend linearly on [GRK]lambda[grk]",
2476 "(in which case we can extrapolate the derivative of the Hamiltonian",
2477 "with respect to [GRK]lambda[grk], as is the default when [TT]free_energy[tt] is on),",
2478 "the energy differences to the other state need to be calculated",
2479 "explicitly during the simulation. This can be controlled with",
2480 "the [TT].mdp[tt] option [TT]foreign_lambda[tt].[PAR]",
2482 "Input option [TT]-f[tt] expects multiple [TT]dhdl.xvg[tt] files. ",
2483 "Two types of input files are supported:[BR]",
2484 "[TT]*[tt] Files with only one [IT]y[it]-value, for such files it is assumed ",
2485 " that the [IT]y[it]-value is dH/d[GRK]lambda[grk] and that the Hamiltonian depends ",
2486 " linearly on [GRK]lambda[grk]. The [GRK]lambda[grk] value of the simulation is inferred ",
2487 " from the subtitle (if present), otherwise from a number in the",
2488 " subdirectory in the file name.",
2489 "[BR]",
2490 "[TT]*[tt] Files with more than one [IT]y[it]-value. The files should have columns ",
2491 " with dH/d[GRK]lambda[grk] and [GRK]Delta[grk][GRK]lambda[grk]. The [GRK]lambda[grk] values are inferred ",
2492 " from the legends: [GRK]lambda[grk] of the simulation from the legend of dH/d[GRK]lambda[grk] ",
2493 " and the foreign [GRK]lambda[grk] values from the legends of Delta H.[PAR]",
2494 "The [GRK]lambda[grk] of the simulation is parsed from [TT]dhdl.xvg[tt] file's legend ",
2495 "containing the string 'dH', the foreign [GRK]lambda[grk] values from the legend ",
2496 "containing the capitalized letters 'D' and 'H'. The temperature ",
2497 "is parsed from the legend line containing 'T ='.[PAR]",
2499 "The input option [TT]-g[tt] expects multiple [TT].edr[tt] files. ",
2500 "These can contain either lists of energy differences (see the",
2501 "[TT].mdp[tt] option [TT]separate_dhdl_file[tt]), or a series of histograms",
2502 "(see the [TT].mdp[tt] options [TT]dh_hist_size[tt] and [TT]dh_hist_spacing[tt]).",
2503 "The temperature and [GRK]lambda[grk] values are automatically deduced from",
2504 "the [TT]ener.edr[tt] file.[PAR]"
2506 "The free energy estimates are determined using BAR with bisection, ",
2507 "with the precision of the output set with [TT]-prec[tt]. ",
2508 "An error estimate taking into account time correlations ",
2509 "is made by splitting the data into blocks and determining ",
2510 "the free energy differences over those blocks and assuming ",
2511 "the blocks are independent. ",
2512 "The final error estimate is determined from the average variance ",
2513 "over 5 blocks. A range of block numbers for error estimation can ",
2514 "be provided with the options [TT]-nbmin[tt] and [TT]-nbmax[tt].[PAR]",
2516 "[TT]g_bar[tt] tries to aggregate samples with the same 'native' and 'foreign'",
2517 "[GRK]lambda[grk] values, but always assumes independent samples. [BB]Note[bb] that",
2518 "when aggregating energy differences/derivatives with different",
2519 "sampling intervals, this is almost certainly not correct. Usually",
2520 "subsequent energies are correlated and different time intervals mean",
2521 "different degrees of correlation between samples.[PAR]",
2523 "The results are split in two parts: the last part contains the final ",
2524 "results in kJ/mol, together with the error estimate for each part ",
2525 "and the total. The first part contains detailed free energy ",
2526 "difference estimates and phase space overlap measures in units of ",
2527 "kT (together with their computed error estimate). The printed ",
2528 "values are:[BR]",
2529 "[TT]*[tt] lam_A: the [GRK]lambda[grk] values for point A.[BR]",
2530 "[TT]*[tt] lam_B: the [GRK]lambda[grk] values for point B.[BR]",
2531 "[TT]*[tt] DG: the free energy estimate.[BR]",
2532 "[TT]*[tt] s_A: an estimate of the relative entropy of B in A.[BR]",
2533 "[TT]*[tt] s_A: an estimate of the relative entropy of A in B.[BR]",
2534 "[TT]*[tt] stdev: an estimate expected per-sample standard deviation.[PAR]",
2536 "The relative entropy of both states in each other's ensemble can be ",
2537 "interpreted as a measure of phase space overlap: ",
2538 "the relative entropy s_A of the work samples of lambda_B in the ",
2539 "ensemble of lambda_A (and vice versa for s_B), is a ",
2540 "measure of the 'distance' between Boltzmann distributions of ",
2541 "the two states, that goes to zero for identical distributions. See ",
2542 "Wu & Kofke, J. Chem. Phys. 123 084109 (2005) for more information.",
2543 "[PAR]",
2544 "The estimate of the expected per-sample standard deviation, as given ",
2545 "in Bennett's original BAR paper: Bennett, J. Comp. Phys. 22, p 245 (1976).",
2546 "Eq. 10 therein gives an estimate of the quality of sampling (not directly",
2547 "of the actual statistical error, because it assumes independent samples).[PAR]",
2549 "To get a visual estimate of the phase space overlap, use the ",
2550 "[TT]-oh[tt] option to write series of histograms, together with the ",
2551 "[TT]-nbin[tt] option.[PAR]"
2553 static real begin=0,end=-1,temp=-1;
2554 int nd=2,nbmin=5,nbmax=5;
2555 int nbin=100;
2556 gmx_bool calc_s,calc_v;
2557 t_pargs pa[] = {
2558 { "-b", FALSE, etREAL, {&begin}, "Begin time for BAR" },
2559 { "-e", FALSE, etREAL, {&end}, "End time for BAR" },
2560 { "-temp", FALSE, etREAL, {&temp}, "Temperature (K)" },
2561 { "-prec", FALSE, etINT, {&nd}, "The number of digits after the decimal point" },
2562 { "-nbmin", FALSE, etINT, {&nbmin}, "Minimum number of blocks for error estimation" },
2563 { "-nbmax", FALSE, etINT, {&nbmax}, "Maximum number of blocks for error estimation" },
2564 { "-nbin", FALSE, etINT, {&nbin}, "Number of bins for histogram output"}
2567 t_filenm fnm[] = {
2568 { efXVG, "-f", "dhdl", ffOPTRDMULT },
2569 { efEDR, "-g", "ener", ffOPTRDMULT },
2570 { efXVG, "-o", "bar", ffOPTWR },
2571 { efXVG, "-oi", "barint", ffOPTWR },
2572 { efXVG, "-oh", "histogram", ffOPTWR }
2574 #define NFILE asize(fnm)
2576 int f,i,j;
2577 int nf=0; /* file counter */
2578 int nbs;
2579 int nfile_tot; /* total number of input files */
2580 int nxvgfile=0;
2581 int nedrfile=0;
2582 char **fxvgnms;
2583 char **fedrnms;
2584 lambda_t *lb; /* the pre-processed lambda data (linked list head) */
2585 lambda_t lambda_head; /* the head element */
2586 barres_t *results; /* the results */
2587 int nresults; /* number of results in results array */
2589 double *partsum;
2590 double prec,dg_tot,dg,sig, dg_tot_max, dg_tot_min;
2591 FILE *fpb,*fpi;
2592 char lamformat[20];
2593 char dgformat[20],xvg2format[STRLEN],xvg3format[STRLEN],buf[STRLEN];
2594 char ktformat[STRLEN], sktformat[STRLEN];
2595 char kteformat[STRLEN], skteformat[STRLEN];
2596 output_env_t oenv;
2597 double kT, beta;
2598 gmx_bool result_OK=TRUE,bEE=TRUE;
2600 gmx_bool disc_err=FALSE;
2601 double sum_disc_err=0.; /* discretization error */
2602 gmx_bool histrange_err=FALSE;
2603 double sum_histrange_err=0.; /* histogram range error */
2604 double stat_err=0.; /* statistical error */
2606 CopyRight(stderr,argv[0]);
2607 parse_common_args(&argc,argv,
2608 PCA_CAN_VIEW,
2609 NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv);
2611 if (opt2bSet("-f", NFILE, fnm))
2613 nxvgfile = opt2fns(&fxvgnms,"-f",NFILE,fnm);
2615 if (opt2bSet("-g", NFILE, fnm))
2617 nedrfile = opt2fns(&fedrnms,"-g",NFILE,fnm);
2620 /* make linked list */
2621 lb=&lambda_head;
2622 lambda_init(lb, 0, 0);
2623 lb->next=lb;
2624 lb->prev=lb;
2627 nfile_tot = nxvgfile + nedrfile;
2629 if (nfile_tot == 0)
2631 gmx_fatal(FARGS,"No input files!");
2634 if (nd < 0)
2636 gmx_fatal(FARGS,"Can not have negative number of digits");
2638 prec = pow(10,-nd);
2640 snew(partsum,(nbmax+1)*(nbmax+1));
2641 nf = 0;
2643 /* read in all files. First xvg files */
2644 for(f=0; f<nxvgfile; f++)
2646 read_bar_xvg(fxvgnms[f],&temp,lb);
2647 nf++;
2649 /* then .edr files */
2650 for(f=0; f<nedrfile; f++)
2652 read_barsim_edr(fedrnms[f],&temp,lb);;
2653 nf++;
2656 /* fix the times to allow for equilibration */
2657 lambdas_impose_times(lb, begin, end);
2659 if (opt2bSet("-oh",NFILE,fnm))
2661 lambdas_histogram(lb, opt2fn("-oh",NFILE,fnm), nbin, oenv);
2664 /* assemble the output structures from the lambdas */
2665 results=barres_list_create(lb, &nresults);
2667 sum_disc_err=barres_list_max_disc_err(results, nresults);
2669 if (nresults == 0)
2671 printf("\nNo results to calculate.\n");
2672 return 0;
2675 if (sum_disc_err > prec)
2677 prec=sum_disc_err;
2678 nd = ceil(-log10(prec));
2679 printf("WARNING: setting the precision to %g because that is the minimum\n reasonable number, given the expected discretization error.\n", prec);
2683 sprintf(lamformat,"%%6.3f");
2684 sprintf( dgformat,"%%%d.%df",3+nd,nd);
2685 /* the format strings of the results in kT */
2686 sprintf( ktformat,"%%%d.%df",5+nd,nd);
2687 sprintf( sktformat,"%%%ds",6+nd);
2688 /* the format strings of the errors in kT */
2689 sprintf( kteformat,"%%%d.%df",3+nd,nd);
2690 sprintf( skteformat,"%%%ds",4+nd);
2691 sprintf(xvg2format,"%s %s\n","%g",dgformat);
2692 sprintf(xvg3format,"%s %s %s\n","%g",dgformat,dgformat);
2696 fpb = NULL;
2697 if (opt2bSet("-o",NFILE,fnm))
2699 sprintf(buf,"%s (%s)","\\DeltaG","kT");
2700 fpb = xvgropen_type(opt2fn("-o",NFILE,fnm),"Free energy differences",
2701 "\\lambda",buf,exvggtXYDY,oenv);
2704 fpi = NULL;
2705 if (opt2bSet("-oi",NFILE,fnm))
2707 sprintf(buf,"%s (%s)","\\DeltaG","kT");
2708 fpi = xvgropen(opt2fn("-oi",NFILE,fnm),"Free energy integral",
2709 "\\lambda",buf,oenv);
2714 if (nbmin > nbmax)
2715 nbmin=nbmax;
2717 /* first calculate results */
2718 bEE = TRUE;
2719 disc_err = FALSE;
2720 for(f=0; f<nresults; f++)
2722 /* Determine the free energy difference with a factor of 10
2723 * more accuracy than requested for printing.
2725 calc_bar(&(results[f]), 0.1*prec, nbmin, nbmax,
2726 &bEE, partsum);
2728 if (results[f].dg_disc_err > prec/10.)
2729 disc_err=TRUE;
2730 if (results[f].dg_histrange_err > prec/10.)
2731 histrange_err=TRUE;
2734 /* print results in kT */
2735 kT = BOLTZ*temp;
2736 beta = 1/kT;
2738 printf("\nTemperature: %g K\n", temp);
2740 printf("\nDetailed results in kT (see help for explanation):\n\n");
2741 printf("%6s ", " lam_A");
2742 printf("%6s ", " lam_B");
2743 printf(sktformat, "DG ");
2744 if (bEE)
2745 printf(skteformat, "+/- ");
2746 if (disc_err)
2747 printf(skteformat, "disc ");
2748 if (histrange_err)
2749 printf(skteformat, "range ");
2750 printf(sktformat, "s_A ");
2751 if (bEE)
2752 printf(skteformat, "+/- " );
2753 printf(sktformat, "s_B ");
2754 if (bEE)
2755 printf(skteformat, "+/- " );
2756 printf(sktformat, "stdev ");
2757 if (bEE)
2758 printf(skteformat, "+/- ");
2759 printf("\n");
2760 for(f=0; f<nresults; f++)
2762 printf(lamformat, results[f].a->native_lambda);
2763 printf(" ");
2764 printf(lamformat, results[f].b->native_lambda);
2765 printf(" ");
2766 printf(ktformat, results[f].dg);
2767 printf(" ");
2768 if (bEE)
2770 printf(kteformat, results[f].dg_err);
2771 printf(" ");
2773 if (disc_err)
2775 printf(kteformat, results[f].dg_disc_err);
2776 printf(" ");
2778 if (histrange_err)
2780 printf(kteformat, results[f].dg_histrange_err);
2781 printf(" ");
2783 printf(ktformat, results[f].sa);
2784 printf(" ");
2785 if (bEE)
2787 printf(kteformat, results[f].sa_err);
2788 printf(" ");
2790 printf(ktformat, results[f].sb);
2791 printf(" ");
2792 if (bEE)
2794 printf(kteformat, results[f].sb_err);
2795 printf(" ");
2797 printf(ktformat, results[f].dg_stddev);
2798 printf(" ");
2799 if (bEE)
2801 printf(kteformat, results[f].dg_stddev_err);
2803 printf("\n");
2805 /* Check for negative relative entropy with a 95% certainty. */
2806 if (results[f].sa < -2*results[f].sa_err ||
2807 results[f].sb < -2*results[f].sb_err)
2809 result_OK=FALSE;
2813 if (!result_OK)
2815 printf("\nWARNING: Some of these results violate the Second Law of "
2816 "Thermodynamics: \n"
2817 " This is can be the result of severe undersampling, or "
2818 "(more likely)\n"
2819 " there is something wrong with the simulations.\n");
2823 /* final results in kJ/mol */
2824 printf("\n\nFinal results in kJ/mol:\n\n");
2825 dg_tot = 0;
2826 for(f=0; f<nresults; f++)
2829 if (fpi != NULL)
2831 fprintf(fpi, xvg2format, results[f].a->native_lambda, dg_tot);
2835 if (fpb != NULL)
2837 fprintf(fpb, xvg3format,
2838 0.5*(results[f].a->native_lambda +
2839 results[f].b->native_lambda),
2840 results[f].dg,results[f].dg_err);
2843 /*printf("lambda %4.2f - %4.2f, DG ", results[f].lambda_a,
2844 results[f].lambda_b);*/
2845 printf("lambda ");
2846 printf(lamformat, results[f].a->native_lambda);
2847 printf(" - ");
2848 printf(lamformat, results[f].b->native_lambda);
2849 printf(", DG ");
2851 printf(dgformat,results[f].dg*kT);
2852 if (bEE)
2854 printf(" +/- ");
2855 printf(dgformat,results[f].dg_err*kT);
2857 if (histrange_err)
2859 printf(" (max. range err. = ");
2860 printf(dgformat,results[f].dg_histrange_err*kT);
2861 printf(")");
2862 sum_histrange_err += results[f].dg_histrange_err*kT;
2865 printf("\n");
2866 dg_tot += results[f].dg;
2868 printf("\n");
2869 printf("total ");
2870 printf(lamformat, results[0].a->native_lambda);
2871 printf(" - ");
2872 printf(lamformat, results[nresults-1].b->native_lambda);
2873 printf(", DG ");
2875 printf(dgformat,dg_tot*kT);
2876 if (bEE)
2878 stat_err=bar_err(nbmin,nbmax,partsum)*kT;
2879 printf(" +/- ");
2880 printf(dgformat, max(max(stat_err, sum_disc_err), sum_histrange_err));
2882 printf("\n");
2883 if (disc_err)
2885 printf("\nmaximum discretization error = ");
2886 printf(dgformat,sum_disc_err);
2887 if (bEE && stat_err < sum_disc_err)
2889 printf("WARNING: discretization error (%g) is larger than statistical error.\n Decrease histogram spacing for more accurate results\n", stat_err);
2892 if (histrange_err)
2894 printf("\nmaximum histogram range error = ");
2895 printf(dgformat,sum_histrange_err);
2896 if (bEE && stat_err < sum_histrange_err)
2898 printf("WARNING: histogram range error (%g) is larger than statistical error.\n Increase histogram range for more accurate results\n", stat_err);
2902 printf("\n");
2905 if (fpi != NULL)
2907 fprintf(fpi, xvg2format,
2908 results[nresults-1].b->native_lambda, dg_tot);
2909 ffclose(fpi);
2912 do_view(oenv,opt2fn_null("-o",NFILE,fnm),"-xydy");
2913 do_view(oenv,opt2fn_null("-oi",NFILE,fnm),"-xydy");
2915 thanx(stderr);
2917 return 0;