Remove historical times from t_trxframe
[gromacs.git] / src / gromacs / fileio / trxio.cpp
bloba98031cbbc4f8f1535bf2afe2b49593d02082fc5
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, 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/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"
74 #if GMX_USE_PLUGINS
75 #include "gromacs/fileio/vmdio.h"
76 #endif
78 /* defines for frame counter output */
79 #define SKIP1 10
80 #define SKIP2 100
81 #define SKIP3 1000
83 struct t_trxstatus
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 int nxframe;
91 t_fileio *fio;
92 tng_trajectory_t tng;
93 int natoms;
94 double DT, BOX[3];
95 gmx_bool bReadBox;
96 char *persistent_line; /* Persistent line for reading g96 trajectories */
97 #if GMX_USE_PLUGINS
98 gmx_vmdplugin_t *vmdplugin;
99 #endif
102 /* utility functions */
104 gmx_bool bRmod_fd(double a, double b, double c, gmx_bool bDouble)
106 int iq;
107 double tol;
109 tol = 2*(bDouble ? GMX_DOUBLE_EPS : GMX_FLOAT_EPS);
111 iq = (int)((a - b + tol*a)/c);
113 if (fabs(a - b - c*iq) <= tol*fabs(a))
115 return TRUE;
117 else
119 return FALSE;
125 int check_times2(real t, real t0, gmx_bool bDouble)
127 int r;
129 #if !GMX_DOUBLE
130 /* since t is float, we can not use double precision for bRmod */
131 bDouble = FALSE;
132 #endif
134 r = -1;
135 if ((!bTimeSet(TBEGIN) || (t >= rTimeValue(TBEGIN))) &&
136 (!bTimeSet(TEND) || (t <= rTimeValue(TEND))))
138 if (bTimeSet(TDELTA) && !bRmod_fd(t, t0, rTimeValue(TDELTA), bDouble))
140 r = -1;
142 else
144 r = 0;
147 else if (bTimeSet(TEND) && (t >= rTimeValue(TEND)))
149 r = 1;
151 if (debug)
153 fprintf(debug, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n",
154 t, t0, rTimeValue(TBEGIN), rTimeValue(TEND), rTimeValue(TDELTA), r);
156 return r;
159 int check_times(real t)
161 return check_times2(t, t, FALSE);
164 static void initcount(t_trxstatus *status)
166 status->__frame = -1;
169 static void status_init(t_trxstatus *status)
171 status->nxframe = 0;
172 status->xframe = NULL;
173 status->fio = NULL;
174 status->__frame = -1;
175 status->t0 = 0;
176 status->tf = 0;
177 status->persistent_line = NULL;
178 status->tng = NULL;
182 int nframes_read(t_trxstatus *status)
184 return status->__frame;
187 static void printcount_(t_trxstatus *status, const gmx_output_env_t *oenv,
188 const char *l, real t)
190 if ((status->__frame < 2*SKIP1 || status->__frame % SKIP1 == 0) &&
191 (status->__frame < 2*SKIP2 || status->__frame % SKIP2 == 0) &&
192 (status->__frame < 2*SKIP3 || status->__frame % SKIP3 == 0))
194 fprintf(stderr, "\r%-14s %6d time %8.3f ", l, status->__frame,
195 output_env_conv_time(oenv, t));
199 static void printcount(t_trxstatus *status, const gmx_output_env_t *oenv, real t,
200 gmx_bool bSkip)
202 status->__frame++;
203 printcount_(status, oenv, bSkip ? "Skipping frame" : "Reading frame", t);
206 static void printlast(t_trxstatus *status, const gmx_output_env_t *oenv, real t)
208 printcount_(status, oenv, "Last frame", t);
209 fprintf(stderr, "\n");
212 static void printincomp(t_trxstatus *status, t_trxframe *fr)
214 if (fr->not_ok & HEADER_NOT_OK)
216 fprintf(stderr, "WARNING: Incomplete header: nr %d time %g\n",
217 status->__frame+1, fr->time);
219 else if (fr->not_ok)
221 fprintf(stderr, "WARNING: Incomplete frame: nr %d time %g\n",
222 status->__frame+1, fr->time);
226 int prec2ndec(real prec)
228 if (prec <= 0)
230 gmx_fatal(FARGS, "DEATH HORROR prec (%g) <= 0 in prec2ndec", prec);
233 return (int)(log(prec)/log(10.0)+0.5);
236 real ndec2prec(int ndec)
238 return pow(10.0, ndec);
241 t_fileio *trx_get_fileio(t_trxstatus *status)
243 return status->fio;
246 float trx_get_time_of_final_frame(t_trxstatus *status)
248 t_fileio *stfio = trx_get_fileio(status);
249 int filetype = gmx_fio_getftp(stfio);
250 int bOK;
251 float lasttime = -1;
253 if (filetype == efXTC)
255 lasttime =
256 xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio),
257 gmx_fio_getxdr(stfio),
258 status->natoms, &bOK);
259 if (!bOK)
261 gmx_fatal(FARGS, "Error reading last frame. Maybe seek not supported." );
264 else if (filetype == efTNG)
266 tng_trajectory_t tng = status->tng;
267 if (!tng)
269 gmx_fatal(FARGS, "Error opening TNG file.");
271 lasttime = gmx_tng_get_time_of_final_frame(tng);
273 else
275 gmx_incons("Only supported for TNG and XTC");
277 return lasttime;
280 void clear_trxframe(t_trxframe *fr, gmx_bool bFirst)
282 fr->not_ok = 0;
283 fr->bTitle = FALSE;
284 fr->bStep = FALSE;
285 fr->bTime = FALSE;
286 fr->bLambda = FALSE;
287 fr->bFepState = FALSE;
288 fr->bAtoms = FALSE;
289 fr->bPrec = FALSE;
290 fr->bX = FALSE;
291 fr->bV = FALSE;
292 fr->bF = FALSE;
293 fr->bBox = FALSE;
294 if (bFirst)
296 fr->flags = 0;
297 fr->bDouble = FALSE;
298 fr->natoms = -1;
299 fr->title = NULL;
300 fr->step = 0;
301 fr->time = 0;
302 fr->lambda = 0;
303 fr->fep_state = 0;
304 fr->atoms = NULL;
305 fr->prec = 0;
306 fr->x = NULL;
307 fr->v = NULL;
308 fr->f = NULL;
309 clear_mat(fr->box);
310 fr->bPBC = FALSE;
311 fr->ePBC = -1;
315 void set_trxframe_ePBC(t_trxframe *fr, int ePBC)
317 fr->bPBC = (ePBC == -1);
318 fr->ePBC = ePBC;
321 int write_trxframe_indexed(t_trxstatus *status, t_trxframe *fr, int nind,
322 const int *ind, gmx_conect gc)
324 char title[STRLEN];
325 rvec *xout = NULL, *vout = NULL, *fout = NULL;
326 int i, ftp = -1;
327 real prec;
329 if (fr->bPrec)
331 prec = fr->prec;
333 else
335 prec = 1000.0;
338 if (status->tng)
340 ftp = efTNG;
342 else if (status->fio)
344 ftp = gmx_fio_getftp(status->fio);
346 else
348 gmx_incons("No input file available");
351 switch (ftp)
353 case efTRR:
354 case efTNG:
355 break;
356 default:
357 if (!fr->bX)
359 gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
360 ftp2ext(ftp));
362 break;
365 switch (ftp)
367 case efTRR:
368 case efTNG:
369 if (fr->bV)
371 snew(vout, nind);
372 for (i = 0; i < nind; i++)
374 copy_rvec(fr->v[ind[i]], vout[i]);
377 if (fr->bF)
379 snew(fout, nind);
380 for (i = 0; i < nind; i++)
382 copy_rvec(fr->f[ind[i]], fout[i]);
385 /* no break */
386 case efXTC:
387 if (fr->bX)
389 snew(xout, nind);
390 for (i = 0; i < nind; i++)
392 copy_rvec(fr->x[ind[i]], xout[i]);
395 break;
396 default:
397 break;
400 switch (ftp)
402 case efTNG:
403 gmx_write_tng_from_trxframe(status->tng, fr, nind);
404 break;
405 case efXTC:
406 write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec);
407 break;
408 case efTRR:
409 gmx_trr_write_frame(status->fio, nframes_read(status),
410 fr->time, fr->step, fr->box, nind, xout, vout, fout);
411 break;
412 case efGRO:
413 case efPDB:
414 case efBRK:
415 case efENT:
416 if (!fr->bAtoms)
418 gmx_fatal(FARGS, "Can not write a %s file without atom names",
419 ftp2ext(ftp));
421 sprintf(title, "frame t= %.3f", fr->time);
422 if (ftp == efGRO)
424 write_hconf_indexed_p(gmx_fio_getfp(status->fio), title, fr->atoms, nind, ind,
425 prec2ndec(prec),
426 fr->x, fr->bV ? fr->v : NULL, 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);
433 break;
434 case efG96:
435 write_g96_conf(gmx_fio_getfp(status->fio), fr, nind, ind);
436 break;
437 default:
438 gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s",
439 ftp2ext(ftp));
440 break;
443 switch (ftp)
445 case efTRR:
446 case efTNG:
447 if (vout)
449 sfree(vout);
451 if (fout)
453 sfree(fout);
455 /* no break */
456 case efXTC:
457 sfree(xout);
458 break;
459 default:
460 break;
463 return 0;
466 void trjtools_gmx_prepare_tng_writing(const char *filename,
467 char filemode,
468 t_trxstatus *in,
469 t_trxstatus **out,
470 const char *infile,
471 const int natoms,
472 const gmx_mtop_t *mtop,
473 const int *index,
474 const char *index_group_name)
476 if (filemode != 'w' && filemode != 'a')
478 gmx_incons("Sorry, can only prepare for TNG output.");
481 if (*out == NULL)
483 snew((*out), 1);
485 status_init(*out);
487 if (in != NULL)
489 gmx_prepare_tng_writing(filename,
490 filemode,
491 &in->tng,
492 &(*out)->tng,
493 natoms,
494 mtop,
495 index,
496 index_group_name);
498 else if (efTNG == fn2ftp(infile))
500 tng_trajectory_t tng_in;
501 gmx_tng_open(infile, 'r', &tng_in);
503 gmx_prepare_tng_writing(filename,
504 filemode,
505 &tng_in,
506 &(*out)->tng,
507 natoms,
508 mtop,
509 index,
510 index_group_name);
514 void write_tng_frame(t_trxstatus *status,
515 t_trxframe *frame)
517 gmx_write_tng_from_trxframe(status->tng, frame, -1);
520 int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc)
522 char title[STRLEN];
523 real prec;
525 if (fr->bPrec)
527 prec = fr->prec;
529 else
531 prec = 1000.0;
534 if (status->tng)
536 gmx_tng_set_compression_precision(status->tng, prec);
537 write_tng_frame(status, fr);
539 return 0;
542 switch (gmx_fio_getftp(status->fio))
544 case efTRR:
545 break;
546 default:
547 if (!fr->bX)
549 gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
550 ftp2ext(gmx_fio_getftp(status->fio)));
552 break;
555 switch (gmx_fio_getftp(status->fio))
557 case efXTC:
558 write_xtc(status->fio, fr->natoms, fr->step, fr->time, fr->box, fr->x, prec);
559 break;
560 case efTRR:
561 gmx_trr_write_frame(status->fio, fr->step, fr->time, fr->lambda, fr->box, fr->natoms,
562 fr->bX ? fr->x : NULL, fr->bV ? fr->v : NULL, fr->bF ? fr->f : NULL);
563 break;
564 case efGRO:
565 case efPDB:
566 case efBRK:
567 case efENT:
568 if (!fr->bAtoms)
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 prec2ndec(prec), fr->x, fr->bV ? fr->v : NULL, fr->box);
579 else
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);
585 break;
586 case efG96:
587 write_g96_conf(gmx_fio_getfp(status->fio), fr, -1, NULL);
588 break;
589 default:
590 gmx_fatal(FARGS, "Sorry, write_trxframe can not write %s",
591 ftp2ext(gmx_fio_getftp(status->fio)));
592 break;
595 return 0;
598 int write_trx(t_trxstatus *status, int nind, const int *ind, t_atoms *atoms,
599 int step, real time, matrix box, rvec x[], rvec *v,
600 gmx_conect gc)
602 t_trxframe fr;
604 clear_trxframe(&fr, TRUE);
605 fr.bStep = TRUE;
606 fr.step = step;
607 fr.bTime = TRUE;
608 fr.time = time;
609 fr.bAtoms = atoms != NULL;
610 fr.atoms = atoms;
611 fr.bX = TRUE;
612 fr.x = x;
613 fr.bV = v != NULL;
614 fr.v = v;
615 fr.bBox = TRUE;
616 copy_mat(box, fr.box);
618 return write_trxframe_indexed(status, &fr, nind, ind, gc);
621 void close_trx(t_trxstatus *status)
623 gmx_tng_close(&status->tng);
624 if (status->fio)
626 gmx_fio_close(status->fio);
628 sfree(status);
631 t_trxstatus *open_trx(const char *outfile, const char *filemode)
633 t_trxstatus *stat;
634 if (filemode[0] != 'w' && filemode[0] != 'a' && filemode[1] != '+')
636 gmx_fatal(FARGS, "Sorry, write_trx can only write");
639 snew(stat, 1);
640 status_init(stat);
642 stat->fio = gmx_fio_open(outfile, filemode);
643 return stat;
646 static gmx_bool gmx_next_frame(t_trxstatus *status, t_trxframe *fr)
648 gmx_trr_header_t sh;
649 gmx_bool bOK, bRet;
651 bRet = FALSE;
653 if (gmx_trr_read_frame_header(status->fio, &sh, &bOK))
655 fr->bDouble = sh.bDouble;
656 fr->natoms = sh.natoms;
657 fr->bStep = TRUE;
658 fr->step = sh.step;
659 fr->bTime = TRUE;
660 fr->time = sh.t;
661 fr->bLambda = TRUE;
662 fr->bFepState = TRUE;
663 fr->lambda = sh.lambda;
664 fr->bBox = sh.box_size > 0;
665 if (fr->flags & (TRX_READ_X | TRX_NEED_X))
667 if (fr->x == NULL)
669 snew(fr->x, sh.natoms);
671 fr->bX = sh.x_size > 0;
673 if (fr->flags & (TRX_READ_V | TRX_NEED_V))
675 if (fr->v == NULL)
677 snew(fr->v, sh.natoms);
679 fr->bV = sh.v_size > 0;
681 if (fr->flags & (TRX_READ_F | TRX_NEED_F))
683 if (fr->f == NULL)
685 snew(fr->f, sh.natoms);
687 fr->bF = sh.f_size > 0;
689 if (gmx_trr_read_frame_data(status->fio, &sh, fr->box, fr->x, fr->v, fr->f))
691 bRet = TRUE;
693 else
695 fr->not_ok = DATA_NOT_OK;
698 else
699 if (!bOK)
701 fr->not_ok = HEADER_NOT_OK;
704 return bRet;
707 static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
709 t_atoms atoms;
710 t_symtab *symtab;
711 matrix boxpdb;
712 // Initiate model_nr to -1 rather than NOTSET.
713 // It is not worthwhile introducing extra variables in the
714 // read_pdbfile call to verify that a model_nr was read.
715 int ePBC, model_nr = -1, na;
716 char title[STRLEN], *time;
717 double dbl;
719 atoms.nr = fr->natoms;
720 atoms.atom = NULL;
721 atoms.pdbinfo = NULL;
722 /* the other pointers in atoms should not be accessed if these are NULL */
723 snew(symtab, 1);
724 open_symtab(symtab);
725 na = read_pdbfile(fp, title, &model_nr, &atoms, symtab, fr->x, &ePBC, boxpdb, TRUE, NULL);
726 free_symtab(symtab);
727 sfree(symtab);
728 set_trxframe_ePBC(fr, ePBC);
729 if (nframes_read(status) == 0)
731 fprintf(stderr, " '%s', %d atoms\n", title, fr->natoms);
733 fr->bPrec = TRUE;
734 fr->prec = 10000;
735 fr->bX = TRUE;
736 fr->bBox = (boxpdb[XX][XX] != 0.0);
737 if (fr->bBox)
739 copy_mat(boxpdb, fr->box);
742 if (model_nr != -1)
744 fr->bStep = TRUE;
745 fr->step = model_nr;
747 time = std::strstr(title, " t= ");
748 if (time)
750 fr->bTime = TRUE;
751 sscanf(time+4, "%lf", &dbl);
752 fr->time = (real)dbl;
754 else
756 fr->bTime = FALSE;
757 /* this is a bit dirty, but it will work: if no time is read from
758 comment line in pdb file, set time to current frame number */
759 if (fr->bStep)
761 fr->time = (real)fr->step;
763 else
765 fr->time = (real)nframes_read(status);
768 if (na == 0)
770 return FALSE;
772 else
774 if (na != fr->natoms)
776 gmx_fatal(FARGS, "Number of atoms in pdb frame %d is %d instead of %d",
777 nframes_read(status), na, fr->natoms);
779 return TRUE;
783 static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
785 initcount(status);
787 fprintf(stderr, "Reading frames from pdb file");
788 frewind(fp);
789 get_pdb_coordnum(fp, &fr->natoms);
790 if (fr->natoms == 0)
792 gmx_fatal(FARGS, "\nNo coordinates in pdb file\n");
794 frewind(fp);
795 snew(fr->x, fr->natoms);
796 pdb_next_x(status, fp, fr);
798 return fr->natoms;
801 gmx_bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxframe *fr)
803 real pt;
804 int ct;
805 gmx_bool bOK, bRet, bMissingData = FALSE, bSkip = FALSE;
806 int ftp;
808 bRet = FALSE;
809 pt = status->tf;
813 clear_trxframe(fr, FALSE);
815 if (status->tng)
817 /* Special treatment for TNG files */
818 ftp = efTNG;
820 else
822 ftp = gmx_fio_getftp(status->fio);
824 switch (ftp)
826 case efTRR:
827 bRet = gmx_next_frame(status, fr);
828 break;
829 case efCPT:
830 /* Checkpoint files can not contain mulitple frames */
831 break;
832 case efG96:
834 t_symtab *symtab;
835 snew(symtab, 1);
836 open_symtab(symtab);
837 read_g96_conf(gmx_fio_getfp(status->fio), NULL, fr,
838 symtab, status->persistent_line);
839 free_symtab(symtab);
840 bRet = (fr->natoms > 0);
841 break;
843 case efXTC:
844 if (bTimeSet(TBEGIN) && (status->tf < rTimeValue(TBEGIN)))
846 if (xtc_seek_time(status->fio, rTimeValue(TBEGIN), fr->natoms, TRUE))
848 gmx_fatal(FARGS, "Specified frame (time %f) doesn't exist or file corrupt/inconsistent.",
849 rTimeValue(TBEGIN));
851 initcount(status);
853 bRet = read_next_xtc(status->fio, fr->natoms, &fr->step, &fr->time, fr->box,
854 fr->x, &fr->prec, &bOK);
855 fr->bPrec = (bRet && fr->prec > 0);
856 fr->bStep = bRet;
857 fr->bTime = bRet;
858 fr->bX = bRet;
859 fr->bBox = bRet;
860 if (!bOK)
862 /* Actually the header could also be not ok,
863 but from bOK from read_next_xtc this can't be distinguished */
864 fr->not_ok = DATA_NOT_OK;
866 break;
867 case efTNG:
868 bRet = gmx_read_next_tng_frame(status->tng, fr, NULL, 0);
869 break;
870 case efPDB:
871 bRet = pdb_next_x(status, gmx_fio_getfp(status->fio), fr);
872 break;
873 case efGRO:
874 bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio), fr);
875 break;
876 default:
877 #if GMX_USE_PLUGINS
878 bRet = read_next_vmd_frame(status->vmdplugin, fr);
879 #else
880 gmx_fatal(FARGS, "DEATH HORROR in read_next_frame ftp=%s,status=%s",
881 ftp2ext(gmx_fio_getftp(status->fio)),
882 gmx_fio_getname(status->fio));
883 #endif
885 status->tf = fr->time;
887 if (bRet)
889 bMissingData = (((fr->flags & TRX_NEED_X) && !fr->bX) ||
890 ((fr->flags & TRX_NEED_V) && !fr->bV) ||
891 ((fr->flags & TRX_NEED_F) && !fr->bF));
892 bSkip = FALSE;
893 if (!bMissingData)
895 ct = check_times2(fr->time, status->t0, fr->bDouble);
896 if (ct == 0 || ((fr->flags & TRX_DONT_SKIP) && ct < 0))
898 printcount(status, oenv, fr->time, FALSE);
900 else if (ct > 0)
902 bRet = FALSE;
904 else
906 printcount(status, oenv, fr->time, TRUE);
907 bSkip = TRUE;
913 while (bRet && (bMissingData || bSkip));
915 if (!bRet)
917 printlast(status, oenv, pt);
918 if (fr->not_ok)
920 printincomp(status, fr);
924 return bRet;
927 int read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status,
928 const char *fn, t_trxframe *fr, int flags)
930 t_fileio *fio;
931 gmx_bool bFirst, bOK;
932 int ftp = fn2ftp(fn);
934 clear_trxframe(fr, TRUE);
935 fr->flags = flags;
937 bFirst = TRUE;
939 snew((*status), 1);
941 status_init( *status );
942 (*status)->nxframe = 1;
943 initcount(*status);
945 if (efTNG == ftp)
947 /* Special treatment for TNG files */
948 gmx_tng_open(fn, 'r', &(*status)->tng);
950 else
952 fio = (*status)->fio = gmx_fio_open(fn, "r");
954 switch (ftp)
956 case efTRR:
957 break;
958 case efCPT:
959 read_checkpoint_trxframe(fio, fr);
960 bFirst = FALSE;
961 break;
962 case efG96:
964 /* Can not rewind a compressed file, so open it twice */
965 if (!(*status)->persistent_line)
967 /* allocate the persistent line */
968 snew((*status)->persistent_line, STRLEN+1);
970 t_symtab *symtab;
971 snew(symtab, 1);
972 open_symtab(symtab);
973 read_g96_conf(gmx_fio_getfp(fio), fn, fr, symtab, (*status)->persistent_line);
974 free_symtab(symtab);
975 gmx_fio_close(fio);
976 clear_trxframe(fr, FALSE);
977 if (flags & (TRX_READ_X | TRX_NEED_X))
979 snew(fr->x, fr->natoms);
981 if (flags & (TRX_READ_V | TRX_NEED_V))
983 snew(fr->v, fr->natoms);
985 (*status)->fio = gmx_fio_open(fn, "r");
986 break;
988 case efXTC:
989 if (read_first_xtc(fio, &fr->natoms, &fr->step, &fr->time, fr->box, &fr->x,
990 &fr->prec, &bOK) == 0)
992 GMX_RELEASE_ASSERT(!bOK, "Inconsistent results - OK status from read_first_xtc, but 0 atom coords read");
993 fr->not_ok = DATA_NOT_OK;
995 if (fr->not_ok)
997 fr->natoms = 0;
998 printincomp(*status, fr);
1000 else
1002 fr->bPrec = (fr->prec > 0);
1003 fr->bStep = TRUE;
1004 fr->bTime = TRUE;
1005 fr->bX = TRUE;
1006 fr->bBox = TRUE;
1007 printcount(*status, oenv, fr->time, FALSE);
1009 bFirst = FALSE;
1010 break;
1011 case efTNG:
1012 fr->step = -1;
1013 if (!gmx_read_next_tng_frame((*status)->tng, fr, NULL, 0))
1015 fr->not_ok = DATA_NOT_OK;
1016 fr->natoms = 0;
1017 printincomp(*status, fr);
1019 else
1021 printcount(*status, oenv, fr->time, FALSE);
1023 bFirst = FALSE;
1024 break;
1025 case efPDB:
1026 pdb_first_x(*status, gmx_fio_getfp(fio), fr);
1027 if (fr->natoms)
1029 printcount(*status, oenv, fr->time, FALSE);
1031 bFirst = FALSE;
1032 break;
1033 case efGRO:
1034 if (gro_first_x_or_v(gmx_fio_getfp(fio), fr))
1036 printcount(*status, oenv, fr->time, FALSE);
1038 bFirst = FALSE;
1039 break;
1040 default:
1041 #if GMX_USE_PLUGINS
1042 fprintf(stderr, "The file format of %s is not a known trajectory format to GROMACS.\n"
1043 "Please make sure that the file is a trajectory!\n"
1044 "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n"
1045 "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n", fn);
1046 gmx_fio_fp_close(fio); /*only close the file without removing FIO entry*/
1047 if (!read_first_vmd_frame(fn, &(*status)->vmdplugin, fr))
1049 gmx_fatal(FARGS, "Not supported in read_first_frame: %s", fn);
1051 #else
1052 gmx_fatal(FARGS, "Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n"
1053 "GROMACS is not compiled with plug-in support. Thus it cannot read non-GROMACS trajectory formats using the VMD plug-ins.\n"
1054 "Please compile with plug-in support if you want to read non-GROMACS trajectory formats.\n", fn);
1055 #endif
1056 break;
1058 (*status)->tf = fr->time;
1060 /* Return FALSE if we read a frame that's past the set ending time. */
1061 if (!bFirst && (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) > 0))
1063 (*status)->t0 = fr->time;
1064 return FALSE;
1067 if (bFirst ||
1068 (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) < 0))
1070 /* Read a frame when no frame was read or the first was skipped */
1071 if (!read_next_frame(oenv, *status, fr))
1073 return FALSE;
1076 (*status)->t0 = fr->time;
1078 /* We need the number of atoms for random-access XTC searching, even when
1079 * we don't have access to the actual frame data.
1081 (*status)->natoms = fr->natoms;
1083 return (fr->natoms > 0);
1086 /***** C O O R D I N A T E S T U F F *****/
1088 int read_first_x(const gmx_output_env_t *oenv, t_trxstatus **status, const char *fn,
1089 real *t, rvec **x, matrix box)
1091 t_trxframe fr;
1093 read_first_frame(oenv, status, fn, &fr, TRX_NEED_X);
1095 snew((*status)->xframe, 1);
1096 (*status)->nxframe = 1;
1097 (*(*status)->xframe) = fr;
1098 *t = (*status)->xframe->time;
1099 *x = (*status)->xframe->x;
1100 copy_mat((*status)->xframe->box, box);
1102 return (*status)->xframe->natoms;
1105 gmx_bool read_next_x(const gmx_output_env_t *oenv, t_trxstatus *status, real *t,
1106 rvec x[], matrix box)
1108 gmx_bool bRet;
1110 status->xframe->x = x;
1111 /*xframe[status].x = x;*/
1112 bRet = read_next_frame(oenv, status, status->xframe);
1113 *t = status->xframe->time;
1114 copy_mat(status->xframe->box, box);
1116 return bRet;
1119 void close_trj(t_trxstatus *status)
1121 gmx_tng_close(&status->tng);
1122 if (status->fio)
1124 gmx_fio_close(status->fio);
1127 /* The memory in status->xframe is lost here,
1128 * but the read_first_x/read_next_x functions are deprecated anyhow.
1129 * read_first_frame/read_next_frame and close_trx should be used.
1131 sfree(status);
1134 void rewind_trj(t_trxstatus *status)
1136 initcount(status);
1138 gmx_fio_rewind(status->fio);
1141 /***** T O P O L O G Y S T U F F ******/
1143 t_topology *read_top(const char *fn, int *ePBC)
1145 int epbc, natoms;
1146 t_topology *top;
1148 snew(top, 1);
1149 epbc = read_tpx_top(fn, NULL, NULL, &natoms, NULL, NULL, top);
1150 if (ePBC)
1152 *ePBC = epbc;
1155 return top;