Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / fileio / trxio.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014, 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.
10  *
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.
15  *
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.
20  *
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.
25  *
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.
33  *
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.
36  */
37 #include "gmxpre.h"
38
39 #include "trxio.h"
40
41 #include "config.h"
42
43 #include <assert.h>
44 #include <math.h>
45
46 #include "gromacs/fileio/confio.h"
47 #include "gromacs/fileio/gmxfio.h"
48 #include "gromacs/fileio/pdbio.h"
49 #include "gromacs/fileio/timecontrol.h"
50 #include "gromacs/fileio/tngio.h"
51 #include "gromacs/fileio/tngio_for_tools.h"
52 #include "gromacs/fileio/tpxio.h"
53 #include "gromacs/fileio/trnio.h"
54 #include "gromacs/fileio/trx.h"
55 #include "gromacs/fileio/xdrf.h"
56 #include "gromacs/fileio/xtcio.h"
57 #include "gromacs/legacyheaders/checkpoint.h"
58 #include "gromacs/legacyheaders/names.h"
59 #include "gromacs/math/vec.h"
60 #include "gromacs/topology/atoms.h"
61 #include "gromacs/utility/fatalerror.h"
62 #include "gromacs/utility/futil.h"
63 #include "gromacs/utility/smalloc.h"
64
65 #ifdef GMX_USE_PLUGINS
66 #include "gromacs/fileio/vmdio.h"
67 #endif
68
69 /* defines for frame counter output */
70 #define SKIP1   10
71 #define SKIP2  100
72 #define SKIP3 1000
73
74 struct t_trxstatus
75 {
76     int                     __frame;
77     t_trxframe             *xframe;
78     int                     nxframe;
79     t_fileio               *fio;
80     tng_trajectory_t        tng;
81     int                     NATOMS;
82     double                  DT, BOX[3];
83     gmx_bool                bReadBox;
84     char                   *persistent_line; /* Persistent line for reading g96 trajectories */
85 };
86
87 /* utility functions */
88
89 gmx_bool bRmod_fd(double a, double b, double c, gmx_bool bDouble)
90 {
91     int    iq;
92     double tol;
93
94     tol = 2*(bDouble ? GMX_DOUBLE_EPS : GMX_FLOAT_EPS);
95
96     iq = (int)((a - b + tol*a)/c);
97
98     if (fabs(a - b - c*iq) <= tol*fabs(a))
99     {
100         return TRUE;
101     }
102     else
103     {
104         return FALSE;
105     }
106 }
107
108
109
110 int check_times2(real t, real t0, gmx_bool bDouble)
111 {
112     int  r;
113
114 #ifndef GMX_DOUBLE
115     /* since t is float, we can not use double precision for bRmod */
116     bDouble = FALSE;
117 #endif
118
119     r = -1;
120     if ((!bTimeSet(TBEGIN) || (t >= rTimeValue(TBEGIN)))  &&
121         (!bTimeSet(TEND)   || (t <= rTimeValue(TEND))))
122     {
123         if (bTimeSet(TDELTA) && !bRmod_fd(t, t0, rTimeValue(TDELTA), bDouble))
124         {
125             r = -1;
126         }
127         else
128         {
129             r = 0;
130         }
131     }
132     else if (bTimeSet(TEND) && (t >= rTimeValue(TEND)))
133     {
134         r = 1;
135     }
136     if (debug)
137     {
138         fprintf(debug, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n",
139                 t, t0, rTimeValue(TBEGIN), rTimeValue(TEND), rTimeValue(TDELTA), r);
140     }
141     return r;
142 }
143
144 int check_times(real t)
145 {
146     return check_times2(t, t, FALSE);
147 }
148
149 static void initcount(t_trxstatus *status)
150 {
151     status->__frame = -1;
152 }
153
154 static void status_init(t_trxstatus *status)
155 {
156     status->nxframe         = 0;
157     status->xframe          = NULL;
158     status->fio             = NULL;
159     status->__frame         = -1;
160     status->persistent_line = NULL;
161     status->tng             = NULL;
162 }
163
164
165 int nframes_read(t_trxstatus *status)
166 {
167     return status->__frame;
168 }
169
170 static void printcount_(t_trxstatus *status, const output_env_t oenv,
171                         const char *l, real t)
172 {
173     if ((status->__frame < 2*SKIP1 || status->__frame % SKIP1 == 0) &&
174         (status->__frame < 2*SKIP2 || status->__frame % SKIP2 == 0) &&
175         (status->__frame < 2*SKIP3 || status->__frame % SKIP3 == 0))
176     {
177         fprintf(stderr, "\r%-14s %6d time %8.3f   ", l, status->__frame,
178                 output_env_conv_time(oenv, t));
179     }
180 }
181
182 static void printcount(t_trxstatus *status, const output_env_t oenv, real t,
183                        gmx_bool bSkip)
184 {
185     status->__frame++;
186     printcount_(status, oenv, bSkip ? "Skipping frame" : "Reading frame", t);
187 }
188
189 static void printlast(t_trxstatus *status, const output_env_t oenv, real t)
190 {
191     printcount_(status, oenv, "Last frame", t);
192     fprintf(stderr, "\n");
193 }
194
195 static void printincomp(t_trxstatus *status, t_trxframe *fr)
196 {
197     if (fr->not_ok & HEADER_NOT_OK)
198     {
199         fprintf(stderr, "WARNING: Incomplete header: nr %d time %g\n",
200                 status->__frame+1, fr->time);
201     }
202     else if (fr->not_ok)
203     {
204         fprintf(stderr, "WARNING: Incomplete frame: nr %d time %g\n",
205                 status->__frame+1, fr->time);
206     }
207 }
208
209 int prec2ndec(real prec)
210 {
211     if (prec <= 0)
212     {
213         gmx_fatal(FARGS, "DEATH HORROR prec (%g) <= 0 in prec2ndec", prec);
214     }
215
216     return (int)(log(prec)/log(10.0)+0.5);
217 }
218
219 real ndec2prec(int ndec)
220 {
221     return pow(10.0, ndec);
222 }
223
224 t_fileio *trx_get_fileio(t_trxstatus *status)
225 {
226     return status->fio;
227 }
228
229 float trx_get_time_of_final_frame(t_trxstatus *status)
230 {
231     t_fileio *stfio    = trx_get_fileio(status);
232     int       filetype = gmx_fio_getftp(stfio);
233     int       bOK;
234     float     lasttime = -1;
235
236     if (filetype == efXTC)
237     {
238         lasttime =
239             xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio),
240                                         gmx_fio_getxdr(stfio),
241                                         status->xframe->natoms, &bOK);
242         if (!bOK)
243         {
244             gmx_fatal(FARGS, "Error reading last frame. Maybe seek not supported." );
245         }
246     }
247     else if (filetype == efTNG)
248     {
249         tng_trajectory_t tng = status->tng;
250         if (!tng)
251         {
252             gmx_fatal(FARGS, "Error opening TNG file.");
253         }
254         lasttime = gmx_tng_get_time_of_final_frame(tng);
255     }
256     else
257     {
258         gmx_incons("Only supported for TNG and XTC");
259     }
260     return lasttime;
261 }
262
263 void clear_trxframe(t_trxframe *fr, gmx_bool bFirst)
264 {
265     fr->not_ok    = 0;
266     fr->bTitle    = FALSE;
267     fr->bStep     = FALSE;
268     fr->bTime     = FALSE;
269     fr->bLambda   = FALSE;
270     fr->bFepState = FALSE;
271     fr->bAtoms    = FALSE;
272     fr->bPrec     = FALSE;
273     fr->bX        = FALSE;
274     fr->bV        = FALSE;
275     fr->bF        = FALSE;
276     fr->bBox      = FALSE;
277     if (bFirst)
278     {
279         fr->flags     = 0;
280         fr->bDouble   = FALSE;
281         fr->natoms    = -1;
282         fr->t0        = 0;
283         fr->tf        = 0;
284         fr->tpf       = 0;
285         fr->tppf      = 0;
286         fr->title     = NULL;
287         fr->step      = 0;
288         fr->time      = 0;
289         fr->lambda    = 0;
290         fr->fep_state = 0;
291         fr->atoms     = NULL;
292         fr->prec      = 0;
293         fr->x         = NULL;
294         fr->v         = NULL;
295         fr->f         = NULL;
296         clear_mat(fr->box);
297         fr->bPBC   = FALSE;
298         fr->ePBC   = -1;
299     }
300 }
301
302 void set_trxframe_ePBC(t_trxframe *fr, int ePBC)
303 {
304     fr->bPBC = (ePBC == -1);
305     fr->ePBC = ePBC;
306 }
307
308 int write_trxframe_indexed(t_trxstatus *status, t_trxframe *fr, int nind,
309                            const atom_id *ind, gmx_conect gc)
310 {
311     char  title[STRLEN];
312     rvec *xout = NULL, *vout = NULL, *fout = NULL;
313     int   i, ftp = -1;
314     real  prec;
315
316     if (fr->bPrec)
317     {
318         prec = fr->prec;
319     }
320     else
321     {
322         prec = 1000.0;
323     }
324
325     if (status->tng)
326     {
327         ftp = efTNG;
328     }
329     else if (status->fio)
330     {
331         ftp = gmx_fio_getftp(status->fio);
332     }
333     else
334     {
335         gmx_incons("No input file available");
336     }
337
338     switch (ftp)
339     {
340         case efTRR:
341         case efTNG:
342             break;
343         default:
344             if (!fr->bX)
345             {
346                 gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
347                           ftp2ext(ftp));
348             }
349             break;
350     }
351
352     switch (ftp)
353     {
354         case efTRR:
355         case efTNG:
356             if (fr->bV)
357             {
358                 snew(vout, nind);
359                 for (i = 0; i < nind; i++)
360                 {
361                     copy_rvec(fr->v[ind[i]], vout[i]);
362                 }
363             }
364             if (fr->bF)
365             {
366                 snew(fout, nind);
367                 for (i = 0; i < nind; i++)
368                 {
369                     copy_rvec(fr->f[ind[i]], fout[i]);
370                 }
371             }
372         /* no break */
373         case efXTC:
374             if (fr->bX)
375             {
376                 snew(xout, nind);
377                 for (i = 0; i < nind; i++)
378                 {
379                     copy_rvec(fr->x[ind[i]], xout[i]);
380                 }
381             }
382             break;
383         default:
384             break;
385     }
386
387     switch (ftp)
388     {
389         case efTNG:
390             gmx_write_tng_from_trxframe(status->tng, fr, nind);
391             break;
392         case efXTC:
393             write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec);
394             break;
395         case efTRR:
396             fwrite_trn(status->fio, nframes_read(status),
397                        fr->time, fr->step, fr->box, nind, xout, vout, fout);
398             break;
399         case efGRO:
400         case efPDB:
401         case efBRK:
402         case efENT:
403             if (!fr->bAtoms)
404             {
405                 gmx_fatal(FARGS, "Can not write a %s file without atom names",
406                           ftp2ext(ftp));
407             }
408             sprintf(title, "frame t= %.3f", fr->time);
409             if (ftp == efGRO)
410             {
411                 write_hconf_indexed_p(gmx_fio_getfp(status->fio), title, fr->atoms, nind, ind,
412                                       prec2ndec(prec),
413                                       fr->x, fr->bV ? fr->v : NULL, fr->box);
414             }
415             else
416             {
417                 write_pdbfile_indexed(gmx_fio_getfp(status->fio), title, fr->atoms,
418                                       fr->x, -1, fr->box, ' ', fr->step, nind, ind, gc, TRUE);
419             }
420             break;
421         case efG96:
422             write_g96_conf(gmx_fio_getfp(status->fio), fr, nind, ind);
423             break;
424         default:
425             gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s",
426                       ftp2ext(ftp));
427             break;
428     }
429
430     switch (ftp)
431     {
432         case efTRR:
433         case efTNG:
434             if (vout)
435             {
436                 sfree(vout);
437             }
438             if (fout)
439             {
440                 sfree(fout);
441             }
442         /* no break */
443         case efXTC:
444             sfree(xout);
445             break;
446         default:
447             break;
448     }
449
450     return 0;
451 }
452
453 void trjtools_gmx_prepare_tng_writing(const char       *filename,
454                                       char              filemode,
455                                       t_trxstatus      *in,
456                                       t_trxstatus     **out,
457                                       const char       *infile,
458                                       const int         natoms,
459                                       const gmx_mtop_t *mtop,
460                                       const atom_id    *index,
461                                       const char       *index_group_name)
462 {
463     if (filemode != 'w' && filemode != 'a')
464     {
465         gmx_incons("Sorry, can only prepare for TNG output.");
466     }
467
468     if (*out == NULL)
469     {
470         snew((*out), 1);
471     }
472     status_init(*out);
473
474     if (in != NULL)
475     {
476         gmx_prepare_tng_writing(filename,
477                                 filemode,
478                                 &in->tng,
479                                 &(*out)->tng,
480                                 natoms,
481                                 mtop,
482                                 index,
483                                 index_group_name);
484     }
485     else if (efTNG == fn2ftp(infile))
486     {
487         tng_trajectory_t tng_in;
488         gmx_tng_open(infile, 'r', &tng_in);
489
490         gmx_prepare_tng_writing(filename,
491                                 filemode,
492                                 &tng_in,
493                                 &(*out)->tng,
494                                 natoms,
495                                 mtop,
496                                 index,
497                                 index_group_name);
498     }
499 }
500
501 void write_tng_frame(t_trxstatus *status,
502                      t_trxframe  *frame)
503 {
504     gmx_write_tng_from_trxframe(status->tng, frame, -1);
505 }
506
507 int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc)
508 {
509     char title[STRLEN];
510     real prec;
511
512     if (fr->bPrec)
513     {
514         prec = fr->prec;
515     }
516     else
517     {
518         prec = 1000.0;
519     }
520
521     if (status->tng)
522     {
523         gmx_tng_set_compression_precision(status->tng, prec);
524         write_tng_frame(status, fr);
525
526         return 0;
527     }
528
529     switch (gmx_fio_getftp(status->fio))
530     {
531         case efTRR:
532             break;
533         default:
534             if (!fr->bX)
535             {
536                 gmx_fatal(FARGS, "Need coordinates to write a %s trajectory",
537                           ftp2ext(gmx_fio_getftp(status->fio)));
538             }
539             break;
540     }
541
542     switch (gmx_fio_getftp(status->fio))
543     {
544         case efXTC:
545             write_xtc(status->fio, fr->natoms, fr->step, fr->time, fr->box, fr->x, prec);
546             break;
547         case efTRR:
548             fwrite_trn(status->fio, fr->step, fr->time, fr->lambda, fr->box, fr->natoms,
549                        fr->bX ? fr->x : NULL, fr->bV ? fr->v : NULL, fr->bF ? fr->f : NULL);
550             break;
551         case efGRO:
552         case efPDB:
553         case efBRK:
554         case efENT:
555             if (!fr->bAtoms)
556             {
557                 gmx_fatal(FARGS, "Can not write a %s file without atom names",
558                           ftp2ext(gmx_fio_getftp(status->fio)));
559             }
560             sprintf(title, "frame t= %.3f", fr->time);
561             if (gmx_fio_getftp(status->fio) == efGRO)
562             {
563                 write_hconf_p(gmx_fio_getfp(status->fio), title, fr->atoms,
564                               prec2ndec(prec), fr->x, fr->bV ? fr->v : NULL, fr->box);
565             }
566             else
567             {
568                 write_pdbfile(gmx_fio_getfp(status->fio), title,
569                               fr->atoms, fr->x, fr->bPBC ? fr->ePBC : -1, fr->box,
570                               ' ', fr->step, gc, TRUE);
571             }
572             break;
573         case efG96:
574             write_g96_conf(gmx_fio_getfp(status->fio), fr, -1, NULL);
575             break;
576         default:
577             gmx_fatal(FARGS, "Sorry, write_trxframe can not write %s",
578                       ftp2ext(gmx_fio_getftp(status->fio)));
579             break;
580     }
581
582     return 0;
583 }
584
585 int write_trx(t_trxstatus *status, int nind, const atom_id *ind, t_atoms *atoms,
586               int step, real time, matrix box, rvec x[], rvec *v,
587               gmx_conect gc)
588 {
589     t_trxframe fr;
590
591     clear_trxframe(&fr, TRUE);
592     fr.bStep  = TRUE;
593     fr.step   = step;
594     fr.bTime  = TRUE;
595     fr.time   = time;
596     fr.bAtoms = atoms != NULL;
597     fr.atoms  = atoms;
598     fr.bX     = TRUE;
599     fr.x      = x;
600     fr.bV     = v != NULL;
601     fr.v      = v;
602     fr.bBox   = TRUE;
603     copy_mat(box, fr.box);
604
605     return write_trxframe_indexed(status, &fr, nind, ind, gc);
606 }
607
608 void close_trx(t_trxstatus *status)
609 {
610     gmx_tng_close(&status->tng);
611     if (status->fio)
612     {
613         gmx_fio_close(status->fio);
614     }
615     sfree(status);
616 }
617
618 t_trxstatus *open_trx(const char *outfile, const char *filemode)
619 {
620     t_trxstatus *stat;
621     if (filemode[0] != 'w' && filemode[0] != 'a' && filemode[1] != '+')
622     {
623         gmx_fatal(FARGS, "Sorry, write_trx can only write");
624     }
625
626     snew(stat, 1);
627     status_init(stat);
628
629     stat->fio = gmx_fio_open(outfile, filemode);
630     return stat;
631 }
632
633 static gmx_bool gmx_next_frame(t_trxstatus *status, t_trxframe *fr)
634 {
635     t_trnheader sh;
636     gmx_bool    bOK, bRet;
637
638     bRet = FALSE;
639
640     if (fread_trnheader(status->fio, &sh, &bOK))
641     {
642         fr->bDouble   = sh.bDouble;
643         fr->natoms    = sh.natoms;
644         fr->bStep     = TRUE;
645         fr->step      = sh.step;
646         fr->bTime     = TRUE;
647         fr->time      = sh.t;
648         fr->bLambda   = TRUE;
649         fr->bFepState = TRUE;
650         fr->lambda    = sh.lambda;
651         fr->bBox      = sh.box_size > 0;
652         if (fr->flags & (TRX_READ_X | TRX_NEED_X))
653         {
654             if (fr->x == NULL)
655             {
656                 snew(fr->x, sh.natoms);
657             }
658             fr->bX = sh.x_size > 0;
659         }
660         if (fr->flags & (TRX_READ_V | TRX_NEED_V))
661         {
662             if (fr->v == NULL)
663             {
664                 snew(fr->v, sh.natoms);
665             }
666             fr->bV = sh.v_size > 0;
667         }
668         if (fr->flags & (TRX_READ_F | TRX_NEED_F))
669         {
670             if (fr->f == NULL)
671             {
672                 snew(fr->f, sh.natoms);
673             }
674             fr->bF = sh.f_size > 0;
675         }
676         if (fread_htrn(status->fio, &sh, fr->box, fr->x, fr->v, fr->f))
677         {
678             bRet = TRUE;
679         }
680         else
681         {
682             fr->not_ok = DATA_NOT_OK;
683         }
684     }
685     else
686     if (!bOK)
687     {
688         fr->not_ok = HEADER_NOT_OK;
689     }
690
691     return bRet;
692 }
693
694 static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
695 {
696     t_atoms   atoms;
697     matrix    boxpdb;
698     int       ePBC, model_nr, na;
699     char      title[STRLEN], *time;
700     double    dbl;
701
702     atoms.nr      = fr->natoms;
703     atoms.atom    = NULL;
704     atoms.pdbinfo = NULL;
705     /* the other pointers in atoms should not be accessed if these are NULL */
706     model_nr = NOTSET;
707     na       = read_pdbfile(fp, title, &model_nr, &atoms, fr->x, &ePBC, boxpdb, TRUE, NULL);
708     set_trxframe_ePBC(fr, ePBC);
709     if (nframes_read(status) == 0)
710     {
711         fprintf(stderr, " '%s', %d atoms\n", title, fr->natoms);
712     }
713     fr->bPrec = TRUE;
714     fr->prec  = 10000;
715     fr->bX    = TRUE;
716     fr->bBox  = (boxpdb[XX][XX] != 0.0);
717     if (fr->bBox)
718     {
719         copy_mat(boxpdb, fr->box);
720     }
721
722     if (model_nr != NOTSET)
723     {
724         fr->bStep = TRUE;
725         fr->step  = model_nr;
726     }
727     time = strstr(title, " t= ");
728     if (time)
729     {
730         fr->bTime = TRUE;
731         sscanf(time+4, "%lf", &dbl);
732         fr->time = (real)dbl;
733     }
734     else
735     {
736         fr->bTime = FALSE;
737         /* this is a bit dirty, but it will work: if no time is read from
738            comment line in pdb file, set time to current frame number */
739         if (fr->bStep)
740         {
741             fr->time = (real)fr->step;
742         }
743         else
744         {
745             fr->time = (real)nframes_read(status);
746         }
747     }
748     if (na == 0)
749     {
750         return FALSE;
751     }
752     else
753     {
754         if (na != fr->natoms)
755         {
756             gmx_fatal(FARGS, "Number of atoms in pdb frame %d is %d instead of %d",
757                       nframes_read(status), na, fr->natoms);
758         }
759         return TRUE;
760     }
761 }
762
763 static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr)
764 {
765     initcount(status);
766
767     fprintf(stderr, "Reading frames from pdb file");
768     frewind(fp);
769     get_pdb_coordnum(fp, &fr->natoms);
770     if (fr->natoms == 0)
771     {
772         gmx_fatal(FARGS, "\nNo coordinates in pdb file\n");
773     }
774     frewind(fp);
775     snew(fr->x, fr->natoms);
776     pdb_next_x(status, fp, fr);
777
778     return fr->natoms;
779 }
780
781 gmx_bool read_next_frame(const output_env_t oenv, t_trxstatus *status, t_trxframe *fr)
782 {
783     real     pt;
784     int      ct;
785     gmx_bool bOK, bRet, bMissingData = FALSE, bSkip = FALSE;
786     int      dummy = 0;
787     int      ftp;
788
789     bRet = FALSE;
790     pt   = fr->tf;
791
792     do
793     {
794         clear_trxframe(fr, FALSE);
795         fr->tppf = fr->tpf;
796         fr->tpf  = fr->tf;
797
798         if (status->tng)
799         {
800             /* Special treatment for TNG files */
801             ftp = efTNG;
802         }
803         else
804         {
805             ftp = gmx_fio_getftp(status->fio);
806         }
807         switch (ftp)
808         {
809             case efTRR:
810                 bRet = gmx_next_frame(status, fr);
811                 break;
812             case efCPT:
813                 /* Checkpoint files can not contain mulitple frames */
814                 break;
815             case efG96:
816                 read_g96_conf(gmx_fio_getfp(status->fio), NULL, fr,
817                               status->persistent_line);
818                 bRet = (fr->natoms > 0);
819                 break;
820             case efXTC:
821                 /* B. Hess 2005-4-20
822                  * Sometimes is off by one frame
823                  * and sometimes reports frame not present/file not seekable
824                  */
825                 /* DvdS 2005-05-31: this has been fixed along with the increased
826                  * accuracy of the control over -b and -e options.
827                  */
828                 if (bTimeSet(TBEGIN) && (fr->tf < rTimeValue(TBEGIN)))
829                 {
830                     if (xtc_seek_time(status->fio, rTimeValue(TBEGIN), fr->natoms, TRUE))
831                     {
832                         gmx_fatal(FARGS, "Specified frame (time %f) doesn't exist or file corrupt/inconsistent.",
833                                   rTimeValue(TBEGIN));
834                     }
835                     initcount(status);
836                 }
837                 bRet = read_next_xtc(status->fio, fr->natoms, &fr->step, &fr->time, fr->box,
838                                      fr->x, &fr->prec, &bOK);
839                 fr->bPrec = (bRet && fr->prec > 0);
840                 fr->bStep = bRet;
841                 fr->bTime = bRet;
842                 fr->bX    = bRet;
843                 fr->bBox  = bRet;
844                 if (!bOK)
845                 {
846                     /* Actually the header could also be not ok,
847                        but from bOK from read_next_xtc this can't be distinguished */
848                     fr->not_ok = DATA_NOT_OK;
849                 }
850                 break;
851             case efTNG:
852                 bRet = gmx_read_next_tng_frame(status->tng, fr, NULL, 0);
853                 break;
854             case efPDB:
855                 bRet = pdb_next_x(status, gmx_fio_getfp(status->fio), fr);
856                 break;
857             case efGRO:
858                 bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio), fr);
859                 break;
860             default:
861 #ifdef GMX_USE_PLUGINS
862                 bRet = read_next_vmd_frame(fr);
863 #else
864                 gmx_fatal(FARGS, "DEATH HORROR in read_next_frame ftp=%s,status=%s",
865                           ftp2ext(gmx_fio_getftp(status->fio)),
866                           gmx_fio_getname(status->fio));
867 #endif
868         }
869         fr->tf = fr->time;
870
871         if (bRet)
872         {
873             bMissingData = (((fr->flags & TRX_NEED_X) && !fr->bX) ||
874                             ((fr->flags & TRX_NEED_V) && !fr->bV) ||
875                             ((fr->flags & TRX_NEED_F) && !fr->bF));
876             bSkip = FALSE;
877             if (!bMissingData)
878             {
879                 ct = check_times2(fr->time, fr->t0, fr->bDouble);
880                 if (ct == 0 || ((fr->flags & TRX_DONT_SKIP) && ct < 0))
881                 {
882                     printcount(status, oenv, fr->time, FALSE);
883                 }
884                 else if (ct > 0)
885                 {
886                     bRet = FALSE;
887                 }
888                 else
889                 {
890                     printcount(status, oenv, fr->time, TRUE);
891                     bSkip = TRUE;
892                 }
893             }
894         }
895
896     }
897     while (bRet && (bMissingData || bSkip));
898
899     if (!bRet)
900     {
901         printlast(status, oenv, pt);
902         if (fr->not_ok)
903         {
904             printincomp(status, fr);
905         }
906     }
907
908     return bRet;
909 }
910
911 int read_first_frame(const output_env_t oenv, t_trxstatus **status,
912                      const char *fn, t_trxframe *fr, int flags)
913 {
914     t_fileio      *fio;
915     gmx_bool       bFirst, bOK;
916     int            dummy = 0;
917     int            ftp   = fn2ftp(fn);
918     gmx_int64_t   *tng_ids;
919
920     clear_trxframe(fr, TRUE);
921     fr->flags = flags;
922
923     bFirst = TRUE;
924
925     snew((*status), 1);
926
927     status_init( *status );
928     (*status)->nxframe = 1;
929     initcount(*status);
930
931     if (efTNG == ftp)
932     {
933         /* Special treatment for TNG files */
934         gmx_tng_open(fn, 'r', &(*status)->tng);
935     }
936     else
937     {
938         fio = (*status)->fio = gmx_fio_open(fn, "r");
939     }
940     switch (ftp)
941     {
942         case efTRR:
943             break;
944         case efCPT:
945             read_checkpoint_trxframe(fio, fr);
946             bFirst = FALSE;
947             break;
948         case efG96:
949             /* Can not rewind a compressed file, so open it twice */
950             if (!(*status)->persistent_line)
951             {
952                 /* allocate the persistent line */
953                 snew((*status)->persistent_line, STRLEN+1);
954             }
955             read_g96_conf(gmx_fio_getfp(fio), fn, fr, (*status)->persistent_line);
956             gmx_fio_close(fio);
957             clear_trxframe(fr, FALSE);
958             if (flags & (TRX_READ_X | TRX_NEED_X))
959             {
960                 snew(fr->x, fr->natoms);
961             }
962             if (flags & (TRX_READ_V | TRX_NEED_V))
963             {
964                 snew(fr->v, fr->natoms);
965             }
966             fio = (*status)->fio = gmx_fio_open(fn, "r");
967             break;
968         case efXTC:
969             if (read_first_xtc(fio, &fr->natoms, &fr->step, &fr->time, fr->box, &fr->x,
970                                &fr->prec, &bOK) == 0)
971             {
972                 assert(!bOK);
973                 fr->not_ok = DATA_NOT_OK;
974             }
975             if (fr->not_ok)
976             {
977                 fr->natoms = 0;
978                 printincomp(*status, fr);
979             }
980             else
981             {
982                 fr->bPrec = (fr->prec > 0);
983                 fr->bStep = TRUE;
984                 fr->bTime = TRUE;
985                 fr->bX    = TRUE;
986                 fr->bBox  = TRUE;
987                 printcount(*status, oenv, fr->time, FALSE);
988             }
989             bFirst = FALSE;
990             break;
991         case efTNG:
992             fr->step = -1;
993             if (!gmx_read_next_tng_frame((*status)->tng, fr, NULL, 0))
994             {
995                 fr->not_ok = DATA_NOT_OK;
996                 fr->natoms = 0;
997                 printincomp(*status, fr);
998             }
999             else
1000             {
1001                 printcount(*status, oenv, fr->time, FALSE);
1002             }
1003             bFirst = FALSE;
1004             break;
1005         case efPDB:
1006             pdb_first_x(*status, gmx_fio_getfp(fio), fr);
1007             if (fr->natoms)
1008             {
1009                 printcount(*status, oenv, fr->time, FALSE);
1010             }
1011             bFirst = FALSE;
1012             break;
1013         case efGRO:
1014             if (gro_first_x_or_v(gmx_fio_getfp(fio), fr))
1015             {
1016                 printcount(*status, oenv, fr->time, FALSE);
1017             }
1018             bFirst = FALSE;
1019             break;
1020         default:
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))
1028             {
1029                 gmx_fatal(FARGS, "Not supported in read_first_frame: %s", fn);
1030             }
1031 #else
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);
1035 #endif
1036             break;
1037     }
1038     fr->tf = fr->time;
1039
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))
1042     {
1043         fr->t0 = fr->time;
1044         return FALSE;
1045     }
1046
1047     if (bFirst ||
1048         (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) < 0))
1049     {
1050         /* Read a frame when no frame was read or the first was skipped */
1051         if (!read_next_frame(oenv, *status, fr))
1052         {
1053             return FALSE;
1054         }
1055     }
1056     fr->t0 = fr->time;
1057
1058     return (fr->natoms > 0);
1059 }
1060
1061 /***** C O O R D I N A T E   S T U F F *****/
1062
1063 int read_first_x(const output_env_t oenv, t_trxstatus **status, const char *fn,
1064                  real *t, rvec **x, matrix box)
1065 {
1066     t_trxframe fr;
1067
1068     read_first_frame(oenv, status, fn, &fr, TRX_NEED_X);
1069
1070     snew((*status)->xframe, 1);
1071     (*status)->nxframe   = 1;
1072     (*(*status)->xframe) = fr;
1073     *t                   = (*status)->xframe->time;
1074     *x                   = (*status)->xframe->x;
1075     copy_mat((*status)->xframe->box, box);
1076
1077     return (*status)->xframe->natoms;
1078 }
1079
1080 gmx_bool read_next_x(const output_env_t oenv, t_trxstatus *status, real *t,
1081                      rvec x[], matrix box)
1082 {
1083     gmx_bool bRet;
1084
1085     status->xframe->x = x;
1086     /*xframe[status].x = x;*/
1087     bRet = read_next_frame(oenv, status, status->xframe);
1088     *t   = status->xframe->time;
1089     copy_mat(status->xframe->box, box);
1090
1091     return bRet;
1092 }
1093
1094 void close_trj(t_trxstatus *status)
1095 {
1096     gmx_tng_close(&status->tng);
1097     if (status->fio)
1098     {
1099         gmx_fio_close(status->fio);
1100     }
1101
1102     /* The memory in status->xframe is lost here,
1103      * but the read_first_x/read_next_x functions are deprecated anyhow.
1104      * read_first_frame/read_next_frame and close_trx should be used.
1105      */
1106     sfree(status);
1107 }
1108
1109 void rewind_trj(t_trxstatus *status)
1110 {
1111     initcount(status);
1112
1113     gmx_fio_rewind(status->fio);
1114 }
1115
1116 /***** T O P O L O G Y   S T U F F ******/
1117
1118 t_topology *read_top(const char *fn, int *ePBC)
1119 {
1120     int         epbc, natoms;
1121     t_topology *top;
1122
1123     snew(top, 1);
1124     epbc = read_tpx_top(fn, NULL, NULL, &natoms, NULL, NULL, NULL, top);
1125     if (ePBC)
1126     {
1127         *ePBC = epbc;
1128     }
1129
1130     return top;
1131 }