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, 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.
59 static void ana_dih(FILE *out,char *index,int nframes,real dih[],t_dih *dd)
62 real mind,maxd,sum,av,var,prev,width;
65 mind=5400,maxd=-5400,sum=0,av=0,var=0;
68 for(i=0; (i<nframes); i++) {
69 if ((dih[i]-prev) > 180) {
73 else if ((dih[i]-prev) < -180)
78 mind=min(mind,dih[i]);
79 maxd=max(maxd,dih[i]);
82 for(i=0; (i<nframes); i++)
85 width=(360.0/dd->mult);
86 bTrans=((maxd - mind) > width);
88 fprintf(out,"%-10s %10.3f %10.3f %10.3f %10.3f %10.3f %-10s%3.0f\n",
89 index,mind,av,maxd,var,sqrt(var),
90 bTrans ? "Yep" : "",width);
93 static int find_min(real phi,int ntab,real phitab[])
99 /* Set closest minimum to the first one */
101 mind=fabs(phi-phitab[0]);
103 for(i=1; (i<ntab); i++) {
104 mm=fabs(phi-phitab[i]);
110 if (mind < width*0.5 )
116 static int vphi(t_dih *dih,real phi,int mult)
118 static real m2[] = { 90, 270 };
119 static real m3[] = { 60, 180, 300 };
120 static real m4[] = { 45, 135, 225, 315 };
121 static real m6[] = { 30, 90, 150, 210, 270, 330 };
126 phiref=RAD2DEG*(phi-dih->phi0);
134 vpp=find_min(phiref,2,m2);
137 vpp=find_min(phiref,3,m3);
140 vpp=find_min(phiref,4,m4);
143 vpp=find_min(phiref,6,m6);
146 gmx_fatal(FARGS,"No such multiplicity %d",dih->mult);
155 typedef struct t_cluster {
159 struct t_cluster *next;
162 static t_cluster *search_cluster(t_cluster *cl,char *minimum)
166 while (ccl != NULL) {
167 if (strcmp(minimum,ccl->minimum)==0)
174 static void add_cluster(t_cluster **cl,int ndih,char *minimum)
182 ccl->minimum=strdup(minimum);
189 while (loper->next != NULL)
195 static void p_cluster(FILE *out,t_cluster *cl)
199 fprintf(out,"* * * C L U S T E R A N A L Y S I S * * *\n\n");
200 fprintf(out," Frequency Dihedral minima\n");
202 while (loper != NULL) {
203 fprintf(out,"%10d %s\n",loper->freq,loper->minimum);
208 static void ana_cluster(FILE *out, t_xrama *xr,real **dih,real time[],
209 t_topology *top,int nframes,int mult)
211 t_cluster *cl=NULL,*scl;
215 /* Number of dihedrals + terminating NULL
216 * this allows for using string routines
218 snew(minimum,xr->ndih+1);
220 for(i=0; (i<nframes); i++) {
222 for(j=0; (j<xr->ndih); j++) {
223 minimum[j] = vphi(&xr->dih[j],dih[j][i],
224 mult == -1 ? xr->dih[j].mult : mult);
225 if (minimum[j] == NOMIN)
229 if ((scl=search_cluster(cl,minimum)) == NULL)
230 add_cluster(&cl,xr->ndih,minimum);
240 static void ana_trans(FILE *out, t_xrama *xr,real **dih,real time[],
241 t_topology *top,int nframes, const output_env_t oenv)
244 real prev_phi,prev_psi;
248 fprintf(out,"\n\t* * * D I H E D R A L S T A T I S T I C S * * *\n\n");
249 fprintf(out,"%-10s %10s %10s %10s %10s %10s %10s\n",
250 "index","minimum","average","maximum","variance","std.dev",
252 for(i=0; (i<xr->ndih); i++) {
253 sprintf(buf,"dih-%d",i);
254 ana_dih(out,buf,nframes,dih[i],&(xr->dih[i]));
256 for(i=0; (i<xr->npp); i++) {
257 sprintf(buf,"%s",xr->pp[i].label);
258 outd=xvgropen(buf,"Dihedral Angles","Time (ps)","Degrees",oenv);
262 prev_phi=dih[phi][0];
263 prev_psi=dih[psi][0];
264 for(j=0; (j<nframes); j++) {
266 if ((dih[phi][j]-prev_phi) > 180)
268 else if ((dih[phi][j]-prev_phi) < -180)
270 prev_phi=dih[phi][j];
271 if ((dih[psi][j]-prev_psi) > 180)
273 else if ((dih[psi][j]-prev_psi) < -180)
275 prev_psi=dih[psi][j];
276 fprintf(outd,"%10g %10g %10g\n",time[j],prev_phi,prev_psi);
282 int gmx_dih(int argc,char *argv[])
284 const char *desc[] = {
285 "[TT]g_dih[tt] can do two things. The default is to analyze dihedral transitions",
286 "by merely computing all the dihedral angles defined in your topology",
287 "for the whole trajectory. When a dihedral flips over to another minimum",
288 "an angle/time plot is made.[PAR]",
289 "The opther option is to discretize the dihedral space into a number of",
290 "bins, and group each conformation in dihedral space in the",
291 "appropriate bin. The output is then given as a number of dihedral",
292 "conformations sorted according to occupancy."
294 static int mult = -1;
295 static gmx_bool bSA = FALSE;
297 { "-sa", FALSE, etBOOL, {&bSA},
298 "Perform cluster analysis in dihedral space instead of analysing dihedral transitions." },
299 { "-mult", FALSE, etINT, {&mult},
300 "mulitiplicity for dihedral angles (by default read from topology)" }
307 int i,nframes,maxframes=1000;
310 { efTRX, "-f", NULL, ffREAD },
311 { efTPX, NULL, NULL, ffREAD },
312 { efOUT, NULL, NULL, ffWRITE }
314 #define NFILE asize(fnm)
316 CopyRight(stderr,argv[0]);
317 parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
318 NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv);
321 fprintf(stderr,"Using %d for dihedral multiplicity rather than topology values\n",mult);
324 init_rama(oenv,ftp2fn(efTRX,NFILE,fnm),
325 ftp2fn(efTPX,NFILE,fnm),xr,3);
326 top=read_top(ftp2fn(efTPX,NFILE,fnm),NULL);
328 /* Brute force malloc, may be too big... */
330 for(i=0; (i<xr->ndih); i++)
331 snew(dih[i],maxframes);
332 snew(time,maxframes);
334 fprintf(stderr,"\n");
336 while (new_data(xr)) {
337 for(i=0; (i<xr->ndih); i++) {
338 dd=xr->dih[i].ang*RAD2DEG;
347 if (nframes > maxframes) {
349 for(i=0; (i<xr->ndih); i++)
350 srenew(dih[i],maxframes);
351 srenew(time,maxframes);
355 fprintf(stderr,"\nCalculated all dihedrals, now analysing...\n");
357 out=ftp2FILE(efOUT,NFILE,fnm,"w");
360 /* Cluster and structure analysis */
361 ana_cluster(out,xr,dih,time,top,nframes,mult);
364 /* Analyse transitions... */
365 ana_trans(out,xr,dih,time,top,nframes,oenv);