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, 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/futil.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
[] = { "int", "float", "double", "large int", "char", "string" };
59 /*___________________________________________________________________________
61 | what follows are the C routine to read/write compressed coordinates together
62 | with some routines to assist in this task (those are marked
63 | static and cannot be called from user programs)
66 // Integers above 2^24 do not have unique representations in
67 // 32-bit floats ie with 24 bits of precision. We use maxAbsoluteInt
68 // to check that float values can be transformed into an in-range
69 // 32-bit integer. There is no need to ensure we are within the range
70 // of ints with exact floating-point representations. However, we should
71 // reject all floats above that which converts to an in-range 32-bit integer.
72 const float maxAbsoluteInt
= nextafterf(float(INT_MAX
), 0.F
); // NOLINT(cert-err58-cpp)
75 # define SQR(x) ((x) * (x))
77 static const int magicints
[] = {
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
79 10, 12, 16, 20, 25, 32, 40, 50, 64, 80,
80 101, 128, 161, 203, 256, 322, 406, 512, 645, 812,
81 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192,
82 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536, 82570,
83 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561, 832255,
84 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042, 8388607,
85 10568983, 13316085, 16777216
89 /* note that magicints[FIRSTIDX-1] == 0 */
90 #define LASTIDX static_cast<int>((sizeof(magicints) / sizeof(*magicints)))
93 /*____________________________________________________________________________
95 | sendbits - encode num into buf using the specified number of bits
97 | This routines appends the value of num to the bits already present in
98 | the array buf. You need to give it the number of bits to use and you
99 | better make sure that this number of bits is enough to hold the value
100 | Also num must be positive.
104 static void sendbits(int buf
[], int num_of_bits
, int num
)
107 unsigned int cnt
, lastbyte
;
111 cbuf
= (reinterpret_cast<unsigned char*>(buf
)) + 3 * sizeof(*buf
);
112 cnt
= static_cast<unsigned int>(buf
[0]);
114 lastbyte
= static_cast<unsigned int>(buf
[2]);
115 while (num_of_bits
>= 8)
117 lastbyte
= (lastbyte
<< 8) | ((num
>> (num_of_bits
- 8)) /* & 0xff*/);
118 cbuf
[cnt
++] = lastbyte
>> lastbits
;
123 lastbyte
= (lastbyte
<< num_of_bits
) | num
;
124 lastbits
+= num_of_bits
;
128 cbuf
[cnt
++] = lastbyte
>> lastbits
;
136 cbuf
[cnt
] = lastbyte
<< (8 - lastbits
);
140 /*_________________________________________________________________________
142 | sizeofint - calculate bitsize of an integer
144 | return the number of bits needed to store an integer with given max size
148 static int sizeofint(const int size
)
153 while (size
>= num
&& num_of_bits
< 32)
161 /*___________________________________________________________________________
163 | sizeofints - calculate 'bitsize' of compressed ints
165 | given the number of small unsigned integers and the maximum value
166 | return the number of bits needed to read or write them with the
167 | routines receiveints and sendints. You need this parameter when
168 | calling these routines. Note that for many calls I can use
169 | the variable 'smallidx' which is exactly the number of bits, and
170 | So I don't need to call 'sizeofints for those calls.
173 static int sizeofints(const int num_of_ints
, const unsigned int sizes
[])
177 unsigned int num_of_bytes
, num_of_bits
, bytecnt
, tmp
;
181 for (i
= 0; i
< num_of_ints
; i
++)
184 for (bytecnt
= 0; bytecnt
< num_of_bytes
; bytecnt
++)
186 tmp
= bytes
[bytecnt
] * sizes
[i
] + tmp
;
187 bytes
[bytecnt
] = tmp
& 0xff;
192 bytes
[bytecnt
++] = tmp
& 0xff;
195 num_of_bytes
= bytecnt
;
199 while (bytes
[num_of_bytes
] >= num
)
204 return num_of_bits
+ num_of_bytes
* 8;
207 /*____________________________________________________________________________
209 | sendints - send a small set of small integers in compressed format
211 | this routine is used internally by xdr3dfcoord, to send a set of
212 | small integers to the buffer.
213 | Multiplication with fixed (specified maximum ) sizes is used to get
214 | to one big, multibyte integer. Allthough the routine could be
215 | modified to handle sizes bigger than 16777216, or more than just
216 | a few integers, this is not done, because the gain in compression
217 | isn't worth the effort. Note that overflowing the multiplication
218 | or the byte buffer (32 bytes) is unchecked and causes bad results.
222 static void sendints(int buf
[],
223 const int num_of_ints
,
224 const int num_of_bits
,
225 unsigned int sizes
[],
229 int i
, num_of_bytes
, bytecnt
;
230 unsigned int bytes
[32], tmp
;
236 bytes
[num_of_bytes
++] = tmp
& 0xff;
240 for (i
= 1; i
< num_of_ints
; i
++)
242 if (nums
[i
] >= sizes
[i
])
245 "major breakdown in sendints num %u doesn't "
250 /* use one step multiply */
252 for (bytecnt
= 0; bytecnt
< num_of_bytes
; bytecnt
++)
254 tmp
= bytes
[bytecnt
] * sizes
[i
] + tmp
;
255 bytes
[bytecnt
] = tmp
& 0xff;
260 bytes
[bytecnt
++] = tmp
& 0xff;
263 num_of_bytes
= bytecnt
;
265 if (num_of_bits
>= num_of_bytes
* 8)
267 for (i
= 0; i
< num_of_bytes
; i
++)
269 sendbits(buf
, 8, bytes
[i
]);
271 sendbits(buf
, num_of_bits
- num_of_bytes
* 8, 0);
275 for (i
= 0; i
< num_of_bytes
- 1; i
++)
277 sendbits(buf
, 8, bytes
[i
]);
279 sendbits(buf
, num_of_bits
- (num_of_bytes
- 1) * 8, bytes
[i
]);
284 /*___________________________________________________________________________
286 | receivebits - decode number from buf using specified number of bits
288 | extract the number of bits from the array buf and construct an integer
289 | from it. Return that value.
293 static int receivebits(int buf
[], int num_of_bits
)
296 int cnt
, num
, lastbits
;
297 unsigned int lastbyte
;
299 int mask
= (1 << num_of_bits
) - 1;
301 cbuf
= reinterpret_cast<unsigned char*>(buf
) + 3 * sizeof(*buf
);
303 lastbits
= static_cast<unsigned int>(buf
[1]);
304 lastbyte
= static_cast<unsigned int>(buf
[2]);
307 while (num_of_bits
>= 8)
309 lastbyte
= (lastbyte
<< 8) | cbuf
[cnt
++];
310 num
|= (lastbyte
>> lastbits
) << (num_of_bits
- 8);
315 if (lastbits
< num_of_bits
)
318 lastbyte
= (lastbyte
<< 8) | cbuf
[cnt
++];
320 lastbits
-= num_of_bits
;
321 num
|= (lastbyte
>> lastbits
) & ((1 << num_of_bits
) - 1);
330 /*____________________________________________________________________________
332 | receiveints - decode 'small' integers from the buf array
334 | this routine is the inverse from sendints() and decodes the small integers
335 | written to buf by calculating the remainder and doing divisions with
336 | the given sizes[]. You need to specify the total number of bits to be
337 | used from buf in num_of_bits.
341 static void receiveints(int buf
[], const int num_of_ints
, int num_of_bits
, const unsigned int sizes
[], int nums
[])
344 int i
, j
, num_of_bytes
, p
, num
;
346 bytes
[0] = bytes
[1] = bytes
[2] = bytes
[3] = 0;
348 while (num_of_bits
> 8)
350 bytes
[num_of_bytes
++] = receivebits(buf
, 8);
355 bytes
[num_of_bytes
++] = receivebits(buf
, num_of_bits
);
357 for (i
= num_of_ints
- 1; i
> 0; i
--)
360 for (j
= num_of_bytes
- 1; j
>= 0; j
--)
362 num
= (num
<< 8) | bytes
[j
];
365 num
= num
- p
* sizes
[i
];
369 nums
[0] = bytes
[0] | (bytes
[1] << 8) | (bytes
[2] << 16) | (bytes
[3] << 24);
372 /*____________________________________________________________________________
374 | xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
376 | this routine reads or writes (depending on how you opened the file with
377 | xdropen() ) a large number of 3d coordinates (stored in *fp).
378 | The number of coordinates triplets to write is given by *size. On
379 | read this number may be zero, in which case it reads as many as were written
380 | or it may specify the number if triplets to read (which should match the
382 | Compression is achieved by first converting all floating numbers to integer
383 | using multiplication by *precision and rounding to the nearest integer.
384 | Then the minimum and maximum value are calculated to determine the range.
385 | The limited range of integers so found, is used to compress the coordinates.
386 | In addition the differences between succesive coordinates is calculated.
387 | If the difference happens to be 'small' then only the difference is saved,
388 | compressing the data even more. The notion of 'small' is changed dynamically
389 | and is enlarged or reduced whenever needed or possible.
390 | Extra compression is achieved in the case of GROMOS and coordinates of
391 | water molecules. GROMOS first writes out the Oxygen position, followed by
392 | the two hydrogens. In order to make the differences smaller (and thereby
393 | compression the data better) the order is changed into first one hydrogen
394 | then the oxygen, followed by the other hydrogen. This is rather special, but
395 | it shouldn't harm in the general case.
399 int xdr3dfcoord(XDR
* xdrs
, float* fp
, int* size
, float* precision
)
405 /* preallocate a small buffer and ip on the stack - if we need more
406 we can always malloc(). This is faster for small values of size: */
407 unsigned prealloc_size
= 3 * 16;
408 int prealloc_ip
[3 * 16], prealloc_buf
[3 * 20];
409 int we_should_free
= 0;
411 int minint
[3], maxint
[3], mindiff
, *lip
, diff
;
412 int lint1
, lint2
, lint3
, oldlint1
, oldlint2
, oldlint3
, smallidx
;
414 unsigned sizeint
[3], sizesmall
[3], bitsizeint
[3], size3
, *luip
;
416 int smallnum
, smaller
, larger
, i
, is_small
, is_smaller
, run
, prevrun
;
418 int tmp
, *thiscoord
, prevcoord
[3];
419 unsigned int tmpcoord
[30];
422 unsigned int bitsize
;
427 bRead
= (xdrs
->x_op
== XDR_DECODE
);
428 bitsizeint
[0] = bitsizeint
[1] = bitsizeint
[2] = 0;
429 prevcoord
[0] = prevcoord
[1] = prevcoord
[2] = 0;
431 // The static analyzer warns about garbage values for thiscoord[] further
432 // down. It might be thrown off by all the reinterpret_casts, but we might
433 // as well make sure the small preallocated buffer is zero-initialized.
434 for (i
= 0; i
< static_cast<int>(prealloc_size
); i
++)
441 /* xdrs is open for writing */
443 if (xdr_int(xdrs
, size
) == 0)
448 /* when the number of coordinates is small, don't try to compress; just
449 * write them as floats using xdr_vector
453 return (xdr_vector(xdrs
, reinterpret_cast<char*>(fp
), static_cast<unsigned int>(size3
),
454 static_cast<unsigned int>(sizeof(*fp
)),
455 reinterpret_cast<xdrproc_t
>(xdr_float
)));
458 if (xdr_float(xdrs
, precision
) == 0)
463 if (size3
<= prealloc_size
)
471 bufsize
= static_cast<int>(size3
* 1.2);
472 ip
= reinterpret_cast<int*>(malloc(size3
* sizeof(*ip
)));
473 buf
= reinterpret_cast<int*>(malloc(bufsize
* sizeof(*buf
)));
474 if (ip
== nullptr || buf
== nullptr)
476 fprintf(stderr
, "malloc failed\n");
480 /* buf[0-2] are special and do not contain actual data */
481 buf
[0] = buf
[1] = buf
[2] = 0;
482 minint
[0] = minint
[1] = minint
[2] = INT_MAX
;
483 maxint
[0] = maxint
[1] = maxint
[2] = INT_MIN
;
488 oldlint1
= oldlint2
= oldlint3
= 0;
489 while (lfp
< fp
+ size3
)
491 /* find nearest integer */
494 lf
= *lfp
* *precision
+ 0.5;
498 lf
= *lfp
* *precision
- 0.5;
500 if (std::fabs(lf
) > maxAbsoluteInt
)
502 /* scaling would cause overflow */
505 lint1
= static_cast<int>(lf
);
506 if (lint1
< minint
[0])
510 if (lint1
> maxint
[0])
518 lf
= *lfp
* *precision
+ 0.5;
522 lf
= *lfp
* *precision
- 0.5;
524 if (std::fabs(lf
) > maxAbsoluteInt
)
526 /* scaling would cause overflow */
529 lint2
= static_cast<int>(lf
);
530 if (lint2
< minint
[1])
534 if (lint2
> maxint
[1])
542 lf
= *lfp
* *precision
+ 0.5;
546 lf
= *lfp
* *precision
- 0.5;
548 if (std::abs(lf
) > maxAbsoluteInt
)
550 /* scaling would cause overflow */
553 lint3
= static_cast<int>(lf
);
554 if (lint3
< minint
[2])
558 if (lint3
> maxint
[2])
564 diff
= std::abs(oldlint1
- lint1
) + std::abs(oldlint2
- lint2
) + std::abs(oldlint3
- lint3
);
565 if (diff
< mindiff
&& lfp
> fp
+ 3)
573 if ((xdr_int(xdrs
, &(minint
[0])) == 0) || (xdr_int(xdrs
, &(minint
[1])) == 0)
574 || (xdr_int(xdrs
, &(minint
[2])) == 0) || (xdr_int(xdrs
, &(maxint
[0])) == 0)
575 || (xdr_int(xdrs
, &(maxint
[1])) == 0) || (xdr_int(xdrs
, &(maxint
[2])) == 0))
585 if (static_cast<float>(maxint
[0]) - static_cast<float>(minint
[0]) >= maxAbsoluteInt
586 || static_cast<float>(maxint
[1]) - static_cast<float>(minint
[1]) >= maxAbsoluteInt
587 || static_cast<float>(maxint
[2]) - static_cast<float>(minint
[2]) >= maxAbsoluteInt
)
589 /* turning value in unsigned by subtracting minint
590 * would cause overflow
594 sizeint
[0] = maxint
[0] - minint
[0] + 1;
595 sizeint
[1] = maxint
[1] - minint
[1] + 1;
596 sizeint
[2] = maxint
[2] - minint
[2] + 1;
598 /* check if one of the sizes is to big to be multiplied */
599 if ((sizeint
[0] | sizeint
[1] | sizeint
[2]) > 0xffffff)
601 bitsizeint
[0] = sizeofint(sizeint
[0]);
602 bitsizeint
[1] = sizeofint(sizeint
[1]);
603 bitsizeint
[2] = sizeofint(sizeint
[2]);
604 bitsize
= 0; /* flag the use of large sizes */
608 bitsize
= sizeofints(3, sizeint
);
610 luip
= reinterpret_cast<unsigned int*>(ip
);
612 while (smallidx
< LASTIDX
&& magicints
[smallidx
] < mindiff
)
616 if (xdr_int(xdrs
, &smallidx
) == 0)
626 maxidx
= std::min(LASTIDX
, smallidx
+ 8);
627 minidx
= maxidx
- 8; /* often this equal smallidx */
628 smaller
= magicints
[std::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
= reinterpret_cast<int*>(luip
) + i
* 3;
637 if (smallidx
< maxidx
&& i
>= 1 && std::abs(thiscoord
[0] - prevcoord
[0]) < larger
638 && std::abs(thiscoord
[1] - prevcoord
[1]) < larger
639 && std::abs(thiscoord
[2] - prevcoord
[2]) < larger
)
643 else if (smallidx
> minidx
)
653 if (std::abs(thiscoord
[0] - thiscoord
[3]) < smallnum
654 && std::abs(thiscoord
[1] - thiscoord
[4]) < smallnum
655 && std::abs(thiscoord
[2] - thiscoord
[5]) < smallnum
)
657 /* interchange first with second atom for better
658 * compression of water molecules
661 thiscoord
[0] = thiscoord
[3];
664 thiscoord
[1] = thiscoord
[4];
667 thiscoord
[2] = thiscoord
[5];
672 tmpcoord
[0] = thiscoord
[0] - minint
[0];
673 tmpcoord
[1] = thiscoord
[1] - minint
[1];
674 tmpcoord
[2] = thiscoord
[2] - minint
[2];
677 sendbits(buf
, bitsizeint
[0], tmpcoord
[0]);
678 sendbits(buf
, bitsizeint
[1], tmpcoord
[1]);
679 sendbits(buf
, bitsizeint
[2], tmpcoord
[2]);
683 sendints(buf
, 3, bitsize
, sizeint
, tmpcoord
);
685 prevcoord
[0] = thiscoord
[0];
686 prevcoord
[1] = thiscoord
[1];
687 prevcoord
[2] = thiscoord
[2];
688 thiscoord
= thiscoord
+ 3;
692 if (is_small
== 0 && is_smaller
== -1)
696 while (is_small
&& run
< 8 * 3)
699 && (SQR(thiscoord
[0] - prevcoord
[0]) + SQR(thiscoord
[1] - prevcoord
[1])
700 + SQR(thiscoord
[2] - prevcoord
[2])
701 >= smaller
* smaller
))
706 tmpcoord
[run
++] = thiscoord
[0] - prevcoord
[0] + smallnum
;
707 tmpcoord
[run
++] = thiscoord
[1] - prevcoord
[1] + smallnum
;
708 tmpcoord
[run
++] = thiscoord
[2] - prevcoord
[2] + smallnum
;
710 prevcoord
[0] = thiscoord
[0];
711 prevcoord
[1] = thiscoord
[1];
712 prevcoord
[2] = thiscoord
[2];
715 thiscoord
= thiscoord
+ 3;
717 if (i
< *size
&& 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)
771 * (xdr_opaque(xdrs
, reinterpret_cast<char*>(&(buf
[3])), static_cast<unsigned int>(buf
[0])));
782 /* xdrs is open for reading */
784 if (xdr_int(xdrs
, &lsize
) == 0)
788 if (*size
!= 0 && lsize
!= *size
)
791 "wrong number of coordinates in xdr3dfcoord; "
792 "%d arg vs %d in file",
800 return (xdr_vector(xdrs
, reinterpret_cast<char*>(fp
), static_cast<unsigned int>(size3
),
801 static_cast<unsigned int>(sizeof(*fp
)),
802 reinterpret_cast<xdrproc_t
>(xdr_float
)));
804 if (xdr_float(xdrs
, precision
) == 0)
809 if (size3
<= prealloc_size
)
817 bufsize
= static_cast<int>(size3
* 1.2);
818 ip
= reinterpret_cast<int*>(malloc(size3
* sizeof(*ip
)));
819 buf
= reinterpret_cast<int*>(malloc(bufsize
* sizeof(*buf
)));
820 if (ip
== nullptr || buf
== nullptr)
822 fprintf(stderr
, "malloc failed\n");
827 buf
[0] = buf
[1] = buf
[2] = 0;
829 if ((xdr_int(xdrs
, &(minint
[0])) == 0) || (xdr_int(xdrs
, &(minint
[1])) == 0)
830 || (xdr_int(xdrs
, &(minint
[2])) == 0) || (xdr_int(xdrs
, &(maxint
[0])) == 0)
831 || (xdr_int(xdrs
, &(maxint
[1])) == 0) || (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 smaller
= magicints
[std::max(FIRSTIDX
, smallidx
- 1)] / 2;
869 smallnum
= magicints
[smallidx
] / 2;
870 sizesmall
[0] = sizesmall
[1] = sizesmall
[2] = magicints
[smallidx
];
872 /* buf[0] holds the length in bytes */
874 if (xdr_int(xdrs
, &(buf
[0])) == 0)
885 if (xdr_opaque(xdrs
, reinterpret_cast<char*>(&(buf
[3])), static_cast<unsigned int>(buf
[0])) == 0)
896 buf
[0] = buf
[1] = buf
[2] = 0;
899 inv_precision
= 1.0 / *precision
;
905 thiscoord
= reinterpret_cast<int*>(lip
) + i
* 3;
909 thiscoord
[0] = receivebits(buf
, bitsizeint
[0]);
910 thiscoord
[1] = receivebits(buf
, bitsizeint
[1]);
911 thiscoord
[2] = receivebits(buf
, bitsizeint
[2]);
915 receiveints(buf
, 3, bitsize
, sizeint
, thiscoord
);
919 thiscoord
[0] += minint
[0];
920 thiscoord
[1] += minint
[1];
921 thiscoord
[2] += minint
[2];
923 prevcoord
[0] = thiscoord
[0];
924 prevcoord
[1] = thiscoord
[1];
925 prevcoord
[2] = thiscoord
[2];
928 flag
= receivebits(buf
, 1);
932 run
= receivebits(buf
, 5);
933 is_smaller
= run
% 3;
940 for (k
= 0; k
< run
; k
+= 3)
942 receiveints(buf
, 3, smallidx
, sizesmall
, thiscoord
);
944 thiscoord
[0] += prevcoord
[0] - smallnum
;
945 thiscoord
[1] += prevcoord
[1] - smallnum
;
946 thiscoord
[2] += prevcoord
[2] - smallnum
;
949 /* interchange first with second atom for better
950 * compression of water molecules
953 thiscoord
[0] = prevcoord
[0];
956 thiscoord
[1] = prevcoord
[1];
959 thiscoord
[2] = prevcoord
[2];
961 *lfp
++ = prevcoord
[0] * inv_precision
;
962 *lfp
++ = prevcoord
[1] * inv_precision
;
963 *lfp
++ = prevcoord
[2] * inv_precision
;
967 prevcoord
[0] = thiscoord
[0];
968 prevcoord
[1] = thiscoord
[1];
969 prevcoord
[2] = thiscoord
[2];
971 *lfp
++ = thiscoord
[0] * inv_precision
;
972 *lfp
++ = thiscoord
[1] * inv_precision
;
973 *lfp
++ = thiscoord
[2] * inv_precision
;
978 *lfp
++ = thiscoord
[0] * inv_precision
;
979 *lfp
++ = thiscoord
[1] * inv_precision
;
980 *lfp
++ = thiscoord
[2] * inv_precision
;
982 smallidx
+= is_smaller
;
986 if (smallidx
> FIRSTIDX
)
988 smaller
= magicints
[smallidx
- 1] / 2;
995 else if (is_smaller
> 0)
998 smallnum
= magicints
[smallidx
] / 2;
1000 sizesmall
[0] = sizesmall
[1] = sizesmall
[2] = magicints
[smallidx
];
1012 /******************************************************************
1014 XTC files have a relatively simple structure.
1015 They have a header of 16 bytes and the rest are
1016 the compressed coordinates of the files. Due to the
1017 compression 00 is not present in the coordinates.
1018 The first 4 bytes of the header are the magic number
1019 1995 (0x000007CB). If we find this number we are guaranteed
1020 to be in the header, due to the presence of so many zeros.
1021 The second 4 bytes are the number of atoms in the frame, and is
1022 assumed to be constant. The third 4 bytes are the frame number.
1023 The last 4 bytes are a floating point representation of the time.
1025 ********************************************************************/
1027 /* Must match definition in xtcio.c */
1029 # define XTC_MAGIC 1995
1032 static const int header_size
= 16;
1034 /* Check if we are at the header start.
1035 At the same time it will also read 1 int */
1036 static int xtc_at_header_start(FILE* fp
, XDR
* xdrs
, int natoms
, int* timestep
, float* time
)
1044 if ((off
= gmx_ftell(fp
)) < 0)
1048 /* read magic natoms and timestep */
1049 for (i
= 0; i
< 3; i
++)
1051 if (!xdr_int(xdrs
, &(i_inp
[i
])))
1053 gmx_fseek(fp
, off
+ XDR_INT_SIZE
, SEEK_SET
);
1058 if (i_inp
[0] != XTC_MAGIC
)
1060 if (gmx_fseek(fp
, off
+ XDR_INT_SIZE
, SEEK_SET
))
1066 /* read time and box */
1067 for (i
= 0; i
< 10; i
++)
1069 if (!xdr_float(xdrs
, &(f_inp
[i
])))
1071 gmx_fseek(fp
, off
+ XDR_INT_SIZE
, SEEK_SET
);
1075 /* Make a rigourous check to see if we are in the beggining of a header
1076 Hopefully there are no ambiguous cases */
1077 /* This check makes use of the fact that the box matrix has 3 zeroes on the upper
1078 right triangle and that the first element must be nonzero unless the entire matrix is zero
1080 if (i_inp
[1] == natoms
1081 && ((f_inp
[1] != 0 && f_inp
[6] == 0) || (f_inp
[1] == 0 && f_inp
[5] == 0 && f_inp
[9] == 0)))
1083 if (gmx_fseek(fp
, off
+ XDR_INT_SIZE
, SEEK_SET
))
1088 *timestep
= i_inp
[2];
1091 if (gmx_fseek(fp
, off
+ XDR_INT_SIZE
, SEEK_SET
))
1098 static int xtc_get_next_frame_number(FILE* fp
, XDR
* xdrs
, int natoms
)
1105 if ((off
= gmx_ftell(fp
)) < 0)
1110 /* read one int just to make sure we dont read this frame but the next */
1111 xdr_int(xdrs
, &step
);
1114 ret
= xtc_at_header_start(fp
, xdrs
, natoms
, &step
, &time
);
1117 if (gmx_fseek(fp
, off
, SEEK_SET
))
1125 if (gmx_fseek(fp
, off
, SEEK_SET
))
1134 static float xtc_get_next_frame_time(FILE* fp
, XDR
* xdrs
, int natoms
, gmx_bool
* bOK
)
1142 if ((off
= gmx_ftell(fp
)) < 0)
1146 /* read one int just to make sure we dont read this frame but the next */
1147 xdr_int(xdrs
, &step
);
1150 ret
= xtc_at_header_start(fp
, xdrs
, natoms
, &step
, &time
);
1154 if (gmx_fseek(fp
, off
, SEEK_SET
))
1163 if (gmx_fseek(fp
, off
, SEEK_SET
))
1173 static float xtc_get_current_frame_time(FILE* fp
, XDR
* xdrs
, int natoms
, gmx_bool
* bOK
)
1181 if ((off
= gmx_ftell(fp
)) < 0)
1188 ret
= xtc_at_header_start(fp
, xdrs
, natoms
, &step
, &time
);
1192 if (gmx_fseek(fp
, off
, SEEK_SET
))
1201 if (gmx_fseek(fp
, off
, SEEK_SET
))
1210 if (gmx_fseek(fp
, -2 * XDR_INT_SIZE
, SEEK_CUR
))
1218 /* Currently not used, just for completeness */
1219 static int xtc_get_current_frame_number(FILE* fp
, XDR
* xdrs
, int natoms
, gmx_bool
* bOK
)
1227 if ((off
= gmx_ftell(fp
)) < 0)
1235 ret
= xtc_at_header_start(fp
, xdrs
, natoms
, &step
, &time
);
1239 if (gmx_fseek(fp
, off
, SEEK_SET
))
1248 if (gmx_fseek(fp
, off
, SEEK_SET
))
1257 if (gmx_fseek(fp
, -2 * XDR_INT_SIZE
, SEEK_CUR
))
1266 static gmx_off_t
xtc_get_next_frame_start(FILE* fp
, XDR
* xdrs
, int natoms
)
1272 /* read one int just to make sure we dont read this frame but the next */
1273 xdr_int(xdrs
, &step
);
1276 ret
= xtc_at_header_start(fp
, xdrs
, natoms
, &step
, &time
);
1279 if ((res
= gmx_ftell(fp
)) >= 0)
1281 return res
- XDR_INT_SIZE
;
1296 static float xdr_xtc_estimate_dt(FILE* fp
, XDR
* xdrs
, int natoms
, gmx_bool
* bOK
)
1303 if ((off
= gmx_ftell(fp
)) < 0)
1308 tinit
= xtc_get_current_frame_time(fp
, xdrs
, natoms
, bOK
);
1315 res
= xtc_get_next_frame_time(fp
, xdrs
, natoms
, bOK
);
1323 if (0 != gmx_fseek(fp
, off
, SEEK_SET
))
1331 int xdr_xtc_seek_frame(int frame
, FILE* fp
, XDR
* xdrs
, int natoms
)
1334 gmx_off_t high
, pos
;
1337 /* round to 4 bytes */
1340 if (gmx_fseek(fp
, 0, SEEK_END
))
1345 if ((high
= gmx_ftell(fp
)) < 0)
1350 /* round to 4 bytes */
1351 high
/= XDR_INT_SIZE
;
1352 high
*= XDR_INT_SIZE
;
1353 offset
= ((high
/ 2) / XDR_INT_SIZE
) * XDR_INT_SIZE
;
1355 if (gmx_fseek(fp
, offset
, SEEK_SET
))
1362 fr
= xtc_get_next_frame_number(fp
, xdrs
, natoms
);
1367 if (fr
!= frame
&& llabs(low
- high
) > header_size
)
1377 /* round to 4 bytes */
1378 offset
= (((high
+ low
) / 2) / 4) * 4;
1380 if (gmx_fseek(fp
, offset
, SEEK_SET
))
1390 if (offset
<= header_size
)
1395 if (gmx_fseek(fp
, offset
, SEEK_SET
))
1400 if ((pos
= xtc_get_next_frame_start(fp
, xdrs
, natoms
)) < 0)
1402 /* we probably hit an end of file */
1406 if (gmx_fseek(fp
, pos
, SEEK_SET
))
1415 int xdr_xtc_seek_time(real time
, FILE* fp
, XDR
* xdrs
, int natoms
, gmx_bool bSeekForwardOnly
)
1419 gmx_bool bOK
= FALSE
;
1421 gmx_off_t high
, offset
, pos
;
1424 if (bSeekForwardOnly
)
1426 low
= gmx_ftell(fp
) - header_size
;
1428 if (gmx_fseek(fp
, 0, SEEK_END
))
1433 if ((high
= gmx_ftell(fp
)) < 0)
1438 high
/= XDR_INT_SIZE
;
1439 high
*= XDR_INT_SIZE
;
1440 offset
= (((high
- low
) / 2) / XDR_INT_SIZE
) * XDR_INT_SIZE
;
1442 if (gmx_fseek(fp
, offset
, SEEK_SET
))
1449 * No need to call xdr_xtc_estimate_dt here - since xdr_xtc_estimate_dt is called first thing in
1450 the loop dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK);
1460 dt
= xdr_xtc_estimate_dt(fp
, xdrs
, natoms
, &bOK
);
1471 /* Found a place in the trajectory that has positive time step while
1472 other has negative time step */
1481 /* Found a place in the trajectory that has positive time step while
1482 other has negative time step */
1488 t
= xtc_get_next_frame_time(fp
, xdrs
, natoms
, &bOK
);
1494 /* If we are before the target time and the time step is positive or 0, or we have
1495 after the target time and the time step is negative, or the difference between
1496 the current time and the target time is bigger than dt and above all the distance between
1497 high and low is bigger than 1 frame, then do another step of binary search. Otherwise
1498 stop and check if we reached the solution */
1499 if ((((t
< time
&& dt_sign
>= 0) || (t
> time
&& dt_sign
== -1))
1500 || ((t
- time
) >= dt
&& dt_sign
>= 0) || ((time
- t
) >= -dt
&& dt_sign
< 0))
1501 && (llabs(low
- high
) > header_size
))
1503 if (dt
>= 0 && dt_sign
!= -1)
1514 else if (dt
<= 0 && dt_sign
== -1)
1527 /* We should never reach here */
1530 /* round to 4 bytes and subtract header*/
1531 offset
= (((high
+ low
) / 2) / XDR_INT_SIZE
) * XDR_INT_SIZE
;
1532 if (gmx_fseek(fp
, offset
, SEEK_SET
))
1539 if (llabs(low
- high
) <= header_size
)
1543 /* re-estimate dt */
1544 if (xdr_xtc_estimate_dt(fp
, xdrs
, natoms
, &bOK
) != dt
)
1548 dt
= xdr_xtc_estimate_dt(fp
, xdrs
, natoms
, &bOK
);
1551 if (t
>= time
&& t
- time
< dt
)
1558 if (offset
<= header_size
)
1563 gmx_fseek(fp
, offset
, SEEK_SET
);
1565 if ((pos
= xtc_get_next_frame_start(fp
, xdrs
, natoms
)) < 0)
1570 if (gmx_fseek(fp
, pos
, SEEK_SET
))
1577 float xdr_xtc_get_last_frame_time(FILE* fp
, XDR
* xdrs
, int natoms
, gmx_bool
* bOK
)
1582 off
= gmx_ftell(fp
);
1589 if (gmx_fseek(fp
, -3 * XDR_INT_SIZE
, SEEK_END
) != 0)
1595 time
= xtc_get_current_frame_time(fp
, xdrs
, natoms
, bOK
);
1601 if (gmx_fseek(fp
, off
, SEEK_SET
) != 0)
1610 int xdr_xtc_get_last_frame_number(FILE* fp
, XDR
* xdrs
, int natoms
, gmx_bool
* bOK
)
1616 if ((off
= gmx_ftell(fp
)) < 0)
1623 if (gmx_fseek(fp
, -3 * XDR_INT_SIZE
, SEEK_END
))
1629 frame
= xtc_get_current_frame_number(fp
, xdrs
, natoms
, bOK
);
1636 if (gmx_fseek(fp
, off
, SEEK_SET
))