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"
59 /* defines for frame counter output */
64 /* Globals for gromos-87 input */
65 typedef enum { effXYZ
, effXYZBox
, effG87
, effG87Box
, effNR
} eFileFormat
;
79 static void initcount(t_trxstatus
*status
)
84 static void status_init(t_trxstatus
*status
)
93 int nframes_read(t_trxstatus
*status
)
95 return status
->__frame
;
98 static void printcount_(t_trxstatus
*status
, const output_env_t oenv
,
101 if ((status
->__frame
< 2*SKIP1
|| status
->__frame
% SKIP1
== 0) &&
102 (status
->__frame
< 2*SKIP2
|| status
->__frame
% SKIP2
== 0) &&
103 (status
->__frame
< 2*SKIP3
|| status
->__frame
% SKIP3
== 0))
104 fprintf(stderr
,"\r%-14s %6d time %8.3f ",l
,status
->__frame
,
105 output_env_conv_time(oenv
,t
));
108 static void printcount(t_trxstatus
*status
, const output_env_t oenv
,real t
,
112 printcount_(status
, oenv
,bSkip
? "Skipping frame" : "Reading frame",t
);
115 static void printlast(t_trxstatus
*status
, const output_env_t oenv
,real t
)
117 printcount_(status
, oenv
,"Last frame",t
);
118 fprintf(stderr
,"\n");
121 static void printincomp(t_trxstatus
*status
, t_trxframe
*fr
)
123 if (fr
->not_ok
& HEADER_NOT_OK
)
124 fprintf(stderr
,"WARNING: Incomplete header: nr %d time %g\n",
125 status
->__frame
+1,fr
->time
);
127 fprintf(stderr
,"WARNING: Incomplete frame: nr %d time %g\n",
128 status
->__frame
+1,fr
->time
);
131 int prec2ndec(real prec
)
134 gmx_fatal(FARGS
,"DEATH HORROR prec (%g) <= 0 in prec2ndec",prec
);
136 return (int)(log(prec
)/log(10.0)+0.5);
140 t_fileio
*trx_get_fileio(t_trxstatus
*status
)
147 void clear_trxframe(t_trxframe
*fr
,bool bFirst
)
182 void set_trxframe_ePBC(t_trxframe
*fr
,int ePBC
)
184 fr
->bPBC
= (ePBC
== -1);
188 int write_trxframe_indexed(t_trxstatus
*status
,t_trxframe
*fr
,int nind
,
189 atom_id
*ind
, gmx_conect gc
)
192 rvec
*xout
=NULL
,*vout
=NULL
,*fout
=NULL
;
201 switch (gmx_fio_getftp(status
->fio
)) {
207 gmx_fatal(FARGS
,"Need coordinates to write a %s trajectory",
208 ftp2ext(gmx_fio_getftp(status
->fio
)));
212 switch (gmx_fio_getftp(status
->fio
)) {
217 for(i
=0; i
<nind
; i
++)
218 copy_rvec(fr
->v
[ind
[i
]],vout
[i
]);
222 for(i
=0; i
<nind
; i
++)
223 copy_rvec(fr
->f
[ind
[i
]],fout
[i
]);
229 for(i
=0; i
<nind
; i
++)
230 copy_rvec(fr
->x
[ind
[i
]],xout
[i
]);
237 switch (gmx_fio_getftp(status
->fio
)) {
239 write_xtc(status
->fio
,nind
,fr
->step
,fr
->time
,fr
->box
,xout
,prec
);
243 fwrite_trn(status
->fio
,nframes_read(status
),
244 fr
->time
,fr
->step
,fr
->box
,nind
,xout
,vout
,fout
);
251 gmx_fatal(FARGS
,"Can not write a %s file without atom names",
252 ftp2ext(gmx_fio_getftp(status
->fio
)));
253 sprintf(title
,"frame t= %.3f",fr
->time
);
254 if (gmx_fio_getftp(status
->fio
) == efGRO
)
255 write_hconf_indexed_p(gmx_fio_getfp(status
->fio
),title
,fr
->atoms
,nind
,ind
,
257 fr
->x
,fr
->bV
? fr
->v
: NULL
,fr
->box
);
259 write_pdbfile_indexed(gmx_fio_getfp(status
->fio
),title
,fr
->atoms
,
260 fr
->x
,-1,fr
->box
,' ',fr
->step
,nind
,ind
,gc
,TRUE
);
263 write_gms(gmx_fio_getfp(status
->fio
),nind
,xout
,fr
->box
);
266 write_g96_conf(gmx_fio_getfp(status
->fio
),fr
,nind
,ind
);
269 gmx_fatal(FARGS
,"Sorry, write_trxframe_indexed can not write %s",
270 ftp2ext(gmx_fio_getftp(status
->fio
)));
274 switch (gmx_fio_getftp(status
->fio
)) {
278 if (vout
) sfree(vout
);
279 if (fout
) sfree(fout
);
291 int write_trxframe(t_trxstatus
*status
,t_trxframe
*fr
,gmx_conect gc
)
301 switch (gmx_fio_getftp(status
->fio
)) {
307 gmx_fatal(FARGS
,"Need coordinates to write a %s trajectory",
308 ftp2ext(gmx_fio_getftp(status
->fio
)));
312 switch (gmx_fio_getftp(status
->fio
)) {
314 write_xtc(status
->fio
,fr
->natoms
,fr
->step
,fr
->time
,fr
->box
,fr
->x
,prec
);
318 fwrite_trn(status
->fio
,fr
->step
,fr
->time
,fr
->lambda
,fr
->box
,fr
->natoms
,
319 fr
->bX
? fr
->x
:NULL
,fr
->bV
? fr
->v
:NULL
,fr
->bF
? fr
->f
:NULL
);
326 gmx_fatal(FARGS
,"Can not write a %s file without atom names",
327 ftp2ext(gmx_fio_getftp(status
->fio
)));
328 sprintf(title
,"frame t= %.3f",fr
->time
);
329 if (gmx_fio_getftp(status
->fio
) == efGRO
)
330 write_hconf_p(gmx_fio_getfp(status
->fio
),title
,fr
->atoms
,
331 prec2ndec(prec
),fr
->x
,fr
->bV
? fr
->v
: NULL
,fr
->box
);
333 write_pdbfile(gmx_fio_getfp(status
->fio
),title
,
334 fr
->atoms
,fr
->x
,fr
->bPBC
? fr
->ePBC
: -1,fr
->box
,
335 ' ',fr
->step
,gc
,TRUE
);
338 write_gms(gmx_fio_getfp(status
->fio
),fr
->natoms
,fr
->x
,fr
->box
);
341 write_g96_conf(gmx_fio_getfp(status
->fio
),fr
,-1,NULL
);
344 gmx_fatal(FARGS
,"Sorry, write_trxframe can not write %s",
345 ftp2ext(gmx_fio_getftp(status
->fio
)));
352 int write_trx(t_trxstatus
*status
,int nind
,atom_id
*ind
,t_atoms
*atoms
,
353 int step
,real time
,matrix box
,rvec x
[],rvec
*v
,
358 clear_trxframe(&fr
,TRUE
);
363 fr
.bAtoms
= atoms
!=NULL
;
370 copy_mat(box
,fr
.box
);
372 return write_trxframe_indexed(status
,&fr
,nind
,ind
,gc
);
375 void close_trx(t_trxstatus
*status
)
377 gmx_fio_close(status
->fio
);
381 t_trxstatus
*open_trx(const char *outfile
,const char *filemode
)
384 if (filemode
[0]!='w' && filemode
[0]!='a' && filemode
[1]!='+')
385 gmx_fatal(FARGS
,"Sorry, write_trx can only write");
390 stat
->fio
=gmx_fio_open(outfile
,filemode
);
394 static bool gmx_next_frame(t_trxstatus
*status
,t_trxframe
*fr
)
401 if (fread_trnheader(status
->fio
,&sh
,&bOK
)) {
402 fr
->bDouble
=sh
.bDouble
;
403 fr
->natoms
=sh
.natoms
;
409 fr
->lambda
= sh
.lambda
;
410 fr
->bBox
= sh
.box_size
>0;
411 if (fr
->flags
& (TRX_READ_X
| TRX_NEED_X
)) {
413 snew(fr
->x
,sh
.natoms
);
414 fr
->bX
= sh
.x_size
>0;
416 if (fr
->flags
& (TRX_READ_V
| TRX_NEED_V
)) {
418 snew(fr
->v
,sh
.natoms
);
419 fr
->bV
= sh
.v_size
>0;
421 if (fr
->flags
& (TRX_READ_F
| TRX_NEED_F
)) {
423 snew(fr
->f
,sh
.natoms
);
424 fr
->bF
= sh
.f_size
>0;
426 if (fread_htrn(status
->fio
,&sh
,fr
->box
,fr
->x
,fr
->v
,fr
->f
))
429 fr
->not_ok
= DATA_NOT_OK
;
432 fr
->not_ok
= HEADER_NOT_OK
;
437 static void choose_ff(FILE *fp
)
445 printf(" Select File Format\n");
446 printf("---------------------------\n");
447 printf("1. XYZ File\n");
448 printf("2. XYZ File with Box\n");
449 printf("3. Gromos-87 Ascii Trajectory\n");
450 printf("4. Gromos-87 Ascii Trajectory with Box\n");
456 printf("\nChoice: ");
464 } while ((i
< 0) || (i
>= effNR
));
467 stat
->eFF
= (eFileFormat
) i
;
469 for(m
=0; (m
<DIM
); m
++) stat
->BOX
[m
]=0;
471 stat
->bReadBox
= (stat
->eFF
== effG87Box
) || (stat
->eFF
== effXYZBox
);
476 if( 5 != fscanf(fp
,"%d%lf%lf%lf%lf",&stat
->NATOMS
,&stat
->BOX
[XX
],&stat
->BOX
[YY
],&stat
->BOX
[ZZ
],&stat
->DT
))
478 gmx_fatal(FARGS
,"Error reading natoms/box in file");
483 printf("GROMOS! OH DEAR...\n\n");
484 printf("Number of atoms ? ");
486 if (1 != scanf("%d",&stat
->NATOMS
))
488 gmx_fatal(FARGS
,"Error reading natoms in file");
491 printf("Time between timeframes ? ");
493 if( 1 != scanf("%lf",&stat
->DT
))
495 gmx_fatal(FARGS
,"Error reading dt from file");
498 if (stat
->eFF
== effG87
) {
499 printf("Box X Y Z ? ");
501 if(3 != scanf("%lf%lf%lf",&stat
->BOX
[XX
],&stat
->BOX
[YY
],&stat
->BOX
[ZZ
]))
503 gmx_fatal(FARGS
,"Error reading box in file");
514 printf("Hellow World\n");
518 static bool do_read_xyz(t_trxstatus
*status
, FILE *fp
,int natoms
,
524 for(i
=0; (i
<natoms
); i
++) {
525 for(m
=0; (m
<DIM
); m
++) {
526 if (fscanf(fp
,"%lf",&x0
) != 1) {
528 fprintf(stderr
,"error reading statusfile: x[%d][%d]\n",i
,m
);
535 if (status
->bReadBox
) {
536 for(m
=0; (m
<DIM
); m
++) {
537 if (fscanf(fp
,"%lf",&x0
) != 1)
545 static bool xyz_next_x(t_trxstatus
*status
, FILE *fp
, const output_env_t oenv
,
546 real
*t
, int natoms
, rvec x
[], matrix box
)
547 /* Reads until a new x can be found (return TRUE)
548 * or eof (return FALSE)
554 while (!bTimeSet(TBEGIN
) || (*t
< rTimeValue(TBEGIN
))) {
555 if (!do_read_xyz(status
,fp
,natoms
,x
,box
))
557 printcount(status
,oenv
,*t
,FALSE
);
561 if (!bTimeSet(TEND
) || (*t
<= rTimeValue(TEND
))) {
562 if (!do_read_xyz(status
,fp
,natoms
,x
,box
)) {
563 printlast(status
, oenv
,*t
);
566 printcount(status
,oenv
,*t
,FALSE
);
571 printlast(status
,oenv
,pt
);
575 static int xyz_first_x(t_trxstatus
*status
, FILE *fp
, const output_env_t oenv
,
576 real
*t
, rvec
**x
, matrix box
)
577 /* Reads fp, mallocs x, and returns x and box
578 * Returns natoms when successful, FALSE otherwise
588 for(m
=0; (m
<DIM
); m
++)
589 box
[m
][m
]=status
->BOX
[m
];
591 snew(*x
,status
->NATOMS
);
593 if (!xyz_next_x(status
, fp
,oenv
,t
,status
->NATOMS
,*x
,box
))
597 return status
->NATOMS
;
600 static bool pdb_next_x(t_trxstatus
*status
, FILE *fp
,t_trxframe
*fr
)
604 int ePBC
,model_nr
,na
;
605 char title
[STRLEN
],*time
;
608 atoms
.nr
= fr
->natoms
;
611 /* the other pointers in atoms should not be accessed if these are NULL */
613 na
=read_pdbfile(fp
,title
,&model_nr
,&atoms
,fr
->x
,&ePBC
,boxpdb
,TRUE
,NULL
);
614 set_trxframe_ePBC(fr
,ePBC
);
615 if (nframes_read(status
)==0)
616 fprintf(stderr
," '%s', %d atoms\n",title
, fr
->natoms
);
620 fr
->bBox
= (boxpdb
[XX
][XX
] != 0.0);
622 copy_mat(boxpdb
,fr
->box
);
625 if (model_nr
!=NOTSET
) {
629 time
=strstr(title
," t= ");
632 sscanf(time
+4,"%lf",&dbl
);
636 /* this is a bit dirty, but it will work: if no time is read from
637 comment line in pdb file, set time to current frame number */
639 fr
->time
=(real
)fr
->step
;
641 fr
->time
=(real
)nframes_read(status
);
646 if (na
!= fr
->natoms
)
647 gmx_fatal(FARGS
,"Number of atoms in pdb frame %d is %d instead of %d",
648 nframes_read(status
),na
,fr
->natoms
);
653 static int pdb_first_x(t_trxstatus
*status
, FILE *fp
, t_trxframe
*fr
)
657 fprintf(stderr
,"Reading frames from pdb file");
659 get_pdb_coordnum(fp
, &fr
->natoms
);
661 gmx_fatal(FARGS
,"\nNo coordinates in pdb file\n");
663 snew(fr
->x
,fr
->natoms
);
664 pdb_next_x(status
, fp
, fr
);
669 bool read_next_frame(const output_env_t oenv
,t_trxstatus
*status
,t_trxframe
*fr
)
673 bool bOK
,bRet
,bMissingData
=FALSE
,bSkip
=FALSE
;
680 clear_trxframe(fr
,FALSE
);
684 switch (gmx_fio_getftp(status
->fio
)) {
687 bRet
= gmx_next_frame(status
,fr
);
690 /* Checkpoint files can not contain mulitple frames */
693 read_g96_conf(gmx_fio_getfp(status
->fio
),NULL
,fr
);
694 bRet
= (fr
->natoms
> 0);
697 bRet
= xyz_next_x(status
, gmx_fio_getfp(status
->fio
),oenv
,&fr
->time
,
698 fr
->natoms
, fr
->x
,fr
->box
);
705 * Sometimes is off by one frame
706 * and sometimes reports frame not present/file not seekable
708 /* DvdS 2005-05-31: this has been fixed along with the increased
709 * accuracy of the control over -b and -e options.
711 if (bTimeSet(TBEGIN
) && (fr
->time
< rTimeValue(TBEGIN
))) {
712 if (xtc_seek_time(status
->fio
, rTimeValue(TBEGIN
),fr
->natoms
)) {
713 gmx_fatal(FARGS
,"Specified frame doesn't exist or file not seekable");
717 bRet
= read_next_xtc(status
->fio
,fr
->natoms
,&fr
->step
,&fr
->time
,fr
->box
,
718 fr
->x
,&fr
->prec
,&bOK
);
719 fr
->bPrec
= (bRet
&& fr
->prec
> 0);
725 /* Actually the header could also be not ok,
726 but from bOK from read_next_xtc this can't be distinguished */
727 fr
->not_ok
= DATA_NOT_OK
;
731 bRet
= pdb_next_x(status
, gmx_fio_getfp(status
->fio
),fr
);
734 bRet
= gro_next_x_or_v(gmx_fio_getfp(status
->fio
),fr
);
738 bRet
= read_next_vmd_frame(dummy
,fr
);
740 gmx_fatal(FARGS
,"DEATH HORROR in read_next_frame ftp=%s,status=%s",
741 ftp2ext(gmx_fio_getftp(status
->fio
)),
742 gmx_fio_getname(status
->fio
));
747 bMissingData
= ((fr
->flags
& TRX_NEED_X
&& !fr
->bX
) ||
748 (fr
->flags
& TRX_NEED_V
&& !fr
->bV
) ||
749 (fr
->flags
& TRX_NEED_F
&& !fr
->bF
));
752 ct
=check_times2(fr
->time
,fr
->t0
,fr
->tpf
,fr
->tppf
,fr
->bDouble
);
753 if (ct
== 0 || (fr
->flags
& TRX_DONT_SKIP
&& ct
<0)) {
754 printcount(status
, oenv
,fr
->time
,FALSE
);
758 printcount(status
, oenv
,fr
->time
,TRUE
);
764 } while (bRet
&& (bMissingData
|| bSkip
));
767 printlast(status
, oenv
,pt
);
769 printincomp(status
, fr
);
775 int read_first_frame(const output_env_t oenv
,t_trxstatus
**status
,
776 const char *fn
,t_trxframe
*fr
,int flags
)
782 clear_trxframe(fr
,TRUE
);
789 status_init( *status
);
790 (*status
)->nxframe
=1;
793 fio
= (*status
)->fio
=gmx_fio_open(fn
,"r");
794 switch (gmx_fio_getftp(fio
))
800 read_checkpoint_trxframe(fio
,fr
);
804 /* Can not rewind a compressed file, so open it twice */
805 read_g96_conf(gmx_fio_getfp(fio
),fn
,fr
);
807 clear_trxframe(fr
,FALSE
);
808 if (flags
& (TRX_READ_X
| TRX_NEED_X
))
809 snew(fr
->x
,fr
->natoms
);
810 if (flags
& (TRX_READ_V
| TRX_NEED_V
))
811 snew(fr
->v
,fr
->natoms
);
812 fio
= (*status
)->fio
=gmx_fio_open(fn
,"r");
815 fr
->natoms
=xyz_first_x(*status
, gmx_fio_getfp(fio
),oenv
,&fr
->time
,
821 printcount(*status
,oenv
,fr
->time
,FALSE
);
826 if (read_first_xtc(fio
,&fr
->natoms
,&fr
->step
,&fr
->time
,fr
->box
,&fr
->x
,
827 &fr
->prec
,&bOK
) == 0) {
829 gmx_fatal(FARGS
,"No XTC!\n");
831 fr
->not_ok
= DATA_NOT_OK
;
836 printincomp(*status
,fr
);
838 fr
->bPrec
= (fr
->prec
> 0);
843 printcount(*status
,oenv
,fr
->time
,FALSE
);
848 pdb_first_x(*status
, gmx_fio_getfp(fio
),fr
);
850 printcount(*status
,oenv
,fr
->time
,FALSE
);
854 if (gro_first_x_or_v(gmx_fio_getfp(fio
),fr
))
855 printcount(*status
,oenv
,fr
->time
,FALSE
);
860 gmx_fio_fp_close(fio
); /*only close the file without removing FIO entry*/
861 if (!read_first_vmd_frame(&dummy
,fn
,fr
,flags
))
863 gmx_fatal(FARGS
,"Not supported in read_first_frame: %s",fn
);
866 gmx_fatal(FARGS
,"Not supported in read_first_frame: %s",fn
);
871 /* Return FALSE if we read a frame that's past the set ending time. */
872 if (!bFirst
&& (!(fr
->flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) > 0)) {
878 (!(fr
->flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) < 0))
879 /* Read a frame when no frame was read or the first was skipped */
880 if (!read_next_frame(oenv
,*status
,fr
))
884 return (fr
->natoms
> 0);
887 /***** C O O R D I N A T E S T U F F *****/
889 int read_first_x(const output_env_t oenv
,t_trxstatus
**status
,const char *fn
,
890 real
*t
,rvec
**x
,matrix box
)
894 read_first_frame(oenv
,status
,fn
,&fr
,TRX_NEED_X
);
896 snew((*status
)->xframe
, 1);
897 (*status
)->nxframe
=1;
898 (*(*status
)->xframe
) = fr
;
899 *t
= (*status
)->xframe
->time
;
900 *x
= (*status
)->xframe
->x
;
901 copy_mat((*status
)->xframe
->box
,box
);
903 return (*status
)->xframe
->natoms
;
906 bool read_next_x(const output_env_t oenv
, t_trxstatus
*status
,real
*t
,
907 int natoms
, rvec x
[], matrix box
)
911 status
->xframe
->x
= x
;
912 /*xframe[status].x = x;*/
913 bRet
= read_next_frame(oenv
,status
,status
->xframe
);
914 *t
= status
->xframe
->time
;
915 copy_mat(status
->xframe
->box
,box
);
920 void close_trj(t_trxstatus
*status
)
922 gmx_fio_close(status
->fio
);
923 /* The memory in status->xframe is lost here,
924 * but the read_first_x/read_next_x functions are deprecated anyhow.
925 * read_first_frame/read_next_frame and close_trx should be used.
930 void rewind_trj(t_trxstatus
*status
)
934 gmx_fio_rewind(status
->fio
);
937 /***** V E L O C I T Y S T U F F *****/
939 static void clear_v(t_trxframe
*fr
)
944 for(i
=0; i
<fr
->natoms
; i
++)
945 clear_rvec(fr
->v
[i
]);
948 int read_first_v(const output_env_t oenv
, t_trxstatus
**status
,const char *fn
,
949 real
*t
, rvec
**v
,matrix box
)
953 read_first_frame(oenv
,status
,fn
,&fr
,TRX_NEED_V
);
957 copy_mat(fr
.box
,box
);
962 bool read_next_v(const output_env_t oenv
,t_trxstatus
*status
,real
*t
,
963 int natoms
,rvec v
[], matrix box
)
968 clear_trxframe(&fr
,TRUE
);
969 fr
.flags
= TRX_NEED_V
;
973 bRet
= read_next_frame(oenv
,status
,&fr
);
976 copy_mat(fr
.box
,box
);