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 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
51 #include "gmx_fatal.h"
56 # define gmx_fseek(A, B, C) fseeko(A, B, C)
57 # define gmx_ftell(A) ftello(A)
58 # define gmx_off_t off_t
60 # define gmx_fseek(A, B, C) fseek(A, B, C)
61 # define gmx_ftell(A) ftell(A)
62 # define gmx_off_t int
67 /* This is just for clarity - it can never be anything but 4! */
68 #define XDR_INT_SIZE 4
70 /* same order as the definition of xdr_datatype */
71 const char *xdr_datatype_names[] =
82 /*___________________________________________________________________________
84 | what follows are the C routine to read/write compressed coordinates together
85 | with some routines to assist in this task (those are marked
86 | static and cannot be called from user programs)
88 #define MAXABS INT_MAX-2
91 #define MIN(x, y) ((x) < (y) ? (x) : (y))
94 #define MAX(x, y) ((x) > (y) ? (x) : (y))
97 #define SQR(x) ((x)*(x))
99 static const int magicints[] = {
100 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
102 80, 101, 128, 161, 203, 256, 322, 406, 512, 645,
103 812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501,
104 8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536,
105 82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
106 832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042,
107 8388607, 10568983, 13316085, 16777216
111 /* note that magicints[FIRSTIDX-1] == 0 */
112 #define LASTIDX (sizeof(magicints) / sizeof(*magicints))
115 /*____________________________________________________________________________
117 | sendbits - encode num into buf using the specified number of bits
119 | This routines appends the value of num to the bits already present in
120 | the array buf. You need to give it the number of bits to use and you
121 | better make sure that this number of bits is enough to hold the value
122 | Also num must be positive.
126 static void sendbits(int buf[], int num_of_bits, int num)
129 unsigned int cnt, lastbyte;
131 unsigned char * cbuf;
133 cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
134 cnt = (unsigned int) buf[0];
136 lastbyte = (unsigned int) buf[2];
137 while (num_of_bits >= 8)
139 lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
140 cbuf[cnt++] = lastbyte >> lastbits;
145 lastbyte = (lastbyte << num_of_bits) | num;
146 lastbits += num_of_bits;
150 cbuf[cnt++] = lastbyte >> lastbits;
158 cbuf[cnt] = lastbyte << (8 - lastbits);
162 /*_________________________________________________________________________
164 | sizeofint - calculate bitsize of an integer
166 | return the number of bits needed to store an integer with given max size
170 static int sizeofint(const int size)
175 while (size >= num && num_of_bits < 32)
183 /*___________________________________________________________________________
185 | sizeofints - calculate 'bitsize' of compressed ints
187 | given the number of small unsigned integers and the maximum value
188 | return the number of bits needed to read or write them with the
189 | routines receiveints and sendints. You need this parameter when
190 | calling these routines. Note that for many calls I can use
191 | the variable 'smallidx' which is exactly the number of bits, and
192 | So I don't need to call 'sizeofints for those calls.
195 static int sizeofints( const int num_of_ints, unsigned int sizes[])
199 unsigned int num_of_bytes, num_of_bits, bytecnt, tmp;
203 for (i = 0; i < num_of_ints; i++)
206 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
208 tmp = bytes[bytecnt] * sizes[i] + tmp;
209 bytes[bytecnt] = tmp & 0xff;
214 bytes[bytecnt++] = tmp & 0xff;
217 num_of_bytes = bytecnt;
221 while (bytes[num_of_bytes] >= num)
226 return num_of_bits + num_of_bytes * 8;
230 /*____________________________________________________________________________
232 | sendints - send a small set of small integers in compressed format
234 | this routine is used internally by xdr3dfcoord, to send a set of
235 | small integers to the buffer.
236 | Multiplication with fixed (specified maximum ) sizes is used to get
237 | to one big, multibyte integer. Allthough the routine could be
238 | modified to handle sizes bigger than 16777216, or more than just
239 | a few integers, this is not done, because the gain in compression
240 | isn't worth the effort. Note that overflowing the multiplication
241 | or the byte buffer (32 bytes) is unchecked and causes bad results.
245 static void sendints(int buf[], const int num_of_ints, const int num_of_bits,
246 unsigned int sizes[], unsigned int nums[])
249 int i, num_of_bytes, bytecnt;
250 unsigned int bytes[32], tmp;
256 bytes[num_of_bytes++] = tmp & 0xff;
261 for (i = 1; i < num_of_ints; i++)
263 if (nums[i] >= sizes[i])
265 fprintf(stderr, "major breakdown in sendints num %u doesn't "
266 "match size %u\n", nums[i], sizes[i]);
269 /* use one step multiply */
271 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
273 tmp = bytes[bytecnt] * sizes[i] + tmp;
274 bytes[bytecnt] = tmp & 0xff;
279 bytes[bytecnt++] = tmp & 0xff;
282 num_of_bytes = bytecnt;
284 if (num_of_bits >= num_of_bytes * 8)
286 for (i = 0; i < num_of_bytes; i++)
288 sendbits(buf, 8, bytes[i]);
290 sendbits(buf, num_of_bits - num_of_bytes * 8, 0);
294 for (i = 0; i < num_of_bytes-1; i++)
296 sendbits(buf, 8, bytes[i]);
298 sendbits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]);
303 /*___________________________________________________________________________
305 | receivebits - decode number from buf using specified number of bits
307 | extract the number of bits from the array buf and construct an integer
308 | from it. Return that value.
312 static int receivebits(int buf[], int num_of_bits)
315 int cnt, num, lastbits;
316 unsigned int lastbyte;
317 unsigned char * cbuf;
318 int mask = (1 << num_of_bits) -1;
320 cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
322 lastbits = (unsigned int) buf[1];
323 lastbyte = (unsigned int) buf[2];
326 while (num_of_bits >= 8)
328 lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
329 num |= (lastbyte >> lastbits) << (num_of_bits - 8);
334 if (lastbits < num_of_bits)
337 lastbyte = (lastbyte << 8) | cbuf[cnt++];
339 lastbits -= num_of_bits;
340 num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1);
349 /*____________________________________________________________________________
351 | receiveints - decode 'small' integers from the buf array
353 | this routine is the inverse from sendints() and decodes the small integers
354 | written to buf by calculating the remainder and doing divisions with
355 | the given sizes[]. You need to specify the total number of bits to be
356 | used from buf in num_of_bits.
360 static void receiveints(int buf[], const int num_of_ints, int num_of_bits,
361 unsigned int sizes[], int nums[])
364 int i, j, num_of_bytes, p, num;
366 bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0;
368 while (num_of_bits > 8)
370 bytes[num_of_bytes++] = receivebits(buf, 8);
375 bytes[num_of_bytes++] = receivebits(buf, num_of_bits);
377 for (i = num_of_ints-1; i > 0; i--)
380 for (j = num_of_bytes-1; j >= 0; j--)
382 num = (num << 8) | bytes[j];
385 num = num - p * sizes[i];
389 nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
392 /*____________________________________________________________________________
394 | xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
396 | this routine reads or writes (depending on how you opened the file with
397 | xdropen() ) a large number of 3d coordinates (stored in *fp).
398 | The number of coordinates triplets to write is given by *size. On
399 | read this number may be zero, in which case it reads as many as were written
400 | or it may specify the number if triplets to read (which should match the
402 | Compression is achieved by first converting all floating numbers to integer
403 | using multiplication by *precision and rounding to the nearest integer.
404 | Then the minimum and maximum value are calculated to determine the range.
405 | The limited range of integers so found, is used to compress the coordinates.
406 | In addition the differences between succesive coordinates is calculated.
407 | If the difference happens to be 'small' then only the difference is saved,
408 | compressing the data even more. The notion of 'small' is changed dynamically
409 | and is enlarged or reduced whenever needed or possible.
410 | Extra compression is achieved in the case of GROMOS and coordinates of
411 | water molecules. GROMOS first writes out the Oxygen position, followed by
412 | the two hydrogens. In order to make the differences smaller (and thereby
413 | compression the data better) the order is changed into first one hydrogen
414 | then the oxygen, followed by the other hydrogen. This is rather special, but
415 | it shouldn't harm in the general case.
419 int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision)
425 /* preallocate a small buffer and ip on the stack - if we need more
426 we can always malloc(). This is faster for small values of size: */
427 unsigned prealloc_size = 3*16;
428 int prealloc_ip[3*16], prealloc_buf[3*20];
429 int we_should_free = 0;
431 int minint[3], maxint[3], mindiff, *lip, diff;
432 int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
434 unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
436 int smallnum, smaller, larger, i, is_small, is_smaller, run, prevrun;
438 int tmp, *thiscoord, prevcoord[3];
439 unsigned int tmpcoord[30];
441 int bufsize, xdrid, lsize;
442 unsigned int bitsize;
447 bRead = (xdrs->x_op == XDR_DECODE);
448 bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0;
449 prevcoord[0] = prevcoord[1] = prevcoord[2] = 0;
453 /* xdrs is open for writing */
455 if (xdr_int(xdrs, size) == 0)
460 /* when the number of coordinates is small, don't try to compress; just
461 * write them as floats using xdr_vector
465 return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
466 (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
469 if (xdr_float(xdrs, precision) == 0)
474 if (size3 <= prealloc_size)
482 bufsize = size3 * 1.2;
483 ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
484 buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
485 if (ip == NULL || buf == NULL)
487 fprintf(stderr, "malloc failed\n");
491 /* buf[0-2] are special and do not contain actual data */
492 buf[0] = buf[1] = buf[2] = 0;
493 minint[0] = minint[1] = minint[2] = INT_MAX;
494 maxint[0] = maxint[1] = maxint[2] = INT_MIN;
499 oldlint1 = oldlint2 = oldlint3 = 0;
500 while (lfp < fp + size3)
502 /* find nearest integer */
505 lf = *lfp * *precision + 0.5;
509 lf = *lfp * *precision - 0.5;
511 if (fabs(lf) > MAXABS)
513 /* scaling would cause overflow */
517 if (lint1 < minint[0])
521 if (lint1 > maxint[0])
529 lf = *lfp * *precision + 0.5;
533 lf = *lfp * *precision - 0.5;
535 if (fabs(lf) > MAXABS)
537 /* scaling would cause overflow */
541 if (lint2 < minint[1])
545 if (lint2 > maxint[1])
553 lf = *lfp * *precision + 0.5;
557 lf = *lfp * *precision - 0.5;
559 if (fabs(lf) > MAXABS)
561 /* scaling would cause overflow */
565 if (lint3 < minint[2])
569 if (lint3 > maxint[2])
575 diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
576 if (diff < mindiff && lfp > fp + 3)
584 if ( (xdr_int(xdrs, &(minint[0])) == 0) ||
585 (xdr_int(xdrs, &(minint[1])) == 0) ||
586 (xdr_int(xdrs, &(minint[2])) == 0) ||
587 (xdr_int(xdrs, &(maxint[0])) == 0) ||
588 (xdr_int(xdrs, &(maxint[1])) == 0) ||
589 (xdr_int(xdrs, &(maxint[2])) == 0))
599 if ((float)maxint[0] - (float)minint[0] >= MAXABS ||
600 (float)maxint[1] - (float)minint[1] >= MAXABS ||
601 (float)maxint[2] - (float)minint[2] >= MAXABS)
603 /* turning value in unsigned by subtracting minint
604 * would cause overflow
608 sizeint[0] = maxint[0] - minint[0]+1;
609 sizeint[1] = maxint[1] - minint[1]+1;
610 sizeint[2] = maxint[2] - minint[2]+1;
612 /* check if one of the sizes is to big to be multiplied */
613 if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
615 bitsizeint[0] = sizeofint(sizeint[0]);
616 bitsizeint[1] = sizeofint(sizeint[1]);
617 bitsizeint[2] = sizeofint(sizeint[2]);
618 bitsize = 0; /* flag the use of large sizes */
622 bitsize = sizeofints(3, sizeint);
625 luip = (unsigned int *) ip;
627 while (smallidx < LASTIDX && magicints[smallidx] < mindiff)
631 if (xdr_int(xdrs, &smallidx) == 0)
641 maxidx = MIN(LASTIDX, smallidx + 8);
642 minidx = maxidx - 8; /* often this equal smallidx */
643 smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
644 smallnum = magicints[smallidx] / 2;
645 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
646 larger = magicints[maxidx] / 2;
651 thiscoord = (int *)(luip) + i * 3;
652 if (smallidx < maxidx && i >= 1 &&
653 abs(thiscoord[0] - prevcoord[0]) < larger &&
654 abs(thiscoord[1] - prevcoord[1]) < larger &&
655 abs(thiscoord[2] - prevcoord[2]) < larger)
659 else if (smallidx > minidx)
669 if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
670 abs(thiscoord[1] - thiscoord[4]) < smallnum &&
671 abs(thiscoord[2] - thiscoord[5]) < smallnum)
673 /* interchange first with second atom for better
674 * compression of water molecules
676 tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
678 tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
680 tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
686 tmpcoord[0] = thiscoord[0] - minint[0];
687 tmpcoord[1] = thiscoord[1] - minint[1];
688 tmpcoord[2] = thiscoord[2] - minint[2];
691 sendbits(buf, bitsizeint[0], tmpcoord[0]);
692 sendbits(buf, bitsizeint[1], tmpcoord[1]);
693 sendbits(buf, bitsizeint[2], tmpcoord[2]);
697 sendints(buf, 3, bitsize, sizeint, tmpcoord);
699 prevcoord[0] = thiscoord[0];
700 prevcoord[1] = thiscoord[1];
701 prevcoord[2] = thiscoord[2];
702 thiscoord = thiscoord + 3;
706 if (is_small == 0 && is_smaller == -1)
710 while (is_small && run < 8*3)
712 if (is_smaller == -1 && (
713 SQR(thiscoord[0] - prevcoord[0]) +
714 SQR(thiscoord[1] - prevcoord[1]) +
715 SQR(thiscoord[2] - prevcoord[2]) >= smaller * smaller))
720 tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
721 tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
722 tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
724 prevcoord[0] = thiscoord[0];
725 prevcoord[1] = thiscoord[1];
726 prevcoord[2] = thiscoord[2];
729 thiscoord = thiscoord + 3;
732 abs(thiscoord[0] - prevcoord[0]) < smallnum &&
733 abs(thiscoord[1] - prevcoord[1]) < smallnum &&
734 abs(thiscoord[2] - prevcoord[2]) < smallnum)
739 if (run != prevrun || is_smaller != 0)
742 sendbits(buf, 1, 1); /* flag the change in run-length */
743 sendbits(buf, 5, run+is_smaller+1);
747 sendbits(buf, 1, 0); /* flag the fact that runlength did not change */
749 for (k = 0; k < run; k += 3)
751 sendints(buf, 3, smallidx, sizesmall, &tmpcoord[k]);
755 smallidx += is_smaller;
759 smaller = magicints[smallidx-1] / 2;
764 smallnum = magicints[smallidx] / 2;
766 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
773 /* buf[0] holds the length in bytes */
774 if (xdr_int(xdrs, &(buf[0])) == 0)
785 rc = errval * (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]));
797 /* xdrs is open for reading */
799 if (xdr_int(xdrs, &lsize) == 0)
803 if (*size != 0 && lsize != *size)
805 fprintf(stderr, "wrong number of coordinates in xdr3dfcoord; "
806 "%d arg vs %d in file", *size, lsize);
813 return (xdr_vector(xdrs, (char *) fp, (unsigned int)size3,
814 (unsigned int)sizeof(*fp), (xdrproc_t)xdr_float));
816 if (xdr_float(xdrs, precision) == 0)
821 if (size3 <= prealloc_size)
829 bufsize = size3 * 1.2;
830 ip = (int *)malloc((size_t)(size3 * sizeof(*ip)));
831 buf = (int *)malloc((size_t)(bufsize * sizeof(*buf)));
832 if (ip == NULL || buf == NULL)
834 fprintf(stderr, "malloc failed\n");
839 buf[0] = buf[1] = buf[2] = 0;
841 if ( (xdr_int(xdrs, &(minint[0])) == 0) ||
842 (xdr_int(xdrs, &(minint[1])) == 0) ||
843 (xdr_int(xdrs, &(minint[2])) == 0) ||
844 (xdr_int(xdrs, &(maxint[0])) == 0) ||
845 (xdr_int(xdrs, &(maxint[1])) == 0) ||
846 (xdr_int(xdrs, &(maxint[2])) == 0))
856 sizeint[0] = maxint[0] - minint[0]+1;
857 sizeint[1] = maxint[1] - minint[1]+1;
858 sizeint[2] = maxint[2] - minint[2]+1;
860 /* check if one of the sizes is to big to be multiplied */
861 if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
863 bitsizeint[0] = sizeofint(sizeint[0]);
864 bitsizeint[1] = sizeofint(sizeint[1]);
865 bitsizeint[2] = sizeofint(sizeint[2]);
866 bitsize = 0; /* flag the use of large sizes */
870 bitsize = sizeofints(3, sizeint);
873 if (xdr_int(xdrs, &smallidx) == 0)
883 maxidx = MIN(LASTIDX, smallidx + 8);
884 minidx = maxidx - 8; /* often this equal smallidx */
885 smaller = magicints[MAX(FIRSTIDX, smallidx-1)] / 2;
886 smallnum = magicints[smallidx] / 2;
887 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
888 larger = magicints[maxidx];
890 /* buf[0] holds the length in bytes */
892 if (xdr_int(xdrs, &(buf[0])) == 0)
903 if (xdr_opaque(xdrs, (char *)&(buf[3]), (unsigned int)buf[0]) == 0)
915 buf[0] = buf[1] = buf[2] = 0;
918 inv_precision = 1.0 / *precision;
924 thiscoord = (int *)(lip) + i * 3;
928 thiscoord[0] = receivebits(buf, bitsizeint[0]);
929 thiscoord[1] = receivebits(buf, bitsizeint[1]);
930 thiscoord[2] = receivebits(buf, bitsizeint[2]);
934 receiveints(buf, 3, bitsize, sizeint, thiscoord);
938 thiscoord[0] += minint[0];
939 thiscoord[1] += minint[1];
940 thiscoord[2] += minint[2];
942 prevcoord[0] = thiscoord[0];
943 prevcoord[1] = thiscoord[1];
944 prevcoord[2] = thiscoord[2];
947 flag = receivebits(buf, 1);
951 run = receivebits(buf, 5);
952 is_smaller = run % 3;
959 for (k = 0; k < run; k += 3)
961 receiveints(buf, 3, smallidx, sizesmall, thiscoord);
963 thiscoord[0] += prevcoord[0] - smallnum;
964 thiscoord[1] += prevcoord[1] - smallnum;
965 thiscoord[2] += prevcoord[2] - smallnum;
968 /* interchange first with second atom for better
969 * compression of water molecules
971 tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
973 tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
975 tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
977 *lfp++ = prevcoord[0] * inv_precision;
978 *lfp++ = prevcoord[1] * inv_precision;
979 *lfp++ = prevcoord[2] * inv_precision;
983 prevcoord[0] = thiscoord[0];
984 prevcoord[1] = thiscoord[1];
985 prevcoord[2] = thiscoord[2];
987 *lfp++ = thiscoord[0] * inv_precision;
988 *lfp++ = thiscoord[1] * inv_precision;
989 *lfp++ = thiscoord[2] * inv_precision;
994 *lfp++ = thiscoord[0] * inv_precision;
995 *lfp++ = thiscoord[1] * inv_precision;
996 *lfp++ = thiscoord[2] * inv_precision;
998 smallidx += is_smaller;
1002 if (smallidx > FIRSTIDX)
1004 smaller = magicints[smallidx - 1] /2;
1011 else if (is_smaller > 0)
1014 smallnum = magicints[smallidx] / 2;
1016 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
1029 /******************************************************************
1031 XTC files have a relatively simple structure.
1032 They have a header of 16 bytes and the rest are
1033 the compressed coordinates of the files. Due to the
1034 compression 00 is not present in the coordinates.
1035 The first 4 bytes of the header are the magic number
1036 1995 (0x000007CB). If we find this number we are guaranteed
1037 to be in the header, due to the presence of so many zeros.
1038 The second 4 bytes are the number of atoms in the frame, and is
1039 assumed to be constant. The third 4 bytes are the frame number.
1040 The last 4 bytes are a floating point representation of the time.
1042 ********************************************************************/
1044 /* Must match definition in xtcio.c */
1046 #define XTC_MAGIC 1995
1049 static const int header_size = 16;
1051 /* Check if we are at the header start.
1052 At the same time it will also read 1 int */
1053 static int xtc_at_header_start(FILE *fp, XDR *xdrs,
1054 int natoms, int * timestep, float * time)
1062 if ((off = gmx_ftell(fp)) < 0)
1066 /* read magic natoms and timestep */
1067 for (i = 0; i < 3; i++)
1069 if (!xdr_int(xdrs, &(i_inp[i])))
1071 gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET);
1076 if (i_inp[0] != XTC_MAGIC)
1078 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1084 /* read time and box */
1085 for (i = 0; i < 10; i++)
1087 if (!xdr_float(xdrs, &(f_inp[i])))
1089 gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET);
1093 /* Make a rigourous check to see if we are in the beggining of a header
1094 Hopefully there are no ambiguous cases */
1095 /* This check makes use of the fact that the box matrix has 3 zeroes on the upper
1096 right triangle and that the first element must be nonzero unless the entire matrix is zero
1098 if (i_inp[1] == natoms &&
1099 ((f_inp[1] != 0 && f_inp[6] == 0) ||
1100 (f_inp[1] == 0 && f_inp[5] == 0 && f_inp[9] == 0)))
1102 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1107 *timestep = i_inp[2];
1110 if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET))
1118 xtc_get_next_frame_number(FILE *fp, XDR *xdrs, int natoms)
1125 if ((off = gmx_ftell(fp)) < 0)
1130 /* read one int just to make sure we dont read this frame but the next */
1131 xdr_int(xdrs, &step);
1134 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1137 if (gmx_fseek(fp, off, SEEK_SET))
1145 if (gmx_fseek(fp, off, SEEK_SET))
1155 static float xtc_get_next_frame_time(FILE *fp, XDR *xdrs, int natoms,
1164 if ((off = gmx_ftell(fp)) < 0)
1168 /* read one int just to make sure we dont read this frame but the next */
1169 xdr_int(xdrs, &step);
1172 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1176 if (gmx_fseek(fp, off, SEEK_SET))
1185 if (gmx_fseek(fp, off, SEEK_SET))
1197 xtc_get_current_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1205 if ((off = gmx_ftell(fp)) < 0)
1212 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1216 if (gmx_fseek(fp, off, SEEK_SET))
1225 if (gmx_fseek(fp, off, SEEK_SET))
1234 if (gmx_fseek(fp, -2*XDR_INT_SIZE, SEEK_CUR))
1243 /* Currently not used, just for completeness */
1245 xtc_get_current_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1253 if ((off = gmx_ftell(fp)) < 0)
1261 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1265 if (gmx_fseek(fp, off, SEEK_SET))
1274 if (gmx_fseek(fp, off, SEEK_SET))
1284 if (gmx_fseek(fp, -2*XDR_INT_SIZE, SEEK_CUR))
1295 static gmx_off_t xtc_get_next_frame_start(FILE *fp, XDR *xdrs, int natoms)
1302 /* read one int just to make sure we dont read this frame but the next */
1303 xdr_int(xdrs, &step);
1306 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1309 if ((res = gmx_ftell(fp)) >= 0)
1311 return res - XDR_INT_SIZE;
1329 xdr_xtc_estimate_dt(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1336 if ((off = gmx_ftell(fp)) < 0)
1341 tinit = xtc_get_current_frame_time(fp, xdrs, natoms, bOK);
1348 res = xtc_get_next_frame_time(fp, xdrs, natoms, bOK);
1356 if (0 != gmx_fseek(fp, off, SEEK_SET))
1364 /* can be replaced by llabs in 5.0 (allows C99)*/
1366 gmx_llabs(gmx_off_t x)
1372 xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms)
1375 gmx_off_t high, pos;
1378 /* round to 4 bytes */
1381 if (gmx_fseek(fp, 0, SEEK_END))
1386 if ((high = gmx_ftell(fp)) < 0)
1391 /* round to 4 bytes */
1392 high /= XDR_INT_SIZE;
1393 high *= XDR_INT_SIZE;
1394 offset = ((high/2)/XDR_INT_SIZE)*XDR_INT_SIZE;
1396 if (gmx_fseek(fp, offset, SEEK_SET))
1403 fr = xtc_get_next_frame_number(fp, xdrs, natoms);
1408 if (fr != frame && gmx_llabs(low-high) > header_size)
1418 /* round to 4 bytes */
1419 offset = (((high+low)/2)/4)*4;
1421 if (gmx_fseek(fp, offset, SEEK_SET))
1431 if (offset <= header_size)
1436 if (gmx_fseek(fp, offset, SEEK_SET))
1441 if ((pos = xtc_get_next_frame_start(fp, xdrs, natoms)) < 0)
1443 /* we probably hit an end of file */
1447 if (gmx_fseek(fp, pos, SEEK_SET))
1457 int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeekForwardOnly)
1461 gmx_bool bOK = FALSE;
1463 gmx_off_t high, offset, pos;
1467 if (bSeekForwardOnly)
1469 low = gmx_ftell(fp);
1471 if (gmx_fseek(fp, 0, SEEK_END))
1476 if ((high = gmx_ftell(fp)) < 0)
1481 high /= XDR_INT_SIZE;
1482 high *= XDR_INT_SIZE;
1483 offset = (((high-low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1485 if (gmx_fseek(fp, offset, SEEK_SET))
1492 * No need to call xdr_xtc_estimate_dt here - since xdr_xtc_estimate_dt is called first thing in the loop
1493 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1503 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1514 /* Found a place in the trajectory that has positive time step while
1515 other has negative time step */
1524 /* Found a place in the trajectory that has positive time step while
1525 other has negative time step */
1531 t = xtc_get_next_frame_time(fp, xdrs, natoms, &bOK);
1537 /* If we are before the target time and the time step is positive or 0, or we have
1538 after the target time and the time step is negative, or the difference between
1539 the current time and the target time is bigger than dt and above all the distance between high
1540 and low is bigger than 1 frame, then do another step of binary search. Otherwise stop and check
1541 if we reached the solution */
1542 if ((((t < time && dt_sign >= 0) || (t > time && dt_sign == -1)) ||
1543 ((t - time) >= dt && dt_sign >= 0) || ((time - t) >= -dt && dt_sign < 0)) &&
1544 (gmx_llabs(low - high) > header_size))
1546 if (dt >= 0 && dt_sign != -1)
1557 else if (dt <= 0 && dt_sign == -1)
1570 /* We should never reach here */
1573 /* round to 4 bytes and subtract header*/
1574 offset = (((high + low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1575 if (gmx_fseek(fp, offset, SEEK_SET))
1582 if (gmx_llabs(low - high) <= header_size)
1586 /* re-estimate dt */
1587 if (xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK) != dt)
1591 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1594 if (t >= time && t - time < dt)
1601 if (offset <= header_size)
1606 gmx_fseek(fp, offset, SEEK_SET);
1608 if ((pos = xtc_get_next_frame_start(fp, xdrs, natoms)) < 0)
1613 if (gmx_fseek(fp, pos, SEEK_SET))
1621 xdr_xtc_get_last_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1627 off = gmx_ftell(fp);
1634 if ( (res = gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END)) != 0)
1640 time = xtc_get_current_frame_time(fp, xdrs, natoms, bOK);
1646 if ( (res = gmx_fseek(fp, off, SEEK_SET)) != 0)
1656 xdr_xtc_get_last_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK)
1663 if ((off = gmx_ftell(fp)) < 0)
1670 if (gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END))
1676 frame = xtc_get_current_frame_number(fp, xdrs, natoms, bOK);
1683 if (gmx_fseek(fp, off, SEEK_SET))