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]);
230 for(i=0; i<nind; i++)
231 copy_rvec(fr->x[ind[i]],xout[i]);
238 switch (gmx_fio_getftp(status->fio)) {
240 write_xtc(status->fio,nind,fr->step,fr->time,fr->box,xout,prec);
244 fwrite_trn(status->fio,nframes_read(status),
245 fr->time,fr->step,fr->box,nind,xout,vout,fout);
252 gmx_fatal(FARGS,"Can not write a %s file without atom names",
253 ftp2ext(gmx_fio_getftp(status->fio)));
254 sprintf(title,"frame t= %.3f",fr->time);
255 if (gmx_fio_getftp(status->fio) == efGRO)
256 write_hconf_indexed_p(gmx_fio_getfp(status->fio),title,fr->atoms,nind,ind,
258 fr->x,fr->bV ? fr->v : NULL,fr->box);
260 write_pdbfile_indexed(gmx_fio_getfp(status->fio),title,fr->atoms,
261 fr->x,-1,fr->box,' ',fr->step,nind,ind,gc,TRUE);
264 write_gms(gmx_fio_getfp(status->fio),nind,xout,fr->box);
267 write_g96_conf(gmx_fio_getfp(status->fio),fr,nind,ind);
270 gmx_fatal(FARGS,"Sorry, write_trxframe_indexed can not write %s",
271 ftp2ext(gmx_fio_getftp(status->fio)));
275 switch (gmx_fio_getftp(status->fio)) {
279 if (vout) sfree(vout);
280 if (fout) sfree(fout);
293 int write_trxframe(t_trxstatus *status,t_trxframe *fr,gmx_conect gc)
303 switch (gmx_fio_getftp(status->fio)) {
309 gmx_fatal(FARGS,"Need coordinates to write a %s trajectory",
310 ftp2ext(gmx_fio_getftp(status->fio)));
314 switch (gmx_fio_getftp(status->fio)) {
316 write_xtc(status->fio,fr->natoms,fr->step,fr->time,fr->box,fr->x,prec);
320 fwrite_trn(status->fio,fr->step,fr->time,fr->lambda,fr->box,fr->natoms,
321 fr->bX ? fr->x:NULL,fr->bV ? fr->v:NULL ,fr->bF ? fr->f:NULL);
328 gmx_fatal(FARGS,"Can not write a %s file without atom names",
329 ftp2ext(gmx_fio_getftp(status->fio)));
330 sprintf(title,"frame t= %.3f",fr->time);
331 if (gmx_fio_getftp(status->fio) == efGRO)
332 write_hconf_p(gmx_fio_getfp(status->fio),title,fr->atoms,
333 prec2ndec(prec),fr->x,fr->bV ? fr->v : NULL,fr->box);
335 write_pdbfile(gmx_fio_getfp(status->fio),title,
336 fr->atoms,fr->x,fr->bPBC ? fr->ePBC : -1,fr->box,
337 ' ',fr->step,gc,TRUE);
340 write_gms(gmx_fio_getfp(status->fio),fr->natoms,fr->x,fr->box);
343 write_g96_conf(gmx_fio_getfp(status->fio),fr,-1,NULL);
346 gmx_fatal(FARGS,"Sorry, write_trxframe can not write %s",
347 ftp2ext(gmx_fio_getftp(status->fio)));
354 int write_trx(t_trxstatus *status,int nind,atom_id *ind,t_atoms *atoms,
355 int step,real time,matrix box,rvec x[],rvec *v,
360 clear_trxframe(&fr,TRUE);
365 fr.bAtoms = atoms!=NULL;
372 copy_mat(box,fr.box);
374 return write_trxframe_indexed(status,&fr,nind,ind,gc);
377 void close_trx(t_trxstatus *status)
379 gmx_fio_close(status->fio);
383 t_trxstatus *open_trx(const char *outfile,const char *filemode)
386 if (filemode[0]!='w' && filemode[0]!='a' && filemode[1]!='+')
387 gmx_fatal(FARGS,"Sorry, write_trx can only write");
392 stat->fio=gmx_fio_open(outfile,filemode);
396 static gmx_bool gmx_next_frame(t_trxstatus *status,t_trxframe *fr)
403 if (fread_trnheader(status->fio,&sh,&bOK)) {
404 fr->bDouble=sh.bDouble;
405 fr->natoms=sh.natoms;
411 fr->lambda = sh.lambda;
412 fr->bBox = sh.box_size>0;
413 if (fr->flags & (TRX_READ_X | TRX_NEED_X)) {
415 snew(fr->x,sh.natoms);
416 fr->bX = sh.x_size>0;
418 if (fr->flags & (TRX_READ_V | TRX_NEED_V)) {
420 snew(fr->v,sh.natoms);
421 fr->bV = sh.v_size>0;
423 if (fr->flags & (TRX_READ_F | TRX_NEED_F)) {
425 snew(fr->f,sh.natoms);
426 fr->bF = sh.f_size>0;
428 if (fread_htrn(status->fio,&sh,fr->box,fr->x,fr->v,fr->f))
431 fr->not_ok = DATA_NOT_OK;
434 fr->not_ok = HEADER_NOT_OK;
439 static void choose_ff(FILE *fp)
447 printf(" Select File Format\n");
448 printf("---------------------------\n");
449 printf("1. XYZ File\n");
450 printf("2. XYZ File with Box\n");
451 printf("3. Gromos-87 Ascii Trajectory\n");
452 printf("4. Gromos-87 Ascii Trajectory with Box\n");
458 printf("\nChoice: ");
466 } while ((i < 0) || (i >= effNR));
469 stat->eFF = (eFileFormat) i;
471 for(m=0; (m<DIM); m++) stat->BOX[m]=0;
473 stat->bReadBox = (stat->eFF == effG87Box) || (stat->eFF == effXYZBox);
478 if( 5 != fscanf(fp,"%d%lf%lf%lf%lf",&stat->NATOMS,&stat->BOX[XX],&stat->BOX[YY],&stat->BOX[ZZ],&stat->DT))
480 gmx_fatal(FARGS,"Error reading natoms/box in file");
485 printf("GROMOS! OH DEAR...\n\n");
486 printf("Number of atoms ? ");
488 if (1 != scanf("%d",&stat->NATOMS))
490 gmx_fatal(FARGS,"Error reading natoms in file");
493 printf("Time between timeframes ? ");
495 if( 1 != scanf("%lf",&stat->DT))
497 gmx_fatal(FARGS,"Error reading dt from file");
500 if (stat->eFF == effG87) {
501 printf("Box X Y Z ? ");
503 if(3 != scanf("%lf%lf%lf",&stat->BOX[XX],&stat->BOX[YY],&stat->BOX[ZZ]))
505 gmx_fatal(FARGS,"Error reading box in file");
516 printf("Hellow World\n");
520 static gmx_bool do_read_xyz(t_trxstatus *status, FILE *fp,int natoms,
526 for(i=0; (i<natoms); i++) {
527 for(m=0; (m<DIM); m++) {
528 if (fscanf(fp,"%lf",&x0) != 1) {
530 fprintf(stderr,"error reading statusfile: x[%d][%d]\n",i,m);
537 if (status->bReadBox) {
538 for(m=0; (m<DIM); m++) {
539 if (fscanf(fp,"%lf",&x0) != 1)
547 static gmx_bool xyz_next_x(t_trxstatus *status, FILE *fp, const output_env_t oenv,
548 real *t, int natoms, rvec x[], matrix box)
549 /* Reads until a new x can be found (return TRUE)
550 * or eof (return FALSE)
556 while (!bTimeSet(TBEGIN) || (*t < rTimeValue(TBEGIN))) {
557 if (!do_read_xyz(status,fp,natoms,x,box))
559 printcount(status,oenv,*t,FALSE);
563 if (!bTimeSet(TEND) || (*t <= rTimeValue(TEND))) {
564 if (!do_read_xyz(status,fp,natoms,x,box)) {
565 printlast(status, oenv,*t);
568 printcount(status,oenv,*t,FALSE);
573 printlast(status,oenv,pt);
577 static int xyz_first_x(t_trxstatus *status, FILE *fp, const output_env_t oenv,
578 real *t, rvec **x, matrix box)
579 /* Reads fp, mallocs x, and returns x and box
580 * Returns natoms when successful, FALSE otherwise
590 for(m=0; (m<DIM); m++)
591 box[m][m]=status->BOX[m];
593 snew(*x,status->NATOMS);
595 if (!xyz_next_x(status, fp,oenv,t,status->NATOMS,*x,box))
599 return status->NATOMS;
602 static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp,t_trxframe *fr)
606 int ePBC,model_nr,na;
607 char title[STRLEN],*time;
610 atoms.nr = fr->natoms;
613 /* the other pointers in atoms should not be accessed if these are NULL */
615 na=read_pdbfile(fp,title,&model_nr,&atoms,fr->x,&ePBC,boxpdb,TRUE,NULL);
616 set_trxframe_ePBC(fr,ePBC);
617 if (nframes_read(status)==0)
618 fprintf(stderr," '%s', %d atoms\n",title, fr->natoms);
622 fr->bBox = (boxpdb[XX][XX] != 0.0);
624 copy_mat(boxpdb,fr->box);
627 if (model_nr!=NOTSET) {
631 time=strstr(title," t= ");
634 sscanf(time+4,"%lf",&dbl);
638 /* this is a bit dirty, but it will work: if no time is read from
639 comment line in pdb file, set time to current frame number */
641 fr->time=(real)fr->step;
643 fr->time=(real)nframes_read(status);
648 if (na != fr->natoms)
649 gmx_fatal(FARGS,"Number of atoms in pdb frame %d is %d instead of %d",
650 nframes_read(status),na,fr->natoms);
655 static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
659 fprintf(stderr,"Reading frames from pdb file");
661 get_pdb_coordnum(fp, &fr->natoms);
663 gmx_fatal(FARGS,"\nNo coordinates in pdb file\n");
665 snew(fr->x,fr->natoms);
666 pdb_next_x(status, fp, fr);
671 gmx_bool read_next_frame(const output_env_t oenv,t_trxstatus *status,t_trxframe *fr)
675 gmx_bool bOK,bRet,bMissingData=FALSE,bSkip=FALSE;
682 clear_trxframe(fr,FALSE);
686 switch (gmx_fio_getftp(status->fio)) {
689 bRet = gmx_next_frame(status,fr);
692 /* Checkpoint files can not contain mulitple frames */
696 "Reading trajectories in .g96 format is broken. Please use\n"
697 "a different file format.");
698 read_g96_conf(gmx_fio_getfp(status->fio),NULL,fr);
699 bRet = (fr->natoms > 0);
702 bRet = xyz_next_x(status, gmx_fio_getfp(status->fio),oenv,&fr->time,
703 fr->natoms, fr->x,fr->box);
710 * Sometimes is off by one frame
711 * and sometimes reports frame not present/file not seekable
713 /* DvdS 2005-05-31: this has been fixed along with the increased
714 * accuracy of the control over -b and -e options.
716 if (bTimeSet(TBEGIN) && (fr->time < rTimeValue(TBEGIN))) {
717 if (xtc_seek_time(status->fio, rTimeValue(TBEGIN),fr->natoms)) {
718 gmx_fatal(FARGS,"Specified frame doesn't exist or file not seekable");
722 bRet = read_next_xtc(status->fio,fr->natoms,&fr->step,&fr->time,fr->box,
723 fr->x,&fr->prec,&bOK);
724 fr->bPrec = (bRet && fr->prec > 0);
730 /* Actually the header could also be not ok,
731 but from bOK from read_next_xtc this can't be distinguished */
732 fr->not_ok = DATA_NOT_OK;
736 bRet = pdb_next_x(status, gmx_fio_getfp(status->fio),fr);
739 bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio),fr);
743 bRet = read_next_vmd_frame(dummy,fr);
745 gmx_fatal(FARGS,"DEATH HORROR in read_next_frame ftp=%s,status=%s",
746 ftp2ext(gmx_fio_getftp(status->fio)),
747 gmx_fio_getname(status->fio));
752 bMissingData = (((fr->flags & TRX_NEED_X) && !fr->bX) ||
753 ((fr->flags & TRX_NEED_V) && !fr->bV) ||
754 ((fr->flags & TRX_NEED_F) && !fr->bF));
757 ct=check_times2(fr->time,fr->t0,fr->tpf,fr->tppf,fr->bDouble);
758 if (ct == 0 || ((fr->flags & TRX_DONT_SKIP) && ct<0)) {
759 printcount(status, oenv,fr->time,FALSE);
763 printcount(status, oenv,fr->time,TRUE);
769 } while (bRet && (bMissingData || bSkip));
772 printlast(status, oenv,pt);
774 printincomp(status, fr);
780 int read_first_frame(const output_env_t oenv,t_trxstatus **status,
781 const char *fn,t_trxframe *fr,int flags)
787 clear_trxframe(fr,TRUE);
794 status_init( *status );
795 (*status)->nxframe=1;
798 fio = (*status)->fio =gmx_fio_open(fn,"r");
799 switch (gmx_fio_getftp(fio))
805 read_checkpoint_trxframe(fio,fr);
809 /* Can not rewind a compressed file, so open it twice */
810 read_g96_conf(gmx_fio_getfp(fio),fn,fr);
812 clear_trxframe(fr,FALSE);
813 if (flags & (TRX_READ_X | TRX_NEED_X))
814 snew(fr->x,fr->natoms);
815 if (flags & (TRX_READ_V | TRX_NEED_V))
816 snew(fr->v,fr->natoms);
817 fio = (*status)->fio =gmx_fio_open(fn,"r");
820 fr->natoms=xyz_first_x(*status, gmx_fio_getfp(fio),oenv,&fr->time,
826 printcount(*status,oenv,fr->time,FALSE);
831 if (read_first_xtc(fio,&fr->natoms,&fr->step,&fr->time,fr->box,&fr->x,
832 &fr->prec,&bOK) == 0) {
834 gmx_fatal(FARGS,"No XTC!\n");
836 fr->not_ok = DATA_NOT_OK;
841 printincomp(*status,fr);
843 fr->bPrec = (fr->prec > 0);
848 printcount(*status,oenv,fr->time,FALSE);
853 pdb_first_x(*status, gmx_fio_getfp(fio),fr);
855 printcount(*status,oenv,fr->time,FALSE);
859 if (gro_first_x_or_v(gmx_fio_getfp(fio),fr))
860 printcount(*status,oenv,fr->time,FALSE);
865 fprintf(stderr,"The file format of %s is not a known trajectory format to GROMACS.\n"
866 "Please make sure that the file is a trajectory!\n"
867 "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n"
868 "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n",fn);
869 gmx_fio_fp_close(fio); /*only close the file without removing FIO entry*/
870 if (!read_first_vmd_frame(&dummy,fn,fr,flags))
872 gmx_fatal(FARGS,"Not supported in read_first_frame: %s",fn);
875 gmx_fatal(FARGS,"Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n"
876 "GROMACS is not compiled with DLOPEN. Thus it cannot read non-GROMACS trajectory formats.\n"
877 "Please compile with DLOPEN support if you want to read non-GROMACS trajectory formats.\n",fn);
882 /* Return FALSE if we read a frame that's past the set ending time. */
883 if (!bFirst && (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) > 0)) {
889 (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) < 0))
890 /* Read a frame when no frame was read or the first was skipped */
891 if (!read_next_frame(oenv,*status,fr))
895 return (fr->natoms > 0);
898 /***** C O O R D I N A T E S T U F F *****/
900 int read_first_x(const output_env_t oenv,t_trxstatus **status,const char *fn,
901 real *t,rvec **x,matrix box)
905 read_first_frame(oenv,status,fn,&fr,TRX_NEED_X);
907 snew((*status)->xframe, 1);
908 (*status)->nxframe=1;
909 (*(*status)->xframe) = fr;
910 *t = (*status)->xframe->time;
911 *x = (*status)->xframe->x;
912 copy_mat((*status)->xframe->box,box);
914 return (*status)->xframe->natoms;
917 gmx_bool read_next_x(const output_env_t oenv, t_trxstatus *status,real *t,
918 int natoms, rvec x[], matrix box)
922 status->xframe->x= x;
923 /*xframe[status].x = x;*/
924 bRet = read_next_frame(oenv,status,status->xframe);
925 *t = status->xframe->time;
926 copy_mat(status->xframe->box,box);
931 void close_trj(t_trxstatus *status)
933 gmx_fio_close(status->fio);
934 /* The memory in status->xframe is lost here,
935 * but the read_first_x/read_next_x functions are deprecated anyhow.
936 * read_first_frame/read_next_frame and close_trx should be used.
941 void rewind_trj(t_trxstatus *status)
945 gmx_fio_rewind(status->fio);
948 /***** V E L O C I T Y S T U F F *****/
950 static void clear_v(t_trxframe *fr)
955 for(i=0; i<fr->natoms; i++)
956 clear_rvec(fr->v[i]);
959 int read_first_v(const output_env_t oenv, t_trxstatus **status,const char *fn,
960 real *t, rvec **v,matrix box)
964 read_first_frame(oenv,status,fn,&fr,TRX_NEED_V);
968 copy_mat(fr.box,box);
973 gmx_bool read_next_v(const output_env_t oenv,t_trxstatus *status,real *t,
974 int natoms,rvec v[], matrix box)
979 clear_trxframe(&fr,TRUE);
980 fr.flags = TRX_NEED_V;
984 bRet = read_next_frame(oenv,status,&fr);
987 copy_mat(fr.box,box);