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_eneconv_c
= "$Id$";
43 #define TIME_EXPLICIT 0
44 #define TIME_CONTINUE 1
50 bool bRmod(double a
,double b
)
57 if (fabs(a
-b
*iq
) <= tol
*a
)
63 static bool same_time(real t1
,real t2
)
67 return (fabs(t1
-t2
) < tol
);
71 bool bRgt(double a
,double b
)
75 if ( a
> (b
- tol
*(a
+b
)) )
81 static void sort_files(char **fnms
,real
*settime
,int nfile
)
87 for(i
=0;i
<nfile
;i
++) {
89 for(j
=i
+1;j
<nfile
;j
++) {
90 if(settime
[j
]<settime
[minidx
])
95 settime
[i
]=settime
[minidx
];
96 settime
[minidx
]=timeswap
;
105 static int scan_ene_files(char **fnms
,int nfiles
,real
*readtime
, real
*timestep
)
107 /* Check number of energy terms and start time of all files */
108 int i
,in
,nre
,ndr
,nresav
=0,step
;
114 for(i
=0;i
<nfiles
;i
++) {
115 in
= open_enx(fnms
[i
],"r");
116 do_enxnms(in
,&nre
,&enm
);
121 do_enx(in
,&t1
,&step
,&nre
,ee
,&ndr
,dr
);
122 do_enx(in
,&t2
,&step
,&nre
,ee
,&ndr
,dr
);
127 else if (nre
!= nresav
) {
128 fatal_error(0,"Energy files don't match, different number"
129 " of energies (%s)",fnms
[i
]);
132 do_enx(in
,&t1
,&step
,&nre
,ee
,&ndr
,dr
);
136 fprintf(stderr
,"\n");
143 static void edit_files(char **fnms
,int nfiles
,real
*readtime
, real
144 *settime
, int *cont_type
, bool bSetTime
,bool bSort
)
148 char inputstring
[STRLEN
],*chptr
;
152 fprintf(stderr
,"\n\nEnter the new start time:\n\n");
154 fprintf(stderr
,"\n\nEnter the new start time for each file.\n"
155 "There are two special options, both disables sorting:\n\n"
156 "c (continue) - The start time is taken from the end\n"
157 "of the previous file. Use it when your continuation run\n"
158 "restarts with t=0 and there is no overlap.\n\n"
159 "l (last) - The time in this file will be changed the\n"
160 "same amount as in the previous. Use it when the time in the\n"
161 "new run continues from the end of the previous one,\n"
162 "since this takes possible overlap into account.\n\n");
164 fprintf(stderr
," File Current start New start\n"
165 "---------------------------------------------------------\n");
167 for(i
=0;i
<nfiles
;i
++) {
168 fprintf(stderr
,"%25s %10.3f ",fnms
[i
],readtime
[i
]);
171 fgets(inputstring
,STRLEN
-1,stdin
);
172 inputstring
[strlen(inputstring
)-1]=0;
174 if(inputstring
[0]=='c' || inputstring
[0]=='C') {
175 cont_type
[i
]=TIME_CONTINUE
;
180 else if(inputstring
[0]=='l' ||
181 inputstring
[0]=='L') {
182 cont_type
[i
]=TIME_LAST
;
188 settime
[i
]=strtod(inputstring
,&chptr
);
189 if(chptr
==inputstring
) {
190 fprintf(stderr
,"Try that again: ");
193 cont_type
[i
]=TIME_EXPLICIT
;
199 if(cont_type
[0]!=TIME_EXPLICIT
) {
200 cont_type
[0]=TIME_EXPLICIT
;
205 for(i
=0;i
<nfiles
;i
++)
206 settime
[i
]=readtime
[i
];
208 if(bSort
&& (nfiles
>1))
209 sort_files(fnms
,settime
,nfiles
);
211 fprintf(stderr
,"Sorting disabled.\n");
214 /* Write out the new order and start times */
215 fprintf(stderr
,"\nSummary of files and start times used:\n\n"
217 "-----------------------------------------\n");
218 for(i
=0;i
<nfiles
;i
++)
219 switch(cont_type
[i
]) {
221 fprintf(stderr
,"%25s %10.3f\n",fnms
[i
],settime
[i
]);
224 fprintf(stderr
,"%25s Continue from end of last file\n",fnms
[i
]);
227 fprintf(stderr
,"%25s Change by same amount as last file\n",fnms
[i
]);
230 fprintf(stderr
,"\n");
232 settime
[nfiles
]=FLT_MAX
;
233 cont_type
[nfiles
]=TIME_EXPLICIT
;
234 readtime
[nfiles
]=FLT_MAX
;
238 static void copy_ee(t_energy
*src
, t_energy
*dst
, int nre
)
244 dst
[i
].esum
=src
[i
].esum
;
245 dst
[i
].eav
=src
[i
].eav
;
250 static void remove_last_eeframe(t_energy
*lastee
, int laststep
,
251 t_energy
*ee
, int nre
)
258 lastee
[i
].esum
-=ee
[i
].e
;
259 sigmacorr
=lastee
[i
].esum
-(p
-1)*ee
[i
].e
;
260 lastee
[i
].eav
-=(sigmacorr
*sigmacorr
)/((p
-1)*p
);
266 static void update_ee(t_energy
*lastee
,int laststep
,
267 t_energy
*startee
,int startstep
,
268 t_energy
*ee
, int step
,
269 t_energy
*outee
, int nre
)
272 double sigmacorr
,nom
,denom
;
273 double prestart_esum
;
274 double prestart_sigma
;
278 /* add statistics from earlier file if present */
280 outee
[i
].esum
=lastee
[i
].esum
+ee
[i
].esum
;
281 nom
=(lastee
[i
].esum
*(step
+1)-ee
[i
].esum
*(laststep
));
282 denom
=((step
+1.0)*(laststep
)*(step
+1.0+laststep
));
283 sigmacorr
=nom
*nom
/denom
;
284 outee
[i
].eav
=lastee
[i
].eav
+ee
[i
].eav
+sigmacorr
;
287 /* otherwise just copy to output */
288 outee
[i
].esum
=ee
[i
].esum
;
289 outee
[i
].eav
=ee
[i
].eav
;
292 /* if we didnt start to write at the first frame
293 * we must compensate the statistics for this
294 * there are laststep frames in the earlier file
295 * and step+1 frames in this one.
300 prestart_esum
=startee
[i
].esum
-startee
[i
].e
;
301 sigmacorr
=prestart_esum
-(p
-1)*startee
[i
].e
;
302 prestart_sigma
=startee
[i
].eav
-
303 sigmacorr
*sigmacorr
/(p
*(p
-1));
304 sigmacorr
=prestart_esum
/(p
-1)-
306 outee
[i
].esum
-=prestart_esum
;
307 outee
[i
].eav
=outee
[i
].eav
-prestart_sigma
-
308 sigmacorr
*sigmacorr
*((p
-1)*q
)/(q
-p
+1);
311 if((outee
[i
].eav
/(laststep
+step
+1))<(GMX_REAL_EPS
))
317 static void update_last_ee(t_energy
*lastee
, int laststep
,
318 t_energy
*ee
,int step
,int nre
)
322 update_ee(lastee
,laststep
,NULL
,0,ee
,step
,tmp
,nre
);
323 copy_ee(tmp
,lastee
,nre
);
328 int main(int argc
,char *argv
[])
330 static char *desc
[] = {
331 "When [TT]-f[tt] is [IT]not[it] specified:[BR]",
332 "Concatenates several energy files in sorted order.",
333 "In case of double time frames the one",
334 "in the later file is used. By specifying [TT]-settime[tt] you will be",
335 "asked for the start time of each file. The input files are taken",
336 "from the command line,",
337 "such that the command [TT]eneconv -o fixed.edr *.edr[tt] should do",
339 "With [TT]-f[tt] specified:[BR]",
340 "Reads one energy file and writes another, applying the [TT]-dt[tt],",
341 "[TT]-offset[tt], [TT]-t0[tt] and [TT]-settime[tt] options and",
342 "converting to a different format if necessary (indicated by file",
344 "[TT]-settime[tt] is applied first, then [TT]-dt[tt]/[TT]-offset[tt]",
345 "followed by [TT]-b[tt] and [TT]-e[tt] to select which frames to write."
349 t_energy
*ee
,*lastee
,*outee
,*startee
;
350 int step
,laststep
,outstep
,startstep
;
351 int nre
,nfile
,i
,j
,ndr
;
356 real
*readtime
,*settime
,timestep
,t1
,tadjust
;
357 char inputstring
[STRLEN
],*chptr
;
360 bool bNewFile
,bFirst
,bNewOutput
;
363 { efENX
, "-f", NULL
, ffREAD
},
364 { efENX
, "-o", "fixed", ffOPTWR
},
367 #define NFILE asize(fnm)
369 static real delta_t
=0.0, toffset
=0;
370 static bool bSetTime
=FALSE
;
371 static bool bSort
=TRUE
;
372 static real begin
=-1;
376 { "-b", FALSE
, etREAL
, {&begin
},
377 "First time to use"},
378 { "-e", FALSE
, etREAL
, {&end
},
380 { "-dt", FALSE
, etREAL
, {&delta_t
},
381 "Only write out frame when t MOD dt = offset" },
382 { "-offset", FALSE
, etREAL
, {&toffset
},
383 "Time offset for -dt option" },
384 { "-settime", FALSE
, etBOOL
, {&bSetTime
},
385 "Change starting time interactively" },
386 { "-sort", FALSE
, etBOOL
, {&bSort
},
387 "Sort energy files (not frames)"}
390 CopyRight(stderr
,argv
[0]);
391 parse_common_args(&argc
,argv
,PCA_NOEXIT_ON_ARGS
,TRUE
,
392 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,0,NULL
);
396 outstep
=laststep
=startstep
=0;
398 for(i
=1; (i
<argc
); i
++)
399 fnms
[nfile
++]=argv
[i
];
402 snew(settime
,nfile
+1);
403 snew(readtime
,nfile
+1);
404 snew(cont_type
,nfile
+1);
406 if (!opt2bSet("-f",NFILE
,fnm
)) {
408 fatal_error(0,"No input files!");
411 /* get the single filename */
412 fnms
[0]=opt2fn("-f",NFILE
,fnm
);
415 nre
=scan_ene_files(fnms
,nfile
,readtime
,×tep
);
416 edit_files(fnms
,nfile
,readtime
,settime
,cont_type
,bSetTime
,bSort
);
433 for(i
=0;i
<nfile
;i
++) {
436 in
=open_enx(fnms
[i
],"r");
437 do_enxnms(in
,&nre
,&enm
);
439 /* write names to the output file */
440 out
=open_enx(opt2fn("-o",NFILE
,fnm
),"w");
441 do_enxnms(out
,&nre
,&enm
);
444 /* start reading from the next file */
445 while((t
<(settime
[i
+1]-GMX_REAL_EPS
)) &&
446 do_enx(in
,&t1
,&step
,&nre
,ee
,&ndr
,dr
)) {
448 tadjust
=settime
[i
]-t1
;
449 if(cont_type
[i
+1]==TIME_LAST
) {
450 settime
[i
+1]=readtime
[i
+1]-readtime
[i
]+settime
[i
];
451 cont_type
[i
+1]=TIME_EXPLICIT
;
457 if((end
>0) && (t
>(end
+GMX_REAL_EPS
))) {
462 if(t
>=(begin
-GMX_REAL_EPS
)) {
466 copy_ee(ee
,startee
,nre
);
469 update_ee(lastee
,laststep
,startee
,startstep
,ee
,step
,outee
,nre
);
470 outstep
=laststep
+step
-startstep
;
473 /* determine if we should write it */
474 if((t
<(settime
[i
+1]-GMX_REAL_EPS
)) && (t
>=begin
) &&
475 ((delta_t
==0) || (bRmod(t
-toffset
,delta_t
)))) {
479 fprintf(stderr
,"\nContinue writing frames from t=%g, step=%d\n",
482 do_enx(out
,&outt
,&outstep
,&nre
,outee
,&ndr
,dr
);
483 fprintf(stderr
,"\rWriting step %d, time %f ",outstep
,outt
);
486 /* copy statistics to old */
488 update_last_ee(lastee
,laststep
,ee
,step
,nre
);
490 /* remove the last frame from statistics since gromacs2.0 repeats it in the next file */
491 remove_last_eeframe(lastee
,laststep
,ee
,nre
);
492 /* the old part now has (laststep) values, and the new (step+1) */
493 printf("laststep=%d step=%d\n",laststep
,step
);
496 /* set the next time from the last in previous file */
497 if(cont_type
[i
+1]==TIME_CONTINUE
) {
499 /* in this case we have already written the last frame of
500 * previous file, so update begin to avoid doubling it
501 * with the start of the next file
503 begin
=outt
+0.5*timestep
;
504 /* cont_type[i+1]==TIME_EXPLICIT; */
507 if((outt
<end
) && (i
<(nfile
-1)) &&
508 (outt
<(settime
[i
+1]-1.5*timestep
)))
510 "\nWARNING: There might be a gap around t=%g\n",t
);
512 /* move energies to lastee */
515 fprintf(stderr
,"\n");
518 fprintf(stderr
,"No frames written.\n");
520 fprintf(stderr
,"Last frame written was at step %d, time %f\n",outstep
,outt
);