int read_xtc_numframes(char *fn, int *numframes, int64_t **offsets) { XDRFILE *xd; int framebytes, natoms, step; float time; int64_t filesize; if ((xd = xdrfile_open(fn,"r"))==NULL) return exdrFILENOTFOUND; if (xtc_header(xd,&natoms,&step,&time,TRUE) != exdrOK) { xdrfile_close(xd); return exdrHEADER; } if (xdr_seek(xd, 0L, SEEK_END) != exdrOK) { xdrfile_close(xd); return exdrNR; } filesize = xdr_tell(xd); /* Case of fewer than 10 atoms. Framesize known. */ if (natoms < 10) { int i; xdrfile_close(xd); framebytes = XTC_SHORTHEADER_SIZE + XTC_SHORT_BYTESPERATOM*natoms; *numframes = filesize/framebytes; /* Should we complain if framesize doesn't divide filesize? */ /* Allocate memory for the frame index array */ if ((*offsets=(int64_t *)malloc(sizeof(int64_t)*(*numframes)))==NULL) return exdrNOMEM; for (i=0; i<*numframes; i++) { (*offsets)[i] = i*framebytes; } return exdrOK; } else /* No easy way out. We must iterate. */ { int est_nframes; /* Estimation of number of frames, with 20% allowance for error. */ if (xdr_seek(xd, (int64_t) XTC_HEADER_SIZE, SEEK_SET) != exdrOK) { xdrfile_close(xd); return exdrNR; } if (xdrfile_read_int(&framebytes,1,xd) == 0) { xdrfile_close(xd); return exdrENDOFFILE; } framebytes = (framebytes + 3) & ~0x03; //Rounding to the next 32-bit boundary est_nframes = (int) (filesize/((int64_t) (framebytes+XTC_HEADER_SIZE)) + 1); // add one because it'd be easy to underestimate low frame numbers. est_nframes += est_nframes/5; /* Allocate memory for the frame index array */ if ((*offsets=(int64_t *)malloc(sizeof(int64_t)*est_nframes))==NULL) { xdrfile_close(xd); return exdrNOMEM; } (*offsets)[0] = 0L; *numframes = 1; while (1) { if (xdr_seek(xd, (int64_t) (framebytes+XTC_HEADER_SIZE), SEEK_CUR) != exdrOK) { free(*offsets); xdrfile_close(xd); return exdrNR; } if (xdrfile_read_int(&framebytes,1,xd) == 0) break; /* Read was successful; this is another frame */ /* Check if we need to enlarge array */ if (*numframes == est_nframes){ est_nframes += est_nframes/5 + 1; // Increase in 20% stretches if ((*offsets = realloc(*offsets, sizeof(int64_t)*est_nframes))==NULL) { free(*offsets); xdrfile_close(xd); return exdrNOMEM; } } (*offsets)[*numframes] = xdr_tell(xd) - 4L - (int64_t) (XTC_HEADER_SIZE); //Account for the header and the nbytes bytes we read. (*numframes)++; framebytes = (framebytes + 3) & ~0x03; //Rounding to the next 32-bit boundary } xdrfile_close(xd); return exdrOK; } }
static int do_trnheader(XDRFILE *xd,mybool bRead,t_trnheader *sh) { int magic=GROMACS_MAGIC; int nflsz,slen,result; char *version = "GMX_trn_file"; char buf[BUFSIZE]; if (xdrfile_read_int(&magic,1,xd) != 1) return exdrINT; if (bRead) { if (xdrfile_read_int(&slen,1,xd) != 1) return exdrINT; if (slen != strlen(version)+1) return exdrSTRING; if (xdrfile_read_string(buf,BUFSIZE,xd) <= 0) return exdrSTRING; } else { slen = strlen(version)+1; if (xdrfile_read_int(&slen,1,xd) != 1) return exdrINT; if (xdrfile_write_string(version,xd) != (strlen(version)+1) ) return exdrSTRING; } if (xdrfile_read_int(&sh->ir_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->e_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->box_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->vir_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->pres_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->top_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->sym_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->x_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->v_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->f_size,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->natoms,1,xd) != 1) return exdrINT; if ((result = nFloatSize(sh,&nflsz)) != exdrOK) return result; sh->bDouble = (nflsz == sizeof(double)); if (xdrfile_read_int(&sh->step,1,xd) != 1) return exdrINT; if (xdrfile_read_int(&sh->nre,1,xd) != 1) return exdrINT; if (sh->bDouble) { if (xdrfile_read_double(&sh->td,1,xd) != 1) return exdrDOUBLE; sh->tf = sh->td; if (xdrfile_read_double(&sh->lambdad,1,xd) != 1) return exdrDOUBLE; sh->lambdaf = sh->lambdad; } else { if (xdrfile_read_float(&sh->tf,1,xd) != 1) return exdrFLOAT; sh->td = sh->tf; if (xdrfile_read_float(&sh->lambdaf,1,xd) != 1) return exdrFLOAT; sh->lambdad = sh->lambdaf; } return exdrOK; }
static void test_basic() { float test_ii; // 7 significant digits double test_jj; // 16 significant digits #define EPSILON_1 1e-7 #define EPSILON_2 1e-4 printf("Testing basic xdrfile library:"); for (test_ii = 1.0e1; test_ii < 1.0e2; (test_ii = test_ii + pow(M_PI, 0.00011))) { #define BUFLEN 37 XDRFILE *xfp; int i, j, k, len, ncoord = BUFLEN/3; char ptr[BUFLEN], *buf = "abcdefghijklmnopqrstuvwxyz"; char *testfn = "test.xdr"; unsigned char uptr[BUFLEN]; short sptr[BUFLEN], sptr2[BUFLEN]; unsigned short usptr[BUFLEN], usptr2[BUFLEN]; int iptr[BUFLEN], iptr2[BUFLEN]; unsigned int uiptr[BUFLEN], uiptr2[BUFLEN]; float fptr[BUFLEN], fptr2[BUFLEN]; double dptr[BUFLEN], dptr2[BUFLEN]; char optr[BUFLEN], optr2[BUFLEN]; #define NPREC 1 float fprec[] = {234.45}; double dprec[] = {234.45}; /* Can not write a string that's on the stack since all data is treated as variables. */ len = strlen(buf) + 1; if (len >= BUFLEN) die("Increase BUFLEN"); strcpy(ptr, buf); strcpy((char *) uptr, buf); /* Initiate float arrays */ for (i = 0; (i < BUFLEN); i++) { fptr[i] = cos(i * 13.0 / M_PI); dptr[i] = sin(i * 13.0 / M_PI); } /* Initiate opaque array */ memcpy(optr, dptr, BUFLEN); /*************************************/ /* WRITING BIT */ /*************************************/ if ((xfp = xdrfile_open("test.xdr", "w")) == NULL) die("Can not open file for writing"); if (xdrfile_write_char(ptr, len, xfp) != len) die("Writing char string"); if (xdrfile_write_uchar(uptr, len, xfp) != len) die("Writing uchar string"); if (xdrfile_write_short(sptr, BUFLEN,xfp) != BUFLEN) die("Writing short array"); if (xdrfile_write_ushort(usptr, BUFLEN,xfp) != BUFLEN) die("Writing ushort array"); if (xdrfile_write_int(iptr, BUFLEN,xfp) != BUFLEN) die("Writing int array"); if (xdrfile_write_uint(uiptr, BUFLEN,xfp) != BUFLEN) die("Writing uint array"); if (xdrfile_write_float(fptr, BUFLEN,xfp) != BUFLEN) die("Writing float array"); if (xdrfile_write_double(dptr, BUFLEN,xfp) != BUFLEN) die("Writing double array"); if (xdrfile_write_string(buf, xfp) != len) die("Writing string"); if (xdrfile_write_opaque(optr, BUFLEN,xfp) != BUFLEN) die("Writing opaque"); for (k = 0; (k < NPREC); k++) { if (xdrfile_compress_coord_float(fptr, ncoord, fprec[k], xfp) != ncoord) die("Writing compress_coord_float"); if (xdrfile_compress_coord_double(dptr, ncoord, dprec[k], xfp) != ncoord) die("Writing compress_coord_double"); } if (xdrfile_close(xfp) != 0) die("Can not close xdr file"); /*************************************/ /* READING BIT */ /*************************************/ if ((xfp = xdrfile_open(testfn, "r")) == NULL) die("Can not open file for reading"); if ((xdrfile_read_char(ptr, len, xfp)) != len) die("Not the right number of chars read from string"); if (strcmp(ptr, buf) != 0) printf("did not read the expected chars"); if (xdrfile_read_uchar(uptr, len, xfp) != len) die("Not the right number of uchars read from string"); if (strcmp((char *) uptr, buf) != 0) printf("did not read the expected uchars"); if (xdrfile_read_short(sptr2, BUFLEN,xfp) != BUFLEN) die("Reading short array"); for (i = 0; (i < BUFLEN); i++) if (sptr2[i] != sptr[i]) { fprintf(stderr, "i: %5d, wrote: %10d, read: %10d\n", i, sptr[i], sptr2[i]); die("Comparing short array"); } if (xdrfile_read_ushort(usptr2, BUFLEN,xfp) != BUFLEN) die("Reading ushort array"); for (i = 0; (i < BUFLEN); i++) if (usptr2[i] != usptr[i]) { fprintf(stderr, "i: %5d, wrote: %10d, read: %10d\n", i, usptr[i], usptr2[i]); die("Comparing ushort array"); } if (xdrfile_read_int(iptr2, BUFLEN,xfp) != BUFLEN) die("Reading int array"); for (i = 0; (i < BUFLEN); i++) if (iptr2[i] != iptr[i]) { fprintf(stderr, "i: %5d, wrote: %10d, read: %10d\n", i, iptr[i], iptr2[i]); die("Comparing int array"); } if (xdrfile_read_uint(uiptr2, BUFLEN,xfp) != BUFLEN) die("Reading uint array"); for (i = 0; (i < BUFLEN); i++) if (uiptr2[i] != uiptr[i]) { fprintf(stderr, "i: %5d, wrote: %10d, read: %10d\n", i, uiptr[i], uiptr2[i]); die("Comparing uint array"); } if (xdrfile_read_float(fptr2, BUFLEN,xfp) != BUFLEN) die("Reading float array"); for (i = 0; (i < BUFLEN); i++) if (fptr2[i] != fptr[i]) { fprintf(stderr, "i: %5d, wrote: %12g, read: %12g\n", i, fptr[i], fptr2[i]); die("Comparing float array"); } if (xdrfile_read_double(dptr2, BUFLEN,xfp) != BUFLEN) die("Reading double array"); for (i = 0; (i < BUFLEN); i++) if (dptr2[i] != dptr[i]) { fprintf(stderr, "i: %5d, wrote: %12g, read: %12g\n", i, dptr[i], dptr2[i]); die("Comparing double array"); } if (xdrfile_read_string(ptr, BUFLEN,xfp) != len) die("Reading string"); if (strcmp(ptr, buf) != 0) die("Comparing strings"); if (xdrfile_read_opaque(optr2, BUFLEN,xfp) != BUFLEN) die("Reading opaque array"); for (i = 0; (i < BUFLEN); i++) if (optr2[i] != optr[i]) { fprintf(stderr, "i: %5d, wrote: %2d, read: %2d\n", i, optr[i], optr2[i]); die("Comparing opaque array"); } for (k = 0; (k < NPREC); k++) { float ff, fx; double dd, dx; int nc = ncoord; if (xdrfile_decompress_coord_float(fptr2, &nc, &ff, xfp) != ncoord) die("Reading compress_coord_float"); if (fabs(ff - fprec[k]) > EPSILON_1) { printf("Found precision %f, expected %f\n", ff, fprec[k]); die("Float precision"); } if (ff <= 0) ff = 1000; for (i = 0; (i < ncoord); i++) for (j = 0; (j < 3); j++) { fx = rint(fptr[3 * i + j] * ff) / ff; if (fabs(fx - fptr2[3 * i + j]) > EPSILON_1) { printf( "prec: %10g, i: %3d, j: %d, fx: %10g, fptr2: %12g, fptr: %12g\n", ff, i, j, fx, fptr2[3 * i + j], fptr[3 * i + j]); die("Reading decompressed float coordinates"); } } if (xdrfile_decompress_coord_double(dptr2, &nc, &dd, xfp) != ncoord) die("Reading compress_coord_double"); if (fabs(dd - dprec[k]) > EPSILON_2) die("Double precision"); for (i = 0; (i < ncoord); i++) for (j = 0; (j < 3); j++) { dx = rint(dptr[3 * i + j] * dd) / dd; if (fabs(dx - dptr2[3 * i + j]) > EPSILON_2) { printf( "prec: %10g, i: %3d, j: %d, dx: %10g, dptr2: %12g, dptr: %12g\n", dd, i, j, dx, dptr2[3 * i + j], dptr[3 * i + j]); die("Reading decompressed double coordinates"); } } } if (xdrfile_close(xfp) != 0) die("Can not close xdr file"); } #ifdef HAVE_UNISTD unlink(testfn); #endif printf(" PASSED\n"); }