3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
45 int gmx_dyecoupl(int argc, char *argv[])
49 "This tool extracts dye dynamics from trajectory files.",
50 "Currently, R and kappa^2 between dyes is extracted for (F)RET",
51 "simulations with assumed dipolar coupling as in the Foerster equation.",
52 "It further allows the calculation of R(t) and kappa^2(t), R and",
53 "kappa^2 histograms and averages, as well as the instantaneous FRET",
54 "efficiency E(t) for a specified Foerster radius R_0 (switch [TT]-R0[tt]).",
55 "The input dyes have to be whole (see res and mol pbc options",
56 "in [TT]trjconv[tt]).",
57 "The dye transition dipole moment has to be defined by at least",
58 "a single atom pair, however multiple atom pairs can be provided ",
59 "in the index file. The distance R is calculated on the basis of",
60 "the COMs of the given atom pairs.",
61 "The [TT]-pbcdist[tt] option calculates distances to the nearest periodic",
62 "image instead to the distance in the box. This works however only,"
63 "for periodic boundaries in all 3 dimensions.",
64 "The [TT]-norm[tt] option (area-) normalizes the histograms."
67 static gmx_bool bPBCdist = FALSE, bNormHist = FALSE;
74 { "-pbcdist", FALSE, etBOOL, { &bPBCdist },"Distance R based on PBC" },
75 { "-norm", FALSE, etBOOL, { &bNormHist },"Normalize histograms" },
76 { "-bins", FALSE, etINT, {&histbins},"# of histogram bins" },
77 { "-R0", FALSE, etREAL, {&R0},"Foerster radius including kappa^2=2/3 in nm" }
83 { efTRX, "-f", NULL, ffREAD },
84 { efNDX, NULL, NULL, ffREAD },
85 { efXVG, "-ot", "rkappa",ffOPTWR },
86 { efXVG, "-oe", "insteff",ffOPTWR },
87 { efDAT, "-o", "rkappa",ffOPTWR },
88 { efXVG, "-rhist","rhist", ffOPTWR },
89 { efXVG, "-khist", "khist", ffOPTWR }
91 #define NFILE asize(fnm)
94 const char *in_trajfile, *in_ndxfile, *out_xvgrkfile = NULL, *out_xvginstefffile = NULL, *out_xvgrhistfile = NULL, *out_xvgkhistfile = NULL,*out_datfile=NULL;
95 gmx_bool bHaveFirstFrame, bHaveNextFrame, indexOK = TRUE;
97 atom_id *donindex, *accindex;
99 t_atoms *atoms = NULL;
104 int allocblock = 1000;
105 real histexpand = 1e-6;
106 rvec donvec, accvec, donpos, accpos, dist, distnorm;
109 /*we rely on PBC autodetection (...currently)*/
112 real *rvalues=NULL, *kappa2values=NULL, *rhist=NULL, *khist=NULL;
115 FILE *rkfp = NULL, *rhfp = NULL, *khfp = NULL,*datfp=NULL,*iefp=NULL;
116 gmx_bool bRKout, bRhistout, bKhistout,bDatout,bInstEffout,grident;
118 const char *rkleg[2] = { "R", "\\f{Symbol}k\\f{}\\S2\\N" };
119 const char *rhleg[1] = { "p(R)" };
120 const char *khleg[1] = { "p(\\f{Symbol}k\\f{}\\S2\\N)" };
121 const char *ieleg[1] = { "E\\sRET\\N(t)" };
123 real R, kappa2, insteff, Rs = 0., kappa2s = 0., insteffs=0., rmax, rmin, kmin = 0., kmax = 4.,
124 rrange, krange, rincr, kincr,Rfrac;
125 int rkcount = 0, rblocksallocated = 0, kblocksallocated = 0;
127 CopyRight(stderr, argv[0]);
128 parse_common_args(&argc,argv,PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT | PCA_BE_NICE, NFILE,fnm,NPA,pa,asize(desc),desc, 0,NULL,&oenv);
131 /* Check command line options for filenames and set bool flags when switch used*/
132 in_trajfile = opt2fn("-f", NFILE, fnm);
133 in_ndxfile = opt2fn("-n", NFILE, fnm);
134 out_xvgrkfile = opt2fn("-ot", NFILE, fnm);
135 out_xvgrhistfile = opt2fn("-rhist", NFILE, fnm);
136 out_xvgkhistfile = opt2fn("-khist", NFILE, fnm);
137 out_xvginstefffile = opt2fn("-oe", NFILE, fnm);
138 out_datfile = opt2fn("-o",NFILE,fnm);
140 bRKout = opt2bSet("-ot", NFILE, fnm);
141 bRhistout = opt2bSet("-rhist", NFILE, fnm);
142 bKhistout = opt2bSet("-khist", NFILE, fnm);
143 bDatout = opt2bSet("-o", NFILE, fnm);
144 bInstEffout = opt2bSet("-oe", NFILE, fnm);
150 printf("Calculating distances to periodic image.\n");
151 printf("Be careful! This produces only valid results for PBC in all three dimensions\n");
155 if (bInstEffout && R0<=0.)
157 gmx_fatal(FARGS,"You have to specify R0 and R0 has to be larger than 0 nm.\n\n");
160 printf("Select group with donor atom pairs defining the transition moment\n");
161 get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ndon, &donindex,&grpnm);
163 printf("Select group with acceptor atom pairs defining the transition moment\n");
164 get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nacc, &accindex,&grpnm);
166 /*check if groups are identical*/
173 if(accindex[i] != donindex[i])
183 gmx_fatal(FARGS,"Donor and acceptor group are identical. This makes no sense.");
186 printf("Reading first frame\n");
187 /* open trx file for reading */
189 flags = flags | TRX_READ_X;
190 bHaveFirstFrame = read_first_frame(oenv, &status, in_trajfile, &fr, flags);
194 printf("First frame is OK\n");
196 if ((ndon % 2 != 0) || (nacc % 2 != 0))
202 for (i = 0; i < ndon;i++)
204 if (donindex[i] >= natoms)
207 for (i = 0; i < nacc;i++)
209 if (accindex[i] >= natoms)
219 datfp = fopen(out_datfile,"w");
224 rkfp = xvgropen(out_xvgrkfile,
225 "Distance and \\f{Symbol}k\\f{}\\S2\\N trajectory",
226 "Time (ps)", "Distance (nm) / \\f{Symbol}k\\f{}\\S2\\N",
228 xvgr_legend(rkfp, 2, rkleg, oenv);
233 iefp = xvgropen(out_xvginstefffile,
234 "Instantaneous RET Efficiency",
235 "Time (ps)", "RET Efficiency",
237 xvgr_legend(iefp, 1, ieleg, oenv);
243 snew(rvalues, allocblock);
244 rblocksallocated += 1;
245 snew(rhist, histbins);
250 snew(kappa2values, allocblock);
251 kblocksallocated += 1;
252 snew(khist, histbins);
261 for (i = 0; i < ndon / 2; i++)
263 rvec_sub(donvec, fr.x[donindex[2 * i]], donvec);
264 rvec_add(donvec, fr.x[donindex[2 * i + 1]], donvec);
265 rvec_add(donpos, fr.x[donindex[2 * i]], donpos);
266 rvec_add(donpos, fr.x[donindex[2 * i + 1]], donpos);
269 for (i = 0; i < nacc / 2; i++)
271 rvec_sub(accvec, fr.x[accindex[2 * i]], accvec);
272 rvec_add(accvec, fr.x[accindex[2 * i + 1]], accvec);
273 rvec_add(accpos, fr.x[accindex[2 * i]], accpos);
274 rvec_add(accpos, fr.x[accindex[2 * i + 1]], accpos);
277 unitv(donvec, donvec);
278 unitv(accvec, accvec);
280 svmul((real) 1. / ndon, donpos, donpos);
281 svmul((real) 1. / nacc, accpos, accpos);
285 set_pbc(pbc, ePBC, fr.box);
286 pbc_dx(pbc, donpos, accpos, dist);
290 rvec_sub(donpos, accpos, dist);
293 unitv(dist, distnorm);
295 kappa2 = iprod(donvec, accvec)- 3.* (iprod(donvec, distnorm) * iprod(distnorm, accvec));
300 insteff=1/(1+(Rfrac*Rfrac*Rfrac*Rfrac*Rfrac*Rfrac)*2/3/kappa2);
305 fprintf(iefp, "%12.7f %12.7f\n", fr.time, insteff);
315 fprintf(rkfp, "%12.7f %12.7f %12.7f\n", fr.time, R, kappa2);
318 fprintf(datfp, "%12.7f %12.7f %12.7f\n", fr.time, R, kappa2);
322 rvalues[rkcount-1] = R;
323 if (rkcount % allocblock == 0)
325 srenew(rvalues, allocblock*(rblocksallocated+1));
326 rblocksallocated += 1;
332 kappa2values[rkcount-1] = kappa2;
333 if (rkcount % allocblock == 0)
335 srenew(kappa2values, allocblock*(kblocksallocated+1));
336 kblocksallocated += 1;
340 bHaveNextFrame = read_next_frame(oenv, status, &fr);
341 } while (bHaveNextFrame);
355 printf("Writing R-Histogram\n");
358 for (i = 1; i < rkcount; i++)
360 if (rvalues[i] < rmin)
362 else if (rvalues[i] > rmax)
368 rrange = rmax - rmin;
369 rincr = rrange / histbins;
371 for (i = 1; i < rkcount; i++)
373 bin = (int) ((rvalues[i] - rmin) / rincr);
378 for (i = 0; i < histbins; i++)
379 rhist[i] /= rkcount * rrange/histbins;
380 rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution",
381 "R (nm)", "Normalized Probability", oenv);
384 rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution",
385 "R (nm)", "Probability", oenv);
387 xvgr_legend(rhfp, 1, rhleg, oenv);
388 for (i = 0; i < histbins; i++)
390 fprintf(rhfp, "%12.7f %12.7f\n", (i + 0.5) * rincr + rmin,
398 printf("Writing kappa^2-Histogram\n");
399 krange = kmax - kmin;
400 kincr = krange / histbins;
402 for (i = 1; i < rkcount; i++)
404 bin = (int) ((kappa2values[i] - kmin) / kincr);
409 for (i = 0; i < histbins; i++)
410 khist[i] /= rkcount * krange/histbins;
411 khfp = xvgropen(out_xvgkhistfile,
412 "\\f{Symbol}k\\f{}\\S2\\N Distribution",
413 "\\f{Symbol}k\\f{}\\S2\\N",
414 "Normalized Probability", oenv);
417 khfp = xvgropen(out_xvgkhistfile,
418 "\\f{Symbol}k\\f{}\\S2\\N Distribution",
419 "\\f{Symbol}k\\f{}\\S2\\N", "Probability", oenv);
421 xvgr_legend(khfp, 1, khleg, oenv);
422 for (i = 0; i < histbins; i++)
424 fprintf(khfp, "%12.7f %12.7f\n", (i + 0.5) * kincr + kmin,
430 printf("\nAverages:\n");
431 printf("R_avg = %8.4f nm\nKappa^2 = %8.4f\n", Rs / rkcount,
435 printf("E_RETavg = %8.4f\n", insteffs / rkcount);
437 please_cite(stdout,"Hoefling2011");
441 gmx_fatal(FARGS,"Index file invalid, check your index file for correct pairs.\n");
446 gmx_fatal(FARGS,"Could not read first frame of the trajectory.\n");