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 */
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 gmx_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 gmx_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);