Hello,
I was uncertain at which category should I post this message, maybe you need to move it . I am the author of Chemcraft program (visualization tool). Currently I try to implement visualization of .xtc files in Chemcraft. Firstly I was able to read the magic number and the atoms count, but after that I was confused: it is difficult to understand the format, it seems that Gromacs uses some packing since the size of each trajectory step in bytes is not constant. Can you please help? I program in Delphi, so I am unable to include the xtcio.h library in my code. I need to know the algorithm of data encription in Gromacs.
Hi!
The brief description of the XTC format can be found here: https://manual.gromacs.org/current/reference-manual/file-formats.html#xtc
Your findings are correct, XTC uses compression scheme based on XDR library to save space, so the size of each frame is different.
I am not aware of any existing Delphi XTC/XDR readers. You will likely have to write your own, based on our C++ code:
- src/gromacs/fileio/xtcio.cpp · 97340bd599169e6206f3713e7c8136c92f7d9c88 · GROMACS / GROMACS · GitLab
- src/gromacs/fileio/gmx_internal_xdr.cpp · 97340bd599169e6206f3713e7c8136c92f7d9c88 · GROMACS / GROMACS · GitLab
or the Python implementation from MDAnalysis:
Note that XDR is a fairly simple standard supported in various environments. But XDR isn’t really “self-describing” of a particular data layout, so you have to refer to the XTC source code to understand the schema in use.
I have found a file libxdrf.c and try analyze the code in it. It contains some encoding functions; in particular, two functions are used to determine the number of bits needed to describe some digits of specified maximum size: sizeofint and sizeofints:
static int sizeofint(const int size) {
unsigned int num = 1;
int num_of_bits = 0;
while (size >= num && num_of_bits < 32) {
num_of_bits++;
num <<= 1;
}
return num_of_bits;
}
static int sizeofints( const int num_of_ints, unsigned int sizes[]) {
int i, num;
unsigned int num_of_bytes, num_of_bits, bytes[32], bytecnt, tmp;
num_of_bytes = 1;
bytes[0] = 1;
num_of_bits = 0;
for (i=0; i < num_of_ints; i++) {
tmp = 0;
for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++) {
tmp = bytes[bytecnt] * sizes[i] + tmp;
bytes[bytecnt] = tmp & 0xff;
tmp >>= 8;
}
while (tmp != 0) {
bytes[bytecnt++] = tmp & 0xff;
tmp >>= 8;
}
num_of_bytes = bytecnt;
}
num = 1;
num_of_bytes--;
while (bytes[num_of_bytes] >= num) {
num_of_bits++;
num *= 2;
}
return num_of_bits + num_of_bytes * 8;
}
The first is simple – e.g. we need 2 bits to describe a digit from 0 to 2, 4 bits to describe a digit from 0 to 9, etc. The second function is more difficult to understand. When reading xtc files, usually the second function is used?