3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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 forxd
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
33 * GROningen Mixture of Alchemy and Childrens' Stories
54 #include "checkpoint.h"
58 /* defines for frame counter output */
59 static int __frame
=NOTSET
;
63 #define INITCOUNT __frame=-1
66 /* frames for read_first/next_x */
67 static t_trxframe
*xframe
=NULL
;
71 int nframes_read(void)
76 static void printcount_(const output_env_t oenv
,const char *l
,real t
)
78 if ((__frame
< 2*SKIP1
|| __frame
% SKIP1
== 0) &&
79 (__frame
< 2*SKIP2
|| __frame
% SKIP2
== 0) &&
80 (__frame
< 2*SKIP3
|| __frame
% SKIP3
== 0))
81 fprintf(stderr
,"\r%-14s %6d time %8.3f ",l
,__frame
,conv_time(oenv
,t
));
84 static void printcount(const output_env_t oenv
,real t
,bool bSkip
)
87 printcount_(oenv
,bSkip
? "Skipping frame" : "Reading frame",t
);
90 static void printlast(const output_env_t oenv
,real t
)
92 printcount_(oenv
,"Last frame",t
);
96 static void printincomp(t_trxframe
*fr
)
98 if (fr
->not_ok
& HEADER_NOT_OK
)
99 fprintf(stderr
,"WARNING: Incomplete header: nr %d time %g\n",
102 fprintf(stderr
,"WARNING: Incomplete frame: nr %d time %g\n",
106 int prec2ndec(real prec
)
109 gmx_fatal(FARGS
,"DEATH HORROR prec (%g) <= 0 in prec2ndec",prec
);
111 return (int)(log(prec
)/log(10.0)+0.5);
114 /* Globals for gromos-87 input */
115 typedef enum { effXYZ
, effXYZBox
, effG87
, effG87Box
, effNR
} eFileFormat
;
116 static eFileFormat eFF
;
118 static double DT
,BOX
[3];
119 static bool bReadBox
;
121 void clear_trxframe(t_trxframe
*fr
,bool bFirst
)
156 void set_trxframe_ePBC(t_trxframe
*fr
,int ePBC
)
158 fr
->bPBC
= (ePBC
== -1);
162 int write_trxframe_indexed(int fnum
,t_trxframe
*fr
,int nind
,atom_id
*ind
,
166 rvec
*xout
=NULL
,*vout
=NULL
,*fout
=NULL
;
175 switch (gmx_fio_getftp(fnum
)) {
181 gmx_fatal(FARGS
,"Need coordinates to write a %s trajectory",
182 ftp2ext(gmx_fio_getftp(fnum
)));
186 switch (gmx_fio_getftp(fnum
)) {
191 for(i
=0; i
<nind
; i
++)
192 copy_rvec(fr
->v
[ind
[i
]],vout
[i
]);
196 for(i
=0; i
<nind
; i
++)
197 copy_rvec(fr
->f
[ind
[i
]],fout
[i
]);
203 for(i
=0; i
<nind
; i
++)
204 copy_rvec(fr
->x
[ind
[i
]],xout
[i
]);
211 switch (gmx_fio_getftp(fnum
)) {
213 write_xtc(fnum
,nind
,fr
->step
,fr
->time
,fr
->box
,xout
,prec
);
217 fwrite_trn(fnum
,nframes_read(),
218 fr
->time
,fr
->step
,fr
->box
,nind
,xout
,vout
,fout
);
225 gmx_fatal(FARGS
,"Can not write a %s file without atom names",
226 ftp2ext(gmx_fio_getftp(fnum
)));
227 sprintf(title
,"frame t= %.3f",fr
->time
);
228 if (gmx_fio_getftp(fnum
) == efGRO
)
229 write_hconf_indexed_p(gmx_fio_getfp(fnum
),title
,fr
->atoms
,nind
,ind
,
231 fr
->x
,fr
->bV
? fr
->v
: NULL
,fr
->box
);
233 write_pdbfile_indexed(gmx_fio_getfp(fnum
),title
,fr
->atoms
,
234 fr
->x
,-1,fr
->box
,0,fr
->step
,nind
,ind
,gc
);
237 write_gms(gmx_fio_getfp(fnum
),nind
,xout
,fr
->box
);
240 write_g96_conf(gmx_fio_getfp(fnum
),fr
,nind
,ind
);
243 gmx_fatal(FARGS
,"Sorry, write_trxframe_indexed can not write %s",
244 ftp2ext(gmx_fio_getftp(fnum
)));
248 switch (gmx_fio_getftp(fnum
)) {
252 if (vout
) sfree(vout
);
253 if (fout
) sfree(fout
);
265 int write_trxframe(int fnum
,t_trxframe
*fr
,gmx_conect gc
)
275 switch (gmx_fio_getftp(fnum
)) {
281 gmx_fatal(FARGS
,"Need coordinates to write a %s trajectory",
282 ftp2ext(gmx_fio_getftp(fnum
)));
286 switch (gmx_fio_getftp(fnum
)) {
288 write_xtc(fnum
,fr
->natoms
,fr
->step
,fr
->time
,fr
->box
,fr
->x
,prec
);
292 fwrite_trn(fnum
,fr
->step
,fr
->time
,fr
->lambda
,fr
->box
,fr
->natoms
,
293 fr
->bX
? fr
->x
:NULL
,fr
->bV
? fr
->v
:NULL
,fr
->bF
? fr
->f
:NULL
);
300 gmx_fatal(FARGS
,"Can not write a %s file without atom names",
301 ftp2ext(gmx_fio_getftp(fnum
)));
302 sprintf(title
,"frame t= %.3f",fr
->time
);
303 if (gmx_fio_getftp(fnum
) == efGRO
)
304 write_hconf_p(gmx_fio_getfp(fnum
),title
,fr
->atoms
,
305 prec2ndec(prec
),fr
->x
,fr
->bV
? fr
->v
: NULL
,fr
->box
);
307 write_pdbfile(gmx_fio_getfp(fnum
),title
,
308 fr
->atoms
,fr
->x
,fr
->bPBC
? fr
->ePBC
: -1,fr
->box
,
312 write_gms(gmx_fio_getfp(fnum
),fr
->natoms
,fr
->x
,fr
->box
);
315 write_g96_conf(gmx_fio_getfp(fnum
),fr
,-1,NULL
);
318 gmx_fatal(FARGS
,"Sorry, write_trxframe can not write %s",
319 ftp2ext(gmx_fio_getftp(fnum
)));
326 int write_trx(int fnum
,int nind
,atom_id
*ind
,t_atoms
*atoms
,
327 int step
,real time
,matrix box
,rvec x
[],rvec
*v
,
332 clear_trxframe(&fr
,TRUE
);
337 fr
.bAtoms
= atoms
!=NULL
;
344 copy_mat(box
,fr
.box
);
346 return write_trxframe_indexed(fnum
,&fr
,nind
,ind
,gc
);
349 void close_trx(int status
)
351 gmx_fio_close(status
);
354 int open_trx(const char *outfile
,const char *filemode
)
356 if (filemode
[0]!='w' && filemode
[0]!='a')
357 gmx_fatal(FARGS
,"Sorry, write_trx can only write");
359 return gmx_fio_open(outfile
,filemode
);
362 static bool gmx_next_frame(int status
,t_trxframe
*fr
)
369 if (fread_trnheader(status
,&sh
,&bOK
)) {
370 fr
->bDouble
=sh
.bDouble
;
371 fr
->natoms
=sh
.natoms
;
377 fr
->lambda
= sh
.lambda
;
378 fr
->bBox
= sh
.box_size
>0;
379 if (fr
->flags
& (TRX_READ_X
| TRX_NEED_X
)) {
381 snew(fr
->x
,sh
.natoms
);
382 fr
->bX
= sh
.x_size
>0;
384 if (fr
->flags
& (TRX_READ_V
| TRX_NEED_V
)) {
386 snew(fr
->v
,sh
.natoms
);
387 fr
->bV
= sh
.v_size
>0;
389 if (fr
->flags
& (TRX_READ_F
| TRX_NEED_F
)) {
391 snew(fr
->f
,sh
.natoms
);
392 fr
->bF
= sh
.f_size
>0;
394 if (fread_htrn(status
,&sh
,fr
->box
,fr
->x
,fr
->v
,fr
->f
))
397 fr
->not_ok
= DATA_NOT_OK
;
400 fr
->not_ok
= HEADER_NOT_OK
;
405 static void choose_ff(FILE *status
)
411 printf(" Select File Format\n");
412 printf("---------------------------\n");
413 printf("1. XYZ File\n");
414 printf("2. XYZ File with Box\n");
415 printf("3. Gromos-87 Ascii Trajectory\n");
416 printf("4. Gromos-87 Ascii Trajectory with Box\n");
419 printf("\nChoice: ");
427 } while ((i
< 0) || (i
>= effNR
));
430 eFF
= (eFileFormat
) i
;
432 for(m
=0; (m
<DIM
); m
++) BOX
[m
]=0;
434 bReadBox
= (eFF
== effG87Box
) || (eFF
== effXYZBox
);
439 if( 5 != fscanf(status
,"%d%lf%lf%lf%lf",&NATOMS
,&BOX
[XX
],&BOX
[YY
],&BOX
[ZZ
],&DT
))
441 gmx_fatal(FARGS
,"Error reading natoms/box in file");
446 printf("GROMOS! OH DEAR...\n\n");
447 printf("Number of atoms ? ");
449 if (1 != scanf("%d",&NATOMS
))
451 gmx_fatal(FARGS
,"Error reading natoms in file");
454 printf("Time between timeframes ? ");
456 if( 1 != scanf("%lf",&DT
))
458 gmx_fatal(FARGS
,"Error reading dt from file");
462 printf("Box X Y Z ? ");
464 if(3 != scanf("%lf%lf%lf",&BOX
[XX
],&BOX
[YY
],&BOX
[ZZ
]))
466 gmx_fatal(FARGS
,"Error reading box in file");
477 printf("Hellow World\n");
481 static bool do_read_xyz(FILE *status
,int natoms
,rvec x
[],matrix box
)
486 for(i
=0; (i
<natoms
); i
++) {
487 for(m
=0; (m
<DIM
); m
++) {
488 if (fscanf(status
,"%lf",&x0
) != 1) {
490 fprintf(stderr
,"error reading statusfile: x[%d][%d]\n",i
,m
);
498 for(m
=0; (m
<DIM
); m
++) {
499 if (fscanf(status
,"%lf",&x0
) != 1)
507 static bool xyz_next_x(FILE *status
, const output_env_t oenv
,
508 real
*t
, int natoms
, rvec x
[], matrix box
)
509 /* Reads until a new x can be found (return TRUE)
510 * or eof (return FALSE)
516 while (!bTimeSet(TBEGIN
) || (*t
< rTimeValue(TBEGIN
))) {
517 if (!do_read_xyz(status
,natoms
,x
,box
))
519 printcount(oenv
,*t
,FALSE
);
523 if (!bTimeSet(TEND
) || (*t
<= rTimeValue(TEND
))) {
524 if (!do_read_xyz(status
,natoms
,x
,box
)) {
528 printcount(oenv
,*t
,FALSE
);
537 static int xyz_first_x(FILE *status
, const output_env_t oenv
,
538 real
*t
, rvec
**x
, matrix box
)
539 /* Reads status, mallocs x, and returns x and box
540 * Returns natoms when succesful, FALSE otherwise
550 for(m
=0; (m
<DIM
); m
++)
555 if (!xyz_next_x(status
,oenv
,t
,NATOMS
,*x
,box
))
562 static bool pdb_next_x(FILE *status
,t_trxframe
*fr
)
566 int ePBC
,model_nr
,na
;
567 char title
[STRLEN
],*time
;
570 atoms
.nr
= fr
->natoms
;
573 /* the other pointers in atoms should not be accessed if these are NULL */
575 na
=read_pdbfile(status
,title
,&model_nr
,&atoms
,fr
->x
,&ePBC
,boxpdb
,TRUE
,NULL
);
576 set_trxframe_ePBC(fr
,ePBC
);
577 if (nframes_read()==0)
578 fprintf(stderr
," '%s', %d atoms\n",title
, fr
->natoms
);
582 fr
->bBox
= (boxpdb
[XX
][XX
] != 0.0);
584 copy_mat(boxpdb
,fr
->box
);
587 if (model_nr
!=NOTSET
) {
591 time
=strstr(title
," t= ");
594 sscanf(time
+4,"%lf",&dbl
);
598 /* this is a bit dirty, but it will work: if no time is read from
599 comment line in pdb file, set time to current frame number */
601 fr
->time
=(real
)fr
->step
;
603 fr
->time
=(real
)nframes_read();
608 if (na
!= fr
->natoms
)
609 gmx_fatal(FARGS
,"Number of atoms in pdb frame %d is %d instead of %d",
610 nframes_read(),na
,fr
->natoms
);
615 static int pdb_first_x(FILE *status
, t_trxframe
*fr
)
619 fprintf(stderr
,"Reading frames from pdb file");
621 get_pdb_coordnum(status
, &fr
->natoms
);
623 gmx_fatal(FARGS
,"\nNo coordinates in pdb file\n");
625 snew(fr
->x
,fr
->natoms
);
626 pdb_next_x(status
, fr
);
631 bool read_next_frame(const output_env_t oenv
,int status
,t_trxframe
*fr
)
635 bool bOK
,bRet
,bMissingData
=FALSE
,bSkip
=FALSE
;
641 clear_trxframe(fr
,FALSE
);
645 switch (gmx_fio_getftp(status
)) {
648 bRet
= gmx_next_frame(status
,fr
);
651 /* Checkpoint files can not contain mulitple frames */
654 read_g96_conf(gmx_fio_getfp(status
),NULL
,fr
);
655 bRet
= (fr
->natoms
> 0);
658 bRet
= xyz_next_x(gmx_fio_getfp(status
),oenv
,&fr
->time
,fr
->natoms
,
666 * Sometimes is off by one frame
667 * and sometimes reports frame not present/file not seekable
669 /* DvdS 2005-05-31: this has been fixed along with the increased
670 * accuracy of the control over -b and -e options.
672 if (bTimeSet(TBEGIN
) && (fr
->time
< rTimeValue(TBEGIN
))) {
673 if (xtc_seek_time(rTimeValue(TBEGIN
),status
,fr
->natoms
)) {
674 gmx_fatal(FARGS
,"Specified frame doesn't exist or file not seekable");
678 bRet
= read_next_xtc(status
,fr
->natoms
,&fr
->step
,&fr
->time
,fr
->box
,
679 fr
->x
,&fr
->prec
,&bOK
);
680 fr
->bPrec
= (bRet
&& fr
->prec
> 0);
686 /* Actually the header could also be not ok,
687 but from bOK from read_next_xtc this can't be distinguished */
688 fr
->not_ok
= DATA_NOT_OK
;
692 bRet
= pdb_next_x(gmx_fio_getfp(status
),fr
);
695 bRet
= gro_next_x_or_v(gmx_fio_getfp(status
),fr
);
698 gmx_fatal(FARGS
,"DEATH HORROR in read_next_frame ftp=%s,status=%d",
699 ftp2ext(gmx_fio_getftp(status
)),status
);
703 bMissingData
= ((fr
->flags
& TRX_NEED_X
&& !fr
->bX
) ||
704 (fr
->flags
& TRX_NEED_V
&& !fr
->bV
) ||
705 (fr
->flags
& TRX_NEED_F
&& !fr
->bF
));
708 ct
=check_times2(fr
->time
,fr
->t0
,fr
->tpf
,fr
->tppf
,fr
->bDouble
);
709 if (ct
== 0 || (fr
->flags
& TRX_DONT_SKIP
&& ct
<0)) {
710 printcount(oenv
,fr
->time
,FALSE
);
714 printcount(oenv
,fr
->time
,TRUE
);
720 } while (bRet
&& (bMissingData
|| bSkip
));
731 int read_first_frame(const output_env_t oenv
,int *status
,
732 const char *fn
,t_trxframe
*fr
,int flags
)
737 clear_trxframe(fr
,TRUE
);
743 fp
= *status
=gmx_fio_open(fn
,"r");
744 switch (gmx_fio_getftp(fp
))
750 read_checkpoint_trxframe(fp
,fr
);
754 /* Can not rewind a compressed file, so open it twice */
755 read_g96_conf(gmx_fio_getfp(fp
),fn
,fr
);
757 clear_trxframe(fr
,FALSE
);
758 if (flags
& (TRX_READ_X
| TRX_NEED_X
))
759 snew(fr
->x
,fr
->natoms
);
760 if (flags
& (TRX_READ_V
| TRX_NEED_V
))
761 snew(fr
->v
,fr
->natoms
);
762 fp
= *status
=gmx_fio_open(fn
,"r");
765 fr
->natoms
=xyz_first_x(gmx_fio_getfp(fp
),oenv
,&fr
->time
,&fr
->x
,fr
->box
);
770 printcount(oenv
,fr
->time
,FALSE
);
775 if (read_first_xtc(fp
,&fr
->natoms
,&fr
->step
,&fr
->time
,fr
->box
,&fr
->x
,
776 &fr
->prec
,&bOK
) == 0) {
778 gmx_fatal(FARGS
,"No XTC!\n");
780 fr
->not_ok
= DATA_NOT_OK
;
787 fr
->bPrec
= (fr
->prec
> 0);
792 printcount(oenv
,fr
->time
,FALSE
);
797 pdb_first_x(gmx_fio_getfp(fp
),fr
);
799 printcount(oenv
,fr
->time
,FALSE
);
803 if (gro_first_x_or_v(gmx_fio_getfp(fp
),fr
))
804 printcount(oenv
,fr
->time
,FALSE
);
808 gmx_fatal(FARGS
,"Not supported in read_first_frame: %s",fn
);
813 (!(fr
->flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) < 0))
814 /* Read a frame when no frame was read or the first was skipped */
815 if (!read_next_frame(oenv
,*status
,fr
))
819 return (fr
->natoms
> 0);
822 /***** C O O R D I N A T E S T U F F *****/
824 int read_first_x(const output_env_t oenv
,int *status
,const char *fn
,
825 real
*t
,rvec
**x
,matrix box
)
829 read_first_frame(oenv
,status
,fn
,&fr
,TRX_NEED_X
);
830 if (*status
>= nxframe
) {
832 srenew(xframe
,nxframe
);
834 xframe
[*status
] = fr
;
835 *t
= xframe
[*status
].time
;
836 *x
= xframe
[*status
].x
;
837 copy_mat(xframe
[*status
].box
,box
);
839 return xframe
[*status
].natoms
;
842 bool read_next_x(const output_env_t oenv
, int status
,real
*t
, int natoms
,
843 rvec x
[], matrix box
)
847 xframe
[status
].x
= x
;
848 bRet
= read_next_frame(oenv
,status
,&xframe
[status
]);
849 *t
= xframe
[status
].time
;
850 copy_mat(xframe
[status
].box
,box
);
855 void close_trj(int status
)
857 gmx_fio_close(status
);
860 void rewind_trj(int status
)
864 gmx_fio_rewind(status
);
867 /***** V E L O C I T Y S T U F F *****/
869 static void clear_v(t_trxframe
*fr
)
874 for(i
=0; i
<fr
->natoms
; i
++)
875 clear_rvec(fr
->v
[i
]);
878 int read_first_v(const output_env_t oenv
, int *status
,const char *fn
,real
*t
,
883 read_first_frame(oenv
,status
,fn
,&fr
,TRX_NEED_V
);
887 copy_mat(fr
.box
,box
);
892 bool read_next_v(const output_env_t oenv
,int status
,real
*t
,int natoms
,rvec v
[],
898 clear_trxframe(&fr
,TRUE
);
899 fr
.flags
= TRX_NEED_V
;
903 bRet
= read_next_frame(oenv
,status
,&fr
);
906 copy_mat(fr
.box
,box
);