added Verlet scheme and NxN non-bonded functionality
[gromacs.git] / src / tools / gmx_kinetics.c
bloba5ecf7632de3fc0e005044c9da901cfa586cf297
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 <stdlib.h>
41 #include "statutil.h"
42 #include "sysstuff.h"
43 #include "typedefs.h"
44 #include "smalloc.h"
45 #include "macros.h"
46 #include "gmx_fatal.h"
47 #include "vec.h"
48 #include "copyrite.h"
49 #include "futil.h"
50 #include "readinp.h"
51 #include "statutil.h"
52 #include "txtdump.h"
53 #include "gstat.h"
54 #include "xvgr.h"
55 #include "physics.h"
56 #include "gmx_ana.h"
58 enum { epAuf, epEuf, epAfu, epEfu, epNR };
59 enum { eqAif, eqEif, eqAfi, eqEfi, eqAui, eqEui, eqAiu, eqEiu, eqNR };
60 static char *eep[epNR] = { "Af", "Ef", "Au", "Eu" };
61 static char *eeq[eqNR] = { "Aif","Eif","Afi","Efi","Aui","Eui","Aiu","Eiu" };
63 typedef struct {
64 int nreplica; /* Number of replicas in the calculation */
65 int nframe; /* Number of time frames */
66 int nstate; /* Number of states the system can be in, e.g. F,I,U */
67 int nparams; /* Is 2, 4 or 8 */
68 gmx_bool *bMask; /* Determine whether this replica is part of the d2 comp. */
69 gmx_bool bSum;
70 gmx_bool bDiscrete; /* Use either discrete folding (0/1) or a continuous */
71 /* criterion */
72 int nmask; /* Number of replicas taken into account */
73 real dt; /* Timestep between frames */
74 int j0,j1; /* Range of frames used in calculating delta */
75 real **temp,**data,**data2;
76 int **state; /* State index running from 0 (F) to nstate-1 (U) */
77 real **beta,**fcalt,**icalt;
78 real *time,*sumft,*sumit,*sumfct,*sumict;
79 real *params;
80 real *d2_replica;
81 } t_remd_data;
83 #ifdef HAVE_LIBGSL
84 #include <gsl/gsl_multimin.h>
86 static char *itoa(int i)
88 static char ptr[12];
90 sprintf(ptr,"%d",i);
91 return ptr;
94 static char *epnm(int nparams,int index)
96 static char buf[32],from[8],to[8];
97 int nn,ni,ii;
99 range_check(index,0,nparams);
100 if ((nparams == 2) || (nparams == 4))
101 return eep[index];
102 else if ((nparams > 4) && (nparams % 4 == 0))
103 return eeq[index];
104 else
105 gmx_fatal(FARGS,"Don't know how to handle %d parameters",nparams);
107 return NULL;
110 static gmx_bool bBack(t_remd_data *d)
112 return (d->nparams > 2);
115 static real is_folded(t_remd_data *d,int irep,int jframe)
117 if (d->state[irep][jframe] == 0)
118 return 1.0;
119 else
120 return 0.0;
123 static real is_unfolded(t_remd_data *d,int irep,int jframe)
125 if (d->state[irep][jframe] == d->nstate-1)
126 return 1.0;
127 else
128 return 0.0;
131 static real is_intermediate(t_remd_data *d,int irep,int jframe)
133 if ((d->state[irep][jframe] == 1) && (d->nstate > 2))
134 return 1.0;
135 else
136 return 0.0;
139 static void integrate_dfdt(t_remd_data *d)
141 int i,j;
142 double beta,ddf,ddi,df,db,fac,sumf,sumi,area;
144 d->sumfct[0] = 0;
145 d->sumict[0] = 0;
146 for(i=0; (i<d->nreplica); i++) {
147 if (d->bMask[i]) {
148 if (d->bDiscrete) {
149 ddf = 0.5*d->dt*is_folded(d,i,0);
150 ddi = 0.5*d->dt*is_intermediate(d,i,0);
152 else {
153 ddf = 0.5*d->dt*d->state[i][0];
154 ddi = 0.0;
156 d->fcalt[i][0] = ddf;
157 d->icalt[i][0] = ddi;
158 d->sumfct[0] += ddf;
159 d->sumict[0] += ddi;
162 for(j=1; (j<d->nframe); j++) {
163 if (j==d->nframe-1)
164 fac = 0.5*d->dt;
165 else
166 fac = d->dt;
167 sumf = sumi = 0;
168 for(i=0; (i<d->nreplica); i++) {
169 if (d->bMask[i]) {
170 beta = d->beta[i][j];
171 if ((d->nstate <= 2) || d->bDiscrete) {
172 if (d->bDiscrete)
173 df = (d->params[epAuf]*exp(-beta*d->params[epEuf])*
174 is_unfolded(d,i,j));
175 else {
176 area = (d->data2 ? d->data2[i][j] : 1.0);
177 df = area*d->params[epAuf]*exp(-beta*d->params[epEuf]);
179 if (bBack(d)) {
180 db = 0;
181 if (d->bDiscrete)
182 db = (d->params[epAfu]*exp(-beta*d->params[epEfu])*
183 is_folded(d,i,j));
184 else
185 gmx_fatal(FARGS,"Back reaction not implemented with continuous");
186 ddf = fac*(df-db);
188 else
189 ddf = fac*df;
190 d->fcalt[i][j] = d->fcalt[i][j-1] + ddf;
191 sumf += ddf;
193 else {
194 ddf = fac*((d->params[eqAif]*exp(-beta*d->params[eqEif])*
195 is_intermediate(d,i,j)) -
196 (d->params[eqAfi]*exp(-beta*d->params[eqEfi])*
197 is_folded(d,i,j)));
198 ddi = fac*((d->params[eqAui]*exp(-beta*d->params[eqEui])*
199 is_unfolded(d,i,j)) -
200 (d->params[eqAiu]*exp(-beta*d->params[eqEiu])*
201 is_intermediate(d,i,j)));
202 d->fcalt[i][j] = d->fcalt[i][j-1] + ddf;
203 d->icalt[i][j] = d->icalt[i][j-1] + ddi;
204 sumf += ddf;
205 sumi += ddi;
209 d->sumfct[j] = d->sumfct[j-1] + sumf;
210 d->sumict[j] = d->sumict[j-1] + sumi;
212 if (debug) {
213 fprintf(debug,"@type xy\n");
214 for(j=0; (j<d->nframe); j++) {
215 fprintf(debug,"%8.3f %12.5e\n",d->time[j],d->sumfct[j]);
217 fprintf(debug,"&\n");
221 static void sum_ft(t_remd_data *d)
223 int i,j;
224 double fac;
226 for(j=0; (j<d->nframe); j++) {
227 d->sumft[j] = 0;
228 d->sumit[j] = 0;
229 if ((j == 0) || (j==d->nframe-1))
230 fac = d->dt*0.5;
231 else
232 fac = d->dt;
233 for(i=0; (i<d->nreplica); i++) {
234 if (d->bMask[i]) {
235 if (d->bDiscrete) {
236 d->sumft[j] += fac*is_folded(d,i,j);
237 d->sumit[j] += fac*is_intermediate(d,i,j);
239 else
240 d->sumft[j] += fac*d->state[i][j];
246 static double calc_d2(t_remd_data *d)
248 int i,j;
249 double dd2,d2=0,dr2,tmp;
251 integrate_dfdt(d);
253 if (d->bSum) {
254 for(j=d->j0; (j<d->j1); j++) {
255 if (d->bDiscrete) {
256 d2 += sqr(d->sumft[j]-d->sumfct[j]);
257 if (d->nstate > 2)
258 d2 += sqr(d->sumit[j]-d->sumict[j]);
260 else
261 d2 += sqr(d->sumft[j]-d->sumfct[j]);
264 else {
265 for(i=0; (i<d->nreplica); i++) {
266 dr2 = 0;
267 if (d->bMask[i]) {
268 for(j=d->j0; (j<d->j1); j++) {
269 tmp = sqr(is_folded(d,i,j)-d->fcalt[i][j]);
270 d2 += tmp;
271 dr2 += tmp;
272 if (d->nstate > 2) {
273 tmp = sqr(is_intermediate(d,i,j)-d->icalt[i][j]);
274 d2 += tmp;
275 dr2 += tmp;
278 d->d2_replica[i] = dr2/(d->j1-d->j0);
282 dd2 = (d2/(d->j1-d->j0))/(d->bDiscrete ? d->nmask : 1);
284 return dd2;
287 static double my_f(const gsl_vector *v,void *params)
289 t_remd_data *d = (t_remd_data *) params;
290 double penalty=0;
291 int i;
293 for(i=0; (i<d->nparams); i++) {
294 d->params[i] = gsl_vector_get(v, i);
295 if (d->params[i] < 0)
296 penalty += 10;
298 if (penalty > 0)
299 return penalty;
300 else
301 return calc_d2(d);
304 static void optimize_remd_parameters(FILE *fp,t_remd_data *d,int maxiter,
305 real tol)
307 real size,d2;
308 int iter = 0;
309 int status = 0;
310 int i;
312 const gsl_multimin_fminimizer_type *T;
313 gsl_multimin_fminimizer *s;
315 gsl_vector *x,*dx;
316 gsl_multimin_function my_func;
318 my_func.f = &my_f;
319 my_func.n = d->nparams;
320 my_func.params = (void *) d;
322 /* Starting point */
323 x = gsl_vector_alloc (my_func.n);
324 for(i=0; (i<my_func.n); i++)
325 gsl_vector_set (x, i, d->params[i]);
327 /* Step size, different for each of the parameters */
328 dx = gsl_vector_alloc (my_func.n);
329 for(i=0; (i<my_func.n); i++)
330 gsl_vector_set (dx, i, 0.1*d->params[i]);
332 T = gsl_multimin_fminimizer_nmsimplex;
333 s = gsl_multimin_fminimizer_alloc (T, my_func.n);
335 gsl_multimin_fminimizer_set (s, &my_func, x, dx);
336 gsl_vector_free (x);
337 gsl_vector_free (dx);
339 printf ("%5s","Iter");
340 for(i=0; (i<my_func.n); i++)
341 printf(" %12s",epnm(my_func.n,i));
342 printf (" %12s %12s\n","NM Size","Chi2");
344 do {
345 iter++;
346 status = gsl_multimin_fminimizer_iterate (s);
348 if (status != 0)
349 gmx_fatal(FARGS,"Something went wrong in the iteration in minimizer %s",
350 gsl_multimin_fminimizer_name(s));
352 d2 = gsl_multimin_fminimizer_minimum(s);
353 size = gsl_multimin_fminimizer_size(s);
354 status = gsl_multimin_test_size(size,tol);
356 if (status == GSL_SUCCESS)
357 printf ("Minimum found using %s at:\n",
358 gsl_multimin_fminimizer_name(s));
360 printf ("%5d", iter);
361 for(i=0; (i<my_func.n); i++)
362 printf(" %12.4e",gsl_vector_get (s->x,i));
363 printf (" %12.4e %12.4e\n",size,d2);
365 while ((status == GSL_CONTINUE) && (iter < maxiter));
367 gsl_multimin_fminimizer_free (s);
370 static void preprocess_remd(FILE *fp,t_remd_data *d,real cutoff,real tref,
371 real ucut,gmx_bool bBack,real Euf,real Efu,
372 real Ei,real t0,real t1,gmx_bool bSum,gmx_bool bDiscrete,
373 int nmult)
375 int i,j,ninter;
376 real dd,tau_f,tau_u;
378 ninter = (ucut > cutoff) ? 1 : 0;
379 if (ninter && (ucut <= cutoff))
380 gmx_fatal(FARGS,"You have requested an intermediate but the cutoff for intermediates %f is smaller than the normal cutoff(%f)",ucut,cutoff);
382 if (!bBack) {
383 d->nparams = 2;
384 d->nstate = 2;
386 else {
387 d->nparams = 4*(1+ninter);
388 d->nstate = 2+ninter;
390 d->bSum = bSum;
391 d->bDiscrete = bDiscrete;
392 snew(d->beta, d->nreplica);
393 snew(d->state,d->nreplica);
394 snew(d->bMask,d->nreplica);
395 snew(d->d2_replica,d->nreplica);
396 snew(d->sumft,d->nframe);
397 snew(d->sumit,d->nframe);
398 snew(d->sumfct,d->nframe);
399 snew(d->sumict,d->nframe);
400 snew(d->params,d->nparams);
401 snew(d->fcalt,d->nreplica);
402 snew(d->icalt,d->nreplica);
404 /* convert_times(d->nframe,d->time); */
406 if (t0 < 0)
407 d->j0 = 0;
408 else
409 for(d->j0=0; (d->j0<d->nframe) && (d->time[d->j0] < t0); d->j0++)
411 if (t1 < 0)
412 d->j1=d->nframe;
413 else
414 for(d->j1=0; (d->j1<d->nframe) && (d->time[d->j1] < t1); d->j1++)
416 if ((d->j1-d->j0) < d->nparams+2)
417 gmx_fatal(FARGS,"Start (%f) or end time (%f) for fitting inconsistent. Reduce t0, increase t1 or supply more data",t0,t1);
418 fprintf(fp,"Will optimize from %g to %g\n",
419 d->time[d->j0],d->time[d->j1-1]);
420 d->nmask = d->nreplica;
421 for(i=0; (i<d->nreplica); i++) {
422 snew(d->beta[i],d->nframe);
423 snew(d->state[i],d->nframe);
424 snew(d->fcalt[i],d->nframe);
425 snew(d->icalt[i],d->nframe);
426 d->bMask[i] = TRUE;
427 for(j=0; (j<d->nframe); j++) {
428 d->beta[i][j] = 1.0/(BOLTZ*d->temp[i][j]);
429 dd = d->data[i][j];
430 if (bDiscrete) {
431 if (dd <= cutoff)
432 d->state[i][j] = 0;
433 else if ((ucut > cutoff) && (dd <= ucut))
434 d->state[i][j] = 1;
435 else
436 d->state[i][j] = d->nstate-1;
438 else
439 d->state[i][j] = dd*nmult;
442 sum_ft(d);
444 /* Assume forward rate constant is half the total time in this
445 * simulation and backward is ten times as long */
446 if (bDiscrete) {
447 tau_f = d->time[d->nframe-1];
448 tau_u = 4*tau_f;
449 d->params[epEuf] = Euf;
450 d->params[epAuf] = exp(d->params[epEuf]/(BOLTZ*tref))/tau_f;
451 if (bBack) {
452 d->params[epEfu] = Efu;
453 d->params[epAfu] = exp(d->params[epEfu]/(BOLTZ*tref))/tau_u;
454 if (ninter >0) {
455 d->params[eqEui] = Ei;
456 d->params[eqAui] = exp(d->params[eqEui]/(BOLTZ*tref))/tau_u;
457 d->params[eqEiu] = Ei;
458 d->params[eqAiu] = exp(d->params[eqEiu]/(BOLTZ*tref))/tau_u;
461 else {
462 d->params[epAfu] = 0;
463 d->params[epEfu] = 0;
466 else {
467 d->params[epEuf] = Euf;
468 if (d->data2)
469 d->params[epAuf] = 0.1;
470 else
471 d->params[epAuf] = 20.0;
475 static real tau(real A,real E,real T)
477 return exp(E/(BOLTZ*T))/A;
480 static real folded_fraction(t_remd_data *d,real tref)
482 real tauf,taub;
484 tauf = tau(d->params[epAuf],d->params[epEuf],tref);
485 taub = tau(d->params[epAfu],d->params[epEfu],tref);
487 return (taub/(tauf+taub));
490 static void print_tau(FILE *gp,t_remd_data *d,real tref)
492 real tauf,taub,ddd,fff,DG,DH,TDS,Tm,Tb,Te,Fb,Fe,Fm;
493 int i,np=d->nparams;
495 ddd = calc_d2(d);
496 fprintf(gp,"Final value for Chi2 = %12.5e (%d replicas)\n",ddd,d->nmask);
497 tauf = tau(d->params[epAuf],d->params[epEuf],tref);
498 fprintf(gp,"%s = %12.5e %s = %12.5e (kJ/mole)\n",
499 epnm(np,epAuf),d->params[epAuf],
500 epnm(np,epEuf),d->params[epEuf]);
501 if (bBack(d)) {
502 taub = tau(d->params[epAfu],d->params[epEfu],tref);
503 fprintf(gp,"%s = %12.5e %s = %12.5e (kJ/mole)\n",
504 epnm(np,epAfu),d->params[epAfu],
505 epnm(np,epEfu),d->params[epEfu]);
506 fprintf(gp,"Equilibrium properties at T = %g\n",tref);
507 fprintf(gp,"tau_f = %8.3f ns, tau_b = %8.3f ns\n",tauf/1000,taub/1000);
508 fff = taub/(tauf+taub);
509 DG = BOLTZ*tref*log(fff/(1-fff));
510 DH = d->params[epEfu]-d->params[epEuf];
511 TDS = DH-DG;
512 fprintf(gp,"Folded fraction F = %8.3f\n",fff);
513 fprintf(gp,"Unfolding energies: DG = %8.3f DH = %8.3f TDS = %8.3f\n",
514 DG,DH,TDS);
515 Tb = 260;
516 Te = 420;
517 Tm = 0;
518 Fm = 0;
519 Fb = folded_fraction(d,Tb);
520 Fe = folded_fraction(d,Te);
521 while((Te-Tb > 0.001) && (Fm != 0.5)) {
522 Tm = 0.5*(Tb+Te);
523 Fm = folded_fraction(d,Tm);
524 if (Fm > 0.5) {
525 Fb = Fm;
526 Tb = Tm;
528 else if (Fm < 0.5) {
529 Te = Tm;
530 Fe = Fm;
533 if ((Fb-0.5)*(Fe-0.5) <= 0)
534 fprintf(gp,"Melting temperature Tm = %8.3f K\n",Tm);
535 else
536 fprintf(gp,"No melting temperature detected between 260 and 420K\n");
537 if (np > 4) {
538 char *ptr;
539 fprintf(gp,"Data for intermediates at T = %g\n",tref);
540 fprintf(gp,"%8s %10s %10s %10s\n","Name","A","E","tau");
541 for(i=0; (i<np/2); i++) {
542 tauf = tau(d->params[2*i],d->params[2*i+1],tref);
543 ptr = epnm(d->nparams,2*i);
544 fprintf(gp,"%8s %10.3e %10.3e %10.3e\n",ptr+1,
545 d->params[2*i],d->params[2*i+1],tauf/1000);
549 else {
550 fprintf(gp,"Equilibrium properties at T = %g\n",tref);
551 fprintf(gp,"tau_f = %8.3f\n",tauf);
555 static void dump_remd_parameters(FILE *gp,t_remd_data *d,const char *fn,
556 const char *fn2,const char *rfn,
557 const char *efn,const char *mfn,int skip,real tref,
558 output_env_t oenv)
560 FILE *fp,*hp;
561 int i,j,np=d->nparams;
562 real rhs,tauf,taub,fff,DG;
563 real *params;
564 const char *leg[] = { "Measured", "Fit", "Difference" };
565 const char *mleg[] = { "Folded fraction","DG (kJ/mole)"};
566 char **rleg;
567 real fac[] = { 0.97, 0.98, 0.99, 1.0, 1.01, 1.02, 1.03 };
568 #define NFAC asize(fac)
569 real d2[NFAC];
570 double norm;
572 integrate_dfdt(d);
573 print_tau(gp,d,tref);
574 norm = (d->bDiscrete ? 1.0/d->nmask : 1.0);
576 if (fn) {
577 fp = xvgropen(fn,"Optimized fit to data","Time (ps)","Fraction Folded",oenv);
578 xvgr_legend(fp,asize(leg),leg,oenv);
579 for(i=0; (i<d->nframe); i++) {
580 if ((skip <= 0) || ((i % skip) == 0)) {
581 fprintf(fp,"%12.5e %12.5e %12.5e %12.5e\n",d->time[i],
582 d->sumft[i]*norm,d->sumfct[i]*norm,
583 (d->sumft[i]-d->sumfct[i])*norm);
586 ffclose(fp);
588 if (!d->bSum && rfn) {
589 snew(rleg,d->nreplica*2);
590 for(i=0; (i<d->nreplica); i++) {
591 snew(rleg[2*i],32);
592 snew(rleg[2*i+1],32);
593 sprintf(rleg[2*i],"\\f{4}F(t) %d",i);
594 sprintf(rleg[2*i+1],"\\f{12}F \\f{4}(t) %d",i);
596 fp = xvgropen(rfn,"Optimized fit to data","Time (ps)","Fraction Folded",oenv);
597 xvgr_legend(fp,d->nreplica*2,(const char**)rleg,oenv);
598 for(j=0; (j<d->nframe); j++) {
599 if ((skip <= 0) || ((j % skip) == 0)) {
600 fprintf(fp,"%12.5e",d->time[j]);
601 for(i=0; (i<d->nreplica); i++)
602 fprintf(fp," %5f %9.2e",is_folded(d,i,j),d->fcalt[i][j]);
603 fprintf(fp,"\n");
606 ffclose(fp);
609 if (fn2 && (d->nstate > 2)) {
610 fp = xvgropen(fn2,"Optimized fit to data","Time (ps)",
611 "Fraction Intermediate",oenv);
612 xvgr_legend(fp,asize(leg),leg,oenv);
613 for(i=0; (i<d->nframe); i++) {
614 if ((skip <= 0) || ((i % skip) == 0))
615 fprintf(fp,"%12.5e %12.5e %12.5e %12.5e\n",d->time[i],
616 d->sumit[i]*norm,d->sumict[i]*norm,
617 (d->sumit[i]-d->sumict[i])*norm);
619 ffclose(fp);
621 if (mfn) {
622 if (bBack(d)) {
623 fp = xvgropen(mfn,"Melting curve","T (K)","",oenv);
624 xvgr_legend(fp,asize(mleg),mleg,oenv);
625 for(i=260; (i<=420); i++) {
626 tauf = tau(d->params[epAuf],d->params[epEuf],1.0*i);
627 taub = tau(d->params[epAfu],d->params[epEfu],1.0*i);
628 fff = taub/(tauf+taub);
629 DG = BOLTZ*i*log(fff/(1-fff));
630 fprintf(fp,"%5d %8.3f %8.3f\n",i,fff,DG);
632 ffclose(fp);
636 if (efn) {
637 snew(params,d->nparams);
638 for(i=0; (i<d->nparams); i++)
639 params[i] = d->params[i];
641 hp = xvgropen(efn,"Chi2 as a function of relative parameter",
642 "Fraction","Chi2",oenv);
643 for(j=0; (j<d->nparams); j++) {
644 /* Reset all parameters to optimized values */
645 fprintf(hp,"@type xy\n");
646 for(i=0; (i<d->nparams); i++)
647 d->params[i] = params[i];
648 /* Now modify one of them */
649 for(i=0; (i<NFAC); i++) {
650 d->params[j] = fac[i]*params[j];
651 d2[i] = calc_d2(d);
652 fprintf(gp,"%s = %12g d2 = %12g\n",epnm(np,j),d->params[j],d2[i]);
653 fprintf(hp,"%12g %12g\n",fac[i],d2[i]);
655 fprintf(hp,"&\n");
657 ffclose(hp);
658 for(i=0; (i<d->nparams); i++)
659 d->params[i] = params[i];
660 sfree(params);
662 if (!d->bSum) {
663 for(i=0; (i<d->nreplica); i++)
664 fprintf(gp,"Chi2[%3d] = %8.2e\n",i,d->d2_replica[i]);
667 #endif /*HAVE_LIBGSL*/
669 int gmx_kinetics(int argc,char *argv[])
671 const char *desc[] = {
672 "[TT]g_kinetics[tt] reads two [TT].xvg[tt] files, each one containing data for N replicas.",
673 "The first file contains the temperature of each replica at each timestep,",
674 "and the second contains real values that can be interpreted as",
675 "an indicator for folding. If the value in the file is larger than",
676 "the cutoff it is taken to be unfolded and the other way around.[PAR]",
677 "From these data an estimate of the forward and backward rate constants",
678 "for folding is made at a reference temperature. In addition,",
679 "a theoretical melting curve and free energy as a function of temperature",
680 "are printed in an [TT].xvg[tt] file.[PAR]",
681 "The user can give a max value to be regarded as intermediate",
682 "([TT]-ucut[tt]), which, when given will trigger the use of an intermediate state",
683 "in the algorithm to be defined as those structures that have",
684 "cutoff < DATA < ucut. Structures with DATA values larger than ucut will",
685 "not be regarded as potential folders. In this case 8 parameters are optimized.[PAR]",
686 "The average fraction foled is printed in an [TT].xvg[tt] file together with the fit to it.",
687 "If an intermediate is used a further file will show the build of the intermediate and the fit to that process.[PAR]",
688 "The program can also be used with continuous variables (by setting",
689 "[TT]-nodiscrete[tt]). In this case kinetics of other processes can be",
690 "studied. This is very much a work in progress and hence the manual",
691 "(this information) is lagging behind somewhat.[PAR]",
692 "In order to compile this program you need access to the GNU",
693 "scientific library."
695 static int nreplica = 1;
696 static real tref = 298.15;
697 static real cutoff = 0.2;
698 static real ucut = 0.0;
699 static real Euf = 10;
700 static real Efu = 30;
701 static real Ei = 10;
702 static gmx_bool bHaveT = TRUE;
703 static real t0 = -1;
704 static real t1 = -1;
705 static real tb = 0;
706 static real te = 0;
707 static real tol = 1e-3;
708 static int maxiter = 100;
709 static int skip = 0;
710 static int nmult = 1;
711 static gmx_bool bBack = TRUE;
712 static gmx_bool bSplit = TRUE;
713 static gmx_bool bSum = TRUE;
714 static gmx_bool bDiscrete = TRUE;
715 t_pargs pa[] = {
716 { "-time", FALSE, etBOOL, {&bHaveT},
717 "Expect a time in the input" },
718 { "-b", FALSE, etREAL, {&tb},
719 "First time to read from set" },
720 { "-e", FALSE, etREAL, {&te},
721 "Last time to read from set" },
722 { "-bfit", FALSE, etREAL, {&t0},
723 "Time to start the fit from" },
724 { "-efit", FALSE, etREAL, {&t1},
725 "Time to end the fit" },
726 { "-T", FALSE, etREAL, {&tref},
727 "Reference temperature for computing rate constants" },
728 { "-n", FALSE, etINT, {&nreplica},
729 "Read data for this number of replicas. Only necessary when files are written in xmgrace format using @type and & as delimiters." },
730 { "-cut", FALSE, etREAL, {&cutoff},
731 "Cut-off (max) value for regarding a structure as folded" },
732 { "-ucut", FALSE, etREAL, {&ucut},
733 "Cut-off (max) value for regarding a structure as intermediate (if not folded)" },
734 { "-euf", FALSE, etREAL, {&Euf},
735 "Initial guess for energy of activation for folding (kJ/mol)" },
736 { "-efu", FALSE, etREAL, {&Efu},
737 "Initial guess for energy of activation for unfolding (kJ/mol)" },
738 { "-ei", FALSE, etREAL, {&Ei},
739 "Initial guess for energy of activation for intermediates (kJ/mol)" },
740 { "-maxiter", FALSE, etINT, {&maxiter},
741 "Max number of iterations" },
742 { "-back", FALSE, etBOOL, {&bBack},
743 "Take the back reaction into account" },
744 { "-tol", FALSE, etREAL,{&tol},
745 "Absolute tolerance for convergence of the Nelder and Mead simplex algorithm" },
746 { "-skip", FALSE, etINT, {&skip},
747 "Skip points in the output [TT].xvg[tt] file" },
748 { "-split", FALSE, etBOOL,{&bSplit},
749 "Estimate error by splitting the number of replicas in two and refitting" },
750 { "-sum", FALSE, etBOOL,{&bSum},
751 "Average folding before computing [GRK]chi[grk]^2" },
752 { "-discrete", FALSE, etBOOL, {&bDiscrete},
753 "Use a discrete folding criterion (F <-> U) or a continuous one" },
754 { "-mult", FALSE, etINT, {&nmult},
755 "Factor to multiply the data with before discretization" }
757 #define NPA asize(pa)
759 FILE *fp;
760 real dt_t,dt_d,dt_d2;
761 int nset_t,nset_d,nset_d2,n_t,n_d,n_d2,i;
762 const char *tfile,*dfile,*dfile2;
763 t_remd_data remd;
764 output_env_t oenv;
766 t_filenm fnm[] = {
767 { efXVG, "-f", "temp", ffREAD },
768 { efXVG, "-d", "data", ffREAD },
769 { efXVG, "-d2", "data2", ffOPTRD },
770 { efXVG, "-o", "ft_all", ffWRITE },
771 { efXVG, "-o2", "it_all", ffOPTWR },
772 { efXVG, "-o3", "ft_repl", ffOPTWR },
773 { efXVG, "-ee", "err_est", ffOPTWR },
774 { efLOG, "-g", "remd", ffWRITE },
775 { efXVG, "-m", "melt", ffWRITE }
777 #define NFILE asize(fnm)
779 CopyRight(stderr,argv[0]);
780 parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_BE_NICE | PCA_TIME_UNIT,
781 NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL,&oenv);
783 #ifdef HAVE_LIBGSL
784 please_cite(stdout,"Spoel2006d");
785 if (cutoff < 0)
786 gmx_fatal(FARGS,"cutoff should be >= 0 (rather than %f)",cutoff);
788 tfile = opt2fn("-f",NFILE,fnm);
789 dfile = opt2fn("-d",NFILE,fnm);
790 dfile2 = opt2fn_null("-d2",NFILE,fnm);
792 fp = ffopen(opt2fn("-g",NFILE,fnm),"w");
794 remd.temp = read_xvg_time(tfile,bHaveT,
795 opt2parg_bSet("-b",NPA,pa),tb,
796 opt2parg_bSet("-e",NPA,pa),te,
797 nreplica,&nset_t,&n_t,&dt_t,&remd.time);
798 printf("Read %d sets of %d points in %s, dt = %g\n\n",nset_t,n_t,tfile,dt_t);
799 sfree(remd.time);
801 remd.data = read_xvg_time(dfile,bHaveT,
802 opt2parg_bSet("-b",NPA,pa),tb,
803 opt2parg_bSet("-e",NPA,pa),te,
804 nreplica,&nset_d,&n_d,&dt_d,&remd.time);
805 printf("Read %d sets of %d points in %s, dt = %g\n\n",nset_d,n_d,dfile,dt_d);
807 if ((nset_t != nset_d) || (n_t != n_d) || (dt_t != dt_d))
808 gmx_fatal(FARGS,"Files %s and %s are inconsistent. Check log file",
809 tfile,dfile);
811 if (dfile2) {
812 remd.data2 = read_xvg_time(dfile2,bHaveT,
813 opt2parg_bSet("-b",NPA,pa),tb,
814 opt2parg_bSet("-e",NPA,pa),te,
815 nreplica,&nset_d2,&n_d2,&dt_d2,&remd.time);
816 printf("Read %d sets of %d points in %s, dt = %g\n\n",
817 nset_d2,n_d2,dfile2,dt_d2);
818 if ((nset_d2 != nset_d) || (n_d != n_d2) || (dt_d != dt_d2))
819 gmx_fatal(FARGS,"Files %s and %s are inconsistent. Check log file",
820 dfile,dfile2);
822 else {
823 remd.data2 = NULL;
826 remd.nreplica = nset_d;
827 remd.nframe = n_d;
828 remd.dt = 1;
829 preprocess_remd(fp,&remd,cutoff,tref,ucut,bBack,Euf,Efu,Ei,t0,t1,
830 bSum,bDiscrete,nmult);
832 optimize_remd_parameters(fp,&remd,maxiter,tol);
834 dump_remd_parameters(fp,&remd,opt2fn("-o",NFILE,fnm),
835 opt2fn_null("-o2",NFILE,fnm),
836 opt2fn_null("-o3",NFILE,fnm),
837 opt2fn_null("-ee",NFILE,fnm),
838 opt2fn("-m",NFILE,fnm),skip,tref,oenv);
840 if (bSplit) {
841 printf("Splitting set of replicas in two halves\n");
842 for(i=0; (i<remd.nreplica); i++)
843 remd.bMask[i] = FALSE;
844 remd.nmask = 0;
845 for(i=0; (i<remd.nreplica); i+=2) {
846 remd.bMask[i] = TRUE;
847 remd.nmask++;
849 sum_ft(&remd);
850 optimize_remd_parameters(fp,&remd,maxiter,tol);
851 dump_remd_parameters(fp,&remd,"test1.xvg",NULL,NULL,NULL,NULL,skip,tref,oenv);
853 for(i=0; (i<remd.nreplica); i++)
854 remd.bMask[i] = !remd.bMask[i];
855 remd.nmask = remd.nreplica - remd.nmask;
857 sum_ft(&remd);
858 optimize_remd_parameters(fp,&remd,maxiter,tol);
859 dump_remd_parameters(fp,&remd,"test2.xvg",NULL,NULL,NULL,NULL,skip,tref,oenv);
861 for(i=0; (i<remd.nreplica); i++)
862 remd.bMask[i] = FALSE;
863 remd.nmask = 0;
864 for(i=0; (i<remd.nreplica/2); i++) {
865 remd.bMask[i] = TRUE;
866 remd.nmask++;
868 sum_ft(&remd);
869 optimize_remd_parameters(fp,&remd,maxiter,tol);
870 dump_remd_parameters(fp,&remd,"test1.xvg",NULL,NULL,NULL,NULL,skip,tref,oenv);
872 for(i=0; (i<remd.nreplica); i++)
873 remd.bMask[i] = FALSE;
874 remd.nmask = 0;
875 for(i=remd.nreplica/2; (i<remd.nreplica); i++) {
876 remd.bMask[i] = TRUE;
877 remd.nmask++;
879 sum_ft(&remd);
880 optimize_remd_parameters(fp,&remd,maxiter,tol);
881 dump_remd_parameters(fp,&remd,"test1.xvg",NULL,NULL,NULL,NULL,skip,tref,oenv);
883 ffclose(fp);
885 view_all(oenv, NFILE, fnm);
887 thanx(stderr);
888 #else
889 fprintf(stderr,"This program should be compiled with the GNU scientific library. Please install the library and reinstall GROMACS.\n");
890 #endif /*HAVE_LIBGSL*/
892 return 0;