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, 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.
48 #include "xdr_datatype.h"
51 #include "gmx_fatal.h"
54 /* This is just for clarity - it can never be anything but 4! */
55 #define XDR_INT_SIZE 4
57 /* same order as the definition of xdr_datatype */
58 const char *xdr_datatype_names[] =
69 /*___________________________________________________________________________
71 | what follows are the C routine to read/write compressed coordinates together
72 | with some routines to assist in this task (those are marked
73 | static and cannot be called from user programs)
75 #define MAXABS INT_MAX-2
78 #define MIN(x, y) ((x) < (y) ? (x) : (y))
81 #define MAX(x, y) ((x) > (y) ? (x) : (y))
84 #define SQR(x) ((x)*(x))
86 static const int magicints[] = {
87 0, 0, 0, 0, 0, 0, 0, 0, 0,
88 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
89 80, 101, 128, 161, 203, 256, 322, 406, 512, 645,
90 812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501,
91 8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536,
92 82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
93 832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042,
94 8388607, 10568983, 13316085, 16777216
98 /* note that magicints[FIRSTIDX-1] == 0 */
99 #define LASTIDX (sizeof(magicints) / sizeof(*magicints))
102 /*____________________________________________________________________________
104 | sendbits - encode num into buf using the specified number of bits
106 | This routines appends the value of num to the bits already present in
107 | the array buf. You need to give it the number of bits to use and you
108 | better make sure that this number of bits is enough to hold the value
109 | Also num must be positive.
113 static void sendbits(int buf[], int num_of_bits, int num)
116 unsigned int cnt, lastbyte;
118 unsigned char * cbuf;
120 cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
121 cnt = (unsigned int) buf[0];
123 lastbyte = (unsigned int) buf[2];
124 while (num_of_bits >= 8)
126 lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
127 cbuf[cnt++] = lastbyte >> lastbits;
132 lastbyte = (lastbyte << num_of_bits) | num;
133 lastbits += num_of_bits;
137 cbuf[cnt++] = lastbyte >> lastbits;
145 cbuf[cnt] = lastbyte << (8 - lastbits);
149 /*_________________________________________________________________________
151 | sizeofint - calculate bitsize of an integer
153 | return the number of bits needed to store an integer with given max size
157 static int sizeofint(const int size)
162 while (size >= num && num_of_bits < 32)
170 /*___________________________________________________________________________
172 | sizeofints - calculate 'bitsize' of compressed ints
174 | given the number of small unsigned integers and the maximum value
175 | return the number of bits needed to read or write them with the
176 | routines receiveints and sendints. You need this parameter when
177 | calling these routines. Note that for many calls I can use
178 | the variable 'smallidx' which is exactly the number of bits, and
179 | So I don't need to call 'sizeofints for those calls.
182 static int sizeofints( const int num_of_ints, unsigned int sizes[])
186 unsigned int num_of_bytes, num_of_bits, bytecnt, tmp;
190 for (i = 0; i < num_of_ints; i++)
193 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
195 tmp = bytes[bytecnt] * sizes[i] + tmp;
196 bytes[bytecnt] = tmp & 0xff;
201 bytes[bytecnt++] = tmp & 0xff;
204 num_of_bytes = bytecnt;
208 while (bytes[num_of_bytes] >= num)
213 return num_of_bits + num_of_bytes * 8;
217 /*____________________________________________________________________________
219 | sendints - send a small set of small integers in compressed format
221 | this routine is used internally by xdr3dfcoord, to send a set of
222 | small integers to the buffer.
223 | Multiplication with fixed (specified maximum ) sizes is used to get
224 | to one big, multibyte integer. Allthough the routine could be
225 | modified to handle sizes bigger than 16777216, or more than just
226 | a few integers, this is not done, because the gain in compression
227 | isn't worth the effort. Note that overflowing the multiplication
228 | or the byte buffer (32 bytes) is unchecked and causes bad results.
232 static void sendints(int buf[], const int num_of_ints, const int num_of_bits,
233 unsigned int sizes[], unsigned int nums[])
236 int i, num_of_bytes, bytecnt;
237 unsigned int bytes[32], tmp;
243 bytes[num_of_bytes++] = tmp & 0xff;
248 for (i = 1; i < num_of_ints; i++)
250 if (nums[i] >= sizes[i])
252 fprintf(stderr, "major breakdown in sendints num %u doesn't "
253 "match size %u\n", nums[i], sizes[i]);
256 /* use one step multiply */
258 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
260 tmp = bytes[bytecnt] * sizes[i] + tmp;
261 bytes[bytecnt] = tmp & 0xff;
266 bytes[bytecnt++] = tmp & 0xff;
269 num_of_bytes = bytecnt;
271 if (num_of_bits >= num_of_bytes * 8)
273 for (i = 0; i < num_of_bytes; i++)
275 sendbits(buf, 8, bytes[i]);
277 sendbits(buf, num_of_bits - num_of_bytes * 8, 0);
281 for (i = 0; i < num_of_bytes-1; i++)
283 sendbits(buf, 8, bytes[i]);
285 sendbits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]);
290 /*___________________________________________________________________________
292 | receivebits - decode number from buf using specified number of bits
294 | extract the number of bits from the array buf and construct an integer
295 | from it. Return that value.
299 static int receivebits(int buf[], int num_of_bits)
302 int cnt, num, lastbits;
303 unsigned int lastbyte;
304 unsigned char * cbuf;
305 int mask = (1 << num_of_bits) -1;
307 cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
309 lastbits = (unsigned int) buf[1];
310 lastbyte = (unsigned int) buf[2];
313 while (num_of_bits >= 8)
315 lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
316 num |= (lastbyte >> lastbits) << (num_of_bits - 8);
321 if (lastbits < num_of_bits)
324 lastbyte = (lastbyte << 8) | cbuf[cnt++];
326 lastbits -= num_of_bits;
327 num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1);
336 /*____________________________________________________________________________
338 | receiveints - decode 'small' integers from the buf array
340 | this routine is the inverse from sendints() and decodes the small integers
341 | written to buf by calculating the remainder and doing divisions with
342 | the given sizes[]. You need to specify the total number of bits to be
343 | used from buf in num_of_bits.
347 static void receiveints(int buf[], const int num_of_ints, int num_of_bits,
348 unsigned int sizes[], int nums[])
351 int i, j, num_of_bytes, p, num;
353 bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0;
355 while (num_of_bits > 8)
357 bytes[num_of_bytes++] = receivebits(buf, 8);
362 bytes[num_of_bytes++] = receivebits(buf, num_of_bits);
364 for (i = num_of_ints-1; i > 0; i--)
367 for (j = num_of_bytes-1; j >= 0; j--)
369 num = (num << 8) | bytes[j];
372 num = num - p * sizes[i];
376 nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
379 /*____________________________________________________________________________
381 | xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
383 | this routine reads or writes (depending on how you opened the file with
384 | xdropen() ) a large number of 3d coordinates (stored in *fp).
385 | The number of coordinates triplets to write is given by *size. On
386 | read this number may be zero, in which case it reads as many as were written
387 | or it may specify the number if triplets to read (which should match the
389 | Compression is achieved by first converting all floating numbers to integer
390 | using multiplication by *precision and rounding to the nearest integer.
391 | Then the minimum and maximum value are calculated to determine the range.
392 | The limited range of integers so found, is used to compress the coordinates.
393 | In addition the differences between succesive coordinates is calculated.
394 | If the difference happens to be 'small' then only the difference is saved,
395 | compressing the data even more. The notion of 'small' is changed dynamically
396 | and is enlarged or reduced whenever needed or possible.
397 | Extra compression is achieved in the case of GROMOS and coordinates of
398 | water molecules. GROMOS first writes out the Oxygen position, followed by
399 | the two hydrogens. In order to make the differences smaller (and thereby
400 | compression the data better) the order is changed into first one hydrogen
401 | then the oxygen, followed by the other hydrogen. This is rather special, but
402 | it shouldn't harm in the general case.
406 int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision)
412 /* preallocate a small buffer and ip on the stack - if we need more
413 we can always malloc(). This is faster for small values of size: */
414 unsigned prealloc_size = 3*16;
415 int prealloc_ip[3*16], prealloc_buf[3*20];
416 int we_should_free = 0;
418 int minint[3], maxint[3], mindiff, *lip, diff;
419 int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
421 unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
423 int smallnum, smaller, larger, i, is_small, is_smaller, run, prevrun;
425 int tmp, *thiscoord, prevcoord[3];
426 unsigned int tmpcoord[30];
428 int bufsize, xdrid, lsize;
429 unsigned int bitsize;
434 bRead = (xdrs->x_op == XDR_DECODE);
435 bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0;
436 prevcoord[0] = prevcoord[1] = prevcoord[2] = 0;
440 /* xdrs is open for writing */
442 if (xdr_int(xdrs, size) == 0)
447 /* when the number of coordinates is small, don't try to compress; just
448 * write them as floats using xdr_vector
452 return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
453 (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
456 if (xdr_float(xdrs, precision) == 0)
461 if (size3 <= prealloc_size)
469 bufsize = size3 * 1.2;
470 ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
471 buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
472 if (ip == NULL || buf == NULL)
474 fprintf(stderr, "malloc failed\n");
478 /* buf[0-2] are special and do not contain actual data */
479 buf[0] = buf[1] = buf[2] = 0;
480 minint[0] = minint[1] = minint[2] = INT_MAX;
481 maxint[0] = maxint[1] = maxint[2] = INT_MIN;
486 oldlint1 = oldlint2 = oldlint3 = 0;
487 while (lfp < fp + size3)
489 /* find nearest integer */
492 lf = *lfp * *precision + 0.5;
496 lf = *lfp * *precision - 0.5;
498 if (fabs(lf) > MAXABS)
500 /* scaling would cause overflow */
504 if (lint1 < minint[0])
508 if (lint1 > maxint[0])
516 lf = *lfp * *precision + 0.5;
520 lf = *lfp * *precision - 0.5;
522 if (fabs(lf) > MAXABS)
524 /* scaling would cause overflow */
528 if (lint2 < minint[1])
532 if (lint2 > maxint[1])
540 lf = *lfp * *precision + 0.5;
544 lf = *lfp * *precision - 0.5;
546 if (fabs(lf) > MAXABS)
548 /* scaling would cause overflow */
552 if (lint3 < minint[2])
556 if (lint3 > maxint[2])
562 diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
563 if (diff < mindiff && lfp > fp + 3)
571 if ( (xdr_int(xdrs, &(minint[0])) == 0) ||
572 (xdr_int(xdrs, &(minint[1])) == 0) ||
573 (xdr_int(xdrs, &(minint[2])) == 0) ||
574 (xdr_int(xdrs, &(maxint[0])) == 0) ||
575 (xdr_int(xdrs, &(maxint[1])) == 0) ||
576 (xdr_int(xdrs, &(maxint[2])) == 0))
586 if ((float)maxint[0] - (float)minint[0] >= MAXABS ||
587 (float)maxint[1] - (float)minint[1] >= MAXABS ||
588 (float)maxint[2] - (float)minint[2] >= MAXABS)
590 /* turning value in unsigned by subtracting minint
591 * would cause overflow
595 sizeint[0] = maxint[0] - minint[0]+1;
596 sizeint[1] = maxint[1] - minint[1]+1;
597 sizeint[2] = maxint[2] - minint[2]+1;
599 /* check if one of the sizes is to big to be multiplied */
600 if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
602 bitsizeint[0] = sizeofint(sizeint[0]);
603 bitsizeint[1] = sizeofint(sizeint[1]);
604 bitsizeint[2] = sizeofint(sizeint[2]);
605 bitsize = 0; /* flag the use of large sizes */
609 bitsize = sizeofints(3, sizeint);
612 luip = (unsigned int *) ip;
614 while (smallidx < LASTIDX && magicints[smallidx] < mindiff)
618 if (xdr_int(xdrs, &smallidx) == 0)
628 maxidx = MIN(LASTIDX, smallidx + 8);
629 minidx = maxidx - 8; /* often this equal smallidx */
630 smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
631 smallnum = magicints[smallidx] / 2;
632 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
633 larger = magicints[maxidx] / 2;
638 thiscoord = (int *)(luip) + i * 3;
639 if (smallidx < maxidx && i >= 1 &&
640 abs(thiscoord[0] - prevcoord[0]) < larger &&
641 abs(thiscoord[1] - prevcoord[1]) < larger &&
642 abs(thiscoord[2] - prevcoord[2]) < larger)
646 else if (smallidx > minidx)
656 if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
657 abs(thiscoord[1] - thiscoord[4]) < smallnum &&
658 abs(thiscoord[2] - thiscoord[5]) < smallnum)
660 /* interchange first with second atom for better
661 * compression of water molecules
663 tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
665 tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
667 tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
673 tmpcoord[0] = thiscoord[0] - minint[0];
674 tmpcoord[1] = thiscoord[1] - minint[1];
675 tmpcoord[2] = thiscoord[2] - minint[2];
678 sendbits(buf, bitsizeint[0], tmpcoord[0]);
679 sendbits(buf, bitsizeint[1], tmpcoord[1]);
680 sendbits(buf, bitsizeint[2], tmpcoord[2]);
684 sendints(buf, 3, bitsize, sizeint, tmpcoord);
686 prevcoord[0] = thiscoord[0];
687 prevcoord[1] = thiscoord[1];
688 prevcoord[2] = thiscoord[2];
689 thiscoord = thiscoord + 3;
693 if (is_small == 0 && is_smaller == -1)
697 while (is_small && run < 8*3)
699 if (is_smaller == -1 && (
700 SQR(thiscoord[0] - prevcoord[0]) +
701 SQR(thiscoord[1] - prevcoord[1]) +
702 SQR(thiscoord[2] - prevcoord[2]) >= smaller * smaller))
707 tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
708 tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
709 tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
711 prevcoord[0] = thiscoord[0];
712 prevcoord[1] = thiscoord[1];
713 prevcoord[2] = thiscoord[2];
716 thiscoord = thiscoord + 3;
719 abs(thiscoord[0] - prevcoord[0]) < smallnum &&
720 abs(thiscoord[1] - prevcoord[1]) < smallnum &&
721 abs(thiscoord[2] - prevcoord[2]) < smallnum)
726 if (run != prevrun || is_smaller != 0)
729 sendbits(buf, 1, 1); /* flag the change in run-length */
730 sendbits(buf, 5, run+is_smaller+1);
734 sendbits(buf, 1, 0); /* flag the fact that runlength did not change */
736 for (k = 0; k < run; k += 3)
738 sendints(buf, 3, smallidx, sizesmall, &tmpcoord[k]);
742 smallidx += is_smaller;
746 smaller = magicints[smallidx-1] / 2;
751 smallnum = magicints[smallidx] / 2;
753 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
760 /* buf[0] holds the length in bytes */
761 if (xdr_int(xdrs, &(buf[0])) == 0)
772 rc = errval * (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]));
784 /* xdrs is open for reading */
786 if (xdr_int(xdrs, &lsize) == 0)
790 if (*size != 0 && lsize != *size)
792 fprintf(stderr, "wrong number of coordinates in xdr3dfcoord; "
793 "%d arg vs %d in file", *size, lsize);
800 return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
801 (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
803 if (xdr_float(xdrs, precision) == 0)
808 if (size3 <= prealloc_size)
816 bufsize = size3 * 1.2;
817 ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
818 buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
819 if (ip == NULL || buf == NULL)
821 fprintf(stderr, "malloc failed\n");
826 buf[0] = buf[1] = buf[2] = 0;
828 if ( (xdr_int(xdrs, &(minint[0])) == 0) ||
829 (xdr_int(xdrs, &(minint[1])) == 0) ||
830 (xdr_int(xdrs, &(minint[2])) == 0) ||
831 (xdr_int(xdrs, &(maxint[0])) == 0) ||
832 (xdr_int(xdrs, &(maxint[1])) == 0) ||
833 (xdr_int(xdrs, &(maxint[2])) == 0))
843 sizeint[0] = maxint[0] - minint[0]+1;
844 sizeint[1] = maxint[1] - minint[1]+1;
845 sizeint[2] = maxint[2] - minint[2]+1;
847 /* check if one of the sizes is to big to be multiplied */
848 if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
850 bitsizeint[0] = sizeofint(sizeint[0]);
851 bitsizeint[1] = sizeofint(sizeint[1]);
852 bitsizeint[2] = sizeofint(sizeint[2]);
853 bitsize = 0; /* flag the use of large sizes */
857 bitsize = sizeofints(3, sizeint);
860 if (xdr_int(xdrs, &smallidx) == 0)
870 maxidx = MIN(LASTIDX, smallidx + 8);
871 minidx = maxidx - 8; /* often this equal smallidx */
872 smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
873 smallnum = magicints[smallidx] / 2;
874 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
875 larger = magicints[maxidx];
877 /* buf[0] holds the length in bytes */
879 if (xdr_int(xdrs, &(buf[0])) == 0)
890 if (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]) == 0)
902 buf[0] = buf[1] = buf[2] = 0;
905 inv_precision = 1.0 / *precision;
911 thiscoord = (int *)(lip) + i * 3;
915 thiscoord[0] = receivebits(buf, bitsizeint[0]);
916 thiscoord[1] = receivebits(buf, bitsizeint[1]);
917 thiscoord[2] = receivebits(buf, bitsizeint[2]);
921 receiveints(buf, 3, bitsize, sizeint, thiscoord);
925 thiscoord[0] += minint[0];
926 thiscoord[1] += minint[1];
927 thiscoord[2] += minint[2];
929 prevcoord[0] = thiscoord[0];
930 prevcoord[1] = thiscoord[1];
931 prevcoord[2] = thiscoord[2];
934 flag = receivebits(buf, 1);
938 run = receivebits(buf, 5);
939 is_smaller = run % 3;
946 for (k = 0; k < run; k += 3)
948 receiveints(buf, 3, smallidx, sizesmall, thiscoord);
950 thiscoord[0] += prevcoord[0] - smallnum;
951 thiscoord[1] += prevcoord[1] - smallnum;
952 thiscoord[2] += prevcoord[2] - smallnum;
955 /* interchange first with second atom for better
956 * compression of water molecules
958 tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
960 tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
962 tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
964 *lfp++ = prevcoord[0] * inv_precision;
965 *lfp++ = prevcoord[1] * inv_precision;
966 *lfp++ = prevcoord[2] * inv_precision;
970 prevcoord[0] = thiscoord[0];
971 prevcoord[1] = thiscoord[1];
972 prevcoord[2] = thiscoord[2];
974 *lfp++ = thiscoord[0] * inv_precision;
975 *lfp++ = thiscoord[1] * inv_precision;
976 *lfp++ = thiscoord[2] * inv_precision;
981 *lfp++ = thiscoord[0] * inv_precision;
982 *lfp++ = thiscoord[1] * inv_precision;
983 *lfp++ = thiscoord[2] * inv_precision;
985 smallidx += is_smaller;
989 if (smallidx > FIRSTIDX)
991 smaller = magicints[smallidx - 1] /2;
998 else if (is_smaller > 0)
1001 smallnum = magicints[smallidx] / 2;
1003 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
1016 /******************************************************************
1018 XTC files have a relatively simple structure.
1019 They have a header of 16 bytes and the rest are
1020 the compressed coordinates of the files. Due to the
1021 compression 00 is not present in the coordinates.
1022 The first 4 bytes of the header are the magic number
1023 1995 (0x000007CB). If we find this number we are guaranteed
1024 to be in the header, due to the presence of so many zeros.
1025 The second 4 bytes are the number of atoms in the frame, and is
1026 assumed to be constant. The third 4 bytes are the frame number.
1027 The last 4 bytes are a floating point representation of the time.
1029 ********************************************************************/
1031 /* Must match definition in xtcio.c */
1033 #define XTC_MAGIC 1995
1036 static const int header_size = 16;
1038 /* Check if we are at the header start.
1039 At the same time it will also read 1 int */
1040 static int xtc_at_header_start(FILE *fp, XDR *xdrs,
1041 int natoms, int * timestep, float * time)
1049 if ((off = gmx_ftell(fp)) < 0)
1053 /* read magic natoms and timestep */
1054 for (i = 0; i < 3; i++)
1056 if (!xdr_int(xdrs, &(i_inp[i])))
1058 gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET);
1063 if (i_inp[0] != XTC_MAGIC)
1065 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1071 /* read time and box */
1072 for (i = 0; i < 10; i++)
1074 if (!xdr_float(xdrs, &(f_inp[i])))
1076 gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET);
1080 /* Make a rigourous check to see if we are in the beggining of a header
1081 Hopefully there are no ambiguous cases */
1082 /* This check makes use of the fact that the box matrix has 3 zeroes on the upper
1083 right triangle and that the first element must be nonzero unless the entire matrix is zero
1085 if (i_inp[1] == natoms &&
1086 ((f_inp[1] != 0 && f_inp[6] == 0) ||
1087 (f_inp[1] == 0 && f_inp[5] == 0 && f_inp[9] == 0)))
1089 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1094 *timestep = i_inp[2];
1097 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1105 xtc_get_next_frame_number(FILE *fp, XDR *xdrs, int natoms)
1112 if ((off = gmx_ftell(fp)) < 0)
1117 /* read one int just to make sure we dont read this frame but the next */
1118 xdr_int(xdrs, &step);
1121 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1124 if (gmx_fseek(fp, off, SEEK_SET))
1132 if (gmx_fseek(fp, off, SEEK_SET))
1142 static float xtc_get_next_frame_time(FILE *fp, XDR *xdrs, int natoms,
1151 if ((off = gmx_ftell(fp)) < 0)
1155 /* read one int just to make sure we dont read this frame but the next */
1156 xdr_int(xdrs, &step);
1159 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1163 if (gmx_fseek(fp, off, SEEK_SET))
1172 if (gmx_fseek(fp, off, SEEK_SET))
1184 xtc_get_current_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1192 if ((off = gmx_ftell(fp)) < 0)
1199 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1203 if (gmx_fseek(fp, off, SEEK_SET))
1212 if (gmx_fseek(fp, off, SEEK_SET))
1221 if (gmx_fseek(fp, -2*XDR_INT_SIZE, SEEK_CUR))
1230 /* Currently not used, just for completeness */
1232 xtc_get_current_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1240 if ((off = gmx_ftell(fp)) < 0)
1248 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1252 if (gmx_fseek(fp, off, SEEK_SET))
1261 if (gmx_fseek(fp, off, SEEK_SET))
1271 if (gmx_fseek(fp, -2*XDR_INT_SIZE, SEEK_CUR))
1282 static gmx_off_t xtc_get_next_frame_start(FILE *fp, XDR *xdrs, int natoms)
1289 /* read one int just to make sure we dont read this frame but the next */
1290 xdr_int(xdrs, &step);
1293 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1296 if ((res = gmx_ftell(fp)) >= 0)
1298 return res - XDR_INT_SIZE;
1316 xdr_xtc_estimate_dt(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1323 if ((off = gmx_ftell(fp)) < 0)
1328 tinit = xtc_get_current_frame_time(fp, xdrs, natoms, bOK);
1335 res = xtc_get_next_frame_time(fp, xdrs, natoms, bOK);
1343 if (0 != gmx_fseek(fp, off, SEEK_SET))
1353 xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms)
1356 gmx_off_t high, pos;
1359 /* round to 4 bytes */
1362 if (gmx_fseek(fp, 0, SEEK_END))
1367 if ((high = gmx_ftell(fp)) < 0)
1372 /* round to 4 bytes */
1373 high /= XDR_INT_SIZE;
1374 high *= XDR_INT_SIZE;
1375 offset = ((high/2)/XDR_INT_SIZE)*XDR_INT_SIZE;
1377 if (gmx_fseek(fp, offset, SEEK_SET))
1384 fr = xtc_get_next_frame_number(fp, xdrs, natoms);
1389 if (fr != frame && abs(low-high) > header_size)
1399 /* round to 4 bytes */
1400 offset = (((high+low)/2)/4)*4;
1402 if (gmx_fseek(fp, offset, SEEK_SET))
1412 if (offset <= header_size)
1417 if (gmx_fseek(fp, offset, SEEK_SET))
1422 if ((pos = xtc_get_next_frame_start(fp, xdrs, natoms)) < 0)
1424 /* we probably hit an end of file */
1428 if (gmx_fseek(fp, pos, SEEK_SET))
1438 int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeekForwardOnly)
1442 gmx_bool bOK = FALSE;
1444 gmx_off_t high, offset, pos;
1448 if (bSeekForwardOnly)
1450 low = gmx_ftell(fp);
1452 if (gmx_fseek(fp, 0, SEEK_END))
1457 if ((high = gmx_ftell(fp)) < 0)
1462 high /= XDR_INT_SIZE;
1463 high *= XDR_INT_SIZE;
1464 offset = (((high-low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1466 if (gmx_fseek(fp, offset, SEEK_SET))
1473 * No need to call xdr_xtc_estimate_dt here - since xdr_xtc_estimate_dt is called first thing in the loop
1474 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1484 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1495 /* Found a place in the trajectory that has positive time step while
1496 other has negative time step */
1505 /* Found a place in the trajectory that has positive time step while
1506 other has negative time step */
1512 t = xtc_get_next_frame_time(fp, xdrs, natoms, &bOK);
1518 /* If we are before the target time and the time step is positive or 0, or we have
1519 after the target time and the time step is negative, or the difference between
1520 the current time and the target time is bigger than dt and above all the distance between high
1521 and low is bigger than 1 frame, then do another step of binary search. Otherwise stop and check
1522 if we reached the solution */
1523 if ((((t < time && dt_sign >= 0) || (t > time && dt_sign == -1)) || ((t
1524 - time) >= dt && dt_sign >= 0)
1525 || ((time - t) >= -dt && dt_sign < 0)) && (abs(low - high)
1528 if (dt >= 0 && dt_sign != -1)
1539 else if (dt <= 0 && dt_sign == -1)
1552 /* We should never reach here */
1555 /* round to 4 bytes and subtract header*/
1556 offset = (((high + low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1557 if (gmx_fseek(fp, offset, SEEK_SET))
1564 if (abs(low - high) <= header_size)
1568 /* re-estimate dt */
1569 if (xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK) != dt)
1573 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1576 if (t >= time && t - time < dt)
1583 if (offset <= header_size)
1588 gmx_fseek(fp, offset, SEEK_SET);
1590 if ((pos = xtc_get_next_frame_start(fp, xdrs, natoms)) < 0)
1595 if (gmx_fseek(fp, pos, SEEK_SET))
1603 xdr_xtc_get_last_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1609 off = gmx_ftell(fp);
1616 if ( (res = gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END)) != 0)
1622 time = xtc_get_current_frame_time(fp, xdrs, natoms, bOK);
1628 if ( (res = gmx_fseek(fp, off, SEEK_SET)) != 0)
1638 xdr_xtc_get_last_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1645 if ((off = gmx_ftell(fp)) < 0)
1652 if (gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END))
1658 frame = xtc_get_current_frame_number(fp, xdrs, natoms, bOK);
1665 if (gmx_fseek(fp, off, SEEK_SET))