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
,gmx_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 gmx_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 gmx_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 gmx_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 gmx_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 gmx_bool
read_next_frame(const output_env_t oenv
,t_trxstatus
*status
,t_trxframe
*fr
)
673 gmx_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 */
694 "Reading trajectories in .g96 format is broken. Please use\n"
695 "a different file format.");
696 read_g96_conf(gmx_fio_getfp(status
->fio
),NULL
,fr
);
697 bRet
= (fr
->natoms
> 0);
700 bRet
= xyz_next_x(status
, gmx_fio_getfp(status
->fio
),oenv
,&fr
->time
,
701 fr
->natoms
, fr
->x
,fr
->box
);
708 * Sometimes is off by one frame
709 * and sometimes reports frame not present/file not seekable
711 /* DvdS 2005-05-31: this has been fixed along with the increased
712 * accuracy of the control over -b and -e options.
714 if (bTimeSet(TBEGIN
) && (fr
->time
< rTimeValue(TBEGIN
))) {
715 if (xtc_seek_time(status
->fio
, rTimeValue(TBEGIN
),fr
->natoms
)) {
716 gmx_fatal(FARGS
,"Specified frame doesn't exist or file not seekable");
720 bRet
= read_next_xtc(status
->fio
,fr
->natoms
,&fr
->step
,&fr
->time
,fr
->box
,
721 fr
->x
,&fr
->prec
,&bOK
);
722 fr
->bPrec
= (bRet
&& fr
->prec
> 0);
728 /* Actually the header could also be not ok,
729 but from bOK from read_next_xtc this can't be distinguished */
730 fr
->not_ok
= DATA_NOT_OK
;
734 bRet
= pdb_next_x(status
, gmx_fio_getfp(status
->fio
),fr
);
737 bRet
= gro_next_x_or_v(gmx_fio_getfp(status
->fio
),fr
);
741 bRet
= read_next_vmd_frame(dummy
,fr
);
743 gmx_fatal(FARGS
,"DEATH HORROR in read_next_frame ftp=%s,status=%s",
744 ftp2ext(gmx_fio_getftp(status
->fio
)),
745 gmx_fio_getname(status
->fio
));
750 bMissingData
= ((fr
->flags
& TRX_NEED_X
&& !fr
->bX
) ||
751 (fr
->flags
& TRX_NEED_V
&& !fr
->bV
) ||
752 (fr
->flags
& TRX_NEED_F
&& !fr
->bF
));
755 ct
=check_times2(fr
->time
,fr
->t0
,fr
->tpf
,fr
->tppf
,fr
->bDouble
);
756 if (ct
== 0 || (fr
->flags
& TRX_DONT_SKIP
&& ct
<0)) {
757 printcount(status
, oenv
,fr
->time
,FALSE
);
761 printcount(status
, oenv
,fr
->time
,TRUE
);
767 } while (bRet
&& (bMissingData
|| bSkip
));
770 printlast(status
, oenv
,pt
);
772 printincomp(status
, fr
);
778 int read_first_frame(const output_env_t oenv
,t_trxstatus
**status
,
779 const char *fn
,t_trxframe
*fr
,int flags
)
785 clear_trxframe(fr
,TRUE
);
792 status_init( *status
);
793 (*status
)->nxframe
=1;
796 fio
= (*status
)->fio
=gmx_fio_open(fn
,"r");
797 switch (gmx_fio_getftp(fio
))
803 read_checkpoint_trxframe(fio
,fr
);
807 /* Can not rewind a compressed file, so open it twice */
808 read_g96_conf(gmx_fio_getfp(fio
),fn
,fr
);
810 clear_trxframe(fr
,FALSE
);
811 if (flags
& (TRX_READ_X
| TRX_NEED_X
))
812 snew(fr
->x
,fr
->natoms
);
813 if (flags
& (TRX_READ_V
| TRX_NEED_V
))
814 snew(fr
->v
,fr
->natoms
);
815 fio
= (*status
)->fio
=gmx_fio_open(fn
,"r");
818 fr
->natoms
=xyz_first_x(*status
, gmx_fio_getfp(fio
),oenv
,&fr
->time
,
824 printcount(*status
,oenv
,fr
->time
,FALSE
);
829 if (read_first_xtc(fio
,&fr
->natoms
,&fr
->step
,&fr
->time
,fr
->box
,&fr
->x
,
830 &fr
->prec
,&bOK
) == 0) {
832 gmx_fatal(FARGS
,"No XTC!\n");
834 fr
->not_ok
= DATA_NOT_OK
;
839 printincomp(*status
,fr
);
841 fr
->bPrec
= (fr
->prec
> 0);
846 printcount(*status
,oenv
,fr
->time
,FALSE
);
851 pdb_first_x(*status
, gmx_fio_getfp(fio
),fr
);
853 printcount(*status
,oenv
,fr
->time
,FALSE
);
857 if (gro_first_x_or_v(gmx_fio_getfp(fio
),fr
))
858 printcount(*status
,oenv
,fr
->time
,FALSE
);
863 fprintf(stderr
,"The file format of %s is not a known trajectory format to GROMACS.\n"
864 "Please make sure that the file is a trajectory!\n"
865 "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n"
866 "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n",fn
);
867 gmx_fio_fp_close(fio
); /*only close the file without removing FIO entry*/
868 if (!read_first_vmd_frame(&dummy
,fn
,fr
,flags
))
870 gmx_fatal(FARGS
,"Not supported in read_first_frame: %s",fn
);
873 gmx_fatal(FARGS
,"Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n"
874 "GROMACS is not compiled with DLOPEN. Thus it cannot read non-GROMACS trajectory formats.\n"
875 "Please compile with DLOPEN support if you want to read non-GROMACS trajectory formats.\n",fn
);
880 /* Return FALSE if we read a frame that's past the set ending time. */
881 if (!bFirst
&& (!(fr
->flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) > 0)) {
887 (!(fr
->flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) < 0))
888 /* Read a frame when no frame was read or the first was skipped */
889 if (!read_next_frame(oenv
,*status
,fr
))
893 return (fr
->natoms
> 0);
896 /***** C O O R D I N A T E S T U F F *****/
898 int read_first_x(const output_env_t oenv
,t_trxstatus
**status
,const char *fn
,
899 real
*t
,rvec
**x
,matrix box
)
903 read_first_frame(oenv
,status
,fn
,&fr
,TRX_NEED_X
);
905 snew((*status
)->xframe
, 1);
906 (*status
)->nxframe
=1;
907 (*(*status
)->xframe
) = fr
;
908 *t
= (*status
)->xframe
->time
;
909 *x
= (*status
)->xframe
->x
;
910 copy_mat((*status
)->xframe
->box
,box
);
912 return (*status
)->xframe
->natoms
;
915 gmx_bool
read_next_x(const output_env_t oenv
, t_trxstatus
*status
,real
*t
,
916 int natoms
, rvec x
[], matrix box
)
920 status
->xframe
->x
= x
;
921 /*xframe[status].x = x;*/
922 bRet
= read_next_frame(oenv
,status
,status
->xframe
);
923 *t
= status
->xframe
->time
;
924 copy_mat(status
->xframe
->box
,box
);
929 void close_trj(t_trxstatus
*status
)
931 gmx_fio_close(status
->fio
);
932 /* The memory in status->xframe is lost here,
933 * but the read_first_x/read_next_x functions are deprecated anyhow.
934 * read_first_frame/read_next_frame and close_trx should be used.
939 void rewind_trj(t_trxstatus
*status
)
943 gmx_fio_rewind(status
->fio
);
946 /***** V E L O C I T Y S T U F F *****/
948 static void clear_v(t_trxframe
*fr
)
953 for(i
=0; i
<fr
->natoms
; i
++)
954 clear_rvec(fr
->v
[i
]);
957 int read_first_v(const output_env_t oenv
, t_trxstatus
**status
,const char *fn
,
958 real
*t
, rvec
**v
,matrix box
)
962 read_first_frame(oenv
,status
,fn
,&fr
,TRX_NEED_V
);
966 copy_mat(fr
.box
,box
);
971 gmx_bool
read_next_v(const output_env_t oenv
,t_trxstatus
*status
,real
*t
,
972 int natoms
,rvec v
[], matrix box
)
977 clear_trxframe(&fr
,TRUE
);
978 fr
.flags
= TRX_NEED_V
;
982 bRet
= read_next_frame(oenv
,status
,&fr
);
985 copy_mat(fr
.box
,box
);