A freeze group can now be allowed to move rigidly in some dimension by using "freezed...
[gromacs/rigid-bodies.git] / src / tools / gmx_bond.c
blobde1d680fe9e2603704672c584d1f06350b4de34d
1 /*
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 3.2.0
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
32 * And Hey:
33 * Green Red Orange Magenta Azure Cyan Skyblue
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38 #include <math.h>
39 #include <string.h>
40 #include "sysstuff.h"
41 #include "typedefs.h"
42 #include "smalloc.h"
43 #include "macros.h"
44 #include "vec.h"
45 #include "pbc.h"
46 #include "xvgr.h"
47 #include "copyrite.h"
48 #include "gmx_fatal.h"
49 #include "futil.h"
50 #include "statutil.h"
51 #include "index.h"
52 #include "gmx_statistics.h"
53 #include "tpxio.h"
54 #include "gmx_ana.h"
57 static void make_dist_leg(FILE *fp,int gnx,atom_id index[],t_atoms *atoms,
58 const output_env_t oenv)
60 char **leg;
61 int i;
63 snew(leg,gnx/2);
64 for(i=0; i<gnx; i+=2) {
65 snew(leg[i/2],256);
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++)
76 sfree(leg[i]);
77 sfree(leg);
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)
86 #define MAXTAB 1000
87 FILE *out,*outd=NULL;
88 int *btab=NULL;
89 real b0=0,b1,db=0;
90 real bond,bav;
91 gmx_stats_t b_one=NULL,*b_all=NULL;
92 /*real mean, mean2, sqrdev2, sigma2;
93 int counter;*/
94 rvec *x;
95 rvec dx;
96 t_trxstatus *status;
97 int natoms;
98 matrix box;
99 real t,fac;
100 int bind,i,nframes,i0,i1;
101 t_pbc pbc;
102 int N;
103 real aver,sigma,error;
105 if (!bAver) {
106 snew(b_all,gnx/2);
107 for(i=0; (i<gnx/2); i++)
108 b_all[i] = gmx_stats_init();
110 else {
111 b_one = gmx_stats_init();
112 snew(btab,MAXTAB+1);
115 natoms=read_first_x(oenv,&status,fn,&t,&x,box);
116 if (natoms == 0)
117 gmx_fatal(FARGS,"No atoms in trajectory!");
119 if (fdist) {
120 outd = xvgropen(fdist,bAverDist ? "Average distance" : "Distances",
121 "Time (ps)","Distance (nm)",oenv);
122 if (!bAverDist)
123 make_dist_leg(outd,gnx,index,&(top->atoms),oenv);
126 nframes=0;
127 do {
128 set_pbc(&pbc,ePBC,box);
129 if (fdist)
130 fprintf(outd," %8.4f",t);
131 nframes++; /* count frames */
132 bav = 0.0;
133 for(i=0; (i<gnx); i+=2) {
134 pbc_dx(&pbc,x[index[i]],x[index[i+1]],dx);
135 bond = norm(dx);
136 if (bAverDist)
137 bav += bond;
138 else if (fdist)
139 fprintf(outd," %.3f",bond);
140 if (bAver) {
141 gmx_stats_add_point(b_one,t,bond,0,0);
142 if (db == 0) {
143 if (blen == -1) {
144 b0 = 0;
145 b1 = 0.2;
146 db = (b1-b0)/MAXTAB;
148 else {
149 b0 = (1.0-tol)*blen;
150 b1 = (1.0+tol)*blen;
151 db = (2.0*(b1-b0))/MAXTAB;
154 bind = (int)((bond-b0)/db+0.5);
155 if ((bind >= 0) && (bind <= MAXTAB))
156 btab[bind]++;
157 else {
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]);
164 else {
165 gmx_stats_add_point(b_all[i/2],t,bond,0,0);
168 if (bAverDist)
169 fprintf(outd," %.5f",bav*2.0/gnx);
170 if (fdist)
171 fprintf(outd,"\n");
172 } while (read_next_x(oenv,status,&t,natoms,x,box));
173 close_trj(status);
175 if (fdist)
176 ffclose(outd);
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" */
185 if (bAver) {
186 printf("\n");
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);
194 sfree(b_one);
196 out=xvgropen(fbond,"Bond Stretching Distribution",
197 "Bond Length (nm)","",oenv);
199 for(i0=0; ((i0 < MAXTAB) && (btab[i0]==0)); i0++)
201 i0=max(0,i0-1);
202 for(i1=MAXTAB; ((i1 > 0) && (btab[i1]==0)); i1--)
204 i1=min(MAXTAB,i1+1);
206 if (i0 >= 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);
212 ffclose(out);
214 else {
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],
219 aver,sigma);
220 gmx_stats_done(b_all[i]);
221 sfree(b_all[i]);
223 sfree(b_all);
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;
247 t_pargs pa[] = {
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])" }
257 FILE *fp;
258 char *grpname;
259 const char *fdist;
260 int gnx;
261 atom_id *index;
262 char title[STRLEN];
263 t_topology top;
264 int ePBC=-1;
265 rvec *x;
266 matrix box;
267 output_env_t oenv;
269 t_filenm fnm[] = {
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,
282 &oenv);
284 if (bAverDist)
285 fdist = opt2fn("-d",NFILE,fnm);
286 else {
287 fdist = opt2fn_null("-d",NFILE,fnm);
288 if (fdist)
289 read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&x,NULL,box,
290 FALSE);
293 rd_index(ftp2fn(efNDX,NFILE,fnm),1,&gnx,&index,&grpname);
294 if ( !even(gnx) )
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);
298 if (!bAver)
299 fp = ftp2FILE(efLOG,NFILE,fnm,"w");
300 else
301 fp = NULL;
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");
309 thanx(stderr);
311 return 0;