1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- */
2 /* vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 */
3 /*
4
5 MDAnalysis --- https://www.mdanalysis.org
6 Copyright (c) 2006-2016 The MDAnalysis Development Team and contributors
7 (see the file AUTHORS for the full list of names)
8
9 Released under the GNU Public Licence, v2 or any higher version
10
11 Please cite your use of MDAnalysis in published work:
12
13 R. J. Gowers, M. Linke, J. Barnoud, T. J. E. Reddy, M. N. Melo, S. L. Seyler,
14 D. L. Dotson, J. Domanski, S. Buchoux, I. M. Kenney, and O. Beckstein.
15 MDAnalysis: A Python package for the rapid analysis of molecular dynamics
16 simulations. In S. Benthall and S. Rostrup editors, Proceedings of the 15th
17 Python in Science Conference, pages 102-109, Austin, TX, 2016. SciPy.
18
19 N. Michaud-Agrawal, E. J. Denning, T. B. Woolf, and O. Beckstein.
20 MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations.
21 J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787
22
23 */
24
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "xdrfile.h"
31 #include "xdrfile_trr.h"
32 #include "trr_seek.h"
33
read_trr_n_frames(char * fn,int * n_frames,int * est_nframes,int64_t ** offsets)34 int read_trr_n_frames(char *fn, int *n_frames, int *est_nframes,
35 int64_t **offsets) {
36 XDRFILE *xd;
37 t_trnheader sh;
38 float time, lambda;
39 int result, framebytes, totalframebytes;
40 int64_t filesize, frame_offset;
41
42 if ((xd = xdrfile_open(fn, "r")) == NULL)
43 return exdrFILENOTFOUND;
44 if (xdr_seek(xd, 0L, SEEK_END) != exdrOK) {
45 xdrfile_close(xd);
46 return exdrNR;
47 }
48 filesize = xdr_tell(xd);
49 if (xdr_seek(xd, 0L, SEEK_SET) != exdrOK) {
50 xdrfile_close(xd);
51 return exdrNR;
52 }
53
54 if ((result = do_trnheader(xd, 1, &sh)) != exdrOK) {
55 xdrfile_close(xd);
56 return result;
57 }
58
59 framebytes = sh.ir_size + sh.e_size + sh.box_size + sh.vir_size +
60 sh.pres_size + sh.top_size + sh.sym_size + sh.x_size +
61 sh.v_size + sh.f_size;
62
63 *est_nframes =
64 (int)(filesize / ((int64_t)(framebytes + TRR_MIN_HEADER_SIZE)) +
65 1); // add one because it'd be easy to underestimate low
66 // frame numbers.
67 *est_nframes += *est_nframes / 5;
68
69 /* Allocate memory for the frame index array */
70 if ((*offsets = malloc(sizeof(int64_t) * *est_nframes)) == NULL) {
71 xdrfile_close(xd);
72 return exdrNOMEM;
73 }
74
75 (*offsets)[0] = 0L;
76 *n_frames = 1;
77 while (1) {
78 if (xdr_seek(xd, (int64_t)(framebytes), SEEK_CUR) != exdrOK) {
79 free(*offsets);
80 xdrfile_close(xd);
81 return exdrNR;
82 }
83 frame_offset = xdr_tell(xd); /* Store it now, before we read the header */
84 if ((result = do_trnheader(xd, 1, &sh)) != exdrOK) /* Interpreting as EOF */
85 break;
86 /* Read was successful; this is another frame */
87 /* Check if we need to enlarge array */
88 if (*n_frames == *est_nframes) {
89 *est_nframes += *est_nframes / 5 + 1; // Increase in 20% stretches
90 if ((*offsets = realloc(*offsets, sizeof(int64_t) * *est_nframes)) ==
91 NULL) {
92 xdrfile_close(xd);
93 return exdrNOMEM;
94 }
95 }
96 (*offsets)[*n_frames] = frame_offset;
97 (*n_frames)++;
98 /* Calculate how much to skip this time */
99 framebytes = sh.ir_size + sh.e_size + sh.box_size + sh.vir_size +
100 sh.pres_size + sh.top_size + sh.sym_size + sh.x_size +
101 sh.v_size + sh.f_size;
102 }
103 xdrfile_close(xd);
104 return exdrOK;
105 }
106