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_relax_c
= "$Id$";
60 real tauc
,dtauc
,S2
,dS2
;
65 void read_shifts(FILE *fp
,int nx
,real shiftx
[],int ny
,real shifty
[])
70 for(i
=0; (i
<nx
); i
++) {
75 /*for(i=0; (i<ny); i++) {
82 complex c_sqr(complex c
)
86 cs
.re
= c
.re
*c
.re
-c
.im
*c
.im
;
87 cs
.im
= 2.0*c
.re
*c
.im
;
92 complex c_add(complex c
,complex d
)
102 complex calc_ylm(int m
,rvec rij
,real r2
,real r_3
,real r_6
)
104 static bool bFirst
=TRUE
;
105 static real y0
,y1
,y2
;
106 real x
,y
,z
,xsq
,ysq
,rxy
,r1
,cphi
,sphi
,cth
,sth
,fac
;
110 y0
= sqrt(5/(4*M_PI
));
111 y1
= sqrt(45/(24*M_PI
));
112 y2
= sqrt(45/(96*M_PI
));
130 /* Now calculate the spherical harmonics */
135 cs
.re
= fac
*(cphi
*cphi
-sphi
*sphi
);
136 /* Use the index as a prefactor... check your formulas */
137 cs
.im
= m
*fac
*cphi
*sphi
;
146 cs
.re
= y0
*(3*cth
*cth
-1);
156 void myfunc(real x
,real a
[],real
*y
,real dyda
[],int na
)
160 * y = a1 + (1-a1) exp(-a2 x)
162 * where in real life a1 is S^2 and a2 = 1/tauc
171 *y
= S2
+ (1-S2
)*eee
;
173 dyda
[2] = x
*tau1
*tau1
*(1-a
[1])*eee
;
176 void fit_one(bool bVerbose
,
177 int nframes
,real x
[],real y
[],real dy
[],real ftol
,
178 real
*S2
,real
*dS2
,real
*tauc
,real
*dtauc
)
180 void mrqmin(real x
[],real y
[],real sig
[],int ndata
,real a
[],
181 int ma
,int lista
[],int mfit
,real
**covar
,real
**alpha
,
183 void (*funcs
)(real x
,real a
[],real
*y
,real dyda
[],int na
),
186 real
*a
,**covar
,**alpha
;
187 real chisq
,ochisq
,alamda
;
189 int i
,j
,ma
,mfit
,*lista
;
196 for(i
=0; (i
<ma
+1); i
++) {
202 a
[1] = 0.99; /* S^2 */
203 a
[2] = 0.1; /* tauc */
204 alamda
= -1; /* Starting value */
209 mrqmin(x
-1,y
-1,dy
-1,nframes
,a
,ma
,lista
,mfit
,covar
,alpha
,
210 &chisq
,myfunc
,&alamda
);
212 fprintf(stderr
,"\rFitting %d chisq=%g, alamda=%g, tau=%g, S^2=%g\t\t\n",
213 j
,chisq
,alamda
,1.0/a
[2],a
[1]);
215 bCont
= (((ochisq
- chisq
) > ftol
*chisq
) ||
216 ((ochisq
== chisq
)));
217 } while (bCont
&& (alamda
!= 0.0) && (j
< 50));
219 fprintf(stderr
,"\n");
221 /* Now get the covariance matrix out */
223 mrqmin(x
-1,y
-1,dy
-1,nframes
,a
,ma
,lista
,mfit
,covar
,alpha
,
224 &chisq
,myfunc
,&alamda
);
227 *dS2
= sqrt(covar
[1][1]);
229 *dtauc
= sqrt(covar
[2][2]);
231 for(i
=0; (i
<ma
+1); i
++) {
241 void calc_tauc(bool bVerbose
,int npair
,t_pair pair
[],real dt
,
242 int nframes
,t_sij spec
[],real
**corr
)
247 real S2
,S22
,tauc
,fac
;
253 for(i
=0; (i
<nframes
); i
++)
256 fprintf(stderr
,"Fitting correlation function to Lipari&Szabo function\n");
257 fac
=1.0/((real
)nframes
);
258 for(i
=0; (i
<npair
); i
++) {
260 /* Use Levenberg-Marquardt method to fit */
261 for(j
=0; (j
<nframes
); j
++)
264 nframes
,x
,corr
[i
],dy
,ftol
,
265 &(spec
[i
].S2
),&(spec
[i
].dS2
),
266 &(spec
[i
].tauc
),&(spec
[i
].dtauc
));
268 sprintf(buf
,"test%d.xvg",i
);
269 fp
= ffopen(buf
,"w");
270 for(j
=0; (j
<nframes
); j
++) {
271 fprintf(fp
,"%10g %10g %10g\n",j
*dt
,corr
[i
][j
],
272 spec
[i
].S2
+ (1-spec
[i
].S2
)*exp(-j
*dt
/spec
[i
].tauc
));
280 void calc_aver(FILE *fp
,int nframes
,int npair
,t_pair pair
[],t_sij
*spec
,
287 md_6
= pow(maxdist
,-6.0);
290 for(i
=0; (i
<npair
); i
++) {
293 fprintf(fp
,"%5d %5d",pair
[i
].ai
,pair
[i
].aj
);
294 for(m
=0; (m
<5); m
++) {
295 c1
.re
= spec
[i
].Ylm
[m
].re
*nf_1
;
296 c1
.im
= spec
[i
].Ylm
[m
].im
*nf_1
;
301 fprintf(fp
," %8.3f+i%8.3f",c1
.re
,c1
.im
);
303 fprintf(fp
," %8.3f-i%8.3f",c1
.re
,-c1
.im
);
306 spec
[i
].rij_3
*= nf_1
;
307 spec
[i
].rij_6
*= nf_1
;
308 spec
[i
].y2
.re
= fac
*c2
.re
;
309 spec
[i
].y2
.im
= fac
*c2
.im
;
310 spec
[i
].bNOE
= (spec
[i
].rij_6
> md_6
);
314 void plot_spectrum(char *noefn
,int npair
,t_pair pair
[],t_sij
*spec
,real taum
)
318 t_rgb rlo
= { 1,0,0 },rhi
= {1,1,1};
319 real Sijmax
,Sijmin
,pow6
,pow3
,pp3
,pp6
,ppy
,tauc
;
326 fp
=xvgropen(noefn
,"Cross Relaxation","Pair Index","\\8s\\4\\sij\\N");
327 for(i
=0; (i
<npair
); i
++) {
329 sij
.re
= -0.4*((taum
-tauc
)*spec
[i
].y2
.re
+ tauc
*spec
[i
].rij_6
);
330 sij
.im
= -0.4* (taum
-tauc
)*spec
[i
].y2
.im
;
332 Sijmax
=max(Sijmax
,sij
.re
);
333 Sijmin
=min(Sijmin
,sij
.re
);
334 fprintf(fp
,"%5d %10g\n",i
,sij
.re
);
337 fprintf(stderr
,"Sijmin: %g, Sijmax: %g\n",Sijmin
,Sijmax
);
338 out
=ffopen("spec.out","w");
341 fprintf(out
,"%5s %5s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n",
342 "at i","at j","S^2","Sig S^2","tauc","Sig tauc",
343 "<rij6>","<rij3>","<ylm>","rij3-6","ylm-rij6");
344 for(i
=0; (i
<npair
); i
++) {
346 pp6
= pow(spec
[i
].rij_6
,pow6
);
347 pp3
= pow(spec
[i
].rij_3
,pow3
);
348 if (spec
[i
].y2
.re
< 0)
349 ppy
= -pow(-spec
[i
].y2
.re
,pow6
);
351 ppy
= pow(spec
[i
].y2
.re
,pow6
);
352 fprintf(out
,"%5d %5d %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f\n",
353 pair
[i
].ai
,pair
[i
].aj
,
354 spec
[i
].S2
,spec
[i
].dS2
,spec
[i
].tauc
,spec
[i
].dtauc
,
355 pp6
,pp3
,ppy
,pp3
-pp6
,ppy
-pp6
);
362 xvgr_file(noefn
,NULL
);
365 void spectrum(bool bVerbose
,
366 char *trj
,char *shifts
,bool bAbInitio
,
367 char *corrfn
,char *noefn
,
368 int maxframes
,bool bFour
,bool bFit
,int nrestart
,
369 int npair
,t_pair pair
[],int nat
,real chem_shifts
[],
370 real taum
,real maxdist
,
371 real w_rls
[],rvec xp
[],t_idef
*idef
)
374 int i
,j
,m
,ii
,jj
,natoms
,status
,nframes
;
378 real r2
,r6
,r_3
,r_6
,tauc
;
385 fprintf(stderr
,"There is no kill like overkill! Going to malloc %d bytes\n",
386 npair
*maxframes
*sizeof(corr
[0][0]));
388 for(i
=0; (i
<npair
); i
++)
389 snew(corr
[i
],maxframes
);
391 natoms
= read_first_x(&status
,trj
,&t0
,&x
,box
);
393 fatal_error(0,"Not enough atoms in trajectory");
395 if (nframes
>= maxframes
) {
396 fprintf(stderr
,"\nThere are more than the %d frames you told me!",
402 fprintf(stderr
,"\rframe: %d",nframes
);
403 rm_pbc(idef
,natoms
,box
,x
,x
);
405 do_fit(natoms
,w_rls
,xp
,x
);
407 for(i
=0; (i
<npair
); i
++) {
410 rvec_sub(x
[ii
],x
[jj
],dx
);
411 copy_rvec(dx
,corr
[i
][nframes
]);
417 spec
[i
].rij_3
+= r_3
;
418 spec
[i
].rij_6
+= r_6
;
419 for(m
=0; (m
<5); m
++) {
420 spec
[i
].Ylm
[m
] = c_add(spec
[i
].Ylm
[m
],
421 calc_ylm(m
-2,dx
,r2
,r_3
,r_6
));
425 } while (read_next_x(status
,&t
,natoms
,x
,box
));
428 fprintf(stderr
,"\n");
430 fp
=ffopen("ylm.out","w");
431 calc_aver(fp
,nframes
,npair
,pair
,spec
,maxdist
);
434 /* Select out the pairs that have to be correlated */
436 for(i
=j
=0; (i
<npair
); i
++) {
438 Corr
[j
] = &(corr
[i
][0][0]);
442 fprintf(stderr
,"There are %d NOEs in your simulation\n",j
);
444 dt
= (t1
-t0
)/(nframes
-1);
447 do_autocorr(corrfn
,"Correlation Function for Interproton Vectors",
448 nframes
,j
,Corr
,dt
,eacP2
,nrestart
,FALSE
,FALSE
,bFour
,TRUE
);
450 calc_tauc(bVerbose
,npair
,pair
,dt
,nframes
/2,spec
,(real
**)corr
);
452 plot_spectrum(noefn
,npair
,pair
,spec
,taum
);
455 int main(int argc
,char *argv
[])
457 static char *desc
[] = {
458 "g_noe calculates a NOE spectrum"
463 int i
,j
,k
,natoms
,nprot
,*prot_ind
;
466 atom_id
*ind_fit
,*all_at
;
475 { efTRX
, "-f", NULL
, ffREAD
},
476 { efTPX
, "-s", NULL
, ffREAD
},
477 { efNDX
, NULL
, NULL
, ffREAD
},
478 { efDAT
, "-d", "shifts", ffREAD
},
479 { efOUT
, "-o","spec", ffWRITE
},
480 { efXVG
, "-corr", "rij-corr", ffWRITE
},
481 { efXVG
, "-noe", "noesy", ffWRITE
}
483 #define NFILE asize(fnm)
484 static real taum
= 0.0, maxdist
= 0.6;
485 static int nlevels
= 15;
486 static int nrestart
= 1;
487 static int maxframes
= 100;
488 static bool bFFT
= TRUE
,bFit
= TRUE
, bVerbose
= TRUE
;
490 { "-taum", FALSE
, etREAL
, &taum
,
491 "Rotational correlation time for your molecule. It is obligatory to pass this option" },
492 { "-maxdist", FALSE
, etREAL
, &maxdist
,
493 "Maximum distance to be plotted" },
494 { "-nlevels", FALSE
, etINT
, &nlevels
,
495 "Number of levels for plotting" },
496 { "-nframes", FALSE
, etINT
, &maxframes
,
497 "Number of frames in your trajectory. Will stop analysis after this" },
498 { "-fft", FALSE
, etBOOL
, &bFFT
,
499 "Use FFT for correlation function" },
500 { "-nrestart", FALSE
, etINT
, &nrestart
,
501 "Number of frames between starting point for computation of ACF without FFT" },
502 { "-fit", FALSE
, etBOOL
, &bFit
,
503 "Do an optimal superposition on reference structure in tpx file" },
504 { "-v", FALSE
, etBOOL
, &bVerbose
,
505 "Tell you what I am about to do" }
508 CopyRight(stderr
,argv
[0]);
509 parse_common_args(&argc
,argv
,PCA_CAN_VIEW
| PCA_CAN_TIME
,TRUE
,
510 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,0,NULL
);
512 fatal_error(0,"Please give me a sensible taum!\n");
515 fprintf(stderr
,"Warning: too many levels, setting to %d\n",nlevels
);
518 top
= read_top(ftp2fn(efTPX
,NFILE
,fnm
));
519 natoms
= top
->atoms
.nr
;
521 read_tpx(ftp2fn(efTPX
,NFILE
,fnm
),&step
,&t
,&lambda
,NULL
,box
,
522 &natoms
,xp
,NULL
,NULL
,NULL
);
524 /* Determine the number of protons, and their index numbers
525 * by checking the mass
528 snew(prot_ind
,natoms
);
529 for(i
=0; (i
<natoms
); i
++)
530 if (top
->atoms
.atom
[i
].m
< 2) {
531 prot_ind
[nprot
++] = i
;
533 fprintf(stderr
,"There %d protons in your topology\n",nprot
);
534 snew(pair
,(nprot
*(nprot
-1)/2));
535 for(i
=k
=0; (i
<nprot
); i
++) {
536 for(j
=i
+1; (j
<nprot
); j
++,k
++) {
537 pair
[k
].ai
= prot_ind
[i
];
538 pair
[k
].aj
= prot_ind
[j
];
543 fprintf(stderr
,"Select group for root least squares fit\n");
544 rd_index(ftp2fn(efNDX
,NFILE
,fnm
),1,&ifit
,&ind_fit
,&gn_fit
);
547 fatal_error(0,"Need >= 3 points to fit!\n");
549 /* Make an array with weights for fitting */
551 for(i
=0; (i
<ifit
); i
++)
552 w_rls
[ind_fit
[i
]]=top
->atoms
.atom
[ind_fit
[i
]].m
;
554 /* Prepare reference frame */
556 for(j
=0; (j
<natoms
); j
++)
558 rm_pbc(&(top
->idef
),natoms
,box
,xp
,xp
);
559 reset_x(ifit
,ind_fit
,natoms
,all_at
,xp
,w_rls
);
563 ftp2fn(efTRX
,NFILE
,fnm
),ftp2fn(efDAT
,NFILE
,fnm
),
564 ftp2bSet(efDAT
,NFILE
,fnm
),opt2fn("-corr",NFILE
,fnm
),
565 opt2fn("-noe",NFILE
,fnm
),
566 maxframes
,bFFT
,bFit
,nrestart
,
567 k
,pair
,natoms
,shifts
,
568 taum
,maxdist
,w_rls
,xp
,&(top
->idef
));