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, 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.
47 #include "xdr_datatype.h"
49 #include "gmx_fatal.h"
52 /* This is just for clarity - it can never be anything but 4! */
53 #define XDR_INT_SIZE 4
55 /* same order as the definition of xdr_datatype */
56 const char *xdr_datatype_names[] =
67 /*___________________________________________________________________________
69 | what follows are the C routine to read/write compressed coordinates together
70 | with some routines to assist in this task (those are marked
71 | static and cannot be called from user programs)
73 #define MAXABS INT_MAX-2
76 #define MIN(x, y) ((x) < (y) ? (x) : (y))
79 #define MAX(x, y) ((x) > (y) ? (x) : (y))
82 #define SQR(x) ((x)*(x))
84 static const int magicints[] = {
85 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
87 80, 101, 128, 161, 203, 256, 322, 406, 512, 645,
88 812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501,
89 8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536,
90 82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
91 832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042,
92 8388607, 10568983, 13316085, 16777216
96 /* note that magicints[FIRSTIDX-1] == 0 */
97 #define LASTIDX (sizeof(magicints) / sizeof(*magicints))
100 /*____________________________________________________________________________
102 | sendbits - encode num into buf using the specified number of bits
104 | This routines appends the value of num to the bits already present in
105 | the array buf. You need to give it the number of bits to use and you
106 | better make sure that this number of bits is enough to hold the value
107 | Also num must be positive.
111 static void sendbits(int buf[], int num_of_bits, int num)
114 unsigned int cnt, lastbyte;
116 unsigned char * cbuf;
118 cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
119 cnt = (unsigned int) buf[0];
121 lastbyte = (unsigned int) buf[2];
122 while (num_of_bits >= 8)
124 lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
125 cbuf[cnt++] = lastbyte >> lastbits;
130 lastbyte = (lastbyte << num_of_bits) | num;
131 lastbits += num_of_bits;
135 cbuf[cnt++] = lastbyte >> lastbits;
143 cbuf[cnt] = lastbyte << (8 - lastbits);
147 /*_________________________________________________________________________
149 | sizeofint - calculate bitsize of an integer
151 | return the number of bits needed to store an integer with given max size
155 static int sizeofint(const int size)
160 while (size >= num && num_of_bits < 32)
168 /*___________________________________________________________________________
170 | sizeofints - calculate 'bitsize' of compressed ints
172 | given the number of small unsigned integers and the maximum value
173 | return the number of bits needed to read or write them with the
174 | routines receiveints and sendints. You need this parameter when
175 | calling these routines. Note that for many calls I can use
176 | the variable 'smallidx' which is exactly the number of bits, and
177 | So I don't need to call 'sizeofints for those calls.
180 static int sizeofints( const int num_of_ints, unsigned int sizes[])
184 unsigned int num_of_bytes, num_of_bits, bytecnt, tmp;
188 for (i = 0; i < num_of_ints; i++)
191 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
193 tmp = bytes[bytecnt] * sizes[i] + tmp;
194 bytes[bytecnt] = tmp & 0xff;
199 bytes[bytecnt++] = tmp & 0xff;
202 num_of_bytes = bytecnt;
206 while (bytes[num_of_bytes] >= num)
211 return num_of_bits + num_of_bytes * 8;
215 /*____________________________________________________________________________
217 | sendints - send a small set of small integers in compressed format
219 | this routine is used internally by xdr3dfcoord, to send a set of
220 | small integers to the buffer.
221 | Multiplication with fixed (specified maximum ) sizes is used to get
222 | to one big, multibyte integer. Allthough the routine could be
223 | modified to handle sizes bigger than 16777216, or more than just
224 | a few integers, this is not done, because the gain in compression
225 | isn't worth the effort. Note that overflowing the multiplication
226 | or the byte buffer (32 bytes) is unchecked and causes bad results.
230 static void sendints(int buf[], const int num_of_ints, const int num_of_bits,
231 unsigned int sizes[], unsigned int nums[])
234 int i, num_of_bytes, bytecnt;
235 unsigned int bytes[32], tmp;
241 bytes[num_of_bytes++] = tmp & 0xff;
246 for (i = 1; i < num_of_ints; i++)
248 if (nums[i] >= sizes[i])
250 fprintf(stderr, "major breakdown in sendints num %u doesn't "
251 "match size %u\n", nums[i], sizes[i]);
254 /* use one step multiply */
256 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
258 tmp = bytes[bytecnt] * sizes[i] + tmp;
259 bytes[bytecnt] = tmp & 0xff;
264 bytes[bytecnt++] = tmp & 0xff;
267 num_of_bytes = bytecnt;
269 if (num_of_bits >= num_of_bytes * 8)
271 for (i = 0; i < num_of_bytes; i++)
273 sendbits(buf, 8, bytes[i]);
275 sendbits(buf, num_of_bits - num_of_bytes * 8, 0);
279 for (i = 0; i < num_of_bytes-1; i++)
281 sendbits(buf, 8, bytes[i]);
283 sendbits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]);
288 /*___________________________________________________________________________
290 | receivebits - decode number from buf using specified number of bits
292 | extract the number of bits from the array buf and construct an integer
293 | from it. Return that value.
297 static int receivebits(int buf[], int num_of_bits)
300 int cnt, num, lastbits;
301 unsigned int lastbyte;
302 unsigned char * cbuf;
303 int mask = (1 << num_of_bits) -1;
305 cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
307 lastbits = (unsigned int) buf[1];
308 lastbyte = (unsigned int) buf[2];
311 while (num_of_bits >= 8)
313 lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
314 num |= (lastbyte >> lastbits) << (num_of_bits - 8);
319 if (lastbits < num_of_bits)
322 lastbyte = (lastbyte << 8) | cbuf[cnt++];
324 lastbits -= num_of_bits;
325 num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1);
334 /*____________________________________________________________________________
336 | receiveints - decode 'small' integers from the buf array
338 | this routine is the inverse from sendints() and decodes the small integers
339 | written to buf by calculating the remainder and doing divisions with
340 | the given sizes[]. You need to specify the total number of bits to be
341 | used from buf in num_of_bits.
345 static void receiveints(int buf[], const int num_of_ints, int num_of_bits,
346 unsigned int sizes[], int nums[])
349 int i, j, num_of_bytes, p, num;
351 bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0;
353 while (num_of_bits > 8)
355 bytes[num_of_bytes++] = receivebits(buf, 8);
360 bytes[num_of_bytes++] = receivebits(buf, num_of_bits);
362 for (i = num_of_ints-1; i > 0; i--)
365 for (j = num_of_bytes-1; j >= 0; j--)
367 num = (num << 8) | bytes[j];
370 num = num - p * sizes[i];
374 nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
377 /*____________________________________________________________________________
379 | xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
381 | this routine reads or writes (depending on how you opened the file with
382 | xdropen() ) a large number of 3d coordinates (stored in *fp).
383 | The number of coordinates triplets to write is given by *size. On
384 | read this number may be zero, in which case it reads as many as were written
385 | or it may specify the number if triplets to read (which should match the
387 | Compression is achieved by first converting all floating numbers to integer
388 | using multiplication by *precision and rounding to the nearest integer.
389 | Then the minimum and maximum value are calculated to determine the range.
390 | The limited range of integers so found, is used to compress the coordinates.
391 | In addition the differences between succesive coordinates is calculated.
392 | If the difference happens to be 'small' then only the difference is saved,
393 | compressing the data even more. The notion of 'small' is changed dynamically
394 | and is enlarged or reduced whenever needed or possible.
395 | Extra compression is achieved in the case of GROMOS and coordinates of
396 | water molecules. GROMOS first writes out the Oxygen position, followed by
397 | the two hydrogens. In order to make the differences smaller (and thereby
398 | compression the data better) the order is changed into first one hydrogen
399 | then the oxygen, followed by the other hydrogen. This is rather special, but
400 | it shouldn't harm in the general case.
404 int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision)
410 /* preallocate a small buffer and ip on the stack - if we need more
411 we can always malloc(). This is faster for small values of size: */
412 unsigned prealloc_size = 3*16;
413 int prealloc_ip[3*16], prealloc_buf[3*20];
414 int we_should_free = 0;
416 int minint[3], maxint[3], mindiff, *lip, diff;
417 int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
419 unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
421 int smallnum, smaller, larger, i, is_small, is_smaller, run, prevrun;
423 int tmp, *thiscoord, prevcoord[3];
424 unsigned int tmpcoord[30];
426 int bufsize, xdrid, lsize;
427 unsigned int bitsize;
432 bRead = (xdrs->x_op == XDR_DECODE);
433 bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0;
434 prevcoord[0] = prevcoord[1] = prevcoord[2] = 0;
438 /* xdrs is open for writing */
440 if (xdr_int(xdrs, size) == 0)
445 /* when the number of coordinates is small, don't try to compress; just
446 * write them as floats using xdr_vector
450 return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
451 (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
454 if (xdr_float(xdrs, precision) == 0)
459 if (size3 <= prealloc_size)
467 bufsize = size3 * 1.2;
468 ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
469 buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
470 if (ip == NULL || buf == NULL)
472 fprintf(stderr, "malloc failed\n");
476 /* buf[0-2] are special and do not contain actual data */
477 buf[0] = buf[1] = buf[2] = 0;
478 minint[0] = minint[1] = minint[2] = INT_MAX;
479 maxint[0] = maxint[1] = maxint[2] = INT_MIN;
484 oldlint1 = oldlint2 = oldlint3 = 0;
485 while (lfp < fp + size3)
487 /* find nearest integer */
490 lf = *lfp * *precision + 0.5;
494 lf = *lfp * *precision - 0.5;
496 if (fabs(lf) > MAXABS)
498 /* scaling would cause overflow */
502 if (lint1 < minint[0])
506 if (lint1 > maxint[0])
514 lf = *lfp * *precision + 0.5;
518 lf = *lfp * *precision - 0.5;
520 if (fabs(lf) > MAXABS)
522 /* scaling would cause overflow */
526 if (lint2 < minint[1])
530 if (lint2 > maxint[1])
538 lf = *lfp * *precision + 0.5;
542 lf = *lfp * *precision - 0.5;
544 if (fabs(lf) > MAXABS)
546 /* scaling would cause overflow */
550 if (lint3 < minint[2])
554 if (lint3 > maxint[2])
560 diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
561 if (diff < mindiff && lfp > fp + 3)
569 if ( (xdr_int(xdrs, &(minint[0])) == 0) ||
570 (xdr_int(xdrs, &(minint[1])) == 0) ||
571 (xdr_int(xdrs, &(minint[2])) == 0) ||
572 (xdr_int(xdrs, &(maxint[0])) == 0) ||
573 (xdr_int(xdrs, &(maxint[1])) == 0) ||
574 (xdr_int(xdrs, &(maxint[2])) == 0))
584 if ((float)maxint[0] - (float)minint[0] >= MAXABS ||
585 (float)maxint[1] - (float)minint[1] >= MAXABS ||
586 (float)maxint[2] - (float)minint[2] >= MAXABS)
588 /* turning value in unsigned by subtracting minint
589 * would cause overflow
593 sizeint[0] = maxint[0] - minint[0]+1;
594 sizeint[1] = maxint[1] - minint[1]+1;
595 sizeint[2] = maxint[2] - minint[2]+1;
597 /* check if one of the sizes is to big to be multiplied */
598 if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
600 bitsizeint[0] = sizeofint(sizeint[0]);
601 bitsizeint[1] = sizeofint(sizeint[1]);
602 bitsizeint[2] = sizeofint(sizeint[2]);
603 bitsize = 0; /* flag the use of large sizes */
607 bitsize = sizeofints(3, sizeint);
610 luip = (unsigned int *) ip;
612 while (smallidx < LASTIDX && magicints[smallidx] < mindiff)
616 if (xdr_int(xdrs, &smallidx) == 0)
626 maxidx = MIN(LASTIDX, smallidx + 8);
627 minidx = maxidx - 8; /* often this equal smallidx */
628 smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
629 smallnum = magicints[smallidx] / 2;
630 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
631 larger = magicints[maxidx] / 2;
636 thiscoord = (int *)(luip) + i * 3;
637 if (smallidx < maxidx && i >= 1 &&
638 abs(thiscoord[0] - prevcoord[0]) < larger &&
639 abs(thiscoord[1] - prevcoord[1]) < larger &&
640 abs(thiscoord[2] - prevcoord[2]) < larger)
644 else if (smallidx > minidx)
654 if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
655 abs(thiscoord[1] - thiscoord[4]) < smallnum &&
656 abs(thiscoord[2] - thiscoord[5]) < smallnum)
658 /* interchange first with second atom for better
659 * compression of water molecules
661 tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
663 tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
665 tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
671 tmpcoord[0] = thiscoord[0] - minint[0];
672 tmpcoord[1] = thiscoord[1] - minint[1];
673 tmpcoord[2] = thiscoord[2] - minint[2];
676 sendbits(buf, bitsizeint[0], tmpcoord[0]);
677 sendbits(buf, bitsizeint[1], tmpcoord[1]);
678 sendbits(buf, bitsizeint[2], tmpcoord[2]);
682 sendints(buf, 3, bitsize, sizeint, tmpcoord);
684 prevcoord[0] = thiscoord[0];
685 prevcoord[1] = thiscoord[1];
686 prevcoord[2] = thiscoord[2];
687 thiscoord = thiscoord + 3;
691 if (is_small == 0 && is_smaller == -1)
695 while (is_small && run < 8*3)
697 if (is_smaller == -1 && (
698 SQR(thiscoord[0] - prevcoord[0]) +
699 SQR(thiscoord[1] - prevcoord[1]) +
700 SQR(thiscoord[2] - prevcoord[2]) >= smaller * smaller))
705 tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
706 tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
707 tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
709 prevcoord[0] = thiscoord[0];
710 prevcoord[1] = thiscoord[1];
711 prevcoord[2] = thiscoord[2];
714 thiscoord = thiscoord + 3;
717 abs(thiscoord[0] - prevcoord[0]) < smallnum &&
718 abs(thiscoord[1] - prevcoord[1]) < smallnum &&
719 abs(thiscoord[2] - prevcoord[2]) < smallnum)
724 if (run != prevrun || is_smaller != 0)
727 sendbits(buf, 1, 1); /* flag the change in run-length */
728 sendbits(buf, 5, run+is_smaller+1);
732 sendbits(buf, 1, 0); /* flag the fact that runlength did not change */
734 for (k = 0; k < run; k += 3)
736 sendints(buf, 3, smallidx, sizesmall, &tmpcoord[k]);
740 smallidx += is_smaller;
744 smaller = magicints[smallidx-1] / 2;
749 smallnum = magicints[smallidx] / 2;
751 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
758 /* buf[0] holds the length in bytes */
759 if (xdr_int(xdrs, &(buf[0])) == 0)
770 rc = errval * (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]));
782 /* xdrs is open for reading */
784 if (xdr_int(xdrs, &lsize) == 0)
788 if (*size != 0 && lsize != *size)
790 fprintf(stderr, "wrong number of coordinates in xdr3dfcoord; "
791 "%d arg vs %d in file", *size, lsize);
798 return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
799 (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
801 if (xdr_float(xdrs, precision) == 0)
806 if (size3 <= prealloc_size)
814 bufsize = size3 * 1.2;
815 ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
816 buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
817 if (ip == NULL || buf == NULL)
819 fprintf(stderr, "malloc failed\n");
824 buf[0] = buf[1] = buf[2] = 0;
826 if ( (xdr_int(xdrs, &(minint[0])) == 0) ||
827 (xdr_int(xdrs, &(minint[1])) == 0) ||
828 (xdr_int(xdrs, &(minint[2])) == 0) ||
829 (xdr_int(xdrs, &(maxint[0])) == 0) ||
830 (xdr_int(xdrs, &(maxint[1])) == 0) ||
831 (xdr_int(xdrs, &(maxint[2])) == 0))
841 sizeint[0] = maxint[0] - minint[0]+1;
842 sizeint[1] = maxint[1] - minint[1]+1;
843 sizeint[2] = maxint[2] - minint[2]+1;
845 /* check if one of the sizes is to big to be multiplied */
846 if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
848 bitsizeint[0] = sizeofint(sizeint[0]);
849 bitsizeint[1] = sizeofint(sizeint[1]);
850 bitsizeint[2] = sizeofint(sizeint[2]);
851 bitsize = 0; /* flag the use of large sizes */
855 bitsize = sizeofints(3, sizeint);
858 if (xdr_int(xdrs, &smallidx) == 0)
868 maxidx = MIN(LASTIDX, smallidx + 8);
869 minidx = maxidx - 8; /* often this equal smallidx */
870 smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
871 smallnum = magicints[smallidx] / 2;
872 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
873 larger = magicints[maxidx];
875 /* buf[0] holds the length in bytes */
877 if (xdr_int(xdrs, &(buf[0])) == 0)
888 if (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]) == 0)
900 buf[0] = buf[1] = buf[2] = 0;
903 inv_precision = 1.0 / *precision;
909 thiscoord = (int *)(lip) + i * 3;
913 thiscoord[0] = receivebits(buf, bitsizeint[0]);
914 thiscoord[1] = receivebits(buf, bitsizeint[1]);
915 thiscoord[2] = receivebits(buf, bitsizeint[2]);
919 receiveints(buf, 3, bitsize, sizeint, thiscoord);
923 thiscoord[0] += minint[0];
924 thiscoord[1] += minint[1];
925 thiscoord[2] += minint[2];
927 prevcoord[0] = thiscoord[0];
928 prevcoord[1] = thiscoord[1];
929 prevcoord[2] = thiscoord[2];
932 flag = receivebits(buf, 1);
936 run = receivebits(buf, 5);
937 is_smaller = run % 3;
944 for (k = 0; k < run; k += 3)
946 receiveints(buf, 3, smallidx, sizesmall, thiscoord);
948 thiscoord[0] += prevcoord[0] - smallnum;
949 thiscoord[1] += prevcoord[1] - smallnum;
950 thiscoord[2] += prevcoord[2] - smallnum;
953 /* interchange first with second atom for better
954 * compression of water molecules
956 tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
958 tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
960 tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
962 *lfp++ = prevcoord[0] * inv_precision;
963 *lfp++ = prevcoord[1] * inv_precision;
964 *lfp++ = prevcoord[2] * inv_precision;
968 prevcoord[0] = thiscoord[0];
969 prevcoord[1] = thiscoord[1];
970 prevcoord[2] = thiscoord[2];
972 *lfp++ = thiscoord[0] * inv_precision;
973 *lfp++ = thiscoord[1] * inv_precision;
974 *lfp++ = thiscoord[2] * inv_precision;
979 *lfp++ = thiscoord[0] * inv_precision;
980 *lfp++ = thiscoord[1] * inv_precision;
981 *lfp++ = thiscoord[2] * inv_precision;
983 smallidx += is_smaller;
987 if (smallidx > FIRSTIDX)
989 smaller = magicints[smallidx - 1] /2;
996 else if (is_smaller > 0)
999 smallnum = magicints[smallidx] / 2;
1001 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
1014 /******************************************************************
1016 XTC files have a relatively simple structure.
1017 They have a header of 16 bytes and the rest are
1018 the compressed coordinates of the files. Due to the
1019 compression 00 is not present in the coordinates.
1020 The first 4 bytes of the header are the magic number
1021 1995 (0x000007CB). If we find this number we are guaranteed
1022 to be in the header, due to the presence of so many zeros.
1023 The second 4 bytes are the number of atoms in the frame, and is
1024 assumed to be constant. The third 4 bytes are the frame number.
1025 The last 4 bytes are a floating point representation of the time.
1027 ********************************************************************/
1029 /* Must match definition in xtcio.c */
1031 #define XTC_MAGIC 1995
1034 static const int header_size = 16;
1036 /* Check if we are at the header start.
1037 At the same time it will also read 1 int */
1038 static int xtc_at_header_start(FILE *fp, XDR *xdrs,
1039 int natoms, int * timestep, float * time)
1047 if ((off = gmx_ftell(fp)) < 0)
1051 /* read magic natoms and timestep */
1052 for (i = 0; i < 3; i++)
1054 if (!xdr_int(xdrs, &(i_inp[i])))
1056 gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET);
1061 if (i_inp[0] != XTC_MAGIC)
1063 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1069 /* read time and box */
1070 for (i = 0; i < 10; i++)
1072 if (!xdr_float(xdrs, &(f_inp[i])))
1074 gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET);
1078 /* Make a rigourous check to see if we are in the beggining of a header
1079 Hopefully there are no ambiguous cases */
1080 /* This check makes use of the fact that the box matrix has 3 zeroes on the upper
1081 right triangle and that the first element must be nonzero unless the entire matrix is zero
1083 if (i_inp[1] == natoms &&
1084 ((f_inp[1] != 0 && f_inp[6] == 0) ||
1085 (f_inp[1] == 0 && f_inp[5] == 0 && f_inp[9] == 0)))
1087 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1092 *timestep = i_inp[2];
1095 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1103 xtc_get_next_frame_number(FILE *fp, XDR *xdrs, int natoms)
1110 if ((off = gmx_ftell(fp)) < 0)
1115 /* read one int just to make sure we dont read this frame but the next */
1116 xdr_int(xdrs, &step);
1119 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1122 if (gmx_fseek(fp, off, SEEK_SET))
1130 if (gmx_fseek(fp, off, SEEK_SET))
1140 static float xtc_get_next_frame_time(FILE *fp, XDR *xdrs, int natoms,
1149 if ((off = gmx_ftell(fp)) < 0)
1153 /* read one int just to make sure we dont read this frame but the next */
1154 xdr_int(xdrs, &step);
1157 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1161 if (gmx_fseek(fp, off, SEEK_SET))
1170 if (gmx_fseek(fp, off, SEEK_SET))
1182 xtc_get_current_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1190 if ((off = gmx_ftell(fp)) < 0)
1197 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1201 if (gmx_fseek(fp, off, SEEK_SET))
1210 if (gmx_fseek(fp, off, SEEK_SET))
1219 if (gmx_fseek(fp, -2*XDR_INT_SIZE, SEEK_CUR))
1228 /* Currently not used, just for completeness */
1230 xtc_get_current_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1238 if ((off = gmx_ftell(fp)) < 0)
1246 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1250 if (gmx_fseek(fp, off, SEEK_SET))
1259 if (gmx_fseek(fp, off, SEEK_SET))
1269 if (gmx_fseek(fp, -2*XDR_INT_SIZE, SEEK_CUR))
1280 static gmx_off_t xtc_get_next_frame_start(FILE *fp, XDR *xdrs, int natoms)
1287 /* read one int just to make sure we dont read this frame but the next */
1288 xdr_int(xdrs, &step);
1291 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1294 if ((res = gmx_ftell(fp)) >= 0)
1296 return res - XDR_INT_SIZE;
1314 xdr_xtc_estimate_dt(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1321 if ((off = gmx_ftell(fp)) < 0)
1326 tinit = xtc_get_current_frame_time(fp, xdrs, natoms, bOK);
1333 res = xtc_get_next_frame_time(fp, xdrs, natoms, bOK);
1341 if (0 != gmx_fseek(fp, off, SEEK_SET))
1351 xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms)
1354 gmx_off_t high, pos;
1357 /* round to 4 bytes */
1360 if (gmx_fseek(fp, 0, SEEK_END))
1365 if ((high = gmx_ftell(fp)) < 0)
1370 /* round to 4 bytes */
1371 high /= XDR_INT_SIZE;
1372 high *= XDR_INT_SIZE;
1373 offset = ((high/2)/XDR_INT_SIZE)*XDR_INT_SIZE;
1375 if (gmx_fseek(fp, offset, SEEK_SET))
1382 fr = xtc_get_next_frame_number(fp, xdrs, natoms);
1387 if (fr != frame && abs(low-high) > header_size)
1397 /* round to 4 bytes */
1398 offset = (((high+low)/2)/4)*4;
1400 if (gmx_fseek(fp, offset, SEEK_SET))
1410 if (offset <= header_size)
1415 if (gmx_fseek(fp, offset, SEEK_SET))
1420 if ((pos = xtc_get_next_frame_start(fp, xdrs, natoms)) < 0)
1422 /* we probably hit an end of file */
1426 if (gmx_fseek(fp, pos, SEEK_SET))
1436 int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeekForwardOnly)
1440 gmx_bool bOK = FALSE;
1442 gmx_off_t high, offset, pos;
1446 if (bSeekForwardOnly)
1448 low = gmx_ftell(fp);
1450 if (gmx_fseek(fp, 0, SEEK_END))
1455 if ((high = gmx_ftell(fp)) < 0)
1460 high /= XDR_INT_SIZE;
1461 high *= XDR_INT_SIZE;
1462 offset = (((high-low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1464 if (gmx_fseek(fp, offset, SEEK_SET))
1471 * No need to call xdr_xtc_estimate_dt here - since xdr_xtc_estimate_dt is called first thing in the loop
1472 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1482 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1493 /* Found a place in the trajectory that has positive time step while
1494 other has negative time step */
1503 /* Found a place in the trajectory that has positive time step while
1504 other has negative time step */
1510 t = xtc_get_next_frame_time(fp, xdrs, natoms, &bOK);
1516 /* If we are before the target time and the time step is positive or 0, or we have
1517 after the target time and the time step is negative, or the difference between
1518 the current time and the target time is bigger than dt and above all the distance between high
1519 and low is bigger than 1 frame, then do another step of binary search. Otherwise stop and check
1520 if we reached the solution */
1521 if ((((t < time && dt_sign >= 0) || (t > time && dt_sign == -1)) || ((t
1522 - time) >= dt && dt_sign >= 0)
1523 || ((time - t) >= -dt && dt_sign < 0)) && (abs(low - high)
1526 if (dt >= 0 && dt_sign != -1)
1537 else if (dt <= 0 && dt_sign == -1)
1550 /* We should never reach here */
1553 /* round to 4 bytes and subtract header*/
1554 offset = (((high + low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1555 if (gmx_fseek(fp, offset, SEEK_SET))
1562 if (abs(low - high) <= header_size)
1566 /* re-estimate dt */
1567 if (xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK) != dt)
1571 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1574 if (t >= time && t - time < dt)
1581 if (offset <= header_size)
1586 gmx_fseek(fp, offset, SEEK_SET);
1588 if ((pos = xtc_get_next_frame_start(fp, xdrs, natoms)) < 0)
1593 if (gmx_fseek(fp, pos, SEEK_SET))
1601 xdr_xtc_get_last_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1607 off = gmx_ftell(fp);
1614 if ( (res = gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END)) != 0)
1620 time = xtc_get_current_frame_time(fp, xdrs, natoms, bOK);
1626 if ( (res = gmx_fseek(fp, off, SEEK_SET)) != 0)
1636 xdr_xtc_get_last_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1643 if ((off = gmx_ftell(fp)) < 0)
1650 if (gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END))
1656 frame = xtc_get_current_frame_number(fp, xdrs, natoms, bOK);
1663 if (gmx_fseek(fp, off, SEEK_SET))