2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
59 #include "checkpoint.h"
63 /* defines for frame counter output */
68 /* Globals for gromos-87 input */
69 typedef enum { effXYZ, effXYZBox, effG87, effG87Box, effNR } eFileFormat;
81 char *persistent_line; /* Persistent line for reading g96 trajectories */
84 static void initcount(t_trxstatus *status)
89 static void status_init(t_trxstatus *status)
95 status->persistent_line=NULL;
99 int nframes_read(t_trxstatus *status)
101 return status->__frame;
104 static void printcount_(t_trxstatus *status, const output_env_t oenv,
105 const char *l,real t)
107 if ((status->__frame < 2*SKIP1 || status->__frame % SKIP1 == 0) &&
108 (status->__frame < 2*SKIP2 || status->__frame % SKIP2 == 0) &&
109 (status->__frame < 2*SKIP3 || status->__frame % SKIP3 == 0))
110 fprintf(stderr,"\r%-14s %6d time %8.3f ",l,status->__frame,
111 output_env_conv_time(oenv,t));
114 static void printcount(t_trxstatus *status, const output_env_t oenv,real t,
118 printcount_(status, oenv,bSkip ? "Skipping frame" : "Reading frame",t);
121 static void printlast(t_trxstatus *status, const output_env_t oenv,real t)
123 printcount_(status, oenv,"Last frame",t);
124 fprintf(stderr,"\n");
127 static void printincomp(t_trxstatus *status, t_trxframe *fr)
129 if (fr->not_ok & HEADER_NOT_OK)
130 fprintf(stderr,"WARNING: Incomplete header: nr %d time %g\n",
131 status->__frame+1,fr->time);
133 fprintf(stderr,"WARNING: Incomplete frame: nr %d time %g\n",
134 status->__frame+1,fr->time);
137 int prec2ndec(real prec)
140 gmx_fatal(FARGS,"DEATH HORROR prec (%g) <= 0 in prec2ndec",prec);
142 return (int)(log(prec)/log(10.0)+0.5);
146 t_fileio *trx_get_fileio(t_trxstatus *status)
153 void clear_trxframe(t_trxframe *fr,gmx_bool bFirst)
188 void set_trxframe_ePBC(t_trxframe *fr,int ePBC)
190 fr->bPBC = (ePBC == -1);
194 int write_trxframe_indexed(t_trxstatus *status,t_trxframe *fr,int nind,
195 atom_id *ind, gmx_conect gc)
198 rvec *xout=NULL,*vout=NULL,*fout=NULL;
207 switch (gmx_fio_getftp(status->fio)) {
213 gmx_fatal(FARGS,"Need coordinates to write a %s trajectory",
214 ftp2ext(gmx_fio_getftp(status->fio)));
218 switch (gmx_fio_getftp(status->fio)) {
223 for(i=0; i<nind; i++)
224 copy_rvec(fr->v[ind[i]],vout[i]);
228 for(i=0; i<nind; i++)
229 copy_rvec(fr->f[ind[i]],fout[i]);
236 for(i=0; i<nind; i++)
237 copy_rvec(fr->x[ind[i]],xout[i]);
244 switch (gmx_fio_getftp(status->fio)) {
246 write_xtc(status->fio,nind,fr->step,fr->time,fr->box,xout,prec);
250 fwrite_trn(status->fio,nframes_read(status),
251 fr->time,fr->step,fr->box,nind,xout,vout,fout);
258 gmx_fatal(FARGS,"Can not write a %s file without atom names",
259 ftp2ext(gmx_fio_getftp(status->fio)));
260 sprintf(title,"frame t= %.3f",fr->time);
261 if (gmx_fio_getftp(status->fio) == efGRO)
262 write_hconf_indexed_p(gmx_fio_getfp(status->fio),title,fr->atoms,nind,ind,
264 fr->x,fr->bV ? fr->v : NULL,fr->box);
266 write_pdbfile_indexed(gmx_fio_getfp(status->fio),title,fr->atoms,
267 fr->x,-1,fr->box,' ',fr->step,nind,ind,gc,TRUE);
270 write_gms(gmx_fio_getfp(status->fio),nind,xout,fr->box);
273 write_g96_conf(gmx_fio_getfp(status->fio),fr,nind,ind);
276 gmx_fatal(FARGS,"Sorry, write_trxframe_indexed can not write %s",
277 ftp2ext(gmx_fio_getftp(status->fio)));
281 switch (gmx_fio_getftp(status->fio)) {
285 if (vout) sfree(vout);
286 if (fout) sfree(fout);
299 int write_trxframe(t_trxstatus *status,t_trxframe *fr,gmx_conect gc)
309 switch (gmx_fio_getftp(status->fio)) {
315 gmx_fatal(FARGS,"Need coordinates to write a %s trajectory",
316 ftp2ext(gmx_fio_getftp(status->fio)));
320 switch (gmx_fio_getftp(status->fio)) {
322 write_xtc(status->fio,fr->natoms,fr->step,fr->time,fr->box,fr->x,prec);
326 fwrite_trn(status->fio,fr->step,fr->time,fr->lambda,fr->box,fr->natoms,
327 fr->bX ? fr->x:NULL,fr->bV ? fr->v:NULL ,fr->bF ? fr->f:NULL);
334 gmx_fatal(FARGS,"Can not write a %s file without atom names",
335 ftp2ext(gmx_fio_getftp(status->fio)));
336 sprintf(title,"frame t= %.3f",fr->time);
337 if (gmx_fio_getftp(status->fio) == efGRO)
338 write_hconf_p(gmx_fio_getfp(status->fio),title,fr->atoms,
339 prec2ndec(prec),fr->x,fr->bV ? fr->v : NULL,fr->box);
341 write_pdbfile(gmx_fio_getfp(status->fio),title,
342 fr->atoms,fr->x,fr->bPBC ? fr->ePBC : -1,fr->box,
343 ' ',fr->step,gc,TRUE);
346 write_gms(gmx_fio_getfp(status->fio),fr->natoms,fr->x,fr->box);
349 write_g96_conf(gmx_fio_getfp(status->fio),fr,-1,NULL);
352 gmx_fatal(FARGS,"Sorry, write_trxframe can not write %s",
353 ftp2ext(gmx_fio_getftp(status->fio)));
360 int write_trx(t_trxstatus *status,int nind,atom_id *ind,t_atoms *atoms,
361 int step,real time,matrix box,rvec x[],rvec *v,
366 clear_trxframe(&fr,TRUE);
371 fr.bAtoms = atoms!=NULL;
378 copy_mat(box,fr.box);
380 return write_trxframe_indexed(status,&fr,nind,ind,gc);
383 void close_trx(t_trxstatus *status)
385 gmx_fio_close(status->fio);
389 t_trxstatus *open_trx(const char *outfile,const char *filemode)
392 if (filemode[0]!='w' && filemode[0]!='a' && filemode[1]!='+')
393 gmx_fatal(FARGS,"Sorry, write_trx can only write");
398 stat->fio=gmx_fio_open(outfile,filemode);
402 static gmx_bool gmx_next_frame(t_trxstatus *status,t_trxframe *fr)
409 if (fread_trnheader(status->fio,&sh,&bOK)) {
410 fr->bDouble=sh.bDouble;
411 fr->natoms=sh.natoms;
417 fr->bFepState = TRUE;
418 fr->lambda = sh.lambda;
419 fr->bBox = sh.box_size>0;
420 if (fr->flags & (TRX_READ_X | TRX_NEED_X)) {
422 snew(fr->x,sh.natoms);
423 fr->bX = sh.x_size>0;
425 if (fr->flags & (TRX_READ_V | TRX_NEED_V)) {
427 snew(fr->v,sh.natoms);
428 fr->bV = sh.v_size>0;
430 if (fr->flags & (TRX_READ_F | TRX_NEED_F)) {
432 snew(fr->f,sh.natoms);
433 fr->bF = sh.f_size>0;
435 if (fread_htrn(status->fio,&sh,fr->box,fr->x,fr->v,fr->f))
438 fr->not_ok = DATA_NOT_OK;
441 fr->not_ok = HEADER_NOT_OK;
446 static void choose_file_format(FILE *fp)
454 printf(" Select File Format\n");
455 printf("---------------------------\n");
456 printf("1. XYZ File\n");
457 printf("2. XYZ File with Box\n");
458 printf("3. Gromos-87 Ascii Trajectory\n");
459 printf("4. Gromos-87 Ascii Trajectory with Box\n");
465 printf("\nChoice: ");
473 } while ((i < 0) || (i >= effNR));
476 stat->eFF = (eFileFormat) i;
478 for(m=0; (m<DIM); m++) stat->BOX[m]=0;
480 stat->bReadBox = (stat->eFF == effG87Box) || (stat->eFF == effXYZBox);
485 if( 5 != fscanf(fp,"%d%lf%lf%lf%lf",&stat->NATOMS,&stat->BOX[XX],&stat->BOX[YY],&stat->BOX[ZZ],&stat->DT))
487 gmx_fatal(FARGS,"Error reading natoms/box in file");
492 printf("GROMOS! OH DEAR...\n\n");
493 printf("Number of atoms ? ");
495 if (1 != scanf("%d",&stat->NATOMS))
497 gmx_fatal(FARGS,"Error reading natoms in file");
500 printf("Time between timeframes ? ");
502 if( 1 != scanf("%lf",&stat->DT))
504 gmx_fatal(FARGS,"Error reading dt from file");
507 if (stat->eFF == effG87) {
508 printf("Box X Y Z ? ");
510 if(3 != scanf("%lf%lf%lf",&stat->BOX[XX],&stat->BOX[YY],&stat->BOX[ZZ]))
512 gmx_fatal(FARGS,"Error reading box in file");
523 printf("Hellow World\n");
527 static gmx_bool do_read_xyz(t_trxstatus *status, FILE *fp,int natoms,
533 for(i=0; (i<natoms); i++) {
534 for(m=0; (m<DIM); m++) {
535 if (fscanf(fp,"%lf",&x0) != 1) {
537 fprintf(stderr,"error reading statusfile: x[%d][%d]\n",i,m);
544 if (status->bReadBox) {
545 for(m=0; (m<DIM); m++) {
546 if (fscanf(fp,"%lf",&x0) != 1)
554 static gmx_bool xyz_next_x(t_trxstatus *status, FILE *fp, const output_env_t oenv,
555 real *t, int natoms, rvec x[], matrix box)
556 /* Reads until a new x can be found (return TRUE)
557 * or eof (return FALSE)
563 while (!bTimeSet(TBEGIN) || (*t < rTimeValue(TBEGIN))) {
564 if (!do_read_xyz(status,fp,natoms,x,box))
566 printcount(status,oenv,*t,FALSE);
570 if (!bTimeSet(TEND) || (*t <= rTimeValue(TEND))) {
571 if (!do_read_xyz(status,fp,natoms,x,box)) {
572 printlast(status, oenv,*t);
575 printcount(status,oenv,*t,FALSE);
580 printlast(status,oenv,pt);
584 static int xyz_first_x(t_trxstatus *status, FILE *fp, const output_env_t oenv,
585 real *t, rvec **x, matrix box)
586 /* Reads fp, mallocs x, and returns x and box
587 * Returns natoms when successful, FALSE otherwise
595 choose_file_format(fp);
597 for(m=0; (m<DIM); m++)
598 box[m][m]=status->BOX[m];
600 snew(*x,status->NATOMS);
602 if (!xyz_next_x(status, fp,oenv,t,status->NATOMS,*x,box))
606 return status->NATOMS;
609 static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp,t_trxframe *fr)
613 int ePBC,model_nr,na;
614 char title[STRLEN],*time;
617 atoms.nr = fr->natoms;
620 /* the other pointers in atoms should not be accessed if these are NULL */
622 na=read_pdbfile(fp,title,&model_nr,&atoms,fr->x,&ePBC,boxpdb,TRUE,NULL);
623 set_trxframe_ePBC(fr,ePBC);
624 if (nframes_read(status)==0)
625 fprintf(stderr," '%s', %d atoms\n",title, fr->natoms);
629 fr->bBox = (boxpdb[XX][XX] != 0.0);
631 copy_mat(boxpdb,fr->box);
634 if (model_nr!=NOTSET) {
638 time=strstr(title," t= ");
641 sscanf(time+4,"%lf",&dbl);
645 /* this is a bit dirty, but it will work: if no time is read from
646 comment line in pdb file, set time to current frame number */
648 fr->time=(real)fr->step;
650 fr->time=(real)nframes_read(status);
655 if (na != fr->natoms)
656 gmx_fatal(FARGS,"Number of atoms in pdb frame %d is %d instead of %d",
657 nframes_read(status),na,fr->natoms);
662 static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
666 fprintf(stderr,"Reading frames from pdb file");
668 get_pdb_coordnum(fp, &fr->natoms);
670 gmx_fatal(FARGS,"\nNo coordinates in pdb file\n");
672 snew(fr->x,fr->natoms);
673 pdb_next_x(status, fp, fr);
678 gmx_bool read_next_frame(const output_env_t oenv,t_trxstatus *status,t_trxframe *fr)
682 gmx_bool bOK,bRet,bMissingData=FALSE,bSkip=FALSE;
689 clear_trxframe(fr,FALSE);
693 switch (gmx_fio_getftp(status->fio)) {
696 bRet = gmx_next_frame(status,fr);
699 /* Checkpoint files can not contain mulitple frames */
702 read_g96_conf(gmx_fio_getfp(status->fio),NULL,fr,
703 status->persistent_line);
704 bRet = (fr->natoms > 0);
707 bRet = xyz_next_x(status, gmx_fio_getfp(status->fio),oenv,&fr->time,
708 fr->natoms, fr->x,fr->box);
715 * Sometimes is off by one frame
716 * and sometimes reports frame not present/file not seekable
718 /* DvdS 2005-05-31: this has been fixed along with the increased
719 * accuracy of the control over -b and -e options.
721 if (bTimeSet(TBEGIN) && (fr->time < rTimeValue(TBEGIN))) {
722 if (xtc_seek_time(status->fio, rTimeValue(TBEGIN),fr->natoms,TRUE)) {
723 gmx_fatal(FARGS,"Specified frame (time %f) doesn't exist or file corrupt/inconsistent.",
728 bRet = read_next_xtc(status->fio,fr->natoms,&fr->step,&fr->time,fr->box,
729 fr->x,&fr->prec,&bOK);
730 fr->bPrec = (bRet && fr->prec > 0);
736 /* Actually the header could also be not ok,
737 but from bOK from read_next_xtc this can't be distinguished */
738 fr->not_ok = DATA_NOT_OK;
742 bRet = pdb_next_x(status, gmx_fio_getfp(status->fio),fr);
745 bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio),fr);
748 #ifdef GMX_USE_PLUGINS
749 bRet = read_next_vmd_frame(dummy,fr);
751 gmx_fatal(FARGS,"DEATH HORROR in read_next_frame ftp=%s,status=%s",
752 ftp2ext(gmx_fio_getftp(status->fio)),
753 gmx_fio_getname(status->fio));
758 bMissingData = (((fr->flags & TRX_NEED_X) && !fr->bX) ||
759 ((fr->flags & TRX_NEED_V) && !fr->bV) ||
760 ((fr->flags & TRX_NEED_F) && !fr->bF));
763 ct=check_times2(fr->time,fr->t0,fr->tpf,fr->tppf,fr->bDouble);
764 if (ct == 0 || ((fr->flags & TRX_DONT_SKIP) && ct<0)) {
765 printcount(status, oenv,fr->time,FALSE);
769 printcount(status, oenv,fr->time,TRUE);
775 } while (bRet && (bMissingData || bSkip));
778 printlast(status, oenv,pt);
780 printincomp(status, fr);
786 int read_first_frame(const output_env_t oenv,t_trxstatus **status,
787 const char *fn,t_trxframe *fr,int flags)
793 clear_trxframe(fr,TRUE);
800 status_init( *status );
801 (*status)->nxframe=1;
804 fio = (*status)->fio =gmx_fio_open(fn,"r");
805 switch (gmx_fio_getftp(fio))
811 read_checkpoint_trxframe(fio,fr);
815 /* Can not rewind a compressed file, so open it twice */
816 if (!(*status)->persistent_line)
818 /* allocate the persistent line */
819 snew((*status)->persistent_line, STRLEN+1);
821 read_g96_conf(gmx_fio_getfp(fio),fn,fr, (*status)->persistent_line);
823 clear_trxframe(fr,FALSE);
824 if (flags & (TRX_READ_X | TRX_NEED_X))
825 snew(fr->x,fr->natoms);
826 if (flags & (TRX_READ_V | TRX_NEED_V))
827 snew(fr->v,fr->natoms);
828 fio = (*status)->fio =gmx_fio_open(fn,"r");
831 fr->natoms=xyz_first_x(*status, gmx_fio_getfp(fio),oenv,&fr->time,
837 printcount(*status,oenv,fr->time,FALSE);
842 if (read_first_xtc(fio,&fr->natoms,&fr->step,&fr->time,fr->box,&fr->x,
843 &fr->prec,&bOK) == 0) {
845 gmx_fatal(FARGS,"No XTC!\n");
847 fr->not_ok = DATA_NOT_OK;
852 printincomp(*status,fr);
854 fr->bPrec = (fr->prec > 0);
859 printcount(*status,oenv,fr->time,FALSE);
864 pdb_first_x(*status, gmx_fio_getfp(fio),fr);
866 printcount(*status,oenv,fr->time,FALSE);
870 if (gro_first_x_or_v(gmx_fio_getfp(fio),fr))
871 printcount(*status,oenv,fr->time,FALSE);
875 #ifdef GMX_USE_PLUGINS
876 fprintf(stderr,"The file format of %s is not a known trajectory format to GROMACS.\n"
877 "Please make sure that the file is a trajectory!\n"
878 "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n"
879 "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n",fn);
880 gmx_fio_fp_close(fio); /*only close the file without removing FIO entry*/
881 if (!read_first_vmd_frame(&dummy,fn,fr,flags))
883 gmx_fatal(FARGS,"Not supported in read_first_frame: %s",fn);
886 gmx_fatal(FARGS,"Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n"
887 "GROMACS is not compiled with plug-in support. Thus it cannot read non-GROMACS trajectory formats using the VMD plug-ins.\n"
888 "Please compile with plug-in support if you want to read non-GROMACS trajectory formats.\n",fn);
893 /* Return FALSE if we read a frame that's past the set ending time. */
894 if (!bFirst && (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) > 0)) {
900 (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) < 0))
901 /* Read a frame when no frame was read or the first was skipped */
902 if (!read_next_frame(oenv,*status,fr))
906 return (fr->natoms > 0);
909 /***** C O O R D I N A T E S T U F F *****/
911 int read_first_x(const output_env_t oenv,t_trxstatus **status,const char *fn,
912 real *t,rvec **x,matrix box)
916 read_first_frame(oenv,status,fn,&fr,TRX_NEED_X);
918 snew((*status)->xframe, 1);
919 (*status)->nxframe=1;
920 (*(*status)->xframe) = fr;
921 *t = (*status)->xframe->time;
922 *x = (*status)->xframe->x;
923 copy_mat((*status)->xframe->box,box);
925 return (*status)->xframe->natoms;
928 gmx_bool read_next_x(const output_env_t oenv, t_trxstatus *status,real *t,
929 int natoms, rvec x[], matrix box)
933 status->xframe->x= x;
934 /*xframe[status].x = x;*/
935 bRet = read_next_frame(oenv,status,status->xframe);
936 *t = status->xframe->time;
937 copy_mat(status->xframe->box,box);
942 void close_trj(t_trxstatus *status)
944 gmx_fio_close(status->fio);
945 /* The memory in status->xframe is lost here,
946 * but the read_first_x/read_next_x functions are deprecated anyhow.
947 * read_first_frame/read_next_frame and close_trx should be used.
952 void rewind_trj(t_trxstatus *status)
956 gmx_fio_rewind(status->fio);
959 /***** V E L O C I T Y S T U F F *****/
961 static void clear_v(t_trxframe *fr)
966 for(i=0; i<fr->natoms; i++)
967 clear_rvec(fr->v[i]);