2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
52 #include "gmx_fatal.h"
57 #define MODE(x) ((mode & (x)) == (x))
61 int nrestart,nout,P,fitfn,nskip;
62 gmx_bool bFour,bNormalize;
63 real tbeginfit,tendfit;
66 static gmx_bool bACFinit = FALSE;
69 enum { enNorm, enCos, enSin };
71 int sffn2effn(const char **sffn)
76 for(i=0; i<effnNR; i++)
77 if (sffn[i+1] && strcmp(sffn[0],sffn[i+1])==0)
83 static void low_do_four_core(int nfour,int nframes,real c1[],real cfour[],
84 int nCos,gmx_bool bPadding)
92 for(i=0; (i<nframes); i++) {
98 for(i=0; (i<nframes); i++)
102 for(i=0; (i<nframes); i++)
106 gmx_fatal(FARGS,"nCos = %d, %s %d",nCos,__FILE__,__LINE__);
108 for( ; (i<nfour); i++)
113 /* printf("aver = %g\n",aver); */
114 for(i=0; (i<nframes); i++)
119 correl(cfour-1,cfour-1,nfour,ans-1);
122 for (i=0; (i<nfour); i++)
123 cfour[i] = ans[i]+sqr(aver);
125 for (i=0; (i<nfour); i++)
131 static void do_ac_core(int nframes,int nout,
132 real corr[],real c1[],int nrestart,
140 printf("WARNING: setting number of restarts to 1\n");
145 "Starting do_ac_core: nframes=%d, nout=%d, nrestart=%d,mode=%lu\n",
146 nframes,nout,nrestart,mode);
148 for(j=0; (j<nout); j++)
151 /* Loop over starting points. */
152 for(j=0; (j<nframes); j+=nrestart) {
155 /* Loop over the correlation length for this starting point */
156 for(k=0; (k<nout) && (j+k < nframes); k++) {
159 /* Switch over possible ACF types.
160 * It might be more efficient to put the loops inside the switch,
161 * but this is more clear, and save development time!
163 if (MODE(eacNormal)) {
164 corr[k] += c1[j]*c1[j+k];
166 else if (MODE(eacCos)) {
167 /* Compute the cos (phi(t)-phi(t+dt)) */
168 corr[k] += cos(c1[j]-c1[j+k]);
170 else if (MODE(eacIden)) {
171 /* Check equality (phi(t)==phi(t+dt)) */
172 corr[k] += (c1[j]==c1[j+k])? 1 : 0;
174 else if (MODE(eacP1) || MODE(eacP2) || MODE(eacP3)) {
175 for(m=0; (m<DIM); m++) {
179 cth=cos_angle(xj,xk);
181 if (cth-1.0 > 1.0e-15) {
182 printf("j: %d, k: %d, xj:(%g,%g,%g), xk:(%g,%g,%g)\n",
183 j,k,xj[XX],xj[YY],xj[ZZ],xk[XX],xk[YY],xk[ZZ]);
186 corr[k] += LegendreP(cth,mode); /* 1.5*cth*cth-0.5; */
188 else if (MODE(eacRcross)) {
189 for(m=0; (m<DIM); m++) {
195 corr[k] += iprod(rr,rr);
197 else if (MODE(eacVector)) {
198 for(m=0; (m<DIM); m++) {
207 gmx_fatal(FARGS,"\nInvalid mode (%d) in do_ac_core",mode);
210 /* Correct for the number of points and copy results to the data array */
211 for(j=0; (j<nout); j++) {
212 n = (nframes-j+(nrestart-1))/nrestart;
217 void normalize_acf(int nout,real corr[])
223 fprintf(debug,"Before normalization\n");
224 for(j=0; (j<nout); j++)
225 fprintf(debug,"%5d %10f\n",j,corr[j]);
228 /* Normalisation makes that c[0] = 1.0 and that other points are scaled
235 for(j=0; (j<nout); j++)
239 fprintf(debug,"After normalization\n");
240 for(j=0; (j<nout); j++)
241 fprintf(debug,"%5d %10f\n",j,corr[j]);
245 void average_acf(gmx_bool bVerbose,int n,int nitem,real **c1)
251 printf("Averaging correlation functions\n");
253 for(j=0; (j<n); j++) {
255 for(i=0; (i<nitem); i++)
261 void norm_and_scale_vectors(int nframes,real c1[],real scale)
266 for(j=0; (j<nframes); j++) {
269 for(m=0; (m<DIM); m++)
274 void dump_tmp(char *s,int n,real c[])
281 fprintf(fp,"%10d %10g\n",i,c[i]);
285 real print_and_integrate(FILE *fp,int n,real dt,real c[],real *fit,int nskip)
290 /* Use trapezoidal rule for calculating integral */
292 for(j=0; (j<n); j++) {
294 if (fp && (nskip == 0 || j % nskip == 0))
295 fprintf(fp,"%10.3f %10.5f\n",j*dt,c0);
303 if (nskip == 0 || j % nskip == 0)
304 fprintf(fp,"%10.3f %10.5f\n",j*dt,fit[j]);
311 real evaluate_integral(int n,real x[],real y[],real dy[],real aver_start,
314 double sum,sum_var,w;
315 double sum_tail=0,sum2_tail=0;
318 /* Use trapezoidal rule for calculating integral */
320 gmx_fatal(FARGS,"Evaluating integral: n = %d (file %s, line %d)",
321 n,__FILE__,__LINE__);
325 for(j=0; (j<n); j++) {
328 w += 0.5*(x[j] - x[j-1]);
330 w += 0.5*(x[j+1] - x[j]);
333 /* Assume all errors are uncorrelated */
334 sum_var += sqr(w*dy[j]);
337 if ((aver_start > 0) && (x[j] >= aver_start)) {
339 sum2_tail += sqrt(sum_var);
345 sum = sum_tail/nsum_tail;
346 /* This is a worst case estimate, assuming all stddev's are correlated. */
347 *stddev = sum2_tail/nsum_tail;
350 *stddev = sqrt(sum_var);
355 void do_four_core(unsigned long mode,int nfour,int nf2,int nframes,
356 real c1[],real csum[],real ctmp[])
365 if (MODE(eacNormal)) {
366 /********************************************
368 ********************************************/
369 low_do_four_core(nfour,nf2,c1,csum,enNorm,FALSE);
371 else if (MODE(eacCos)) {
372 /***************************************************
374 ***************************************************/
375 /* Copy the data to temp array. Since we need it twice
376 * we can't overwrite original.
378 for(j=0; (j<nf2); j++)
381 /* Cosine term of AC function */
382 low_do_four_core(nfour,nf2,ctmp,cfour,enCos,FALSE);
383 for(j=0; (j<nf2); j++)
386 /* Sine term of AC function */
387 low_do_four_core(nfour,nf2,ctmp,cfour,enSin,FALSE);
388 for(j=0; (j<nf2); j++) {
393 else if (MODE(eacP2)) {
394 /***************************************************
395 * Legendre polynomials
396 ***************************************************/
397 /* First normalize the vectors */
398 norm_and_scale_vectors(nframes,c1,1.0);
400 /* For P2 thingies we have to do six FFT based correls
401 * First for XX^2, then for YY^2, then for ZZ^2
402 * Then we have to do XY, YZ and XZ (counting these twice)
403 * After that we sum them and normalise
404 * P2(x) = (3 * cos^2 (x) - 1)/2
405 * for unit vectors u and v we compute the cosine as the inner product
406 * cos(u,v) = uX vX + uY vY + uZ vZ
410 * C(t) = | (3 cos^2(u(t'),u(t'+t)) - 1)/2 dt'
415 * P2(u(0),u(t)) = [3 * (uX(0) uX(t) +
417 * uZ(0) uZ(t))^2 - 1]/2
418 * = [3 * ((uX(0) uX(t))^2 +
421 * 2(uX(0) uY(0) uX(t) uY(t)) +
422 * 2(uX(0) uZ(0) uX(t) uZ(t)) +
423 * 2(uY(0) uZ(0) uY(t) uZ(t))) - 1]/2
425 * = [(3/2) * (<uX^2> + <uY^2> + <uZ^2> +
426 * 2<uXuY> + 2<uXuZ> + 2<uYuZ>) - 0.5]
430 /* Because of normalization the number of -0.5 to subtract
431 * depends on the number of data points!
433 for(j=0; (j<nf2); j++)
434 csum[j] = -0.5*(nf2-j);
436 /***** DIAGONAL ELEMENTS ************/
437 for(m=0; (m<DIM); m++) {
438 /* Copy the vector data in a linear array */
439 for(j=0; (j<nf2); j++)
440 ctmp[j] = sqr(c1[DIM*j+m]);
442 sprintf(buf,"c1diag%d.xvg",m);
443 dump_tmp(buf,nf2,ctmp);
446 low_do_four_core(nfour,nf2,ctmp,cfour,enNorm,FALSE);
449 sprintf(buf,"c1dfout%d.xvg",m);
450 dump_tmp(buf,nf2,cfour);
453 for(j=0; (j<nf2); j++)
454 csum[j] += fac*(cfour[j]);
456 /******* OFF-DIAGONAL ELEMENTS **********/
457 for(m=0; (m<DIM); m++) {
458 /* Copy the vector data in a linear array */
460 for(j=0; (j<nf2); j++)
461 ctmp[j]=c1[DIM*j+m]*c1[DIM*j+m1];
464 sprintf(buf,"c1off%d.xvg",m);
465 dump_tmp(buf,nf2,ctmp);
467 low_do_four_core(nfour,nf2,ctmp,cfour,enNorm,FALSE);
469 sprintf(buf,"c1ofout%d.xvg",m);
470 dump_tmp(buf,nf2,cfour);
473 for(j=0; (j<nf2); j++) {
474 csum[j] += fac*cfour[j];
478 else if (MODE(eacP1) || MODE(eacVector)) {
479 /***************************************************
481 ***************************************************/
483 /* First normalize the vectors */
484 norm_and_scale_vectors(nframes,c1,1.0);
487 /* For vector thingies we have to do three FFT based correls
488 * First for XX, then for YY, then for ZZ
489 * After that we sum them and normalise
491 for(j=0; (j<nf2); j++) {
494 for(m=0; (m<DIM); m++) {
495 /* Copy the vector data in a linear array */
496 for(j=0; (j<nf2); j++)
498 low_do_four_core(nfour,nf2,ctmp,cfour,enNorm,FALSE);
499 for(j=0; (j<nf2); j++)
504 gmx_fatal(FARGS,"\nUnknown mode in do_autocorr (%d)",mode);
507 for(j=0; (j<nf2); j++)
508 c1[j] = csum[j]/(real)(nframes-j);
511 real fit_acf(int ncorr,int fitfn,const output_env_t oenv,gmx_bool bVerbose,
512 real tbeginfit,real tendfit,real dt,real c1[],real *fit)
515 real tStart,tail_corr,sum,sumtot=0,c_start,ct_estimate,*sig;
519 bPrint = bVerbose || bDebugMode();
521 if (bPrint) printf("COR:\n");
525 nf_int = min(ncorr,(int)(tendfit/dt));
526 sum = print_and_integrate(debug,nf_int,dt,c1,NULL,1);
528 /* Estimate the correlation time for better fitting */
529 ct_estimate = 0.5*c1[0];
530 for(i=1; (i<ncorr) && (c1[i]>0); i++)
531 ct_estimate += c1[i];
532 ct_estimate *= dt/c1[0];
535 printf("COR: Correlation time (plain integral from %6.3f to %6.3f ps) = %8.5f ps\n",
537 printf("COR: Relaxation times are computed as fit to an exponential:\n");
538 printf("COR: %s\n",longs_ffn[fitfn]);
539 printf("COR: Fit to correlation function from %6.3f ps to %6.3f ps, results in a\n",tbeginfit,min(ncorr*dt,tendfit));
544 printf("COR:%11s%11s%11s%11s%11s%11s%11s\n",
545 "Fit from","Integral","Tail Value","Sum (ps)"," a1 (ps)",
546 (nfp_ffn[fitfn]>=2) ? " a2 ()" : "",
547 (nfp_ffn[fitfn]>=3) ? " a3 (ps)" : "");
556 for(j=0; ((j<jmax) && (tStart < tendfit) && (tStart < ncorr*dt)); j++) {
557 /* Estimate the correlation time for better fitting */
560 for(i=0; (i<ncorr) && (dt*i < tStart || c1[i]>0); i++) {
562 if (dt*i >= tStart) {
564 ct_estimate = 0.5*c1[i];
567 ct_estimate += c1[i];
571 ct_estimate *= dt/c_start;
573 /* The data is strange, so we need to choose somehting */
574 ct_estimate = tendfit;
577 fprintf(debug,"tStart %g ct_estimate: %g\n",tStart,ct_estimate);
580 if (fitfn == effnEXP3) {
581 fitparm[0] = 0.002*ncorr*dt;
583 fitparm[2] = 0.2*ncorr*dt;
585 /* Good initial guess, this increases the probability of convergence */
586 fitparm[0] = ct_estimate;
591 /* Generate more or less appropriate sigma's */
592 for(i=0; i<ncorr; i++) {
593 sig[i] = sqrt(ct_estimate+dt*i);
596 nf_int = min(ncorr,(int)((tStart+1e-4)/dt));
597 sum = print_and_integrate(debug,nf_int,dt,c1,NULL,1);
598 tail_corr = do_lmfit(ncorr,c1,sig,dt,NULL,tStart,tendfit,oenv,
599 bDebugMode(),fitfn,fitparm,0);
600 sumtot = sum+tail_corr;
601 if (fit && ((jmax == 1) || (j == 1)))
602 for(i=0; (i<ncorr); i++)
603 fit[i] = fit_function(fitfn,fitparm,i*dt);
605 printf("COR:%11.4e%11.4e%11.4e%11.4e",tStart,sum,tail_corr,sumtot);
606 for(i=0; (i<nfp_ffn[fitfn]); i++)
607 printf(" %11.4e",fitparm[i]);
617 void low_do_autocorr(const char *fn,const output_env_t oenv,const char *title,
618 int nframes,int nitem,int nout,real **c1,
619 real dt,unsigned long mode,int nrestart,
620 gmx_bool bAver,gmx_bool bNormalize,
621 gmx_bool bVerbose,real tbeginfit,real tendfit,
622 int eFitFn,int nskip)
628 real c0,sum,Ct2av,Ctav;
629 gmx_bool bFour = acf.bFour;
631 /* Check flags and parameters */
632 nout = get_acfnout();
634 nout = acf.nout = (nframes+1)/2;
635 else if (nout > nframes)
638 if (MODE(eacCos) && MODE(eacVector))
639 gmx_fatal(FARGS,"Incompatible options bCos && bVector (%s, %d)",
641 if ((MODE(eacP3) || MODE(eacRcross)) && bFour) {
642 fprintf(stderr,"Can't combine mode %lu with FFT, turning off FFT\n",mode);
645 if (MODE(eacNormal) && MODE(eacVector))
646 gmx_fatal(FARGS,"Incompatible mode bits: normal and vector (or Legendre)");
648 /* Print flags and parameters */
650 printf("Will calculate %s of %d thingies for %d frames\n",
651 title ? title : "autocorrelation",nitem,nframes);
652 printf("bAver = %s, bFour = %s bNormalize= %s\n",
653 bool_names[bAver],bool_names[bFour],bool_names[bNormalize]);
654 printf("mode = %lu, dt = %g, nrestart = %d\n",mode,dt,nrestart);
657 c0 = log((double)nframes)/log(2.0);
664 fprintf(debug,"Using FFT to calculate %s, #points for FFT = %d\n",
667 /* Allocate temp arrays */
671 nfour = 0; /* To keep the compiler happy */
676 /* Loop over items (e.g. molecules or dihedrals)
677 * In this loop the actual correlation functions are computed, but without
680 k = max(1,pow(10,(int)(log(nitem)/log(100))));
681 for(i=0; i<nitem; i++) {
682 if (bVerbose && ((i%k==0 || i==nitem-1)))
683 fprintf(stderr,"\rThingie %d",i+1);
686 do_four_core(mode,nfour,nframes,nframes,c1[i],csum,ctmp);
688 do_ac_core(nframes,nout,ctmp,c1[i],nrestart,mode);
691 fprintf(stderr,"\n");
697 fp=xvgropen(fn,title,"Time (ps)","C(t)",oenv);
704 average_acf(bVerbose,nframes,nitem,c1);
707 normalize_acf(nout,c1[0]);
709 if (eFitFn != effnNONE) {
710 fit_acf(nout,eFitFn,oenv,fn!=NULL,tbeginfit,tendfit,dt,c1[0],fit);
711 sum = print_and_integrate(fp,nout,dt,c1[0],fit,1);
713 sum = print_and_integrate(fp,nout,dt,c1[0],NULL,1);
715 printf("Correlation time (integral over corrfn): %g (ps)\n",sum);
718 /* Not averaging. Normalize individual ACFs */
721 gp = xvgropen("ct-distr.xvg","Correlation times","item","time (ps)",oenv);
722 for(i=0; i<nitem; i++) {
724 normalize_acf(nout,c1[i]);
725 if (eFitFn != effnNONE) {
726 fit_acf(nout,eFitFn,oenv,fn!=NULL,tbeginfit,tendfit,dt,c1[i],fit);
727 sum = print_and_integrate(fp,nout,dt,c1[i],fit,1);
729 sum = print_and_integrate(fp,nout,dt,c1[i],NULL,1);
732 "CORRelation time (integral over corrfn %d): %g (ps)\n",
738 fprintf(gp,"%5d %.3f\n",i,sum);
745 printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n",
746 Ctav,sqrt((Ct2av - sqr(Ctav))),
747 sqrt((Ct2av - sqr(Ctav))/(nitem-1)));
755 static const char *Leg[] = { NULL, "0", "1", "2", "3", NULL };
757 t_pargs *add_acf_pargs(int *npargs,t_pargs *pa)
760 { "-acflen", FALSE, etINT, {&acf.nout},
761 "Length of the ACF, default is half the number of frames" },
762 { "-normalize",FALSE, etBOOL, {&acf.bNormalize},
764 { "-fftcorr", FALSE, etBOOL, {&acf.bFour},
765 "HIDDENUse fast fourier transform for correlation function" },
766 { "-nrestart", FALSE, etINT, {&acf.nrestart},
767 "HIDDENNumber of frames between time origins for ACF when no FFT is used" },
768 { "-P", FALSE, etENUM, {Leg},
769 "Order of Legendre polynomial for ACF (0 indicates none)" },
770 { "-fitfn", FALSE, etENUM, {s_ffn},
772 { "-ncskip", FALSE, etINT, {&acf.nskip},
773 "Skip this many points in the output file of correlation functions" },
774 { "-beginfit", FALSE, etREAL, {&acf.tbeginfit},
775 "Time where to begin the exponential fit of the correlation function" },
776 { "-endfit", FALSE, etREAL, {&acf.tendfit},
777 "Time where to end the exponential fit of the correlation function, -1 is until the end" },
779 #define NPA asize(acfpa)
783 snew(ppa,*npargs+NPA);
784 for(i=0; (i<*npargs); i++)
786 for(i=0; (i<NPA); i++)
787 ppa[*npargs+i] = acfpa[i];
794 acf.fitfn = effnEXP1;
796 acf.bNormalize = TRUE;
805 void do_autocorr(const char *fn,const output_env_t oenv,const char *title,
806 int nframes,int nitem,real **c1,
807 real dt,unsigned long mode,gmx_bool bAver)
810 printf("ACF data structures have not been initialised. Call add_acf_pargs\n");
813 /* Handle enumerated types */
814 sscanf(Leg[0],"%d",&acf.P);
815 acf.fitfn = sffn2effn(s_ffn);
831 low_do_autocorr(fn,oenv,title,nframes,nitem,acf.nout,c1,dt,mode,
832 acf.nrestart,bAver,acf.bNormalize,
833 bDebugMode(),acf.tbeginfit,acf.tendfit,
834 acf.fitfn,acf.nskip);
837 int get_acfnout(void)
840 gmx_fatal(FARGS,"ACF data not initialized yet");
845 int get_acffitfn(void)
848 gmx_fatal(FARGS,"ACF data not initialized yet");
850 return sffn2effn(s_ffn);
853 void cross_corr(int n,real f[],real g[],real corr[])
858 correl(f-1,g-1,n,corr-1);
860 for(i=0; (i<n); i++) {
862 corr[j-i] += f[i]*g[j];
863 corr[i] /= (real)(n-i);