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_anadih_c
= "$Id$";
43 static int calc_RBbin(real phi
)
45 static const real r30
= M_PI
/6.0;
46 static const real r90
= M_PI
/2.0;
47 static const real r150
= M_PI
*5.0/6.0;
49 if ((phi
< r30
) && (phi
> -r30
))
51 else if ((phi
> -r150
) && (phi
< -r90
))
53 else if ((phi
< r150
) && (phi
> r90
))
58 static int calc_Nbin(real phi
)
60 static const real r30
= 30*DEG2RAD
;
61 static const real r90
= 90*DEG2RAD
;
62 static const real r150
= 150*DEG2RAD
;
63 static const real r210
= 210*DEG2RAD
;
64 static const real r270
= 270*DEG2RAD
;
65 static const real r330
= 330*DEG2RAD
;
66 static const real r360
= 360*DEG2RAD
;
71 if ((phi
> r30
) && (phi
< r90
))
73 else if ((phi
> r150
) && (phi
< r210
))
75 else if ((phi
> r270
) && (phi
< r330
))
80 void ana_dih_trans(char *fn_trans
,char *fn_histo
,
81 real
**dih
,int nframes
,int nangles
,
82 char *grpname
,real t0
,real dt
,bool bRb
)
89 real ttime
,tt
,mind
, maxd
, prev
;
90 int (*calc_bin
)(real
);
92 /* Analysis of dihedral transitions */
93 fprintf(stderr
,"Now calculating transitions...\n");
103 /* dih[i][j] is the dihedral angle i in frame j */
105 for (i
=0; (i
<nangles
); i
++)
109 mind
= maxd
= prev
= dih
[i
][0];
111 cur_bin
= calc_bin(dih
[i
][0]);
113 for (j
=1; (j
<nframes
); j
++)
115 new_bin
= calc_bin(dih
[i
][j
]);
119 else if ((new_bin
!= 0) && (cur_bin
!= new_bin
)) {
126 /* why is all this md rubbish periodic? Remove 360 degree periodicity */
127 if ( (dih
[i
][j
] - prev
) > M_PI
)
129 else if ( (dih
[i
][j
] - prev
) < -M_PI
)
134 mind
= min(mind
, dih
[i
][j
]);
135 maxd
= max(maxd
, dih
[i
][j
]);
136 if ( (maxd
- mind
) > 2*M_PI
/3) /* or 120 degrees, assuming */
137 { /* multiplicity 3. Not so general.*/
140 maxd
= mind
= dih
[i
][j
]; /* get ready for next transition */
146 fprintf(stderr
,"Total number of transitions: %10d\n",ntrans
);
148 ttime
= (dt
*nframes
*nangles
)/ntrans
;
149 fprintf(stderr
,"Time between transitions: %10.3f ps\n",ttime
);
152 sprintf(title
,"Number of transitions: %s",grpname
);
153 fp
=xvgropen(fn_trans
,title
,"Time (ps)","# transitions/timeframe");
154 for(j
=0; (j
<nframes
); j
++) {
156 fprintf(fp
,"%10.3f %10d\n",tt
,tr_f
[j
]);
160 /* Compute histogram from # transitions per dihedral */
162 for(j
=0; (j
<nframes
); j
++)
164 for(i
=0; (i
<nangles
); i
++)
166 for(j
=nframes
; ((tr_f
[j
-1] == 0) && (j
>0)); j
--)
170 sprintf(title
,"Transition time: %s",grpname
);
171 fp
=xvgropen(fn_histo
,title
,"Time (ps)","#");
172 for(i
=j
-1; (i
>0); i
--) {
174 fprintf(fp
,"%10.3f %10d\n",ttime
/i
,tr_f
[i
]);
182 void calc_distribution_props(int nh
,int histo
[],real start
,
183 int nkkk
, t_karplus kkk
[],
186 real d
,dc
,ds
,c1
,c2
,tdc
,tds
;
191 fatal_error(0,"No points in histogram (%s, %d)",__FILE__
,__LINE__
);
194 /* Compute normalisation factor */
196 for(j
=0; (j
<nh
); j
++)
200 for(i
=0; (i
<nkkk
); i
++)
204 for(j
=0; (j
<nh
); j
++) {
213 for(i
=0; (i
<nkkk
); i
++) {
214 c1
= cos(ang
+kkk
[i
].offset
);
216 kkk
[i
].Jc
+= d
*(kkk
[i
].A
*c2
+ kkk
[i
].B
*c1
+ kkk
[i
].C
);
219 *S2
= tdc
*tdc
+tds
*tds
;
222 static void calc_angles(FILE *log
,matrix box
,
223 int n3
,atom_id index
[],real ang
[],rvec x_s
[])
229 for(i
=ix
=0; (ix
<n3
); i
++,ix
+=3)
230 ang
[i
]=bond_angle(box
,x_s
[index
[ix
]],x_s
[index
[ix
+1]],x_s
[index
[ix
+2]],
233 fprintf(debug
,"Angle[0]=%g, costh=%g, index0 = %u, %u, %u\n",
234 ang
[0],costh
,index
[0],index
[1],index
[2]);
235 pr_rvec(debug
,0,"rij",r_ij
,DIM
);
236 pr_rvec(debug
,0,"rkj",r_kj
,DIM
);
237 pr_rvecs(debug
,0,"box",box
,DIM
);
241 static real
calc_fraction(real angles
[], int nangles
)
244 real trans
= 0, gauche
= 0;
247 for (i
= 0; i
< nangles
; i
++)
249 angle
= angles
[i
] * RAD2DEG
;
251 if (angle
> 135 && angle
< 225)
253 else if (angle
> 270 && angle
< 330)
255 else if (angle
< 90 && angle
> 30)
258 if (trans
+gauche
> 0)
259 return trans
/(trans
+gauche
);
264 static void calc_dihs(FILE *log
,matrix box
,
265 int n4
,atom_id index
[],real ang
[],rvec x_s
[])
268 rvec r_ij
,r_kj
,r_kl
,m
,n
;
269 real cos_phi
,sign
,aaa
;
271 for(i
=ix
=0; (ix
<n4
); i
++,ix
+=4) {
273 x_s
[index
[ix
]],x_s
[index
[ix
+1]],x_s
[index
[ix
+2]],
277 ang
[i
]=aaa
; /* not taking into account ryckaert bellemans yet */
281 void make_histo(FILE *log
,
282 int ndata
,real data
[],int npoints
,int histo
[],
290 for(i
=1; (i
<ndata
); i
++) {
291 minx
=min(minx
,data
[i
]);
292 maxx
=max(maxx
,data
[i
]);
294 fprintf(log
,"Min data: %10g Max data: %10g\n",minx
,maxx
);
296 dx
=(double)npoints
/(maxx
-minx
);
299 "Histogramming: ndata=%d, nhisto=%d, minx=%g,maxx=%g,dx=%g\n",
300 ndata
,npoints
,minx
,maxx
,dx
);
301 for(i
=0; (i
<ndata
); i
++) {
302 ind
=(data
[i
]-minx
)*dx
;
303 if ((ind
>= 0) && (ind
< npoints
))
306 fprintf(log
,"index = %d, data[%d] = %g\n",ind
,i
,data
[i
]);
310 void normalize_histo(int npoints
,int histo
[],real dx
,real normhisto
[])
316 for(i
=0; (i
<npoints
); i
++)
319 fprintf(stderr
,"Empty histogram!\n");
323 for(i
=0; (i
<npoints
); i
++)
324 normhisto
[i
]=fac
*histo
[i
];
327 void read_ang_dih(char *trj_fn
,char *tpb_fn
,
328 bool bAngles
,bool bSaveAll
,bool bRb
,
329 int maxangstat
,int angstat
[],
330 int *nframes
,real
**time
,
331 int isize
,atom_id index
[],
337 int i
,angind
,status
,natoms
,nat
,total
,teller
,nangles
,nat_trj
,n_alloc
;
338 real t
,fraction
,pifac
,aa
,angle
;
345 /* Initiate lookup table for sqrt calculations */
346 init_lookup_table(stdout
);
349 top
= read_top(tpb_fn
);
350 natoms
= top
->atoms
.nr
;
351 nat_trj
= read_first_x(&status
,trj_fn
,&t
,&x
,box
);
353 /* Check for consistency of topology and trajectory */
354 if (natoms
< nat_trj
)
355 fprintf(stderr
,"WARNING! Topology has fewer atoms than trajectory\n");
367 snew(angles
[cur
],nangles
);
368 snew(angles
[prev
],nangles
);
370 /* Start the loop over frames */
379 if (teller
>= n_alloc
) {
382 for (i
=0; (i
<nangles
); i
++)
383 srenew(dih
[i
],n_alloc
);
384 srenew(*time
,n_alloc
);
385 srenew(*trans_frac
,n_alloc
);
386 srenew(*aver_angle
,n_alloc
);
391 rm_pbc(&(top
->idef
),nat_trj
,box
,x
,x_s
);
394 calc_angles(stdout
,box
,isize
,index
,angles
[cur
],x_s
);
396 calc_dihs(stdout
,box
,isize
,index
,angles
[cur
],x_s
);
399 fraction
= calc_fraction(angles
[cur
], nangles
);
400 (*trans_frac
)[teller
] = fraction
;
402 /* Change Ryckaert-Bellemans dihedrals to polymer convention
403 * Modified 990913 by Erik:
404 * We actually shouldn't change the convention, since it's
405 * calculated from polymer above, but we change the intervall
406 * from [-180,180] to [0,360].
409 for(i
=0; (i
<nangles
); i
++)
410 if (angles
[cur
][i
] <= 0.0)
411 angles
[cur
][i
] += 2*M_PI
;
414 /* Periodicity in dihedral space... */
416 for(i
=0; (i
<nangles
); i
++) {
417 while (angles
[cur
][i
] <= angles
[prev
][i
] - M_PI
)
418 angles
[cur
][i
]+=2*M_PI
;
419 while (angles
[cur
][i
] > angles
[prev
][i
] + M_PI
)
420 angles
[cur
][i
]-=2*M_PI
;
427 for(i
=0; (i
<nangles
); i
++) {
428 aa
=aa
+angles
[cur
][i
];
430 /* angle in rad / 2Pi * max determines bin. bins go from 0 to maxangstat,
431 even though scale goes from -pi to pi (dihedral) or -pi/2 to pi/2
432 (angle) Basically: translate the x-axis by Pi. Translate it back by
436 angle
= angles
[cur
][i
];
438 while (angle
< -M_PI
)
440 while (angle
>= M_PI
)
446 /* Update the distribution histogram */
447 angind
= (int) ((angle
*maxangstat
)/pifac
+ 0.5);
448 if (angind
==maxangstat
)
450 if ( (angind
< 0) || (angind
>= maxangstat
) )
451 /* this will never happen */
452 fatal_error(0,"angle (%f) index out of range (0..%d) : %d\n",
453 angle
,maxangstat
,angind
);
456 if (angind
==maxangstat
)
457 fprintf(stderr
,"angle %d fr %d = %g\n",i
,cur
,angle
);
462 /* average over all angles */
463 (*aver_angle
)[teller
] = (aa
/nangles
);
465 /* this copies all current dih. angles to dih[i], teller is frame */
467 for (i
= 0; i
< nangles
; i
++)
468 dih
[i
][teller
] = angles
[cur
][i
];
473 /* Increment loop counter */
475 } while (read_next_x(status
,&t
,nat_trj
,x
,box
));