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, 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.
46 #include "gromacs/fileio/confio.h"
47 #include "gromacs/fileio/g96io.h"
48 #include "gromacs/fileio/gmxfio.h"
49 #include "gromacs/fileio/gmxfio-xdr.h"
50 #include "gromacs/fileio/pdbio.h"
51 #include "gromacs/fileio/timecontrol.h"
52 #include "gromacs/fileio/tngio.h"
53 #include "gromacs/fileio/tngio_for_tools.h"
54 #include "gromacs/fileio/tpxio.h"
55 #include "gromacs/fileio/trnio.h"
56 #include "gromacs/fileio/trx.h"
57 #include "gromacs/fileio/xdrf.h"
58 #include "gromacs/fileio/xtcio.h"
59 #include "gromacs/legacyheaders/checkpoint.h"
60 #include "gromacs/legacyheaders/names.h"
61 #include "gromacs/math/vec.h"
62 #include "gromacs/topology/atoms.h"
63 #include "gromacs/utility/fatalerror.h"
64 #include "gromacs/utility/futil.h"
65 #include "gromacs/utility/gmxassert.h"
66 #include "gromacs/utility/smalloc.h"
68 #ifdef GMX_USE_PLUGINS
69 #include "gromacs/fileio/vmdio.h"
72 /* defines for frame counter output */
87 char *persistent_line
; /* Persistent line for reading g96 trajectories */
90 /* utility functions */
92 gmx_bool
bRmod_fd(double a
, double b
, double c
, gmx_bool bDouble
)
97 tol
= 2*(bDouble
? GMX_DOUBLE_EPS
: GMX_FLOAT_EPS
);
99 iq
= (int)((a
- b
+ tol
*a
)/c
);
101 if (fabs(a
- b
- c
*iq
) <= tol
*fabs(a
))
113 int check_times2(real t
, real t0
, gmx_bool bDouble
)
118 /* since t is float, we can not use double precision for bRmod */
123 if ((!bTimeSet(TBEGIN
) || (t
>= rTimeValue(TBEGIN
))) &&
124 (!bTimeSet(TEND
) || (t
<= rTimeValue(TEND
))))
126 if (bTimeSet(TDELTA
) && !bRmod_fd(t
, t0
, rTimeValue(TDELTA
), bDouble
))
135 else if (bTimeSet(TEND
) && (t
>= rTimeValue(TEND
)))
141 fprintf(debug
, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n",
142 t
, t0
, rTimeValue(TBEGIN
), rTimeValue(TEND
), rTimeValue(TDELTA
), r
);
147 int check_times(real t
)
149 return check_times2(t
, t
, FALSE
);
152 static void initcount(t_trxstatus
*status
)
154 status
->__frame
= -1;
157 static void status_init(t_trxstatus
*status
)
160 status
->xframe
= NULL
;
162 status
->__frame
= -1;
163 status
->persistent_line
= NULL
;
168 int nframes_read(t_trxstatus
*status
)
170 return status
->__frame
;
173 static void printcount_(t_trxstatus
*status
, const output_env_t oenv
,
174 const char *l
, real t
)
176 if ((status
->__frame
< 2*SKIP1
|| status
->__frame
% SKIP1
== 0) &&
177 (status
->__frame
< 2*SKIP2
|| status
->__frame
% SKIP2
== 0) &&
178 (status
->__frame
< 2*SKIP3
|| status
->__frame
% SKIP3
== 0))
180 fprintf(stderr
, "\r%-14s %6d time %8.3f ", l
, status
->__frame
,
181 output_env_conv_time(oenv
, t
));
185 static void printcount(t_trxstatus
*status
, const output_env_t oenv
, real t
,
189 printcount_(status
, oenv
, bSkip
? "Skipping frame" : "Reading frame", t
);
192 static void printlast(t_trxstatus
*status
, const output_env_t oenv
, real t
)
194 printcount_(status
, oenv
, "Last frame", t
);
195 fprintf(stderr
, "\n");
198 static void printincomp(t_trxstatus
*status
, t_trxframe
*fr
)
200 if (fr
->not_ok
& HEADER_NOT_OK
)
202 fprintf(stderr
, "WARNING: Incomplete header: nr %d time %g\n",
203 status
->__frame
+1, fr
->time
);
207 fprintf(stderr
, "WARNING: Incomplete frame: nr %d time %g\n",
208 status
->__frame
+1, fr
->time
);
212 int prec2ndec(real prec
)
216 gmx_fatal(FARGS
, "DEATH HORROR prec (%g) <= 0 in prec2ndec", prec
);
219 return (int)(log(prec
)/log(10.0)+0.5);
222 real
ndec2prec(int ndec
)
224 return pow(10.0, ndec
);
227 t_fileio
*trx_get_fileio(t_trxstatus
*status
)
232 float trx_get_time_of_final_frame(t_trxstatus
*status
)
234 t_fileio
*stfio
= trx_get_fileio(status
);
235 int filetype
= gmx_fio_getftp(stfio
);
239 if (filetype
== efXTC
)
242 xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio
),
243 gmx_fio_getxdr(stfio
),
244 status
->natoms
, &bOK
);
247 gmx_fatal(FARGS
, "Error reading last frame. Maybe seek not supported." );
250 else if (filetype
== efTNG
)
252 tng_trajectory_t tng
= status
->tng
;
255 gmx_fatal(FARGS
, "Error opening TNG file.");
257 lasttime
= gmx_tng_get_time_of_final_frame(tng
);
261 gmx_incons("Only supported for TNG and XTC");
266 void clear_trxframe(t_trxframe
*fr
, gmx_bool bFirst
)
273 fr
->bFepState
= FALSE
;
305 void set_trxframe_ePBC(t_trxframe
*fr
, int ePBC
)
307 fr
->bPBC
= (ePBC
== -1);
311 int write_trxframe_indexed(t_trxstatus
*status
, t_trxframe
*fr
, int nind
,
312 const atom_id
*ind
, gmx_conect gc
)
315 rvec
*xout
= NULL
, *vout
= NULL
, *fout
= NULL
;
332 else if (status
->fio
)
334 ftp
= gmx_fio_getftp(status
->fio
);
338 gmx_incons("No input file available");
349 gmx_fatal(FARGS
, "Need coordinates to write a %s trajectory",
362 for (i
= 0; i
< nind
; i
++)
364 copy_rvec(fr
->v
[ind
[i
]], vout
[i
]);
370 for (i
= 0; i
< nind
; i
++)
372 copy_rvec(fr
->f
[ind
[i
]], fout
[i
]);
380 for (i
= 0; i
< nind
; i
++)
382 copy_rvec(fr
->x
[ind
[i
]], xout
[i
]);
393 gmx_write_tng_from_trxframe(status
->tng
, fr
, nind
);
396 write_xtc(status
->fio
, nind
, fr
->step
, fr
->time
, fr
->box
, xout
, prec
);
399 fwrite_trn(status
->fio
, nframes_read(status
),
400 fr
->time
, fr
->step
, fr
->box
, nind
, xout
, vout
, fout
);
408 gmx_fatal(FARGS
, "Can not write a %s file without atom names",
411 sprintf(title
, "frame t= %.3f", fr
->time
);
414 write_hconf_indexed_p(gmx_fio_getfp(status
->fio
), title
, fr
->atoms
, nind
, ind
,
416 fr
->x
, fr
->bV
? fr
->v
: NULL
, fr
->box
);
420 write_pdbfile_indexed(gmx_fio_getfp(status
->fio
), title
, fr
->atoms
,
421 fr
->x
, -1, fr
->box
, ' ', fr
->step
, nind
, ind
, gc
, TRUE
);
425 write_g96_conf(gmx_fio_getfp(status
->fio
), fr
, nind
, ind
);
428 gmx_fatal(FARGS
, "Sorry, write_trxframe_indexed can not write %s",
456 void trjtools_gmx_prepare_tng_writing(const char *filename
,
462 const gmx_mtop_t
*mtop
,
463 const atom_id
*index
,
464 const char *index_group_name
)
466 if (filemode
!= 'w' && filemode
!= 'a')
468 gmx_incons("Sorry, can only prepare for TNG output.");
479 gmx_prepare_tng_writing(filename
,
488 else if (efTNG
== fn2ftp(infile
))
490 tng_trajectory_t tng_in
;
491 gmx_tng_open(infile
, 'r', &tng_in
);
493 gmx_prepare_tng_writing(filename
,
504 void write_tng_frame(t_trxstatus
*status
,
507 gmx_write_tng_from_trxframe(status
->tng
, frame
, -1);
510 int write_trxframe(t_trxstatus
*status
, t_trxframe
*fr
, gmx_conect gc
)
526 gmx_tng_set_compression_precision(status
->tng
, prec
);
527 write_tng_frame(status
, fr
);
532 switch (gmx_fio_getftp(status
->fio
))
539 gmx_fatal(FARGS
, "Need coordinates to write a %s trajectory",
540 ftp2ext(gmx_fio_getftp(status
->fio
)));
545 switch (gmx_fio_getftp(status
->fio
))
548 write_xtc(status
->fio
, fr
->natoms
, fr
->step
, fr
->time
, fr
->box
, fr
->x
, prec
);
551 fwrite_trn(status
->fio
, fr
->step
, fr
->time
, fr
->lambda
, fr
->box
, fr
->natoms
,
552 fr
->bX
? fr
->x
: NULL
, fr
->bV
? fr
->v
: NULL
, fr
->bF
? fr
->f
: NULL
);
560 gmx_fatal(FARGS
, "Can not write a %s file without atom names",
561 ftp2ext(gmx_fio_getftp(status
->fio
)));
563 sprintf(title
, "frame t= %.3f", fr
->time
);
564 if (gmx_fio_getftp(status
->fio
) == efGRO
)
566 write_hconf_p(gmx_fio_getfp(status
->fio
), title
, fr
->atoms
,
567 prec2ndec(prec
), fr
->x
, fr
->bV
? fr
->v
: NULL
, fr
->box
);
571 write_pdbfile(gmx_fio_getfp(status
->fio
), title
,
572 fr
->atoms
, fr
->x
, fr
->bPBC
? fr
->ePBC
: -1, fr
->box
,
573 ' ', fr
->step
, gc
, TRUE
);
577 write_g96_conf(gmx_fio_getfp(status
->fio
), fr
, -1, NULL
);
580 gmx_fatal(FARGS
, "Sorry, write_trxframe can not write %s",
581 ftp2ext(gmx_fio_getftp(status
->fio
)));
588 int write_trx(t_trxstatus
*status
, int nind
, const atom_id
*ind
, t_atoms
*atoms
,
589 int step
, real time
, matrix box
, rvec x
[], rvec
*v
,
594 clear_trxframe(&fr
, TRUE
);
599 fr
.bAtoms
= atoms
!= NULL
;
606 copy_mat(box
, fr
.box
);
608 return write_trxframe_indexed(status
, &fr
, nind
, ind
, gc
);
611 void close_trx(t_trxstatus
*status
)
613 gmx_tng_close(&status
->tng
);
616 gmx_fio_close(status
->fio
);
621 t_trxstatus
*open_trx(const char *outfile
, const char *filemode
)
624 if (filemode
[0] != 'w' && filemode
[0] != 'a' && filemode
[1] != '+')
626 gmx_fatal(FARGS
, "Sorry, write_trx can only write");
632 stat
->fio
= gmx_fio_open(outfile
, filemode
);
636 static gmx_bool
gmx_next_frame(t_trxstatus
*status
, t_trxframe
*fr
)
643 if (fread_trnheader(status
->fio
, &sh
, &bOK
))
645 fr
->bDouble
= sh
.bDouble
;
646 fr
->natoms
= sh
.natoms
;
652 fr
->bFepState
= TRUE
;
653 fr
->lambda
= sh
.lambda
;
654 fr
->bBox
= sh
.box_size
> 0;
655 if (fr
->flags
& (TRX_READ_X
| TRX_NEED_X
))
659 snew(fr
->x
, sh
.natoms
);
661 fr
->bX
= sh
.x_size
> 0;
663 if (fr
->flags
& (TRX_READ_V
| TRX_NEED_V
))
667 snew(fr
->v
, sh
.natoms
);
669 fr
->bV
= sh
.v_size
> 0;
671 if (fr
->flags
& (TRX_READ_F
| TRX_NEED_F
))
675 snew(fr
->f
, sh
.natoms
);
677 fr
->bF
= sh
.f_size
> 0;
679 if (fread_htrn(status
->fio
, &sh
, fr
->box
, fr
->x
, fr
->v
, fr
->f
))
685 fr
->not_ok
= DATA_NOT_OK
;
691 fr
->not_ok
= HEADER_NOT_OK
;
697 static gmx_bool
pdb_next_x(t_trxstatus
*status
, FILE *fp
, t_trxframe
*fr
)
701 int ePBC
, model_nr
, na
;
702 char title
[STRLEN
], *time
;
705 atoms
.nr
= fr
->natoms
;
707 atoms
.pdbinfo
= NULL
;
708 /* the other pointers in atoms should not be accessed if these are NULL */
710 na
= read_pdbfile(fp
, title
, &model_nr
, &atoms
, fr
->x
, &ePBC
, boxpdb
, TRUE
, NULL
);
711 set_trxframe_ePBC(fr
, ePBC
);
712 if (nframes_read(status
) == 0)
714 fprintf(stderr
, " '%s', %d atoms\n", title
, fr
->natoms
);
719 fr
->bBox
= (boxpdb
[XX
][XX
] != 0.0);
722 copy_mat(boxpdb
, fr
->box
);
725 if (model_nr
!= NOTSET
)
730 time
= strstr(title
, " t= ");
734 sscanf(time
+4, "%lf", &dbl
);
735 fr
->time
= (real
)dbl
;
740 /* this is a bit dirty, but it will work: if no time is read from
741 comment line in pdb file, set time to current frame number */
744 fr
->time
= (real
)fr
->step
;
748 fr
->time
= (real
)nframes_read(status
);
757 if (na
!= fr
->natoms
)
759 gmx_fatal(FARGS
, "Number of atoms in pdb frame %d is %d instead of %d",
760 nframes_read(status
), na
, fr
->natoms
);
766 static int pdb_first_x(t_trxstatus
*status
, FILE *fp
, t_trxframe
*fr
)
770 fprintf(stderr
, "Reading frames from pdb file");
772 get_pdb_coordnum(fp
, &fr
->natoms
);
775 gmx_fatal(FARGS
, "\nNo coordinates in pdb file\n");
778 snew(fr
->x
, fr
->natoms
);
779 pdb_next_x(status
, fp
, fr
);
784 gmx_bool
read_next_frame(const output_env_t oenv
, t_trxstatus
*status
, t_trxframe
*fr
)
788 gmx_bool bOK
, bRet
, bMissingData
= FALSE
, bSkip
= FALSE
;
796 clear_trxframe(fr
, FALSE
);
802 /* Special treatment for TNG files */
807 ftp
= gmx_fio_getftp(status
->fio
);
812 bRet
= gmx_next_frame(status
, fr
);
815 /* Checkpoint files can not contain mulitple frames */
818 read_g96_conf(gmx_fio_getfp(status
->fio
), NULL
, fr
,
819 status
->persistent_line
);
820 bRet
= (fr
->natoms
> 0);
824 * Sometimes is off by one frame
825 * and sometimes reports frame not present/file not seekable
827 /* DvdS 2005-05-31: this has been fixed along with the increased
828 * accuracy of the control over -b and -e options.
830 if (bTimeSet(TBEGIN
) && (fr
->tf
< rTimeValue(TBEGIN
)))
832 if (xtc_seek_time(status
->fio
, rTimeValue(TBEGIN
), fr
->natoms
, TRUE
))
834 gmx_fatal(FARGS
, "Specified frame (time %f) doesn't exist or file corrupt/inconsistent.",
839 bRet
= read_next_xtc(status
->fio
, fr
->natoms
, &fr
->step
, &fr
->time
, fr
->box
,
840 fr
->x
, &fr
->prec
, &bOK
);
841 fr
->bPrec
= (bRet
&& fr
->prec
> 0);
848 /* Actually the header could also be not ok,
849 but from bOK from read_next_xtc this can't be distinguished */
850 fr
->not_ok
= DATA_NOT_OK
;
854 bRet
= gmx_read_next_tng_frame(status
->tng
, fr
, NULL
, 0);
857 bRet
= pdb_next_x(status
, gmx_fio_getfp(status
->fio
), fr
);
860 bRet
= gro_next_x_or_v(gmx_fio_getfp(status
->fio
), fr
);
863 #ifdef GMX_USE_PLUGINS
864 bRet
= read_next_vmd_frame(fr
);
866 gmx_fatal(FARGS
, "DEATH HORROR in read_next_frame ftp=%s,status=%s",
867 ftp2ext(gmx_fio_getftp(status
->fio
)),
868 gmx_fio_getname(status
->fio
));
875 bMissingData
= (((fr
->flags
& TRX_NEED_X
) && !fr
->bX
) ||
876 ((fr
->flags
& TRX_NEED_V
) && !fr
->bV
) ||
877 ((fr
->flags
& TRX_NEED_F
) && !fr
->bF
));
881 ct
= check_times2(fr
->time
, fr
->t0
, fr
->bDouble
);
882 if (ct
== 0 || ((fr
->flags
& TRX_DONT_SKIP
) && ct
< 0))
884 printcount(status
, oenv
, fr
->time
, FALSE
);
892 printcount(status
, oenv
, fr
->time
, TRUE
);
899 while (bRet
&& (bMissingData
|| bSkip
));
903 printlast(status
, oenv
, pt
);
906 printincomp(status
, fr
);
913 int read_first_frame(const output_env_t oenv
, t_trxstatus
**status
,
914 const char *fn
, t_trxframe
*fr
, int flags
)
917 gmx_bool bFirst
, bOK
;
918 int ftp
= fn2ftp(fn
);
920 clear_trxframe(fr
, TRUE
);
927 status_init( *status
);
928 (*status
)->nxframe
= 1;
933 /* Special treatment for TNG files */
934 gmx_tng_open(fn
, 'r', &(*status
)->tng
);
938 fio
= (*status
)->fio
= gmx_fio_open(fn
, "r");
945 read_checkpoint_trxframe(fio
, fr
);
949 /* Can not rewind a compressed file, so open it twice */
950 if (!(*status
)->persistent_line
)
952 /* allocate the persistent line */
953 snew((*status
)->persistent_line
, STRLEN
+1);
955 read_g96_conf(gmx_fio_getfp(fio
), fn
, fr
, (*status
)->persistent_line
);
957 clear_trxframe(fr
, FALSE
);
958 if (flags
& (TRX_READ_X
| TRX_NEED_X
))
960 snew(fr
->x
, fr
->natoms
);
962 if (flags
& (TRX_READ_V
| TRX_NEED_V
))
964 snew(fr
->v
, fr
->natoms
);
966 (*status
)->fio
= gmx_fio_open(fn
, "r");
969 if (read_first_xtc(fio
, &fr
->natoms
, &fr
->step
, &fr
->time
, fr
->box
, &fr
->x
,
970 &fr
->prec
, &bOK
) == 0)
972 GMX_RELEASE_ASSERT(!bOK
, "Inconsistent results - OK status from read_first_xtc, but 0 atom coords read");
973 fr
->not_ok
= DATA_NOT_OK
;
978 printincomp(*status
, fr
);
982 fr
->bPrec
= (fr
->prec
> 0);
987 printcount(*status
, oenv
, fr
->time
, FALSE
);
993 if (!gmx_read_next_tng_frame((*status
)->tng
, fr
, NULL
, 0))
995 fr
->not_ok
= DATA_NOT_OK
;
997 printincomp(*status
, fr
);
1001 printcount(*status
, oenv
, fr
->time
, FALSE
);
1006 pdb_first_x(*status
, gmx_fio_getfp(fio
), fr
);
1009 printcount(*status
, oenv
, fr
->time
, FALSE
);
1014 if (gro_first_x_or_v(gmx_fio_getfp(fio
), fr
))
1016 printcount(*status
, oenv
, fr
->time
, FALSE
);
1021 #ifdef GMX_USE_PLUGINS
1022 fprintf(stderr
, "The file format of %s is not a known trajectory format to GROMACS.\n"
1023 "Please make sure that the file is a trajectory!\n"
1024 "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n"
1025 "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n", fn
);
1026 gmx_fio_fp_close(fio
); /*only close the file without removing FIO entry*/
1027 if (!read_first_vmd_frame(fn
, fr
))
1029 gmx_fatal(FARGS
, "Not supported in read_first_frame: %s", fn
);
1032 gmx_fatal(FARGS
, "Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n"
1033 "GROMACS is not compiled with plug-in support. Thus it cannot read non-GROMACS trajectory formats using the VMD plug-ins.\n"
1034 "Please compile with plug-in support if you want to read non-GROMACS trajectory formats.\n", fn
);
1040 /* Return FALSE if we read a frame that's past the set ending time. */
1041 if (!bFirst
&& (!(fr
->flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) > 0))
1048 (!(fr
->flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) < 0))
1050 /* Read a frame when no frame was read or the first was skipped */
1051 if (!read_next_frame(oenv
, *status
, fr
))
1058 /* We need the number of atoms for random-access XTC searching, even when
1059 * we don't have access to the actual frame data.
1061 (*status
)->natoms
= fr
->natoms
;
1063 return (fr
->natoms
> 0);
1066 /***** C O O R D I N A T E S T U F F *****/
1068 int read_first_x(const output_env_t oenv
, t_trxstatus
**status
, const char *fn
,
1069 real
*t
, rvec
**x
, matrix box
)
1073 read_first_frame(oenv
, status
, fn
, &fr
, TRX_NEED_X
);
1075 snew((*status
)->xframe
, 1);
1076 (*status
)->nxframe
= 1;
1077 (*(*status
)->xframe
) = fr
;
1078 *t
= (*status
)->xframe
->time
;
1079 *x
= (*status
)->xframe
->x
;
1080 copy_mat((*status
)->xframe
->box
, box
);
1082 return (*status
)->xframe
->natoms
;
1085 gmx_bool
read_next_x(const output_env_t oenv
, t_trxstatus
*status
, real
*t
,
1086 rvec x
[], matrix box
)
1090 status
->xframe
->x
= x
;
1091 /*xframe[status].x = x;*/
1092 bRet
= read_next_frame(oenv
, status
, status
->xframe
);
1093 *t
= status
->xframe
->time
;
1094 copy_mat(status
->xframe
->box
, box
);
1099 void close_trj(t_trxstatus
*status
)
1101 gmx_tng_close(&status
->tng
);
1104 gmx_fio_close(status
->fio
);
1107 /* The memory in status->xframe is lost here,
1108 * but the read_first_x/read_next_x functions are deprecated anyhow.
1109 * read_first_frame/read_next_frame and close_trx should be used.
1114 void rewind_trj(t_trxstatus
*status
)
1118 gmx_fio_rewind(status
->fio
);
1121 /***** T O P O L O G Y S T U F F ******/
1123 t_topology
*read_top(const char *fn
, int *ePBC
)
1129 epbc
= read_tpx_top(fn
, NULL
, NULL
, &natoms
, NULL
, NULL
, NULL
, top
);