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 * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
47 #include "gromacs/fileio/checkpoint.h"
48 #include "gromacs/fileio/confio.h"
49 #include "gromacs/fileio/filetypes.h"
50 #include "gromacs/fileio/g96io.h"
51 #include "gromacs/fileio/gmxfio.h"
52 #include "gromacs/fileio/gmxfio-xdr.h"
53 #include "gromacs/fileio/groio.h"
54 #include "gromacs/fileio/oenv.h"
55 #include "gromacs/fileio/pdbio.h"
56 #include "gromacs/fileio/timecontrol.h"
57 #include "gromacs/fileio/tngio.h"
58 #include "gromacs/fileio/tngio_for_tools.h"
59 #include "gromacs/fileio/tpxio.h"
60 #include "gromacs/fileio/trrio.h"
61 #include "gromacs/fileio/xdrf.h"
62 #include "gromacs/fileio/xtcio.h"
63 #include "gromacs/math/vec.h"
64 #include "gromacs/mdtypes/md_enums.h"
65 #include "gromacs/topology/atoms.h"
66 #include "gromacs/topology/symtab.h"
67 #include "gromacs/topology/topology.h"
68 #include "gromacs/trajectory/trajectoryframe.h"
69 #include "gromacs/utility/fatalerror.h"
70 #include "gromacs/utility/futil.h"
71 #include "gromacs/utility/gmxassert.h"
72 #include "gromacs/utility/smalloc.h"
75 #include "gromacs/fileio/vmdio.h"
78 /* defines for frame counter output */
85 int flags; /* flags for read_first/next_frame */
87 real t0; /* time of the first frame, needed *
88 * for skipping frames with -dt */
89 real tf; /* internal frame time */
97 char *persistent_line; /* Persistent line for reading g96 trajectories */
99 gmx_vmdplugin_t *vmdplugin;
103 /* utility functions */
105 gmx_bool bRmod_fd(double a, double b, double c, gmx_bool bDouble)
110 tol = 2*(bDouble ? GMX_DOUBLE_EPS : GMX_FLOAT_EPS);
112 iq = (int)((a - b + tol*a)/c);
114 if (fabs(a - b - c*iq) <= tol*fabs(a))
126 int check_times2(real t, real t0, gmx_bool bDouble)
131 /* since t is float, we can not use double precision for bRmod */
136 if ((!bTimeSet(TBEGIN) || (t >= rTimeValue(TBEGIN))) &&
137 (!bTimeSet(TEND) || (t <= rTimeValue(TEND))))
139 if (bTimeSet(TDELTA) && !bRmod_fd(t, t0, rTimeValue(TDELTA), bDouble))
148 else if (bTimeSet(TEND) && (t >= rTimeValue(TEND)))
154 fprintf(debug, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n",
155 t, t0, rTimeValue(TBEGIN), rTimeValue(TEND), rTimeValue(TDELTA), r);
160 int check_times(real t)
162 return check_times2(t, t, FALSE);
165 static void initcount(t_trxstatus *status)
167 status->__frame = -1;
170 static void status_init(t_trxstatus *status)
174 status->xframe = NULL;
176 status->__frame = -1;
179 status->persistent_line = NULL;
184 int nframes_read(t_trxstatus *status)
186 return status->__frame;
189 static void printcount_(t_trxstatus *status, const gmx_output_env_t *oenv,
190 const char *l, real t)
192 if ((status->__frame < 2*SKIP1 || status->__frame % SKIP1 == 0) &&
193 (status->__frame < 2*SKIP2 || status->__frame % SKIP2 == 0) &&
194 (status->__frame < 2*SKIP3 || status->__frame % SKIP3 == 0) &&
195 output_env_get_trajectory_io_verbosity(oenv) != 0)
197 fprintf(stderr, "\r%-14s %6d time %8.3f ", l, status->__frame,
198 output_env_conv_time(oenv, t));
203 static void printcount(t_trxstatus *status, const gmx_output_env_t *oenv, real t,
207 printcount_(status, oenv, bSkip ? "Skipping frame" : "Reading frame", t);
210 static void printlast(t_trxstatus *status, const gmx_output_env_t *oenv, real t)
212 printcount_(status, oenv, "Last frame", t);
213 fprintf(stderr, "\n");
217 static void printincomp(t_trxstatus *status, t_trxframe *fr)
219 if (fr->not_ok & HEADER_NOT_OK)
221 fprintf(stderr, "WARNING: Incomplete header: nr %d time %g\n",
222 status->__frame+1, fr->time);
226 fprintf(stderr, "WARNING: Incomplete frame: nr %d time %g\n",
227 status->__frame+1, fr->time);
232 int prec2ndec(real prec)
236 gmx_fatal(FARGS, "DEATH HORROR prec (%g) <= 0 in prec2ndec", prec);
239 return (int)(log(prec)/log(10.0)+0.5);
242 real ndec2prec(int ndec)
244 return pow(10.0, ndec);
247 t_fileio *trx_get_fileio(t_trxstatus *status)
252 float trx_get_time_of_final_frame(t_trxstatus *status)
254 t_fileio *stfio = trx_get_fileio(status);
255 int filetype = gmx_fio_getftp(stfio);
259 if (filetype == efXTC)
262 xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio),
263 gmx_fio_getxdr(stfio),
264 status->natoms, &bOK);
267 gmx_fatal(FARGS, "Error reading last frame. Maybe seek not supported." );
270 else if (filetype == efTNG)
272 tng_trajectory_t tng = status->tng;
275 gmx_fatal(FARGS, "Error opening TNG file.");
277 lasttime = gmx_tng_get_time_of_final_frame(tng);
281 gmx_incons("Only supported for TNG and XTC");
286 void clear_trxframe(t_trxframe *fr, gmx_bool bFirst)
293 fr->bFepState = FALSE;
320 void set_trxframe_ePBC(t_trxframe *fr, int ePBC)
322 fr->bPBC = (ePBC == -1);
326 int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind,
327 const int *ind, gmx_conect gc)
330 rvec *xout = NULL, *vout = NULL, *fout = NULL;
347 else if (status->fio)
349 ftp = gmx_fio_getftp(status->fio);
353 gmx_incons("No input file available");
364 gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
377 for (i = 0; i < nind; i++)
379 copy_rvec(fr->v[ind[i]], vout[i]);
385 for (i = 0; i < nind; i++)
387 copy_rvec(fr->f[ind[i]], fout[i]);
395 for (i = 0; i < nind; i++)
397 copy_rvec(fr->x[ind[i]], xout[i]);
408 gmx_write_tng_from_trxframe(status->tng, fr, nind);
411 write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec);
414 gmx_trr_write_frame(status->fio, nframes_read(status),
415 fr->time, fr->step, fr->box, nind, xout, vout, fout);
423 gmx_fatal(FARGS, "Can not write a %s file without atom names",
426 sprintf(title, "frame t= %.3f", fr->time);
429 write_hconf_indexed_p(gmx_fio_getfp(status->fio), title, fr->atoms, nind, ind,
430 fr->x, fr->bV ? fr->v : NULL, fr->box);
434 write_pdbfile_indexed(gmx_fio_getfp(status->fio), title, fr->atoms,
435 fr->x, -1, fr->box, ' ', fr->step, nind, ind, gc, TRUE);
439 write_g96_conf(gmx_fio_getfp(status->fio), fr, nind, ind);
442 gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s",
470 void trjtools_gmx_prepare_tng_writing(const char *filename,
476 const gmx_mtop_t *mtop,
478 const char *index_group_name)
480 if (filemode != 'w' && filemode != 'a')
482 gmx_incons("Sorry, can only prepare for TNG output.");
493 gmx_prepare_tng_writing(filename,
502 else if (efTNG == fn2ftp(infile))
504 tng_trajectory_t tng_in;
505 gmx_tng_open(infile, 'r', &tng_in);
507 gmx_prepare_tng_writing(filename,
518 void write_tng_frame(t_trxstatus *status,
521 gmx_write_tng_from_trxframe(status->tng, frame, -1);
524 int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc)
540 gmx_tng_set_compression_precision(status->tng, prec);
541 write_tng_frame(status, fr);
546 switch (gmx_fio_getftp(status->fio))
553 gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
554 ftp2ext(gmx_fio_getftp(status->fio)));
559 switch (gmx_fio_getftp(status->fio))
562 write_xtc(status->fio, fr->natoms, fr->step, fr->time, fr->box, fr->x, prec);
565 gmx_trr_write_frame(status->fio, fr->step, fr->time, fr->lambda, fr->box, fr->natoms,
566 fr->bX ? fr->x : NULL, fr->bV ? fr->v : NULL, fr->bF ? fr->f : NULL);
574 gmx_fatal(FARGS, "Can not write a %s file without atom names",
575 ftp2ext(gmx_fio_getftp(status->fio)));
577 sprintf(title, "frame t= %.3f", fr->time);
578 if (gmx_fio_getftp(status->fio) == efGRO)
580 write_hconf_p(gmx_fio_getfp(status->fio), title, fr->atoms,
581 fr->x, fr->bV ? fr->v : NULL, fr->box);
585 write_pdbfile(gmx_fio_getfp(status->fio), title,
586 fr->atoms, fr->x, fr->bPBC ? fr->ePBC : -1, fr->box,
587 ' ', fr->step, gc, TRUE);
591 write_g96_conf(gmx_fio_getfp(status->fio), fr, -1, NULL);
594 gmx_fatal(FARGS, "Sorry, write_trxframe can not write %s",
595 ftp2ext(gmx_fio_getftp(status->fio)));
602 int write_trx(t_trxstatus *status, int nind, const int *ind, const t_atoms *atoms,
603 int step, real time, matrix box, rvec x[], rvec *v,
608 clear_trxframe(&fr, TRUE);
613 fr.bAtoms = atoms != NULL;
614 fr.atoms = const_cast<t_atoms *>(atoms);
620 copy_mat(box, fr.box);
622 return write_trxframe_indexed(status, &fr, nind, ind, gc);
625 void close_trx(t_trxstatus *status)
627 if (status == nullptr)
631 gmx_tng_close(&status->tng);
634 gmx_fio_close(status->fio);
639 t_trxstatus *open_trx(const char *outfile, const char *filemode)
642 if (filemode[0] != 'w' && filemode[0] != 'a' && filemode[1] != '+')
644 gmx_fatal(FARGS, "Sorry, write_trx can only write");
650 stat->fio = gmx_fio_open(outfile, filemode);
654 static gmx_bool gmx_next_frame(t_trxstatus *status, t_trxframe *fr)
661 if (gmx_trr_read_frame_header(status->fio, &sh, &bOK))
663 fr->bDouble = sh.bDouble;
664 fr->natoms = sh.natoms;
670 fr->bFepState = TRUE;
671 fr->lambda = sh.lambda;
672 fr->bBox = sh.box_size > 0;
673 if (status->flags & (TRX_READ_X | TRX_NEED_X))
677 snew(fr->x, sh.natoms);
679 fr->bX = sh.x_size > 0;
681 if (status->flags & (TRX_READ_V | TRX_NEED_V))
685 snew(fr->v, sh.natoms);
687 fr->bV = sh.v_size > 0;
689 if (status->flags & (TRX_READ_F | TRX_NEED_F))
693 snew(fr->f, sh.natoms);
695 fr->bF = sh.f_size > 0;
697 if (gmx_trr_read_frame_data(status->fio, &sh, fr->box, fr->x, fr->v, fr->f))
703 fr->not_ok = DATA_NOT_OK;
709 fr->not_ok = HEADER_NOT_OK;
715 static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
720 // Initiate model_nr to -1 rather than NOTSET.
721 // It is not worthwhile introducing extra variables in the
722 // read_pdbfile call to verify that a model_nr was read.
723 int ePBC, model_nr = -1, na;
724 char title[STRLEN], *time;
727 atoms.nr = fr->natoms;
729 atoms.pdbinfo = NULL;
730 /* the other pointers in atoms should not be accessed if these are NULL */
733 na = read_pdbfile(fp, title, &model_nr, &atoms, symtab, fr->x, &ePBC, boxpdb, TRUE, NULL);
736 set_trxframe_ePBC(fr, ePBC);
737 if (nframes_read(status) == 0)
739 fprintf(stderr, " '%s', %d atoms\n", title, fr->natoms);
744 fr->bBox = (boxpdb[XX][XX] != 0.0);
747 copy_mat(boxpdb, fr->box);
755 time = std::strstr(title, " t= ");
759 sscanf(time+4, "%lf", &dbl);
760 fr->time = (real)dbl;
765 /* this is a bit dirty, but it will work: if no time is read from
766 comment line in pdb file, set time to current frame number */
769 fr->time = (real)fr->step;
773 fr->time = (real)nframes_read(status);
782 if (na != fr->natoms)
784 gmx_fatal(FARGS, "Number of atoms in pdb frame %d is %d instead of %d",
785 nframes_read(status), na, fr->natoms);
791 static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
795 fprintf(stderr, "Reading frames from pdb file");
797 get_pdb_coordnum(fp, &fr->natoms);
800 gmx_fatal(FARGS, "\nNo coordinates in pdb file\n");
803 snew(fr->x, fr->natoms);
804 pdb_next_x(status, fp, fr);
809 gmx_bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxframe *fr)
813 gmx_bool bOK, bRet, bMissingData = FALSE, bSkip = FALSE;
821 clear_trxframe(fr, FALSE);
825 /* Special treatment for TNG files */
830 ftp = gmx_fio_getftp(status->fio);
835 bRet = gmx_next_frame(status, fr);
838 /* Checkpoint files can not contain mulitple frames */
845 read_g96_conf(gmx_fio_getfp(status->fio), NULL, fr,
846 symtab, status->persistent_line);
848 bRet = (fr->natoms > 0);
852 if (bTimeSet(TBEGIN) && (status->tf < rTimeValue(TBEGIN)))
854 if (xtc_seek_time(status->fio, rTimeValue(TBEGIN), fr->natoms, TRUE))
856 gmx_fatal(FARGS, "Specified frame (time %f) doesn't exist or file corrupt/inconsistent.",
861 bRet = read_next_xtc(status->fio, fr->natoms, &fr->step, &fr->time, fr->box,
862 fr->x, &fr->prec, &bOK);
863 fr->bPrec = (bRet && fr->prec > 0);
870 /* Actually the header could also be not ok,
871 but from bOK from read_next_xtc this can't be distinguished */
872 fr->not_ok = DATA_NOT_OK;
876 bRet = gmx_read_next_tng_frame(status->tng, fr, NULL, 0);
879 bRet = pdb_next_x(status, gmx_fio_getfp(status->fio), fr);
882 bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio), fr);
886 bRet = read_next_vmd_frame(status->vmdplugin, fr);
888 gmx_fatal(FARGS, "DEATH HORROR in read_next_frame ftp=%s,status=%s",
889 ftp2ext(gmx_fio_getftp(status->fio)),
890 gmx_fio_getname(status->fio));
893 status->tf = fr->time;
897 bMissingData = (((status->flags & TRX_NEED_X) && !fr->bX) ||
898 ((status->flags & TRX_NEED_V) && !fr->bV) ||
899 ((status->flags & TRX_NEED_F) && !fr->bF));
903 ct = check_times2(fr->time, status->t0, fr->bDouble);
904 if (ct == 0 || ((status->flags & TRX_DONT_SKIP) && ct < 0))
906 printcount(status, oenv, fr->time, FALSE);
914 printcount(status, oenv, fr->time, TRUE);
921 while (bRet && (bMissingData || bSkip));
925 printlast(status, oenv, pt);
928 printincomp(status, fr);
935 int read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status,
936 const char *fn, t_trxframe *fr, int flags)
939 gmx_bool bFirst, bOK;
940 int ftp = fn2ftp(fn);
942 clear_trxframe(fr, TRUE);
948 status_init( *status );
949 (*status)->nxframe = 1;
951 (*status)->flags = flags;
955 /* Special treatment for TNG files */
956 gmx_tng_open(fn, 'r', &(*status)->tng);
960 fio = (*status)->fio = gmx_fio_open(fn, "r");
967 read_checkpoint_trxframe(fio, fr);
972 /* Can not rewind a compressed file, so open it twice */
973 if (!(*status)->persistent_line)
975 /* allocate the persistent line */
976 snew((*status)->persistent_line, STRLEN+1);
981 read_g96_conf(gmx_fio_getfp(fio), fn, fr, symtab, (*status)->persistent_line);
984 clear_trxframe(fr, FALSE);
985 if (flags & (TRX_READ_X | TRX_NEED_X))
987 snew(fr->x, fr->natoms);
989 if (flags & (TRX_READ_V | TRX_NEED_V))
991 snew(fr->v, fr->natoms);
993 (*status)->fio = gmx_fio_open(fn, "r");
997 if (read_first_xtc(fio, &fr->natoms, &fr->step, &fr->time, fr->box, &fr->x,
998 &fr->prec, &bOK) == 0)
1000 GMX_RELEASE_ASSERT(!bOK, "Inconsistent results - OK status from read_first_xtc, but 0 atom coords read");
1001 fr->not_ok = DATA_NOT_OK;
1006 printincomp(*status, fr);
1010 fr->bPrec = (fr->prec > 0);
1015 printcount(*status, oenv, fr->time, FALSE);
1021 if (!gmx_read_next_tng_frame((*status)->tng, fr, NULL, 0))
1023 fr->not_ok = DATA_NOT_OK;
1025 printincomp(*status, fr);
1029 printcount(*status, oenv, fr->time, FALSE);
1034 pdb_first_x(*status, gmx_fio_getfp(fio), fr);
1037 printcount(*status, oenv, fr->time, FALSE);
1042 if (gro_first_x_or_v(gmx_fio_getfp(fio), fr))
1044 printcount(*status, oenv, fr->time, FALSE);
1050 fprintf(stderr, "The file format of %s is not a known trajectory format to GROMACS.\n"
1051 "Please make sure that the file is a trajectory!\n"
1052 "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n"
1053 "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n", fn);
1054 gmx_fio_fp_close(fio); /*only close the file without removing FIO entry*/
1055 if (!read_first_vmd_frame(fn, &(*status)->vmdplugin, fr))
1057 gmx_fatal(FARGS, "Not supported in read_first_frame: %s", fn);
1060 gmx_fatal(FARGS, "Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n"
1061 "GROMACS is not compiled with plug-in support. Thus it cannot read non-GROMACS trajectory formats using the VMD plug-ins.\n"
1062 "Please compile with plug-in support if you want to read non-GROMACS trajectory formats.\n", fn);
1066 (*status)->tf = fr->time;
1068 /* Return FALSE if we read a frame that's past the set ending time. */
1069 if (!bFirst && (!(flags & TRX_DONT_SKIP) && check_times(fr->time) > 0))
1071 (*status)->t0 = fr->time;
1076 (!(flags & TRX_DONT_SKIP) && check_times(fr->time) < 0))
1078 /* Read a frame when no frame was read or the first was skipped */
1079 if (!read_next_frame(oenv, *status, fr))
1084 (*status)->t0 = fr->time;
1086 /* We need the number of atoms for random-access XTC searching, even when
1087 * we don't have access to the actual frame data.
1089 (*status)->natoms = fr->natoms;
1091 return (fr->natoms > 0);
1094 /***** C O O R D I N A T E S T U F F *****/
1096 int read_first_x(const gmx_output_env_t *oenv, t_trxstatus **status, const char *fn,
1097 real *t, rvec **x, matrix box)
1101 read_first_frame(oenv, status, fn, &fr, TRX_NEED_X);
1103 snew((*status)->xframe, 1);
1104 (*status)->nxframe = 1;
1105 (*(*status)->xframe) = fr;
1106 *t = (*status)->xframe->time;
1107 *x = (*status)->xframe->x;
1108 copy_mat((*status)->xframe->box, box);
1110 return (*status)->xframe->natoms;
1113 gmx_bool read_next_x(const gmx_output_env_t *oenv, t_trxstatus *status, real *t,
1114 rvec x[], matrix box)
1118 status->xframe->x = x;
1119 /*xframe[status].x = x;*/
1120 bRet = read_next_frame(oenv, status, status->xframe);
1121 *t = status->xframe->time;
1122 copy_mat(status->xframe->box, box);
1127 void close_trj(t_trxstatus *status)
1129 if (status == nullptr)
1133 gmx_tng_close(&status->tng);
1136 gmx_fio_close(status->fio);
1139 /* The memory in status->xframe is lost here,
1140 * but the read_first_x/read_next_x functions are deprecated anyhow.
1141 * read_first_frame/read_next_frame and close_trx should be used.
1146 void rewind_trj(t_trxstatus *status)
1150 gmx_fio_rewind(status->fio);
1153 /***** T O P O L O G Y S T U F F ******/
1155 t_topology *read_top(const char *fn, int *ePBC)
1161 epbc = read_tpx_top(fn, NULL, NULL, &natoms, NULL, NULL, top);