4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * GRowing Old MAkes el Chrono Sweat
29 static char *SRCID_g_angle_c
= "$Id$";
46 int main(int argc
,char *argv
[])
48 static char *desc
[] = {
49 "g_angle computes the angle distribution for a number of angles",
50 "or dihedrals. This way you can check whether your simulation",
51 "is correct. With option -ov you can plot the average angle of",
52 "a group of angles as a function of time. With the -all option",
53 "the first graph is the average, the rest are the individual angles.[PAR]",
54 "With the -of option g_angle also calculates the fraction of trans",
55 "dihedrals (only for dihedrals) as function of time, but this is",
56 "probably only fun for a selected few.[PAR]",
57 "With option -oc a dihedral correlation function is calculated.[PAR]",
58 "It should be noted that the indexfile should contain",
59 "atom-triples for angles or atom-quadruplets for dihedrals.",
60 "If this is not the case, the program will crash."
62 static char *opt
[] = { NULL
, "angle", "dihedral", "improper", "ryckaert-bellemans", NULL
};
63 static bool bALL
=FALSE
,bChandler
=FALSE
,bAverCorr
=FALSE
;
64 static real binwidth
=1;
66 { "-type", FALSE
, etENUM
, {opt
},
67 "Type of angle to analyse" },
68 { "-all", FALSE
, etBOOL
, {&bALL
},
69 "Plot all angles separately in the averages file, in the order of appearance in the index file." },
70 { "-binwidth", FALSE
, etREAL
, {&binwidth
},
71 "binwidth (degrees) for calculating the distribution" },
72 { "-chandler", FALSE
, etBOOL
, {&bChandler
},
73 "Use Chandler correlation function (N[trans] = 1, N[gauche] = 0) rather than cosine correlation function. Trans is defined as phi < -60 || phi > 60." },
74 { "-avercorr", FALSE
, etBOOL
, {&bAverCorr
},
75 "Average the correlation functions for the individual angles/dihedrals" }
77 static char *bugs
[] = {
78 "Counting transitions only works for dihedrals with multiplicity 3"
86 real maxang
,Jc
,S2
,norm_fac
,maxstat
;
88 int nframes
,maxangstat
,mult
,*angstat
;
89 int i
,j
,total
,nangles
,natoms
,nat2
,first
,last
,angind
;
90 bool bAver
,bRb
,bPeriodic
,
91 bFrac
, /* calculate fraction too? */
92 bTrans
, /* worry about transtions too? */
93 bCorr
; /* correlation function ? */
94 real t
,aa
,aver
,fraction
; /* fraction trans dihedrals */
97 real
**dih
=NULL
; /* mega array with all dih. angles at all times*/
99 real
*time
,*trans_frac
,*aver_angle
;
101 { efTRX
, "-f", NULL
, ffREAD
},
102 { efTPX
, NULL
, NULL
, ffREAD
},
103 { efNDX
, NULL
, "angle", ffREAD
},
104 { efXVG
, "-od", "angdist", ffWRITE
},
105 { efXVG
, "-ov", "angaver", ffOPTWR
},
106 { efXVG
, "-of", "dihfrac", ffOPTWR
},
107 { efXVG
, "-ot", "dihtrans", ffOPTWR
},
108 { efXVG
, "-oh", "trhisto", ffOPTWR
},
109 { efXVG
, "-oc", "dihcorr", ffOPTWR
}
111 #define NFILE asize(fnm)
115 CopyRight(stderr
,argv
[0]);
117 ppa
= add_acf_pargs(&npargs
,pa
);
118 parse_common_args(&argc
,argv
,PCA_CAN_VIEW
| PCA_CAN_TIME
,TRUE
,
119 NFILE
,fnm
,npargs
,ppa
,asize(desc
),desc
,asize(bugs
),bugs
);
138 /* Calculate bin size */
139 maxangstat
=(int)(maxang
/binwidth
+0.5);
140 binwidth
=maxang
/maxangstat
;
142 rd_index(ftp2fn(efNDX
,NFILE
,fnm
),1,&isize
,&index
,&grpname
);
144 if ((isize
% mult
) != 0)
145 fatal_error(0,"number of index elements not multiple of %d, "
146 "these can not be %s\n",
147 mult
,(mult
==3) ? "angle triplets" : "dihedral quadruplets");
150 /* Check whether specific analyses have to be performed */
151 bCorr
=opt2bSet("-oc",NFILE
,fnm
);
152 bAver
=opt2bSet("-ov",NFILE
,fnm
);
153 bTrans
=opt2bSet("-ot",NFILE
,fnm
);
154 bFrac
=opt2bSet("-of",NFILE
,fnm
);
156 if (bChandler
&& !bCorr
)
160 fprintf(stderr
,"Warning:"
161 " calculating fractions as defined in this program\n"
162 "makes sense for Ryckaert Bellemans dihs. only. Ignoring -of\n\n");
166 if ( (bTrans
|| bFrac
|| bCorr
) && mult
==3)
167 fatal_error(0,"Can only do transition, fraction or correlation\n"
168 "on dihedrals. Select -d\n");
171 * We need to know the nr of frames so we can allocate memory for an array
172 * with all dihedral angles at all timesteps. Works for me.
174 if (bTrans
|| bCorr
|| bALL
)
177 snew(angstat
,maxangstat
);
179 read_ang_dih(ftp2fn(efTRX
,NFILE
,fnm
),ftp2fn(efTPX
,NFILE
,fnm
),(mult
== 3),
180 bALL
|| bCorr
|| bTrans
,bRb
,maxangstat
,angstat
,
181 &nframes
,&time
,isize
,index
,&trans_frac
,&aver_angle
,dih
);
183 dt
=(time
[nframes
-1]-time
[0])/(nframes
-1);
186 sprintf(title
,"Average Angle: %s",grpname
);
187 out
=xvgropen(opt2fn("-ov",NFILE
,fnm
),
188 title
,"Time (ps)","Angle (degrees)");
189 for(i
=0; (i
<nframes
); i
++) {
190 fprintf(out
,"%10.5f %8.3f",time
[i
],aver_angle
[i
]*RAD2DEG
);
192 for(j
=0; (j
<nangles
); j
++)
193 fprintf(out
," %8.3f",dih
[j
][i
]*RAD2DEG
);
200 sprintf(title
,"Trans fraction: %s",grpname
);
201 out
=xvgropen(opt2fn("-of",NFILE
,fnm
),
202 title
,"Time (ps)","Fraction");
204 for(i
=0; (i
<nframes
); i
++) {
205 fprintf(out
,"%10.5f %10.3f\n",time
[i
],trans_frac
[i
]);
206 tfrac
+= trans_frac
[i
];
211 fprintf(stderr
,"Average trans fraction: %g\n",tfrac
);
216 ana_dih_trans(opt2fn("-ot",NFILE
,fnm
),opt2fn("-oh",NFILE
,fnm
),
217 dih
,nframes
,nangles
,grpname
,time
[0],dt
,bRb
);
220 /* Autocorrelation function */
222 fprintf(stderr
,"Not enough frames for correlation function\n");
226 real dval
,sixty
=DEG2RAD
*60;
229 for(i
=0; (i
<nangles
); i
++)
230 for(j
=0; (j
<nframes
); j
++) {
233 bTest
=(dval
> -sixty
) && (dval
< sixty
);
235 bTest
=(dval
< -sixty
) || (dval
> sixty
);
237 dih
[i
][j
] = dval
-tfrac
;
246 do_autocorr(opt2fn("-oc",NFILE
,fnm
),"Dihedral Autocorrelation Function",
247 nframes
,nangles
,dih
,dt
,mode
,bAverCorr
);
252 /* Determine the non-zero part of the distribution */
253 for(first
=0; (first
< maxangstat
-1) && (angstat
[first
+1] == 0); first
++)
255 for(last
=maxangstat
-1; (last
> 0) && (angstat
[last
-1] == 0) ; last
--)
259 for(i
=0; (i
<nframes
); i
++)
263 fprintf(stderr
,"Found points in the range from %d to %d (max %d), "
265 first
,last
,maxangstat
,aver
*RAD2DEG
);
268 sprintf(title
,"Angle Distribution: %s",grpname
);
270 sprintf(title
,"Dihedral Distribution: %s",grpname
);
272 calc_distribution_props(maxangstat
,angstat
,-180.0,0,NULL
,&S2
);
273 fprintf(stderr
,"Order parameter S^2 = %g\n",S2
);
276 bPeriodic
=(mult
==4) && (first
==0) && (last
==maxangstat
-1);
278 out
=xvgropen(opt2fn("-od",NFILE
,fnm
),title
,"Degrees","");
279 fprintf(out
,"@ subtitle \"average angle: %g\\So\\N\"\n",aver
*RAD2DEG
);
280 norm_fac
=1.0/(nangles
*nframes
*binwidth
);
283 for(i
=first
; (i
<=last
); i
++)
284 maxstat
=max(maxstat
,angstat
[i
]*norm_fac
);
285 fprintf(out
,"@with g0\n");
286 fprintf(out
,"@ world xmin -180\n");
287 fprintf(out
,"@ world xmax 180\n");
288 fprintf(out
,"@ world ymin 0\n");
289 fprintf(out
,"@ world ymax %g\n",maxstat
*1.05);
290 fprintf(out
,"@ xaxis tick major 60\n");
291 fprintf(out
,"@ xaxis tick minor 30\n");
292 fprintf(out
,"@ yaxis tick major 0.005\n");
293 fprintf(out
,"@ yaxis tick minor 0.0025\n");
295 for(i
=first
; (i
<=last
); i
++)
296 fprintf(out
,"%10g %10f\n",i
*binwidth
+180.0-maxang
,angstat
[i
]*norm_fac
);
298 /* print first bin again as last one */
299 fprintf(out
,"%10g %10f\n",180.0,angstat
[0]*norm_fac
);
303 xvgr_file(opt2fn("-od",NFILE
,fnm
),NULL
);
305 xvgr_file(opt2fn("-ov",NFILE
,fnm
),"-nxy");