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,2018, 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/tpxio.h"
59 #include "gromacs/fileio/trrio.h"
60 #include "gromacs/fileio/xdrf.h"
61 #include "gromacs/fileio/xtcio.h"
62 #include "gromacs/math/vec.h"
63 #include "gromacs/mdtypes/md_enums.h"
64 #include "gromacs/topology/atoms.h"
65 #include "gromacs/topology/symtab.h"
66 #include "gromacs/topology/topology.h"
67 #include "gromacs/trajectory/trajectoryframe.h"
68 #include "gromacs/utility/fatalerror.h"
69 #include "gromacs/utility/futil.h"
70 #include "gromacs/utility/gmxassert.h"
71 #include "gromacs/utility/smalloc.h"
74 #include "gromacs/fileio/vmdio.h"
77 /* defines for frame counter output */
84 int flags
; /* flags for read_first/next_frame */
86 real t0
; /* time of the first frame, needed *
87 * for skipping frames with -dt */
88 real tf
; /* internal frame time */
91 gmx_tng_trajectory_t tng
;
95 char *persistent_line
; /* Persistent line for reading g96 trajectories */
97 gmx_vmdplugin_t
*vmdplugin
;
101 /* utility functions */
103 gmx_bool
bRmod_fd(double a
, double b
, double c
, gmx_bool bDouble
)
108 tol
= 2*(bDouble
? GMX_DOUBLE_EPS
: GMX_FLOAT_EPS
);
110 iq
= (int)((a
- b
+ tol
*a
)/c
);
112 if (fabs(a
- b
- c
*iq
) <= tol
*fabs(a
))
124 int check_times2(real t
, real t0
, gmx_bool bDouble
)
129 /* since t is float, we can not use double precision for bRmod */
134 if ((!bTimeSet(TBEGIN
) || (t
>= rTimeValue(TBEGIN
))) &&
135 (!bTimeSet(TEND
) || (t
<= rTimeValue(TEND
))))
137 if (bTimeSet(TDELTA
) && !bRmod_fd(t
, t0
, rTimeValue(TDELTA
), bDouble
))
146 else if (bTimeSet(TEND
) && (t
>= rTimeValue(TEND
)))
152 fprintf(debug
, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n",
153 t
, t0
, rTimeValue(TBEGIN
), rTimeValue(TEND
), rTimeValue(TDELTA
), r
);
158 int check_times(real t
)
160 return check_times2(t
, t
, FALSE
);
163 static void initcount(t_trxstatus
*status
)
165 status
->__frame
= -1;
168 static void status_init(t_trxstatus
*status
)
171 status
->xframe
= nullptr;
172 status
->fio
= nullptr;
173 status
->__frame
= -1;
176 status
->persistent_line
= nullptr;
177 status
->tng
= nullptr;
181 int nframes_read(t_trxstatus
*status
)
183 return status
->__frame
;
186 static void printcount_(t_trxstatus
*status
, const gmx_output_env_t
*oenv
,
187 const char *l
, real t
)
189 if ((status
->__frame
< 2*SKIP1
|| status
->__frame
% SKIP1
== 0) &&
190 (status
->__frame
< 2*SKIP2
|| status
->__frame
% SKIP2
== 0) &&
191 (status
->__frame
< 2*SKIP3
|| status
->__frame
% SKIP3
== 0) &&
192 output_env_get_trajectory_io_verbosity(oenv
) != 0)
194 fprintf(stderr
, "\r%-14s %6d time %8.3f ", l
, status
->__frame
,
195 output_env_conv_time(oenv
, t
));
200 static void printcount(t_trxstatus
*status
, const gmx_output_env_t
*oenv
, real t
,
204 printcount_(status
, oenv
, bSkip
? "Skipping frame" : "Reading frame", t
);
207 static void printlast(t_trxstatus
*status
, const gmx_output_env_t
*oenv
, real t
)
209 printcount_(status
, oenv
, "Last frame", t
);
210 fprintf(stderr
, "\n");
214 static void printincomp(t_trxstatus
*status
, t_trxframe
*fr
)
216 if (fr
->not_ok
& HEADER_NOT_OK
)
218 fprintf(stderr
, "WARNING: Incomplete header: nr %d time %g\n",
219 status
->__frame
+1, fr
->time
);
223 fprintf(stderr
, "WARNING: Incomplete frame: nr %d time %g\n",
224 status
->__frame
+1, fr
->time
);
229 int prec2ndec(real prec
)
233 gmx_fatal(FARGS
, "DEATH HORROR prec (%g) <= 0 in prec2ndec", prec
);
236 return (int)(log(prec
)/log(10.0)+0.5);
239 real
ndec2prec(int ndec
)
241 return pow(10.0, ndec
);
244 t_fileio
*trx_get_fileio(t_trxstatus
*status
)
249 float trx_get_time_of_final_frame(t_trxstatus
*status
)
251 t_fileio
*stfio
= trx_get_fileio(status
);
252 int filetype
= gmx_fio_getftp(stfio
);
256 if (filetype
== efXTC
)
259 xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio
),
260 gmx_fio_getxdr(stfio
),
261 status
->natoms
, &bOK
);
264 gmx_fatal(FARGS
, "Error reading last frame. Maybe seek not supported." );
267 else if (filetype
== efTNG
)
269 gmx_tng_trajectory_t tng
= status
->tng
;
272 gmx_fatal(FARGS
, "Error opening TNG file.");
274 lasttime
= gmx_tng_get_time_of_final_frame(tng
);
278 gmx_incons("Only supported for TNG and XTC");
283 void clear_trxframe(t_trxframe
*fr
, gmx_bool bFirst
)
289 fr
->bFepState
= FALSE
;
315 void set_trxframe_ePBC(t_trxframe
*fr
, int ePBC
)
317 fr
->bPBC
= (ePBC
== -1);
321 int write_trxframe_indexed(t_trxstatus
*status
, const t_trxframe
*fr
, int nind
,
322 const int *ind
, gmx_conect gc
)
325 rvec
*xout
= nullptr, *vout
= nullptr, *fout
= nullptr;
342 else if (status
->fio
)
344 ftp
= gmx_fio_getftp(status
->fio
);
348 gmx_incons("No input file available");
359 gmx_fatal(FARGS
, "Need coordinates to write a %s trajectory",
372 for (i
= 0; i
< nind
; i
++)
374 copy_rvec(fr
->v
[ind
[i
]], vout
[i
]);
380 for (i
= 0; i
< nind
; i
++)
382 copy_rvec(fr
->f
[ind
[i
]], fout
[i
]);
390 for (i
= 0; i
< nind
; i
++)
392 copy_rvec(fr
->x
[ind
[i
]], xout
[i
]);
403 gmx_write_tng_from_trxframe(status
->tng
, fr
, nind
);
406 write_xtc(status
->fio
, nind
, fr
->step
, fr
->time
, fr
->box
, xout
, prec
);
409 gmx_trr_write_frame(status
->fio
, nframes_read(status
),
410 fr
->time
, fr
->step
, fr
->box
, nind
, xout
, vout
, fout
);
418 gmx_fatal(FARGS
, "Can not write a %s file without atom names",
421 sprintf(title
, "frame t= %.3f", fr
->time
);
424 write_hconf_indexed_p(gmx_fio_getfp(status
->fio
), title
, fr
->atoms
, nind
, ind
,
425 fr
->x
, fr
->bV
? fr
->v
: nullptr, fr
->box
);
429 write_pdbfile_indexed(gmx_fio_getfp(status
->fio
), title
, fr
->atoms
,
430 fr
->x
, -1, fr
->box
, ' ', fr
->step
, nind
, ind
, gc
, TRUE
, FALSE
);
434 sprintf(title
, "frame t= %.3f", fr
->time
);
435 write_g96_conf(gmx_fio_getfp(status
->fio
), title
, fr
, nind
, ind
);
438 gmx_fatal(FARGS
, "Sorry, write_trxframe_indexed can not write %s",
466 void trjtools_gmx_prepare_tng_writing(const char *filename
,
472 const gmx_mtop_t
*mtop
,
474 const char *index_group_name
)
476 if (filemode
!= 'w' && filemode
!= 'a')
478 gmx_incons("Sorry, can only prepare for TNG output.");
489 gmx_prepare_tng_writing(filename
,
498 else if (efTNG
== fn2ftp(infile
))
500 gmx_tng_trajectory_t tng_in
;
501 gmx_tng_open(infile
, 'r', &tng_in
);
503 gmx_prepare_tng_writing(filename
,
514 void write_tng_frame(t_trxstatus
*status
,
517 gmx_write_tng_from_trxframe(status
->tng
, frame
, -1);
520 int write_trxframe(t_trxstatus
*status
, t_trxframe
*fr
, gmx_conect gc
)
536 gmx_tng_set_compression_precision(status
->tng
, prec
);
537 write_tng_frame(status
, fr
);
542 switch (gmx_fio_getftp(status
->fio
))
549 gmx_fatal(FARGS
, "Need coordinates to write a %s trajectory",
550 ftp2ext(gmx_fio_getftp(status
->fio
)));
555 switch (gmx_fio_getftp(status
->fio
))
558 write_xtc(status
->fio
, fr
->natoms
, fr
->step
, fr
->time
, fr
->box
, fr
->x
, prec
);
561 gmx_trr_write_frame(status
->fio
, fr
->step
, fr
->time
, fr
->lambda
, fr
->box
, fr
->natoms
,
562 fr
->bX
? fr
->x
: nullptr, fr
->bV
? fr
->v
: nullptr, fr
->bF
? fr
->f
: nullptr);
570 gmx_fatal(FARGS
, "Can not write a %s file without atom names",
571 ftp2ext(gmx_fio_getftp(status
->fio
)));
573 sprintf(title
, "frame t= %.3f", fr
->time
);
574 if (gmx_fio_getftp(status
->fio
) == efGRO
)
576 write_hconf_p(gmx_fio_getfp(status
->fio
), title
, fr
->atoms
,
577 fr
->x
, fr
->bV
? fr
->v
: nullptr, fr
->box
);
581 write_pdbfile(gmx_fio_getfp(status
->fio
), title
,
582 fr
->atoms
, fr
->x
, fr
->bPBC
? fr
->ePBC
: -1, fr
->box
,
583 ' ', fr
->step
, gc
, TRUE
);
587 write_g96_conf(gmx_fio_getfp(status
->fio
), title
, fr
, -1, nullptr);
590 gmx_fatal(FARGS
, "Sorry, write_trxframe can not write %s",
591 ftp2ext(gmx_fio_getftp(status
->fio
)));
598 int write_trx(t_trxstatus
*status
, int nind
, const int *ind
, const t_atoms
*atoms
,
599 int step
, real time
, matrix box
, rvec x
[], rvec
*v
,
604 clear_trxframe(&fr
, TRUE
);
609 fr
.bAtoms
= atoms
!= nullptr;
610 fr
.atoms
= const_cast<t_atoms
*>(atoms
);
613 fr
.bV
= v
!= nullptr;
616 copy_mat(box
, fr
.box
);
618 return write_trxframe_indexed(status
, &fr
, nind
, ind
, gc
);
621 void close_trx(t_trxstatus
*status
)
623 if (status
== nullptr)
627 gmx_tng_close(&status
->tng
);
630 gmx_fio_close(status
->fio
);
632 sfree(status
->persistent_line
);
634 sfree(status
->vmdplugin
);
636 /* The memory in status->xframe is lost here,
637 * but the read_first_x/read_next_x functions are deprecated anyhow.
638 * read_first_frame/read_next_frame and close_trx should be used.
643 t_trxstatus
*open_trx(const char *outfile
, const char *filemode
)
646 if (filemode
[0] != 'w' && filemode
[0] != 'a' && filemode
[1] != '+')
648 gmx_fatal(FARGS
, "Sorry, write_trx can only write");
654 stat
->fio
= gmx_fio_open(outfile
, filemode
);
658 static gmx_bool
gmx_next_frame(t_trxstatus
*status
, t_trxframe
*fr
)
665 if (gmx_trr_read_frame_header(status
->fio
, &sh
, &bOK
))
667 fr
->bDouble
= sh
.bDouble
;
668 fr
->natoms
= sh
.natoms
;
674 fr
->bFepState
= TRUE
;
675 fr
->lambda
= sh
.lambda
;
676 fr
->bBox
= sh
.box_size
> 0;
677 if (status
->flags
& (TRX_READ_X
| TRX_NEED_X
))
679 if (fr
->x
== nullptr)
681 snew(fr
->x
, sh
.natoms
);
683 fr
->bX
= sh
.x_size
> 0;
685 if (status
->flags
& (TRX_READ_V
| TRX_NEED_V
))
687 if (fr
->v
== nullptr)
689 snew(fr
->v
, sh
.natoms
);
691 fr
->bV
= sh
.v_size
> 0;
693 if (status
->flags
& (TRX_READ_F
| TRX_NEED_F
))
695 if (fr
->f
== nullptr)
697 snew(fr
->f
, sh
.natoms
);
699 fr
->bF
= sh
.f_size
> 0;
701 if (gmx_trr_read_frame_data(status
->fio
, &sh
, fr
->box
, fr
->x
, fr
->v
, fr
->f
))
707 fr
->not_ok
= DATA_NOT_OK
;
713 fr
->not_ok
= HEADER_NOT_OK
;
719 static gmx_bool
pdb_next_x(t_trxstatus
*status
, FILE *fp
, t_trxframe
*fr
)
724 // Initiate model_nr to -1 rather than NOTSET.
725 // It is not worthwhile introducing extra variables in the
726 // read_pdbfile call to verify that a model_nr was read.
727 int ePBC
, model_nr
= -1, na
;
728 char title
[STRLEN
], *time
, *step
;
731 atoms
.nr
= fr
->natoms
;
732 atoms
.atom
= nullptr;
733 atoms
.pdbinfo
= nullptr;
734 /* the other pointers in atoms should not be accessed if these are NULL */
737 na
= read_pdbfile(fp
, title
, &model_nr
, &atoms
, symtab
, fr
->x
, &ePBC
, boxpdb
, TRUE
, nullptr);
740 set_trxframe_ePBC(fr
, ePBC
);
741 if (nframes_read(status
) == 0)
743 fprintf(stderr
, " '%s', %d atoms\n", title
, fr
->natoms
);
748 fr
->bBox
= (boxpdb
[XX
][XX
] != 0.0);
751 copy_mat(boxpdb
, fr
->box
);
755 step
= std::strstr(title
, " step= ");
756 fr
->bStep
= (step
&& sscanf(step
+7, "%" GMX_SCNd64
, &fr
->step
) == 1);
759 time
= std::strstr(title
, " t= ");
760 fr
->bTime
= (time
&& sscanf(time
+4, "%lf", &dbl
) == 1);
769 if (na
!= fr
->natoms
)
771 gmx_fatal(FARGS
, "Number of atoms in pdb frame %d is %d instead of %d",
772 nframes_read(status
), na
, fr
->natoms
);
778 static int pdb_first_x(t_trxstatus
*status
, FILE *fp
, t_trxframe
*fr
)
782 fprintf(stderr
, "Reading frames from pdb file");
784 get_pdb_coordnum(fp
, &fr
->natoms
);
787 gmx_fatal(FARGS
, "\nNo coordinates in pdb file\n");
790 snew(fr
->x
, fr
->natoms
);
791 pdb_next_x(status
, fp
, fr
);
796 bool read_next_frame(const gmx_output_env_t
*oenv
, t_trxstatus
*status
, t_trxframe
*fr
)
800 gmx_bool bOK
, bMissingData
= FALSE
, bSkip
= FALSE
;
808 clear_trxframe(fr
, FALSE
);
812 /* Special treatment for TNG files */
817 ftp
= gmx_fio_getftp(status
->fio
);
822 bRet
= gmx_next_frame(status
, fr
);
825 /* Checkpoint files can not contain mulitple frames */
829 t_symtab
*symtab
= nullptr;
830 read_g96_conf(gmx_fio_getfp(status
->fio
), nullptr, nullptr, fr
,
831 symtab
, status
->persistent_line
);
832 bRet
= (fr
->natoms
> 0);
836 if (bTimeSet(TBEGIN
) && (status
->tf
< rTimeValue(TBEGIN
)))
838 if (xtc_seek_time(status
->fio
, rTimeValue(TBEGIN
), fr
->natoms
, TRUE
))
840 gmx_fatal(FARGS
, "Specified frame (time %f) doesn't exist or file corrupt/inconsistent.",
845 bRet
= read_next_xtc(status
->fio
, fr
->natoms
, &fr
->step
, &fr
->time
, fr
->box
,
846 fr
->x
, &fr
->prec
, &bOK
);
847 fr
->bPrec
= (bRet
&& fr
->prec
> 0);
854 /* Actually the header could also be not ok,
855 but from bOK from read_next_xtc this can't be distinguished */
856 fr
->not_ok
= DATA_NOT_OK
;
860 bRet
= gmx_read_next_tng_frame(status
->tng
, fr
, nullptr, 0);
863 bRet
= pdb_next_x(status
, gmx_fio_getfp(status
->fio
), fr
);
866 bRet
= gro_next_x_or_v(gmx_fio_getfp(status
->fio
), fr
);
870 bRet
= read_next_vmd_frame(status
->vmdplugin
, fr
);
872 gmx_fatal(FARGS
, "DEATH HORROR in read_next_frame ftp=%s,status=%s",
873 ftp2ext(gmx_fio_getftp(status
->fio
)),
874 gmx_fio_getname(status
->fio
));
877 status
->tf
= fr
->time
;
881 bMissingData
= (((status
->flags
& TRX_NEED_X
) && !fr
->bX
) ||
882 ((status
->flags
& TRX_NEED_V
) && !fr
->bV
) ||
883 ((status
->flags
& TRX_NEED_F
) && !fr
->bF
));
887 ct
= check_times2(fr
->time
, status
->t0
, fr
->bDouble
);
888 if (ct
== 0 || ((status
->flags
& TRX_DONT_SKIP
) && ct
< 0))
890 printcount(status
, oenv
, fr
->time
, FALSE
);
898 printcount(status
, oenv
, fr
->time
, TRUE
);
905 while (bRet
&& (bMissingData
|| bSkip
));
909 printlast(status
, oenv
, pt
);
912 printincomp(status
, fr
);
919 bool read_first_frame(const gmx_output_env_t
*oenv
, t_trxstatus
**status
,
920 const char *fn
, t_trxframe
*fr
, int flags
)
922 t_fileio
*fio
= nullptr;
923 gmx_bool bFirst
, bOK
;
924 int ftp
= fn2ftp(fn
);
926 clear_trxframe(fr
, TRUE
);
932 status_init( *status
);
934 (*status
)->flags
= flags
;
938 /* Special treatment for TNG files */
939 gmx_tng_open(fn
, 'r', &(*status
)->tng
);
943 fio
= (*status
)->fio
= gmx_fio_open(fn
, "r");
950 read_checkpoint_trxframe(fio
, fr
);
955 /* Can not rewind a compressed file, so open it twice */
956 if (!(*status
)->persistent_line
)
958 /* allocate the persistent line */
959 snew((*status
)->persistent_line
, STRLEN
+1);
961 t_symtab
*symtab
= nullptr;
962 read_g96_conf(gmx_fio_getfp(fio
), fn
, nullptr, fr
, symtab
, (*status
)->persistent_line
);
964 clear_trxframe(fr
, FALSE
);
965 if (flags
& (TRX_READ_X
| TRX_NEED_X
))
967 snew(fr
->x
, fr
->natoms
);
969 if (flags
& (TRX_READ_V
| TRX_NEED_V
))
971 snew(fr
->v
, fr
->natoms
);
973 (*status
)->fio
= gmx_fio_open(fn
, "r");
977 if (read_first_xtc(fio
, &fr
->natoms
, &fr
->step
, &fr
->time
, fr
->box
, &fr
->x
,
978 &fr
->prec
, &bOK
) == 0)
980 GMX_RELEASE_ASSERT(!bOK
, "Inconsistent results - OK status from read_first_xtc, but 0 atom coords read");
981 fr
->not_ok
= DATA_NOT_OK
;
986 printincomp(*status
, fr
);
990 fr
->bPrec
= (fr
->prec
> 0);
995 printcount(*status
, oenv
, fr
->time
, FALSE
);
1001 if (!gmx_read_next_tng_frame((*status
)->tng
, fr
, nullptr, 0))
1003 fr
->not_ok
= DATA_NOT_OK
;
1005 printincomp(*status
, fr
);
1009 printcount(*status
, oenv
, fr
->time
, FALSE
);
1014 pdb_first_x(*status
, gmx_fio_getfp(fio
), fr
);
1017 printcount(*status
, oenv
, fr
->time
, FALSE
);
1022 if (gro_first_x_or_v(gmx_fio_getfp(fio
), fr
))
1024 printcount(*status
, oenv
, fr
->time
, FALSE
);
1030 fprintf(stderr
, "The file format of %s is not a known trajectory format to GROMACS.\n"
1031 "Please make sure that the file is a trajectory!\n"
1032 "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n"
1033 "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n", fn
);
1034 gmx_fio_fp_close(fio
); /*only close the file without removing FIO entry*/
1035 if (!read_first_vmd_frame(fn
, &(*status
)->vmdplugin
, fr
))
1037 gmx_fatal(FARGS
, "Not supported in read_first_frame: %s", fn
);
1040 gmx_fatal(FARGS
, "Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n"
1041 "GROMACS is not compiled with plug-in support. Thus it cannot read non-GROMACS trajectory formats using the VMD plug-ins.\n"
1042 "Please compile with plug-in support if you want to read non-GROMACS trajectory formats.\n", fn
);
1046 (*status
)->tf
= fr
->time
;
1048 /* Return FALSE if we read a frame that's past the set ending time. */
1049 if (!bFirst
&& (!(flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) > 0))
1051 (*status
)->t0
= fr
->time
;
1056 (!(flags
& TRX_DONT_SKIP
) && check_times(fr
->time
) < 0))
1058 /* Read a frame when no frame was read or the first was skipped */
1059 if (!read_next_frame(oenv
, *status
, fr
))
1064 (*status
)->t0
= fr
->time
;
1066 /* We need the number of atoms for random-access XTC searching, even when
1067 * we don't have access to the actual frame data.
1069 (*status
)->natoms
= fr
->natoms
;
1071 return (fr
->natoms
> 0);
1074 /***** C O O R D I N A T E S T U F F *****/
1076 int read_first_x(const gmx_output_env_t
*oenv
, t_trxstatus
**status
, const char *fn
,
1077 real
*t
, rvec
**x
, matrix box
)
1081 read_first_frame(oenv
, status
, fn
, &fr
, TRX_NEED_X
);
1083 snew((*status
)->xframe
, 1);
1084 (*(*status
)->xframe
) = fr
;
1085 *t
= (*status
)->xframe
->time
;
1086 *x
= (*status
)->xframe
->x
;
1087 copy_mat((*status
)->xframe
->box
, box
);
1089 return (*status
)->xframe
->natoms
;
1092 gmx_bool
read_next_x(const gmx_output_env_t
*oenv
, t_trxstatus
*status
, real
*t
,
1093 rvec x
[], matrix box
)
1097 status
->xframe
->x
= x
;
1098 /*xframe[status].x = x;*/
1099 bRet
= read_next_frame(oenv
, status
, status
->xframe
);
1100 *t
= status
->xframe
->time
;
1101 copy_mat(status
->xframe
->box
, box
);
1106 void rewind_trj(t_trxstatus
*status
)
1110 gmx_fio_rewind(status
->fio
);
1113 /***** T O P O L O G Y S T U F F ******/
1115 t_topology
*read_top(const char *fn
, int *ePBC
)
1121 epbc
= read_tpx_top(fn
, nullptr, nullptr, &natoms
, nullptr, nullptr, top
);