3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * Green Red Orange Magenta Azure Cyan Skyblue
48 #include "gmx_fatal.h"
52 #include "gmx_statistics.h"
57 static void make_dist_leg(FILE *fp
,int gnx
,atom_id index
[],t_atoms
*atoms
,
58 const output_env_t oenv
)
64 for(i
=0; i
<gnx
; i
+=2) {
66 sprintf(leg
[i
/2],"%s %s%d - %s %s%d",
67 *(atoms
->atomname
[index
[i
]]),
68 *(atoms
->resinfo
[atoms
->atom
[index
[i
]].resind
].name
),
69 atoms
->resinfo
[atoms
->atom
[index
[i
]].resind
].nr
,
70 *(atoms
->atomname
[index
[i
+1]]),
71 *(atoms
->resinfo
[atoms
->atom
[index
[i
+1]].resind
].name
),
72 atoms
->resinfo
[atoms
->atom
[index
[i
+1]].resind
].nr
);
74 xvgr_legend(fp
,gnx
/2,(const char**)leg
,oenv
);
75 for(i
=0; i
<gnx
/2; i
++)
80 static void do_bonds(FILE *log
,const char *fn
,const char *fbond
,
81 const char *fdist
, int gnx
,atom_id index
[],
82 real blen
,real tol
,gmx_bool bAver
,
83 t_topology
*top
,int ePBC
,gmx_bool bAverDist
,
84 const output_env_t oenv
)
91 gmx_stats_t b_one
=NULL
,*b_all
=NULL
;
92 /*real mean, mean2, sqrdev2, sigma2;
100 int bind
,i
,nframes
,i0
,i1
;
103 real aver
,sigma
,error
;
107 for(i
=0; (i
<gnx
/2); i
++)
108 b_all
[i
] = gmx_stats_init();
111 b_one
= gmx_stats_init();
115 natoms
=read_first_x(oenv
,&status
,fn
,&t
,&x
,box
);
117 gmx_fatal(FARGS
,"No atoms in trajectory!");
120 outd
= xvgropen(fdist
,bAverDist
? "Average distance" : "Distances",
121 "Time (ps)","Distance (nm)",oenv
);
123 make_dist_leg(outd
,gnx
,index
,&(top
->atoms
),oenv
);
128 set_pbc(&pbc
,ePBC
,box
);
130 fprintf(outd
," %8.4f",t
);
131 nframes
++; /* count frames */
133 for(i
=0; (i
<gnx
); i
+=2) {
134 pbc_dx(&pbc
,x
[index
[i
]],x
[index
[i
+1]],dx
);
139 fprintf(outd
," %.3f",bond
);
141 gmx_stats_add_point(b_one
,t
,bond
,0,0);
151 db
= (2.0*(b1
-b0
))/MAXTAB
;
154 bind
= (int)((bond
-b0
)/db
+0.5);
155 if ((bind
>= 0) && (bind
<= MAXTAB
))
159 printf("bond: %4d-%4d bond=%10.5e, dx=(%10.5e,%10.5e,%10.5e)\n",
160 index[i],index[i+1],bond,dx[XX],dx[YY],dx[ZZ]);
165 gmx_stats_add_point(b_all
[i
/2],t
,bond
,0,0);
169 fprintf(outd
," %.5f",bav
*2.0/gnx
);
172 } while (read_next_x(oenv
,status
,&t
,natoms
,x
,box
));
179 mean = mean / counter;
180 mean2 = mean2 / counter;
181 sqrdev2 = (mean2 - mean*mean);
182 sigma2 = sqrdev2*counter / (counter - 1);
184 /* For definitions see "Weet wat je meet" */
187 gmx_stats_get_npoints(b_one
,&N
);
188 printf("Total number of samples : %d\n",N
);
189 gmx_stats_get_ase(b_one
,&aver
,&sigma
,&error
);
190 printf("Mean : %g\n",aver
);
191 printf("Standard deviation of the distribution: %g\n",sigma
);
192 printf("Standard deviation of the mean : %g\n",error
);
193 gmx_stats_done(b_one
);
196 out
=xvgropen(fbond
,"Bond Stretching Distribution",
197 "Bond Length (nm)","",oenv
);
199 for(i0
=0; ((i0
< MAXTAB
) && (btab
[i0
]==0)); i0
++)
202 for(i1
=MAXTAB
; ((i1
> 0) && (btab
[i1
]==0)); i1
--)
207 gmx_fatal(FARGS
,"No distribution... (i0 = %d, i1 = %d)? ? ! ! ? !",i0
,i1
);
209 fac
=2.0/(nframes
*gnx
*db
);
210 for(i
=i0
; (i
<=i1
); i
++)
211 fprintf(out
,"%8.5f %8.5f\n",b0
+i
*db
,btab
[i
]*fac
);
215 fprintf(log
,"%5s %5s %8s %8s\n","i","j","b_aver","sigma");
216 for(i
=0; (i
<gnx
/2); i
++) {
217 gmx_stats_get_ase(b_all
[i
],&aver
,&sigma
,NULL
);
218 fprintf(log
,"%5u %5u %8.5f %8.5f\n",1+index
[2*i
],1+index
[2*i
+1],
220 gmx_stats_done(b_all
[i
]);
227 int gmx_bond(int argc
,char *argv
[])
229 const char *desc
[] = {
230 "[TT]g_bond[tt] makes a distribution of bond lengths. If all is well a",
231 "Gaussian distribution should be made when using a harmonic potential.",
232 "Bonds are read from a single group in the index file in order i1-j1",
233 "i2-j2 through in-jn.[PAR]",
234 "[TT]-tol[tt] gives the half-width of the distribution as a fraction",
235 "of the bondlength ([TT]-blen[tt]). That means, for a bond of 0.2",
236 "a tol of 0.1 gives a distribution from 0.18 to 0.22.[PAR]",
237 "Option [TT]-d[tt] plots all the distances as a function of time.",
238 "This requires a structure file for the atom and residue names in",
239 "the output. If however the option [TT]-averdist[tt] is given (as well",
240 "or separately) the average bond length is plotted instead."
242 const char *bugs
[] = {
243 "It should be possible to get bond information from the topology."
245 static real blen
=-1.0,tol
=0.1;
246 static gmx_bool bAver
=TRUE
,bAverDist
=TRUE
;
248 { "-blen", FALSE
, etREAL
, {&blen
},
249 "Bond length. By default length of first bond" },
250 { "-tol", FALSE
, etREAL
, {&tol
},
251 "Half width of distribution as fraction of blen" },
252 { "-aver", FALSE
, etBOOL
, {&bAver
},
253 "Average bond length distributions" },
254 { "-averdist", FALSE
, etBOOL
, {&bAverDist
},
255 "Average distances (turns on [TT]-d[tt])" }
270 { efTRX
, "-f", NULL
, ffREAD
},
271 { efNDX
, NULL
, NULL
, ffREAD
},
272 { efTPS
, NULL
, NULL
, ffOPTRD
},
273 { efXVG
, "-o", "bonds", ffWRITE
},
274 { efLOG
, NULL
, "bonds", ffOPTWR
},
275 { efXVG
, "-d", "distance", ffOPTWR
}
277 #define NFILE asize(fnm)
279 CopyRight(stderr
,argv
[0]);
280 parse_common_args(&argc
,argv
,PCA_CAN_VIEW
| PCA_CAN_TIME
| PCA_BE_NICE
,
281 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,asize(bugs
),bugs
,
285 fdist
= opt2fn("-d",NFILE
,fnm
);
287 fdist
= opt2fn_null("-d",NFILE
,fnm
);
289 read_tps_conf(ftp2fn(efTPS
,NFILE
,fnm
),title
,&top
,&ePBC
,&x
,NULL
,box
,
293 rd_index(ftp2fn(efNDX
,NFILE
,fnm
),1,&gnx
,&index
,&grpname
);
295 fprintf(stderr
,"WARNING: odd number of atoms (%d) in group!\n",gnx
);
296 fprintf(stderr
,"Will gather information on %d bonds\n",gnx
/2);
299 fp
= ftp2FILE(efLOG
,NFILE
,fnm
,"w");
303 do_bonds(fp
,ftp2fn(efTRX
,NFILE
,fnm
),opt2fn("-o",NFILE
,fnm
),fdist
,gnx
,index
,
304 blen
,tol
,bAver
,&top
,ePBC
,bAverDist
,oenv
);
306 do_view(oenv
,opt2fn("-o",NFILE
,fnm
),"-nxy");
307 do_view(oenv
,opt2fn_null("-d",NFILE
,fnm
),"-nxy");