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 * Great Red Oystrich Makes All Chemists Sane
29 static char *SRCID_trjcat_c
= "$Id$";
57 #define TIME_EXPLICIT 0
58 #define TIME_CONTINUE 1
64 static void scan_trj_files(char **fnms
,int nfiles
,real
*readtime
, real
*timestep
)
66 /* Check start time of all files */
67 int i
,status
,oldnatoms
=0,natoms
,step
;
73 for(i
=0;i
<nfiles
;i
++) {
74 natoms
=read_first_x(&status
,fnms
[i
],&t
,&x
,box
);
77 read_next_x(status
,&t2
,natoms
,x
, box
);
83 fatal_error(0,"Different number of atoms in files");
92 static void sort_files(char **fnms
,real
*settime
,int nfile
)
98 for(i
=0;i
<nfile
;i
++) {
100 for(j
=i
+1;j
<nfile
;j
++) {
101 if(settime
[j
]<settime
[minidx
])
106 settime
[i
]=settime
[minidx
];
107 settime
[minidx
]=timeswap
;
109 fnms
[i
]=fnms
[minidx
];
116 static void edit_files(char **fnms
,int nfiles
,real
*readtime
, real
117 *settime
, int *cont_type
, bool bSetTime
,bool bSort
)
121 char inputstring
[STRLEN
],*chptr
;
124 fprintf(stderr
,"\n\nEnter the new start time for each file.\n"
125 "There are two special options, both disable sorting:\n\n"
126 "c (continue) - The start time is taken from the end\n"
127 "of the previous file. Use it when your continuation run\n"
128 "restarts with t=0.\n\n"
129 "l (last) - The time in this file will be changed the\n"
130 "same amount as in the previous. Use it when the time in the\n"
131 "new run continues from the end of the previous one,\n"
132 "since this takes possible overlap into account.\n\n");
134 fprintf(stderr
," File Current start New start\n"
135 "---------------------------------------------------------\n");
137 for(i
=0;i
<nfiles
;i
++) {
138 fprintf(stderr
,"%25s %10.3f ",fnms
[i
],readtime
[i
]);
141 fgets(inputstring
,STRLEN
-1,stdin
);
142 inputstring
[strlen(inputstring
)-1]=0;
144 if(inputstring
[0]=='c' || inputstring
[0]=='C') {
145 cont_type
[i
]=TIME_CONTINUE
;
150 else if(inputstring
[0]=='l' ||
151 inputstring
[0]=='L') {
152 cont_type
[i
]=TIME_LAST
;
158 settime
[i
]=strtod(inputstring
,&chptr
);
159 if(chptr
==inputstring
) {
160 fprintf(stderr
,"'%s' not recognized as a floating point number, 'c' or 'l'. "
161 "Try again: ",inputstring
);
164 cont_type
[i
]=TIME_EXPLICIT
;
170 if(cont_type
[0]!=TIME_EXPLICIT
) {
171 cont_type
[0]=TIME_EXPLICIT
;
176 for(i
=0;i
<nfiles
;i
++)
177 settime
[i
]=readtime
[i
];
180 fprintf(stderr
,"Sorting disabled.\n");
182 sort_files(fnms
,settime
,nfiles
);
185 /* Write out the new order and start times */
186 fprintf(stderr
,"\nSummary of files and start times used:\n\n"
188 "-----------------------------------------\n");
189 for(i
=0;i
<nfiles
;i
++)
190 switch(cont_type
[i
]) {
192 fprintf(stderr
,"%25s %10.3f\n",fnms
[i
],settime
[i
]);
195 fprintf(stderr
,"%25s Continue from last file\n",fnms
[i
]);
198 fprintf(stderr
,"%25s Change by same amount as last file\n",fnms
[i
]);
201 fprintf(stderr
,"\n");
203 settime
[nfiles
]=FLT_MAX
;
204 cont_type
[nfiles
]=TIME_EXPLICIT
;
205 readtime
[nfiles
]=FLT_MAX
;
209 bool bRmod(double a
,double b
)
214 iq
= ((1.0+tol
)*a
)/b
;
216 if (fabs(a
-b
*iq
) <= tol
*a
)
222 int main(int argc
,char *argv
[])
224 static char *desc
[] = {
225 "trjcat concatenates several input trajectory files in sorted order. ",
226 "In case of double time frames the one in the later file is used. ",
227 "By specifying [TT]-settime[tt] you will be asked for the start time ",
228 "of each file. The input files are taken from the command line, ",
229 "such that a command like [TT]trjconv -o fixed.trr *.trr[tt] should do ",
232 static bool bVels
=TRUE
;
234 static bool bSort
=TRUE
;
235 static bool bSetTime
=FALSE
;
236 static real begin
=-1;
240 { "-b", FALSE
, etREAL
, {&begin
},
241 "First time to use"},
242 { "-e", FALSE
, etREAL
, {&end
},
244 { "-prec", FALSE
, etINT
, {&prec
},
245 "Precision for .xtc and .gro writing in number of decimal places" },
246 { "-vel", FALSE
, etBOOL
, {&bVels
},
247 "Read and write velocities if possible" },
248 { "-settime", FALSE
, etBOOL
, {&bSetTime
},
249 "Change starting time interactively" },
250 { "-sort", FALSE
, etBOOL
, {&bSort
},
251 "Sort trajectory files (not frames)"}
255 int status
,ftp
,ftpin
,i
,frame
,natoms
=0,step
,trjout
=0;
257 real xtcpr
,t
,t0
=-1,t1
;
261 bool bNewFile
,bHaveX
=FALSE
,bHaveV
=FALSE
;
262 char *in_file
,*out_file
;
263 int xdr
=0,earliersteps
,nfile
,*cont_type
,last_ok_step
;
264 real
*readtime
,*settime
,tstart
,last_ok_t
=-1,timestep
;
267 { efTRX
, "-o", "trajout", ffWRITE
}
270 #define NFILE asize(fnm)
272 CopyRight(stderr
,argv
[0]);
273 parse_common_args(&argc
,argv
,PCA_NOEXIT_ON_ARGS
,TRUE
,
274 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,
277 /* prec is in nr of decimal places, xtcprec is a multiplication factor: */
279 for (i
=0; i
<prec
; i
++)
285 for(i
=1; (i
<argc
); i
++)
286 fnms
[nfile
++]=argv
[i
];
289 fatal_error(0,"No input files!");
291 snew(settime
,nfile
+1);
292 snew(readtime
,nfile
+1);
293 snew(cont_type
,nfile
+1);
295 scan_trj_files(fnms
,nfile
,readtime
,×tep
);
296 edit_files(fnms
,nfile
,readtime
,settime
,cont_type
,bSetTime
,bSort
);
300 out_file
=opt2fn("-o",NFILE
,fnm
);
301 ftp
=fn2ftp(out_file
);
303 bVels
= ((ftp
==efTRR
) ||(ftp
==efTRJ
) || (ftp
==efGRO
));
304 /* Not checking input format, could be dangerous :-) */
313 /* Lets stitch up some files */
314 for(i
=0;i
<nfile
;i
++) {
317 natoms
=read_first_x_or_v(&status
,fnms
[i
],&tstart
,&x
,&v
,box
);
319 natoms
=read_first_x(&status
,fnms
[i
],&tstart
,&x
,box
);
320 if(cont_type
[i
]==TIME_EXPLICIT
)
321 t0
=settime
[i
]-tstart
;
328 xdr
= open_xtc(out_file
,"w");
331 out
=ffopen(out_file
,"w");
336 trjout
= open_tpx(out_file
,"w");
341 out
=ffopen(out_file
,"w");
347 /* set the new time */
349 if((end
>0) && (t
>(end
+GMX_REAL_EPS
))) {
353 /* determine if we should write it */
354 if((t
<(settime
[i
+1]-0.5*timestep
)) && (t
>=begin
)) {
358 fprintf(stderr
,"\nContinue writing frames from t=%g, frame=%d \n",t
,frame
);
365 fwrite_trn(trjout
,frame
,t
,0,box
,
369 write_xtc(xdr
,natoms
,frame
,t
,box
,x
,xtcpr
);
372 fatal_error(0,"DHE, ftp=%d\n",ftp
);
375 if ( ((frame
% 10) == 0) || (frame
< 10) )
376 fprintf(stderr
," -> frame %6d time %8.3f \r",frame
,t
);
378 } while((t
<settime
[i
+1]) &&
379 ((bVels
&& read_next_x_or_v(status
,&t1
,natoms
,x
,v
,box
)) ||
380 (read_next_x(status
,&t1
,natoms
,x
, box
))));
386 /* set the next time from the last in previous file */
387 if(cont_type
[i
+1]==TIME_CONTINUE
) {
388 begin
=t
+0.5*timestep
;
390 cont_type
[i
+1]=TIME_EXPLICIT
;
392 else if(cont_type
[i
+1]==TIME_LAST
)
393 begin
=t
+0.5*timestep
;
395 if(cont_type
[i
+1]==TIME_EXPLICIT
)
397 (t
<(settime
[i
+1]-1.5*timestep
)))
399 "WARNING: Frames around t=%f have a different spacing than the rest,\n"
400 "might be a gap or overlap that couldn't be corrected automatically.\n",t
);
405 else if (out
!= NULL
)
407 fprintf(stderr
,"\nLast frame written was %d, time %f\n",frame
,last_ok_t
);