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,2015,2016,2017 by the GROMACS development team.
7 * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
8 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
9 * and including many others, as listed in the AUTHORS file in the
10 * top-level source 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.
48 #include "gromacs/fileio/xdr_datatype.h"
49 #include "gromacs/fileio/xdrf.h"
50 #include "gromacs/utility/enumerationhelpers.h"
51 #include "gromacs/utility/futil.h"
53 /* This is just for clarity - it can never be anything but 4! */
54 #define XDR_INT_SIZE 4
56 /* Human-friendly names for XdrDataType enum class */
57 const char* enumValueToString(XdrDataType enumValue)
59 constexpr gmx::EnumerationArray<XdrDataType, const char*> xdrDataTypeNames = {
60 "int", "float", "double", "large int", "char", "string"
62 return xdrDataTypeNames[enumValue];
66 /*___________________________________________________________________________
68 | what follows are the C routine to read/write compressed coordinates together
69 | with some routines to assist in this task (those are marked
70 | static and cannot be called from user programs)
73 // Integers above 2^24 do not have unique representations in
74 // 32-bit floats ie with 24 bits of precision. We use maxAbsoluteInt
75 // to check that float values can be transformed into an in-range
76 // 32-bit integer. There is no need to ensure we are within the range
77 // of ints with exact floating-point representations. However, we should
78 // reject all floats above that which converts to an in-range 32-bit integer.
79 const float maxAbsoluteInt = nextafterf(float(INT_MAX), 0.F); // NOLINT(cert-err58-cpp)
82 # define SQR(x) ((x) * (x))
84 static const int magicints[] = {
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
86 10, 12, 16, 20, 25, 32, 40, 50, 64, 80,
87 101, 128, 161, 203, 256, 322, 406, 512, 645, 812,
88 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192,
89 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536, 82570,
90 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561, 832255,
91 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042, 8388607,
92 10568983, 13316085, 16777216
96 /* note that magicints[FIRSTIDX-1] == 0 */
97 #define LASTIDX static_cast<int>((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;
118 cbuf = (reinterpret_cast<unsigned char*>(buf)) + 3 * sizeof(*buf);
119 cnt = static_cast<unsigned int>(buf[0]);
121 lastbyte = static_cast<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, const 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;
214 /*____________________________________________________________________________
216 | sendints - send a small set of small integers in compressed format
218 | this routine is used internally by xdr3dfcoord, to send a set of
219 | small integers to the buffer.
220 | Multiplication with fixed (specified maximum ) sizes is used to get
221 | to one big, multibyte integer. Allthough the routine could be
222 | modified to handle sizes bigger than 16777216, or more than just
223 | a few integers, this is not done, because the gain in compression
224 | isn't worth the effort. Note that overflowing the multiplication
225 | or the byte buffer (32 bytes) is unchecked and causes bad results.
229 static void sendints(int buf[],
230 const int num_of_ints,
231 const int num_of_bits,
232 unsigned int sizes[],
236 int i, num_of_bytes, bytecnt;
237 unsigned int bytes[32], tmp;
243 bytes[num_of_bytes++] = tmp & 0xff;
247 for (i = 1; i < num_of_ints; i++)
249 if (nums[i] >= sizes[i])
252 "major breakdown in sendints num %u doesn't "
258 /* use one step multiply */
260 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
262 tmp = bytes[bytecnt] * sizes[i] + tmp;
263 bytes[bytecnt] = tmp & 0xff;
268 bytes[bytecnt++] = tmp & 0xff;
271 num_of_bytes = bytecnt;
273 if (num_of_bits >= num_of_bytes * 8)
275 for (i = 0; i < num_of_bytes; i++)
277 sendbits(buf, 8, bytes[i]);
279 sendbits(buf, num_of_bits - num_of_bytes * 8, 0);
283 for (i = 0; i < num_of_bytes - 1; i++)
285 sendbits(buf, 8, bytes[i]);
287 sendbits(buf, num_of_bits - (num_of_bytes - 1) * 8, bytes[i]);
292 /*___________________________________________________________________________
294 | receivebits - decode number from buf using specified number of bits
296 | extract the number of bits from the array buf and construct an integer
297 | from it. Return that value.
301 static int receivebits(int buf[], int num_of_bits)
304 int cnt, num, lastbits;
305 unsigned int lastbyte;
307 int mask = (1 << num_of_bits) - 1;
309 cbuf = reinterpret_cast<unsigned char*>(buf) + 3 * sizeof(*buf);
311 lastbits = static_cast<unsigned int>(buf[1]);
312 lastbyte = static_cast<unsigned int>(buf[2]);
315 while (num_of_bits >= 8)
317 lastbyte = (lastbyte << 8) | cbuf[cnt++];
318 num |= (lastbyte >> lastbits) << (num_of_bits - 8);
323 if (lastbits < num_of_bits)
326 lastbyte = (lastbyte << 8) | cbuf[cnt++];
328 lastbits -= num_of_bits;
329 num |= (lastbyte >> lastbits) & ((1 << num_of_bits) - 1);
338 /*____________________________________________________________________________
340 | receiveints - decode 'small' integers from the buf array
342 | this routine is the inverse from sendints() and decodes the small integers
343 | written to buf by calculating the remainder and doing divisions with
344 | the given sizes[]. You need to specify the total number of bits to be
345 | used from buf in num_of_bits.
349 static void receiveints(int buf[], const int num_of_ints, int num_of_bits, const unsigned int sizes[], int nums[])
352 int i, j, num_of_bytes, p, num;
354 bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0;
356 while (num_of_bits > 8)
358 bytes[num_of_bytes++] = receivebits(buf, 8);
363 bytes[num_of_bytes++] = receivebits(buf, num_of_bits);
365 for (i = num_of_ints - 1; i > 0; i--)
368 for (j = num_of_bytes - 1; j >= 0; j--)
370 num = (num << 8) | bytes[j];
373 num = num - p * sizes[i];
377 nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
380 /*____________________________________________________________________________
382 | xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
384 | this routine reads or writes (depending on how you opened the file with
385 | xdropen() ) a large number of 3d coordinates (stored in *fp).
386 | The number of coordinates triplets to write is given by *size. On
387 | read this number may be zero, in which case it reads as many as were written
388 | or it may specify the number if triplets to read (which should match the
390 | Compression is achieved by first converting all floating numbers to integer
391 | using multiplication by *precision and rounding to the nearest integer.
392 | Then the minimum and maximum value are calculated to determine the range.
393 | The limited range of integers so found, is used to compress the coordinates.
394 | In addition the differences between succesive coordinates is calculated.
395 | If the difference happens to be 'small' then only the difference is saved,
396 | compressing the data even more. The notion of 'small' is changed dynamically
397 | and is enlarged or reduced whenever needed or possible.
398 | Extra compression is achieved in the case of GROMOS and coordinates of
399 | water molecules. GROMOS first writes out the Oxygen position, followed by
400 | the two hydrogens. In order to make the differences smaller (and thereby
401 | compression the data better) the order is changed into first one hydrogen
402 | then the oxygen, followed by the other hydrogen. This is rather special, but
403 | it shouldn't harm in the general case.
407 int xdr3dfcoord(XDR* xdrs, float* fp, int* size, float* precision)
413 /* preallocate a small buffer and ip on the stack - if we need more
414 we can always malloc(). This is faster for small values of size: */
415 unsigned prealloc_size = 3 * 16;
416 int prealloc_ip[3 * 16], prealloc_buf[3 * 20];
417 int we_should_free = 0;
419 int minint[3], maxint[3], mindiff, *lip, diff;
420 int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
422 unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
424 int smallnum, smaller, larger, i, is_small, is_smaller, run, prevrun;
426 int tmp, *thiscoord, prevcoord[3];
427 unsigned int tmpcoord[30];
430 unsigned int bitsize;
435 bRead = (xdrs->x_op == XDR_DECODE);
436 bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0;
437 prevcoord[0] = prevcoord[1] = prevcoord[2] = 0;
439 // The static analyzer warns about garbage values for thiscoord[] further
440 // down. It might be thrown off by all the reinterpret_casts, but we might
441 // as well make sure the small preallocated buffer is zero-initialized.
442 for (i = 0; i < static_cast<int>(prealloc_size); i++)
449 /* xdrs is open for writing */
451 if (xdr_int(xdrs, size) == 0)
456 /* when the number of coordinates is small, don't try to compress; just
457 * write them as floats using xdr_vector
461 return (xdr_vector(xdrs,
462 reinterpret_cast<char*>(fp),
463 static_cast<unsigned int>(size3),
464 static_cast<unsigned int>(sizeof(*fp)),
465 reinterpret_cast<xdrproc_t>(xdr_float)));
468 if (xdr_float(xdrs, precision) == 0)
473 if (size3 <= prealloc_size)
481 bufsize = static_cast<int>(size3 * 1.2);
482 ip = reinterpret_cast<int*>(malloc(size3 * sizeof(*ip)));
483 buf = reinterpret_cast<int*>(malloc(bufsize * sizeof(*buf)));
484 if (ip == nullptr || buf == nullptr)
486 fprintf(stderr, "malloc failed\n");
490 /* buf[0-2] are special and do not contain actual data */
491 buf[0] = buf[1] = buf[2] = 0;
492 minint[0] = minint[1] = minint[2] = INT_MAX;
493 maxint[0] = maxint[1] = maxint[2] = INT_MIN;
498 oldlint1 = oldlint2 = oldlint3 = 0;
499 while (lfp < fp + size3)
501 /* find nearest integer */
504 lf = *lfp * *precision + 0.5;
508 lf = *lfp * *precision - 0.5;
510 if (std::fabs(lf) > maxAbsoluteInt)
512 /* scaling would cause overflow */
515 lint1 = static_cast<int>(lf);
516 if (lint1 < minint[0])
520 if (lint1 > maxint[0])
528 lf = *lfp * *precision + 0.5;
532 lf = *lfp * *precision - 0.5;
534 if (std::fabs(lf) > maxAbsoluteInt)
536 /* scaling would cause overflow */
539 lint2 = static_cast<int>(lf);
540 if (lint2 < minint[1])
544 if (lint2 > maxint[1])
552 lf = *lfp * *precision + 0.5;
556 lf = *lfp * *precision - 0.5;
558 if (std::abs(lf) > maxAbsoluteInt)
560 /* scaling would cause overflow */
563 lint3 = static_cast<int>(lf);
564 if (lint3 < minint[2])
568 if (lint3 > maxint[2])
574 diff = std::abs(oldlint1 - lint1) + std::abs(oldlint2 - lint2) + std::abs(oldlint3 - lint3);
575 if (diff < mindiff && lfp > fp + 3)
583 if ((xdr_int(xdrs, &(minint[0])) == 0) || (xdr_int(xdrs, &(minint[1])) == 0)
584 || (xdr_int(xdrs, &(minint[2])) == 0) || (xdr_int(xdrs, &(maxint[0])) == 0)
585 || (xdr_int(xdrs, &(maxint[1])) == 0) || (xdr_int(xdrs, &(maxint[2])) == 0))
595 if (static_cast<float>(maxint[0]) - static_cast<float>(minint[0]) >= maxAbsoluteInt
596 || static_cast<float>(maxint[1]) - static_cast<float>(minint[1]) >= maxAbsoluteInt
597 || static_cast<float>(maxint[2]) - static_cast<float>(minint[2]) >= maxAbsoluteInt)
599 /* turning value in unsigned by subtracting minint
600 * would cause overflow
604 sizeint[0] = maxint[0] - minint[0] + 1;
605 sizeint[1] = maxint[1] - minint[1] + 1;
606 sizeint[2] = maxint[2] - minint[2] + 1;
608 /* check if one of the sizes is to big to be multiplied */
609 if ((sizeint[0] | sizeint[1] | sizeint[2]) > 0xffffff)
611 bitsizeint[0] = sizeofint(sizeint[0]);
612 bitsizeint[1] = sizeofint(sizeint[1]);
613 bitsizeint[2] = sizeofint(sizeint[2]);
614 bitsize = 0; /* flag the use of large sizes */
618 bitsize = sizeofints(3, sizeint);
620 luip = reinterpret_cast<unsigned int*>(ip);
622 while (smallidx < LASTIDX && magicints[smallidx] < mindiff)
626 if (xdr_int(xdrs, &smallidx) == 0)
636 maxidx = std::min(LASTIDX, smallidx + 8);
637 minidx = maxidx - 8; /* often this equal smallidx */
638 smaller = magicints[std::max(FIRSTIDX, smallidx - 1)] / 2;
639 smallnum = magicints[smallidx] / 2;
640 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
641 larger = magicints[maxidx] / 2;
646 thiscoord = reinterpret_cast<int*>(luip) + i * 3;
647 if (smallidx < maxidx && i >= 1 && std::abs(thiscoord[0] - prevcoord[0]) < larger
648 && std::abs(thiscoord[1] - prevcoord[1]) < larger
649 && std::abs(thiscoord[2] - prevcoord[2]) < larger)
653 else if (smallidx > minidx)
663 if (std::abs(thiscoord[0] - thiscoord[3]) < smallnum
664 && std::abs(thiscoord[1] - thiscoord[4]) < smallnum
665 && std::abs(thiscoord[2] - thiscoord[5]) < smallnum)
667 /* interchange first with second atom for better
668 * compression of water molecules
671 thiscoord[0] = thiscoord[3];
674 thiscoord[1] = thiscoord[4];
677 thiscoord[2] = thiscoord[5];
682 tmpcoord[0] = thiscoord[0] - minint[0];
683 tmpcoord[1] = thiscoord[1] - minint[1];
684 tmpcoord[2] = thiscoord[2] - minint[2];
687 sendbits(buf, bitsizeint[0], tmpcoord[0]);
688 sendbits(buf, bitsizeint[1], tmpcoord[1]);
689 sendbits(buf, bitsizeint[2], tmpcoord[2]);
693 sendints(buf, 3, bitsize, sizeint, tmpcoord);
695 prevcoord[0] = thiscoord[0];
696 prevcoord[1] = thiscoord[1];
697 prevcoord[2] = thiscoord[2];
698 thiscoord = thiscoord + 3;
702 if (is_small == 0 && is_smaller == -1)
706 while (is_small && run < 8 * 3)
709 && (SQR(thiscoord[0] - prevcoord[0]) + SQR(thiscoord[1] - prevcoord[1])
710 + SQR(thiscoord[2] - prevcoord[2])
711 >= smaller * smaller))
716 tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
717 tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
718 tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
720 prevcoord[0] = thiscoord[0];
721 prevcoord[1] = thiscoord[1];
722 prevcoord[2] = thiscoord[2];
725 thiscoord = thiscoord + 3;
727 if (i < *size && abs(thiscoord[0] - prevcoord[0]) < smallnum
728 && abs(thiscoord[1] - prevcoord[1]) < smallnum
729 && abs(thiscoord[2] - prevcoord[2]) < smallnum)
734 if (run != prevrun || is_smaller != 0)
737 sendbits(buf, 1, 1); /* flag the change in run-length */
738 sendbits(buf, 5, run + is_smaller + 1);
742 sendbits(buf, 1, 0); /* flag the fact that runlength did not change */
744 for (k = 0; k < run; k += 3)
746 sendints(buf, 3, smallidx, sizesmall, &tmpcoord[k]);
750 smallidx += is_smaller;
754 smaller = magicints[smallidx - 1] / 2;
759 smallnum = magicints[smallidx] / 2;
761 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
768 /* buf[0] holds the length in bytes */
769 if (xdr_int(xdrs, &(buf[0])) == 0)
781 * (xdr_opaque(xdrs, reinterpret_cast<char*>(&(buf[3])), static_cast<unsigned int>(buf[0])));
792 /* xdrs is open for reading */
794 if (xdr_int(xdrs, &lsize) == 0)
798 if (*size != 0 && lsize != *size)
801 "wrong number of coordinates in xdr3dfcoord; "
802 "%d arg vs %d in file",
811 return (xdr_vector(xdrs,
812 reinterpret_cast<char*>(fp),
813 static_cast<unsigned int>(size3),
814 static_cast<unsigned int>(sizeof(*fp)),
815 reinterpret_cast<xdrproc_t>(xdr_float)));
817 if (xdr_float(xdrs, precision) == 0)
822 if (size3 <= prealloc_size)
830 bufsize = static_cast<int>(size3 * 1.2);
831 ip = reinterpret_cast<int*>(malloc(size3 * sizeof(*ip)));
832 buf = reinterpret_cast<int*>(malloc(bufsize * sizeof(*buf)));
833 if (ip == nullptr || buf == nullptr)
835 fprintf(stderr, "malloc failed\n");
840 buf[0] = buf[1] = buf[2] = 0;
842 if ((xdr_int(xdrs, &(minint[0])) == 0) || (xdr_int(xdrs, &(minint[1])) == 0)
843 || (xdr_int(xdrs, &(minint[2])) == 0) || (xdr_int(xdrs, &(maxint[0])) == 0)
844 || (xdr_int(xdrs, &(maxint[1])) == 0) || (xdr_int(xdrs, &(maxint[2])) == 0))
854 sizeint[0] = maxint[0] - minint[0] + 1;
855 sizeint[1] = maxint[1] - minint[1] + 1;
856 sizeint[2] = maxint[2] - minint[2] + 1;
858 /* check if one of the sizes is to big to be multiplied */
859 if ((sizeint[0] | sizeint[1] | sizeint[2]) > 0xffffff)
861 bitsizeint[0] = sizeofint(sizeint[0]);
862 bitsizeint[1] = sizeofint(sizeint[1]);
863 bitsizeint[2] = sizeofint(sizeint[2]);
864 bitsize = 0; /* flag the use of large sizes */
868 bitsize = sizeofints(3, sizeint);
871 if (xdr_int(xdrs, &smallidx) == 0)
881 smaller = magicints[std::max(FIRSTIDX, smallidx - 1)] / 2;
882 smallnum = magicints[smallidx] / 2;
883 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
885 /* buf[0] holds the length in bytes */
887 if (xdr_int(xdrs, &(buf[0])) == 0)
898 if (xdr_opaque(xdrs, reinterpret_cast<char*>(&(buf[3])), static_cast<unsigned int>(buf[0])) == 0)
909 buf[0] = buf[1] = buf[2] = 0;
912 inv_precision = 1.0 / *precision;
918 thiscoord = reinterpret_cast<int*>(lip) + i * 3;
922 thiscoord[0] = receivebits(buf, bitsizeint[0]);
923 thiscoord[1] = receivebits(buf, bitsizeint[1]);
924 thiscoord[2] = receivebits(buf, bitsizeint[2]);
928 receiveints(buf, 3, bitsize, sizeint, thiscoord);
932 thiscoord[0] += minint[0];
933 thiscoord[1] += minint[1];
934 thiscoord[2] += minint[2];
936 prevcoord[0] = thiscoord[0];
937 prevcoord[1] = thiscoord[1];
938 prevcoord[2] = thiscoord[2];
941 flag = receivebits(buf, 1);
945 run = receivebits(buf, 5);
946 is_smaller = run % 3;
953 for (k = 0; k < run; k += 3)
955 receiveints(buf, 3, smallidx, sizesmall, thiscoord);
957 thiscoord[0] += prevcoord[0] - smallnum;
958 thiscoord[1] += prevcoord[1] - smallnum;
959 thiscoord[2] += prevcoord[2] - smallnum;
962 /* interchange first with second atom for better
963 * compression of water molecules
966 thiscoord[0] = prevcoord[0];
969 thiscoord[1] = prevcoord[1];
972 thiscoord[2] = prevcoord[2];
974 *lfp++ = prevcoord[0] * inv_precision;
975 *lfp++ = prevcoord[1] * inv_precision;
976 *lfp++ = prevcoord[2] * inv_precision;
980 prevcoord[0] = thiscoord[0];
981 prevcoord[1] = thiscoord[1];
982 prevcoord[2] = thiscoord[2];
984 *lfp++ = thiscoord[0] * inv_precision;
985 *lfp++ = thiscoord[1] * inv_precision;
986 *lfp++ = thiscoord[2] * inv_precision;
991 *lfp++ = thiscoord[0] * inv_precision;
992 *lfp++ = thiscoord[1] * inv_precision;
993 *lfp++ = thiscoord[2] * inv_precision;
995 smallidx += is_smaller;
999 if (smallidx > FIRSTIDX)
1001 smaller = magicints[smallidx - 1] / 2;
1008 else if (is_smaller > 0)
1011 smallnum = magicints[smallidx] / 2;
1013 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
1025 /******************************************************************
1027 XTC files have a relatively simple structure.
1028 They have a header of 16 bytes and the rest are
1029 the compressed coordinates of the files. Due to the
1030 compression 00 is not present in the coordinates.
1031 The first 4 bytes of the header are the magic number
1032 1995 (0x000007CB). If we find this number we are guaranteed
1033 to be in the header, due to the presence of so many zeros.
1034 The second 4 bytes are the number of atoms in the frame, and is
1035 assumed to be constant. The third 4 bytes are the frame number.
1036 The last 4 bytes are a floating point representation of the time.
1038 ********************************************************************/
1040 /* Must match definition in xtcio.c */
1042 # define XTC_MAGIC 1995
1045 static const int header_size = 16;
1047 /* Check if we are at the header start.
1048 At the same time it will also read 1 int */
1049 static int xtc_at_header_start(FILE* fp, XDR* xdrs, int natoms, int* timestep, float* time)
1057 if ((off = gmx_ftell(fp)) < 0)
1061 /* read magic natoms and timestep */
1062 for (i = 0; i < 3; i++)
1064 if (!xdr_int(xdrs, &(i_inp[i])))
1066 gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET);
1071 if (i_inp[0] != XTC_MAGIC)
1073 if (gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET))
1079 /* read time and box */
1080 for (i = 0; i < 10; i++)
1082 if (!xdr_float(xdrs, &(f_inp[i])))
1084 gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET);
1088 /* Make a rigourous check to see if we are in the beggining of a header
1089 Hopefully there are no ambiguous cases */
1090 /* This check makes use of the fact that the box matrix has 3 zeroes on the upper
1091 right triangle and that the first element must be nonzero unless the entire matrix is zero
1093 if (i_inp[1] == natoms
1094 && ((f_inp[1] != 0 && f_inp[6] == 0) || (f_inp[1] == 0 && f_inp[5] == 0 && f_inp[9] == 0)))
1096 if (gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET))
1101 *timestep = i_inp[2];
1104 if (gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET))
1111 static int xtc_get_next_frame_number(FILE* fp, XDR* xdrs, int natoms)
1118 if ((off = gmx_ftell(fp)) < 0)
1123 /* read one int just to make sure we dont read this frame but the next */
1124 xdr_int(xdrs, &step);
1127 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1130 if (gmx_fseek(fp, off, SEEK_SET))
1138 if (gmx_fseek(fp, off, SEEK_SET))
1147 static float xtc_get_next_frame_time(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK)
1155 if ((off = gmx_ftell(fp)) < 0)
1159 /* read one int just to make sure we dont read this frame but the next */
1160 xdr_int(xdrs, &step);
1163 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1167 if (gmx_fseek(fp, off, SEEK_SET))
1176 if (gmx_fseek(fp, off, SEEK_SET))
1186 static float xtc_get_current_frame_time(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK)
1194 if ((off = gmx_ftell(fp)) < 0)
1201 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1205 if (gmx_fseek(fp, off, SEEK_SET))
1214 if (gmx_fseek(fp, off, SEEK_SET))
1223 if (gmx_fseek(fp, -2 * XDR_INT_SIZE, SEEK_CUR))
1231 /* Currently not used, just for completeness */
1232 static int 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))
1270 if (gmx_fseek(fp, -2 * XDR_INT_SIZE, SEEK_CUR))
1279 static gmx_off_t xtc_get_next_frame_start(FILE* fp, XDR* xdrs, int natoms)
1285 /* read one int just to make sure we dont read this frame but the next */
1286 xdr_int(xdrs, &step);
1289 ret = xtc_at_header_start(fp, xdrs, natoms, &step, &time);
1292 if ((res = gmx_ftell(fp)) >= 0)
1294 return res - XDR_INT_SIZE;
1309 static float xdr_xtc_estimate_dt(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK)
1316 if ((off = gmx_ftell(fp)) < 0)
1321 tinit = xtc_get_current_frame_time(fp, xdrs, natoms, bOK);
1328 res = xtc_get_next_frame_time(fp, xdrs, natoms, bOK);
1336 if (0 != gmx_fseek(fp, off, SEEK_SET))
1344 int xdr_xtc_seek_frame(int frame, FILE* fp, XDR* xdrs, int natoms)
1347 gmx_off_t high, pos;
1350 /* round to 4 bytes */
1353 if (gmx_fseek(fp, 0, SEEK_END))
1358 if ((high = gmx_ftell(fp)) < 0)
1363 /* round to 4 bytes */
1364 high /= XDR_INT_SIZE;
1365 high *= XDR_INT_SIZE;
1366 offset = ((high / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1368 if (gmx_fseek(fp, offset, SEEK_SET))
1375 fr = xtc_get_next_frame_number(fp, xdrs, natoms);
1380 if (fr != frame && llabs(low - high) > header_size)
1390 /* round to 4 bytes */
1391 offset = (((high + low) / 2) / 4) * 4;
1393 if (gmx_fseek(fp, offset, SEEK_SET))
1403 if (offset <= header_size)
1408 if (gmx_fseek(fp, offset, SEEK_SET))
1413 if ((pos = xtc_get_next_frame_start(fp, xdrs, natoms)) < 0)
1415 /* we probably hit an end of file */
1419 if (gmx_fseek(fp, pos, SEEK_SET))
1428 int xdr_xtc_seek_time(real time, FILE* fp, XDR* xdrs, int natoms, gmx_bool bSeekForwardOnly)
1432 gmx_bool bOK = FALSE;
1434 gmx_off_t high, offset, pos;
1437 if (bSeekForwardOnly)
1439 low = gmx_ftell(fp) - header_size;
1441 if (gmx_fseek(fp, 0, SEEK_END))
1446 if ((high = gmx_ftell(fp)) < 0)
1451 high /= XDR_INT_SIZE;
1452 high *= XDR_INT_SIZE;
1453 offset = (((high - low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1455 if (gmx_fseek(fp, offset, SEEK_SET))
1462 * No need to call xdr_xtc_estimate_dt here - since xdr_xtc_estimate_dt is called first thing in
1463 the loop dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1473 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1484 /* Found a place in the trajectory that has positive time step while
1485 other has negative time step */
1494 /* Found a place in the trajectory that has positive time step while
1495 other has negative time step */
1501 t = xtc_get_next_frame_time(fp, xdrs, natoms, &bOK);
1507 /* If we are before the target time and the time step is positive or 0, or we have
1508 after the target time and the time step is negative, or the difference between
1509 the current time and the target time is bigger than dt and above all the distance between
1510 high and low is bigger than 1 frame, then do another step of binary search. Otherwise
1511 stop and check if we reached the solution */
1512 if ((((t < time && dt_sign >= 0) || (t > time && dt_sign == -1))
1513 || ((t - time) >= dt && dt_sign >= 0) || ((time - t) >= -dt && dt_sign < 0))
1514 && (llabs(low - high) > header_size))
1516 if (dt >= 0 && dt_sign != -1)
1527 else if (dt <= 0 && dt_sign == -1)
1540 /* We should never reach here */
1543 /* round to 4 bytes and subtract header*/
1544 offset = (((high + low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE;
1545 if (gmx_fseek(fp, offset, SEEK_SET))
1552 if (llabs(low - high) <= header_size)
1556 /* re-estimate dt */
1557 if (xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK) != dt)
1561 dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1564 if (t >= time && t - time < dt)
1571 if (offset <= header_size)
1576 gmx_fseek(fp, offset, SEEK_SET);
1578 if ((pos = xtc_get_next_frame_start(fp, xdrs, natoms)) < 0)
1583 if (gmx_fseek(fp, pos, SEEK_SET))
1590 float xdr_xtc_get_last_frame_time(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK)
1595 off = gmx_ftell(fp);
1602 if (gmx_fseek(fp, -3 * XDR_INT_SIZE, SEEK_END) != 0)
1608 time = xtc_get_current_frame_time(fp, xdrs, natoms, bOK);
1614 if (gmx_fseek(fp, off, SEEK_SET) != 0)
1623 int xdr_xtc_get_last_frame_number(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK)
1629 if ((off = gmx_ftell(fp)) < 0)
1636 if (gmx_fseek(fp, -3 * XDR_INT_SIZE, SEEK_END))
1642 frame = xtc_get_current_frame_number(fp, xdrs, natoms, bOK);
1649 if (gmx_fseek(fp, off, SEEK_SET))