Remove gmx custom fixed int (e.g. gmx_int64_t) types
[gromacs.git] / src / gromacs / fileio / trxio.cpp
blobb4ce57ed8a67af47273b68043f28bc78b7e2fdad
1 /*
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.
37 #include "gmxpre.h"
39 #include "trxio.h"
41 #include "config.h"
43 #include <cassert>
44 #include <cmath>
45 #include <cstring>
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"
73 #if GMX_USE_PLUGINS
74 #include "gromacs/fileio/vmdio.h"
75 #endif
77 /* defines for frame counter output */
78 #define SKIP1 10
79 #define SKIP2 100
80 #define SKIP3 1000
82 struct t_trxstatus
84 int flags; /* flags for read_first/next_frame */
85 int __frame;
86 real t0; /* time of the first frame, needed *
87 * for skipping frames with -dt */
88 real tf; /* internal frame time */
89 t_trxframe *xframe;
90 t_fileio *fio;
91 gmx_tng_trajectory_t tng;
92 int natoms;
93 double DT, BOX[3];
94 gmx_bool bReadBox;
95 char *persistent_line; /* Persistent line for reading g96 trajectories */
96 #if GMX_USE_PLUGINS
97 gmx_vmdplugin_t *vmdplugin;
98 #endif
101 /* utility functions */
103 gmx_bool bRmod_fd(double a, double b, double c, gmx_bool bDouble)
105 int iq;
106 double tol;
108 tol = 2*(bDouble ? GMX_DOUBLE_EPS : GMX_FLOAT_EPS);
110 iq = (int)((a - b + tol*a)/c);
112 return fabs(a - b - c*iq) <= tol*fabs(a);
117 int check_times2(real t, real t0, gmx_bool bDouble)
119 int r;
121 #if !GMX_DOUBLE
122 /* since t is float, we can not use double precision for bRmod */
123 bDouble = FALSE;
124 #endif
126 r = -1;
127 if ((!bTimeSet(TBEGIN) || (t >= rTimeValue(TBEGIN))) &&
128 (!bTimeSet(TEND) || (t <= rTimeValue(TEND))))
130 if (bTimeSet(TDELTA) && !bRmod_fd(t, t0, rTimeValue(TDELTA), bDouble))
132 r = -1;
134 else
136 r = 0;
139 else if (bTimeSet(TEND) && (t >= rTimeValue(TEND)))
141 r = 1;
143 if (debug)
145 fprintf(debug, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n",
146 t, t0, rTimeValue(TBEGIN), rTimeValue(TEND), rTimeValue(TDELTA), r);
148 return r;
151 int check_times(real t)
153 return check_times2(t, t, FALSE);
156 static void initcount(t_trxstatus *status)
158 status->__frame = -1;
161 static void status_init(t_trxstatus *status)
163 status->flags = 0;
164 status->xframe = nullptr;
165 status->fio = nullptr;
166 status->__frame = -1;
167 status->t0 = 0;
168 status->tf = 0;
169 status->persistent_line = nullptr;
170 status->tng = nullptr;
174 int nframes_read(t_trxstatus *status)
176 return status->__frame;
179 static void printcount_(t_trxstatus *status, const gmx_output_env_t *oenv,
180 const char *l, real t)
182 if ((status->__frame < 2*SKIP1 || status->__frame % SKIP1 == 0) &&
183 (status->__frame < 2*SKIP2 || status->__frame % SKIP2 == 0) &&
184 (status->__frame < 2*SKIP3 || status->__frame % SKIP3 == 0) &&
185 output_env_get_trajectory_io_verbosity(oenv) != 0)
187 fprintf(stderr, "\r%-14s %6d time %8.3f ", l, status->__frame,
188 output_env_conv_time(oenv, t));
189 fflush(stderr);
193 static void printcount(t_trxstatus *status, const gmx_output_env_t *oenv, real t,
194 gmx_bool bSkip)
196 status->__frame++;
197 printcount_(status, oenv, bSkip ? "Skipping frame" : "Reading frame", t);
200 static void printlast(t_trxstatus *status, const gmx_output_env_t *oenv, real t)
202 printcount_(status, oenv, "Last frame", t);
203 fprintf(stderr, "\n");
204 fflush(stderr);
207 static void printincomp(t_trxstatus *status, t_trxframe *fr)
209 if (fr->not_ok & HEADER_NOT_OK)
211 fprintf(stderr, "WARNING: Incomplete header: nr %d time %g\n",
212 status->__frame+1, fr->time);
214 else if (fr->not_ok)
216 fprintf(stderr, "WARNING: Incomplete frame: nr %d time %g\n",
217 status->__frame+1, fr->time);
219 fflush(stderr);
222 int prec2ndec(real prec)
224 if (prec <= 0)
226 gmx_fatal(FARGS, "DEATH HORROR prec (%g) <= 0 in prec2ndec", prec);
229 return (int)(log(prec)/log(10.0)+0.5);
232 real ndec2prec(int ndec)
234 return pow(10.0, ndec);
237 t_fileio *trx_get_fileio(t_trxstatus *status)
239 return status->fio;
242 float trx_get_time_of_final_frame(t_trxstatus *status)
244 t_fileio *stfio = trx_get_fileio(status);
245 int filetype = gmx_fio_getftp(stfio);
246 gmx_bool bOK;
247 float lasttime = -1;
249 if (filetype == efXTC)
251 lasttime =
252 xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio),
253 gmx_fio_getxdr(stfio),
254 status->natoms, &bOK);
255 if (!bOK)
257 gmx_fatal(FARGS, "Error reading last frame. Maybe seek not supported." );
260 else if (filetype == efTNG)
262 gmx_tng_trajectory_t tng = status->tng;
263 if (!tng)
265 gmx_fatal(FARGS, "Error opening TNG file.");
267 lasttime = gmx_tng_get_time_of_final_frame(tng);
269 else
271 gmx_incons("Only supported for TNG and XTC");
273 return lasttime;
276 void clear_trxframe(t_trxframe *fr, gmx_bool bFirst)
278 fr->not_ok = 0;
279 fr->bStep = FALSE;
280 fr->bTime = FALSE;
281 fr->bLambda = FALSE;
282 fr->bFepState = FALSE;
283 fr->bAtoms = FALSE;
284 fr->bPrec = FALSE;
285 fr->bX = FALSE;
286 fr->bV = FALSE;
287 fr->bF = FALSE;
288 fr->bBox = FALSE;
289 if (bFirst)
291 fr->bDouble = FALSE;
292 fr->natoms = -1;
293 fr->step = 0;
294 fr->time = 0;
295 fr->lambda = 0;
296 fr->fep_state = 0;
297 fr->atoms = nullptr;
298 fr->prec = 0;
299 fr->x = nullptr;
300 fr->v = nullptr;
301 fr->f = nullptr;
302 clear_mat(fr->box);
303 fr->bPBC = FALSE;
304 fr->ePBC = -1;
308 void set_trxframe_ePBC(t_trxframe *fr, int ePBC)
310 fr->bPBC = (ePBC == -1);
311 fr->ePBC = ePBC;
314 int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind,
315 const int *ind, gmx_conect gc)
317 char title[STRLEN];
318 rvec *xout = nullptr, *vout = nullptr, *fout = nullptr;
319 int i, ftp = -1;
320 real prec;
322 if (fr->bPrec)
324 prec = fr->prec;
326 else
328 prec = 1000.0;
331 if (status->tng)
333 ftp = efTNG;
335 else if (status->fio)
337 ftp = gmx_fio_getftp(status->fio);
339 else
341 gmx_incons("No input file available");
344 switch (ftp)
346 case efTRR:
347 case efTNG:
348 break;
349 default:
350 if (!fr->bX)
352 gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
353 ftp2ext(ftp));
355 break;
358 switch (ftp)
360 case efTRR:
361 case efTNG:
362 if (fr->bV)
364 snew(vout, nind);
365 for (i = 0; i < nind; i++)
367 copy_rvec(fr->v[ind[i]], vout[i]);
370 if (fr->bF)
372 snew(fout, nind);
373 for (i = 0; i < nind; i++)
375 copy_rvec(fr->f[ind[i]], fout[i]);
378 if (fr->bX)
380 snew(xout, nind);
381 for (i = 0; i < nind; i++)
383 copy_rvec(fr->x[ind[i]], xout[i]);
386 break;
387 case efXTC:
388 if (fr->bX)
390 snew(xout, nind);
391 for (i = 0; i < nind; i++)
393 copy_rvec(fr->x[ind[i]], xout[i]);
396 break;
397 default:
398 break;
401 switch (ftp)
403 case efTNG:
404 gmx_write_tng_from_trxframe(status->tng, fr, nind);
405 break;
406 case efXTC:
407 write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec);
408 break;
409 case efTRR:
410 gmx_trr_write_frame(status->fio, nframes_read(status),
411 fr->time, fr->step, fr->box, nind, xout, vout, fout);
412 break;
413 case efGRO:
414 case efPDB:
415 case efBRK:
416 case efENT:
417 if (!fr->bAtoms)
419 gmx_fatal(FARGS, "Can not write a %s file without atom names",
420 ftp2ext(ftp));
422 sprintf(title, "frame t= %.3f", fr->time);
423 if (ftp == efGRO)
425 write_hconf_indexed_p(gmx_fio_getfp(status->fio), title, fr->atoms, nind, ind,
426 fr->x, fr->bV ? fr->v : nullptr, fr->box);
428 else
430 write_pdbfile_indexed(gmx_fio_getfp(status->fio), title, fr->atoms,
431 fr->x, -1, fr->box, ' ', fr->step, nind, ind, gc, TRUE, FALSE);
433 break;
434 case efG96:
435 sprintf(title, "frame t= %.3f", fr->time);
436 write_g96_conf(gmx_fio_getfp(status->fio), title, fr, nind, ind);
437 break;
438 default:
439 gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s",
440 ftp2ext(ftp));
443 switch (ftp)
445 case efTRR:
446 case efTNG:
447 if (vout)
449 sfree(vout);
451 if (fout)
453 sfree(fout);
455 sfree(xout);
456 break;
457 case efXTC:
458 sfree(xout);
459 break;
460 default:
461 break;
464 return 0;
467 t_trxstatus *
468 trjtools_gmx_prepare_tng_writing(const char *filename,
469 char filemode,
470 t_trxstatus *in,
471 const char *infile,
472 const int natoms,
473 const gmx_mtop_t *mtop,
474 const int *index,
475 const char *index_group_name)
477 if (filemode != 'w' && filemode != 'a')
479 gmx_incons("Sorry, can only prepare for TNG output.");
481 t_trxstatus *out;
482 snew(out, 1);
483 status_init(out);
485 if (in != nullptr)
487 gmx_prepare_tng_writing(filename,
488 filemode,
489 &in->tng,
490 &out->tng,
491 natoms,
492 mtop,
493 index,
494 index_group_name);
496 else if ((infile) && (efTNG == fn2ftp(infile)))
498 gmx_tng_trajectory_t tng_in;
499 gmx_tng_open(infile, 'r', &tng_in);
501 gmx_prepare_tng_writing(filename,
502 filemode,
503 &tng_in,
504 &out->tng,
505 natoms,
506 mtop,
507 index,
508 index_group_name);
510 else
512 // we start from a file that is not a tng file or have been unable to load the
513 // input file, so we need to populate the fields independently of it
514 gmx_prepare_tng_writing(filename,
515 filemode,
516 nullptr,
517 &out->tng,
518 natoms,
519 mtop,
520 index,
521 index_group_name);
523 return out;
526 void write_tng_frame(t_trxstatus *status,
527 t_trxframe *frame)
529 gmx_write_tng_from_trxframe(status->tng, frame, -1);
532 int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc)
534 char title[STRLEN];
535 real prec;
537 if (fr->bPrec)
539 prec = fr->prec;
541 else
543 prec = 1000.0;
546 if (status->tng)
548 gmx_tng_set_compression_precision(status->tng, prec);
549 write_tng_frame(status, fr);
551 return 0;
554 switch (gmx_fio_getftp(status->fio))
556 case efTRR:
557 break;
558 default:
559 if (!fr->bX)
561 gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
562 ftp2ext(gmx_fio_getftp(status->fio)));
564 break;
567 switch (gmx_fio_getftp(status->fio))
569 case efXTC:
570 write_xtc(status->fio, fr->natoms, fr->step, fr->time, fr->box, fr->x, prec);
571 break;
572 case efTRR:
573 gmx_trr_write_frame(status->fio, fr->step, fr->time, fr->lambda, fr->box, fr->natoms,
574 fr->bX ? fr->x : nullptr, fr->bV ? fr->v : nullptr, fr->bF ? fr->f : nullptr);
575 break;
576 case efGRO:
577 case efPDB:
578 case efBRK:
579 case efENT:
580 if (!fr->bAtoms)
582 gmx_fatal(FARGS, "Can not write a %s file without atom names",
583 ftp2ext(gmx_fio_getftp(status->fio)));
585 sprintf(title, "frame t= %.3f", fr->time);
586 if (gmx_fio_getftp(status->fio) == efGRO)
588 write_hconf_p(gmx_fio_getfp(status->fio), title, fr->atoms,
589 fr->x, fr->bV ? fr->v : nullptr, fr->box);
591 else
593 write_pdbfile(gmx_fio_getfp(status->fio), title,
594 fr->atoms, fr->x, fr->bPBC ? fr->ePBC : -1, fr->box,
595 ' ', fr->step, gc, TRUE);
597 break;
598 case efG96:
599 write_g96_conf(gmx_fio_getfp(status->fio), title, fr, -1, nullptr);
600 break;
601 default:
602 gmx_fatal(FARGS, "Sorry, write_trxframe can not write %s",
603 ftp2ext(gmx_fio_getftp(status->fio)));
606 return 0;
609 int write_trx(t_trxstatus *status, int nind, const int *ind, const t_atoms *atoms,
610 int step, real time, matrix box, rvec x[], rvec *v,
611 gmx_conect gc)
613 t_trxframe fr;
615 clear_trxframe(&fr, TRUE);
616 fr.bStep = TRUE;
617 fr.step = step;
618 fr.bTime = TRUE;
619 fr.time = time;
620 fr.bAtoms = atoms != nullptr;
621 fr.atoms = const_cast<t_atoms *>(atoms);
622 fr.bX = TRUE;
623 fr.x = x;
624 fr.bV = v != nullptr;
625 fr.v = v;
626 fr.bBox = TRUE;
627 copy_mat(box, fr.box);
629 return write_trxframe_indexed(status, &fr, nind, ind, gc);
632 void close_trx(t_trxstatus *status)
634 if (status == nullptr)
636 return;
638 gmx_tng_close(&status->tng);
639 if (status->fio)
641 gmx_fio_close(status->fio);
643 sfree(status->persistent_line);
644 #if GMX_USE_PLUGINS
645 sfree(status->vmdplugin);
646 #endif
647 /* The memory in status->xframe is lost here,
648 * but the read_first_x/read_next_x functions are deprecated anyhow.
649 * read_first_frame/read_next_frame and close_trx should be used.
651 sfree(status);
654 t_trxstatus *open_trx(const char *outfile, const char *filemode)
656 t_trxstatus *stat;
657 if (filemode[0] != 'w' && filemode[0] != 'a' && filemode[1] != '+')
659 gmx_fatal(FARGS, "Sorry, write_trx can only write");
662 snew(stat, 1);
663 status_init(stat);
665 stat->fio = gmx_fio_open(outfile, filemode);
666 return stat;
669 static gmx_bool gmx_next_frame(t_trxstatus *status, t_trxframe *fr)
671 gmx_trr_header_t sh;
672 gmx_bool bOK, bRet;
674 bRet = FALSE;
676 if (gmx_trr_read_frame_header(status->fio, &sh, &bOK))
678 fr->bDouble = sh.bDouble;
679 fr->natoms = sh.natoms;
680 fr->bStep = TRUE;
681 fr->step = sh.step;
682 fr->bTime = TRUE;
683 fr->time = sh.t;
684 fr->bLambda = TRUE;
685 fr->bFepState = TRUE;
686 fr->lambda = sh.lambda;
687 fr->bBox = sh.box_size > 0;
688 if (status->flags & (TRX_READ_X | TRX_NEED_X))
690 if (fr->x == nullptr)
692 snew(fr->x, sh.natoms);
694 fr->bX = sh.x_size > 0;
696 if (status->flags & (TRX_READ_V | TRX_NEED_V))
698 if (fr->v == nullptr)
700 snew(fr->v, sh.natoms);
702 fr->bV = sh.v_size > 0;
704 if (status->flags & (TRX_READ_F | TRX_NEED_F))
706 if (fr->f == nullptr)
708 snew(fr->f, sh.natoms);
710 fr->bF = sh.f_size > 0;
712 if (gmx_trr_read_frame_data(status->fio, &sh, fr->box, fr->x, fr->v, fr->f))
714 bRet = TRUE;
716 else
718 fr->not_ok = DATA_NOT_OK;
721 else if (!bOK)
723 fr->not_ok = HEADER_NOT_OK;
726 return bRet;
729 static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
731 t_atoms atoms;
732 t_symtab *symtab;
733 matrix boxpdb;
734 // Initiate model_nr to -1 rather than NOTSET.
735 // It is not worthwhile introducing extra variables in the
736 // read_pdbfile call to verify that a model_nr was read.
737 int ePBC, model_nr = -1, na;
738 char title[STRLEN], *time, *step;
739 double dbl;
741 atoms.nr = fr->natoms;
742 atoms.atom = nullptr;
743 atoms.pdbinfo = nullptr;
744 /* the other pointers in atoms should not be accessed if these are NULL */
745 snew(symtab, 1);
746 open_symtab(symtab);
747 na = read_pdbfile(fp, title, &model_nr, &atoms, symtab, fr->x, &ePBC, boxpdb, TRUE, nullptr);
748 free_symtab(symtab);
749 sfree(symtab);
750 set_trxframe_ePBC(fr, ePBC);
751 if (nframes_read(status) == 0)
753 fprintf(stderr, " '%s', %d atoms\n", title, fr->natoms);
755 fr->bPrec = TRUE;
756 fr->prec = 10000;
757 fr->bX = TRUE;
758 fr->bBox = (boxpdb[XX][XX] != 0.0);
759 if (fr->bBox)
761 copy_mat(boxpdb, fr->box);
764 fr->step = 0;
765 step = std::strstr(title, " step= ");
766 fr->bStep = (step && sscanf(step+7, "%" SCNd64, &fr->step) == 1);
768 dbl = 0.0;
769 time = std::strstr(title, " t= ");
770 fr->bTime = (time && sscanf(time+4, "%lf", &dbl) == 1);
771 fr->time = dbl;
773 if (na == 0)
775 return FALSE;
777 else
779 if (na != fr->natoms)
781 gmx_fatal(FARGS, "Number of atoms in pdb frame %d is %d instead of %d",
782 nframes_read(status), na, fr->natoms);
784 return TRUE;
788 static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
790 initcount(status);
792 fprintf(stderr, "Reading frames from pdb file");
793 frewind(fp);
794 get_pdb_coordnum(fp, &fr->natoms);
795 if (fr->natoms == 0)
797 gmx_fatal(FARGS, "\nNo coordinates in pdb file\n");
799 frewind(fp);
800 snew(fr->x, fr->natoms);
801 pdb_next_x(status, fp, fr);
803 return fr->natoms;
806 bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxframe *fr)
808 real pt;
809 int ct;
810 gmx_bool bOK, bMissingData = FALSE, bSkip = FALSE;
811 bool bRet = false;
812 int ftp;
814 pt = status->tf;
818 clear_trxframe(fr, FALSE);
820 if (status->tng)
822 /* Special treatment for TNG files */
823 ftp = efTNG;
825 else
827 ftp = gmx_fio_getftp(status->fio);
829 switch (ftp)
831 case efTRR:
832 bRet = gmx_next_frame(status, fr);
833 break;
834 case efCPT:
835 /* Checkpoint files can not contain mulitple frames */
836 break;
837 case efG96:
839 t_symtab *symtab = nullptr;
840 read_g96_conf(gmx_fio_getfp(status->fio), nullptr, nullptr, fr,
841 symtab, status->persistent_line);
842 bRet = (fr->natoms > 0);
843 break;
845 case efXTC:
846 if (bTimeSet(TBEGIN) && (status->tf < rTimeValue(TBEGIN)))
848 if (xtc_seek_time(status->fio, rTimeValue(TBEGIN), fr->natoms, TRUE))
850 gmx_fatal(FARGS, "Specified frame (time %f) doesn't exist or file corrupt/inconsistent.",
851 rTimeValue(TBEGIN));
853 initcount(status);
855 bRet = read_next_xtc(status->fio, fr->natoms, &fr->step, &fr->time, fr->box,
856 fr->x, &fr->prec, &bOK);
857 fr->bPrec = (bRet && fr->prec > 0);
858 fr->bStep = bRet;
859 fr->bTime = bRet;
860 fr->bX = bRet;
861 fr->bBox = bRet;
862 if (!bOK)
864 /* Actually the header could also be not ok,
865 but from bOK from read_next_xtc this can't be distinguished */
866 fr->not_ok = DATA_NOT_OK;
868 break;
869 case efTNG:
870 bRet = gmx_read_next_tng_frame(status->tng, fr, nullptr, 0);
871 break;
872 case efPDB:
873 bRet = pdb_next_x(status, gmx_fio_getfp(status->fio), fr);
874 break;
875 case efGRO:
876 bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio), fr);
877 break;
878 default:
879 #if GMX_USE_PLUGINS
880 bRet = read_next_vmd_frame(status->vmdplugin, fr);
881 #else
882 gmx_fatal(FARGS, "DEATH HORROR in read_next_frame ftp=%s,status=%s",
883 ftp2ext(gmx_fio_getftp(status->fio)),
884 gmx_fio_getname(status->fio));
885 #endif
887 status->tf = fr->time;
889 if (bRet)
891 bMissingData = (((status->flags & TRX_NEED_X) && !fr->bX) ||
892 ((status->flags & TRX_NEED_V) && !fr->bV) ||
893 ((status->flags & TRX_NEED_F) && !fr->bF));
894 bSkip = FALSE;
895 if (!bMissingData)
897 ct = check_times2(fr->time, status->t0, fr->bDouble);
898 if (ct == 0 || ((status->flags & TRX_DONT_SKIP) && ct < 0))
900 printcount(status, oenv, fr->time, FALSE);
902 else if (ct > 0)
904 bRet = false;
906 else
908 printcount(status, oenv, fr->time, TRUE);
909 bSkip = TRUE;
915 while (bRet && (bMissingData || bSkip));
917 if (!bRet)
919 printlast(status, oenv, pt);
920 if (fr->not_ok)
922 printincomp(status, fr);
926 return bRet;
929 bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status,
930 const char *fn, t_trxframe *fr, int flags)
932 t_fileio *fio = nullptr;
933 gmx_bool bFirst, bOK;
934 int ftp = fn2ftp(fn);
936 clear_trxframe(fr, TRUE);
938 bFirst = TRUE;
940 snew((*status), 1);
942 status_init( *status );
943 initcount(*status);
944 (*status)->flags = flags;
946 if (efTNG == ftp)
948 /* Special treatment for TNG files */
949 gmx_tng_open(fn, 'r', &(*status)->tng);
951 else
953 fio = (*status)->fio = gmx_fio_open(fn, "r");
955 switch (ftp)
957 case efTRR:
958 break;
959 case efCPT:
960 read_checkpoint_trxframe(fio, fr);
961 bFirst = FALSE;
962 break;
963 case efG96:
965 /* Can not rewind a compressed file, so open it twice */
966 if (!(*status)->persistent_line)
968 /* allocate the persistent line */
969 snew((*status)->persistent_line, STRLEN+1);
971 t_symtab *symtab = nullptr;
972 read_g96_conf(gmx_fio_getfp(fio), fn, nullptr, fr, symtab, (*status)->persistent_line);
973 gmx_fio_close(fio);
974 clear_trxframe(fr, FALSE);
975 if (flags & (TRX_READ_X | TRX_NEED_X))
977 snew(fr->x, fr->natoms);
979 if (flags & (TRX_READ_V | TRX_NEED_V))
981 snew(fr->v, fr->natoms);
983 (*status)->fio = gmx_fio_open(fn, "r");
984 break;
986 case efXTC:
987 if (read_first_xtc(fio, &fr->natoms, &fr->step, &fr->time, fr->box, &fr->x,
988 &fr->prec, &bOK) == 0)
990 GMX_RELEASE_ASSERT(!bOK, "Inconsistent results - OK status from read_first_xtc, but 0 atom coords read");
991 fr->not_ok = DATA_NOT_OK;
993 if (fr->not_ok)
995 fr->natoms = 0;
996 printincomp(*status, fr);
998 else
1000 fr->bPrec = (fr->prec > 0);
1001 fr->bStep = TRUE;
1002 fr->bTime = TRUE;
1003 fr->bX = TRUE;
1004 fr->bBox = TRUE;
1005 printcount(*status, oenv, fr->time, FALSE);
1007 bFirst = FALSE;
1008 break;
1009 case efTNG:
1010 fr->step = -1;
1011 if (!gmx_read_next_tng_frame((*status)->tng, fr, nullptr, 0))
1013 fr->not_ok = DATA_NOT_OK;
1014 fr->natoms = 0;
1015 printincomp(*status, fr);
1017 else
1019 printcount(*status, oenv, fr->time, FALSE);
1021 bFirst = FALSE;
1022 break;
1023 case efPDB:
1024 pdb_first_x(*status, gmx_fio_getfp(fio), fr);
1025 if (fr->natoms)
1027 printcount(*status, oenv, fr->time, FALSE);
1029 bFirst = FALSE;
1030 break;
1031 case efGRO:
1032 if (gro_first_x_or_v(gmx_fio_getfp(fio), fr))
1034 printcount(*status, oenv, fr->time, FALSE);
1036 bFirst = FALSE;
1037 break;
1038 default:
1039 #if GMX_USE_PLUGINS
1040 fprintf(stderr, "The file format of %s is not a known trajectory format to GROMACS.\n"
1041 "Please make sure that the file is a trajectory!\n"
1042 "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n"
1043 "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n", fn);
1044 gmx_fio_fp_close(fio); /*only close the file without removing FIO entry*/
1045 if (!read_first_vmd_frame(fn, &(*status)->vmdplugin, fr))
1047 gmx_fatal(FARGS, "Not supported in read_first_frame: %s", fn);
1049 #else
1050 gmx_fatal(FARGS, "Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n"
1051 "GROMACS is not compiled with plug-in support. Thus it cannot read non-GROMACS trajectory formats using the VMD plug-ins.\n"
1052 "Please compile with plug-in support if you want to read non-GROMACS trajectory formats.\n", fn);
1053 #endif
1054 break;
1056 (*status)->tf = fr->time;
1058 /* Return FALSE if we read a frame that's past the set ending time. */
1059 if (!bFirst && (!(flags & TRX_DONT_SKIP) && check_times(fr->time) > 0))
1061 (*status)->t0 = fr->time;
1062 return FALSE;
1065 if (bFirst ||
1066 (!(flags & TRX_DONT_SKIP) && check_times(fr->time) < 0))
1068 /* Read a frame when no frame was read or the first was skipped */
1069 if (!read_next_frame(oenv, *status, fr))
1071 return FALSE;
1074 (*status)->t0 = fr->time;
1076 /* We need the number of atoms for random-access XTC searching, even when
1077 * we don't have access to the actual frame data.
1079 (*status)->natoms = fr->natoms;
1081 return (fr->natoms > 0);
1084 /***** C O O R D I N A T E S T U F F *****/
1086 int read_first_x(const gmx_output_env_t *oenv, t_trxstatus **status, const char *fn,
1087 real *t, rvec **x, matrix box)
1089 t_trxframe fr;
1091 read_first_frame(oenv, status, fn, &fr, TRX_NEED_X);
1093 snew((*status)->xframe, 1);
1094 (*(*status)->xframe) = fr;
1095 *t = (*status)->xframe->time;
1096 *x = (*status)->xframe->x;
1097 copy_mat((*status)->xframe->box, box);
1099 return (*status)->xframe->natoms;
1102 gmx_bool read_next_x(const gmx_output_env_t *oenv, t_trxstatus *status, real *t,
1103 rvec x[], matrix box)
1105 gmx_bool bRet;
1107 status->xframe->x = x;
1108 /*xframe[status].x = x;*/
1109 bRet = read_next_frame(oenv, status, status->xframe);
1110 *t = status->xframe->time;
1111 copy_mat(status->xframe->box, box);
1113 return bRet;
1116 void rewind_trj(t_trxstatus *status)
1118 initcount(status);
1120 gmx_fio_rewind(status->fio);
1123 /***** T O P O L O G Y S T U F F ******/
1125 t_topology *read_top(const char *fn, int *ePBC)
1127 int epbc, natoms;
1128 t_topology *top;
1130 snew(top, 1);
1131 epbc = read_tpx_top(fn, nullptr, nullptr, &natoms, nullptr, nullptr, top);
1132 if (ePBC)
1134 *ePBC = epbc;
1137 return top;