in contrib/uiuc/plugins/molfile_plugin/src/jsplugin.c [410:1002]
static int read_js_structure(void *mydata, int *optflags,
molfile_atom_t *atoms) {
jshandle *js = (jshandle *) mydata;
long i;
if (optflags != NULL)
*optflags = MOLFILE_NOOPTIONS; /* set to no options until we read them */
/* read flags data from the file */
fio_read_int32(js->fd, &js->optflags);
if (js->reverseendian)
swap4_aligned(&js->optflags, 1);
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) read option flags: %0x08x\n", js->optflags);
#endif
/* Check to see if block-based trajectory I/O is used */
/* and read in the block size for this file. */
if (js->optflags & JSOPT_TS_BLOCKIO) {
fio_fread(&js->directio_block_size, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->directio_block_size, 1);
#if defined(INFOMSGS)
if (js->verbose) {
printf("jsplugin) Block-based I/O enabled: block size %d bytes\n",
js->directio_block_size);
}
#endif
/* Check to ensure that we can handle the block size used by the */
/* file we are reading. We may use variable block sizes in */
/* the future as more high-end filesystems begin to support */
/* 8KB, 16KB, or larger block sizes for enhanced sequential I/O */
/* performance on very large files. */
if (js->directio_block_size > MOLFILE_DIRECTIO_MAX_BLOCK_SIZE) {
printf("jsplugin) File block size exceeds jsplugin block size limit.\n");
printf("jsplugin) Direct I/O unavailable for file '%s'\n", js->path);
} else {
if (fio_open(js->path, FIO_READ | FIO_DIRECT, &js->directio_fd) < 0) {
printf("jsplugin) Direct I/O unavailable for file '%s'\n", js->path);
} else {
js->directio_enabled = 1;
#if defined(INFOMSGS)
if (js->verbose) {
printf("jsplugin) Direct I/O enabled for file '%s'\n", js->path);
}
#endif
}
}
}
#if defined(ENABLEJSSHORTREADS)
/* test code for an implementation that does short reads that */
/* skip bulk solvent, useful for faster loading of very large */
/* structures */
if (getenv("VMDJSMAXATOMIDX") != NULL) {
long maxatomidx = atoi(getenv("VMDJSMAXATOMIDX"));
if (maxatomidx < 0)
maxatomidx = 0;
if (maxatomidx >= js->natoms)
maxatomidx = js->natoms - 1;
printf("jsplugin) Short-reads of timesteps enabled: %ld / %ld atoms (%.2f%%)\n",
maxatomidx, js->natoms, 100.0*(maxatomidx+1) / ((double) js->natoms));
}
#endif
/* Mark the handle to indicate we've parsed the structure. */
/* If any errors occur after this point, they are likely fatal anyway. */
js->parsed_structure = 1;
/* determine whether or not this file contains structure info or not */
if (js->optflags & JSOPT_STRUCTURE) {
int numatomnames, numatomtypes, numresnames, numsegids, numchains;
char **atomnames = NULL;
char **atomtypes = NULL;
char **resnames = NULL;
char **segids = NULL;
char **chains = NULL;
short *shortbuf = NULL; /* temp buf for decoding atom records */
int *intbuf = NULL; /* temp buf for decoding atom records */
float *fltbuf = NULL; /* temp buf for decoding atom records */
/* read in block of name string table sizes */
fio_read_int32(js->fd, &numatomnames);
fio_read_int32(js->fd, &numatomtypes);
fio_read_int32(js->fd, &numresnames);
fio_read_int32(js->fd, &numsegids);
fio_read_int32(js->fd, &numchains);
if (js->reverseendian) {
swap4_aligned(&numatomnames, 1);
swap4_aligned(&numatomtypes, 1);
swap4_aligned(&numresnames, 1);
swap4_aligned(&numsegids, 1);
swap4_aligned(&numchains, 1);
}
#if defined(INFOMSGS)
if (js->verbose) {
printf("jsplugin) reading string tables...\n");
printf("jsplugin) %d %d %d %d %d\n",
numatomnames, numatomtypes, numresnames, numsegids, numchains);
}
#endif
/* skip forward to first TS if the caller gives us NULL ptrs */
if (optflags == NULL && atoms == NULL) {
size_t offset=0;
offset += numatomnames * (16L * sizeof(char));
offset += numatomtypes * (16L * sizeof(char));
offset += numresnames * (8L * sizeof(char));
offset += numsegids * (8L * sizeof(char));
offset += numchains * (2L * sizeof(char));
offset += js->natoms * sizeof(short); /* atom name indices */
offset += js->natoms * sizeof(short); /* atom type indices */
offset += js->natoms * sizeof(short); /* residue name indices */
offset += js->natoms * sizeof(short); /* segment name indices */
offset += js->natoms * sizeof(short); /* chain name indices */
offset += js->natoms * sizeof(int); /* residue indices */
/* optional per-atom fields */
if (js->optflags & JSOPT_OCCUPANCY)
offset += js->natoms * sizeof(float);
if (js->optflags & JSOPT_BFACTOR)
offset += js->natoms * sizeof(float);
if (js->optflags & JSOPT_MASS)
offset += js->natoms * sizeof(float);
if (js->optflags & JSOPT_CHARGE)
offset += js->natoms * sizeof(float);
if (js->optflags & JSOPT_RADIUS)
offset += js->natoms * sizeof(float);
if (js->optflags & JSOPT_ATOMICNUMBER)
offset += js->natoms * sizeof(int);
fio_fseek(js->fd, offset, FIO_SEEK_CUR);
offset=0;
/* these require actually seeking as we process... */
if (js->optflags & JSOPT_BONDS) {
fio_fread(&js->nbonds, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->nbonds, 1);
#if defined(INFOMSGS)
if (js->verbose) {
printf("jsplugin) %d bonds...\n", js->nbonds);
}
#endif
offset += 2L * js->nbonds * sizeof(int);
if (js->optflags & JSOPT_BONDORDERS)
offset += js->nbonds * sizeof(float);
fio_fseek(js->fd, offset, FIO_SEEK_CUR);
offset=0;
}
if (js->optflags & JSOPT_ANGLES) {
fio_fread(&js->numangles, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->numangles, 1);
#if defined(INFOMSGS)
if (js->verbose) {
printf("jsplugin) %d angles...\n", js->numangles);
}
#endif
fio_fseek(js->fd, sizeof(int)*3L*js->numangles, FIO_SEEK_CUR);
fio_fread(&js->numdihedrals, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->numdihedrals, 1);
#if defined(INFOMSGS)
printf("jsplugin) %d dihedrals...\n", js->numdihedrals);
#endif
fio_fseek(js->fd, sizeof(int)*4L*js->numdihedrals, FIO_SEEK_CUR);
fio_fread(&js->numimpropers, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->numimpropers, 1);
#if defined(INFOMSGS)
if (js->verbose) {
printf("jsplugin) %d impropers...\n", js->numimpropers);
}
#endif
fio_fseek(js->fd, sizeof(int)*4L*js->numimpropers, FIO_SEEK_CUR);
}
if (js->optflags & JSOPT_CTERMS) {
fio_fread(&js->numcterms, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->numcterms, 1);
#if defined(INFOMSGS)
if (js->verbose) {
printf("jsplugin) %d cterms...\n", js->numcterms);
}
#endif
fio_fseek(js->fd, sizeof(int)*8L*js->numcterms, FIO_SEEK_CUR);
}
/* record the file offset for the first timestep */
js_calc_timestep_blocking_info(js);
return MOLFILE_SUCCESS;
}
/* allocate string tables */
atomnames = (char **) malloc(numatomnames * sizeof(char *));
atomtypes = (char **) malloc(numatomtypes * sizeof(char *));
resnames = (char **) malloc(numresnames * sizeof(char *));
segids = (char **) malloc(numsegids * sizeof(char *));
chains = (char **) malloc(numchains * sizeof(char *));
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) atom names...\n");
#endif
/* read in the string tables */
for (i=0; i<numatomnames; i++) {
atomnames[i] = (char *) malloc(16L * sizeof(char));
fio_fread(atomnames[i], 16L * sizeof(char), 1, js->fd);
}
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) atom types...\n");
#endif
for (i=0; i<numatomtypes; i++) {
atomtypes[i] = (char *) malloc(16L * sizeof(char));
fio_fread(atomtypes[i], 16L * sizeof(char), 1, js->fd);
}
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) residue names...\n");
#endif
for (i=0; i<numresnames; i++) {
resnames[i] = (char *) malloc(8L * sizeof(char));
fio_fread(resnames[i], 8L * sizeof(char), 1, js->fd);
}
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) segment names...\n");
#endif
for (i=0; i<numsegids; i++) {
segids[i] = (char *) malloc(8L * sizeof(char));
fio_fread(segids[i], 8L * sizeof(char), 1, js->fd);
}
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) chain names...\n");
#endif
for (i=0; i<numchains; i++) {
chains[i] = (char *) malloc(2L * sizeof(char));
fio_fread(chains[i], 2L * sizeof(char), 1, js->fd);
}
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) reading numeric field tables...\n");
#endif
/* read in all of the atom fields */
shortbuf = (short *) malloc(js->natoms * sizeof(short));
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) atom name indices...\n");
#endif
/* read in atom names */
fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
if (js->reverseendian)
swap2_aligned(shortbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
strcpy(atoms[i].name, atomnames[shortbuf[i]]);
}
for (i=0; i<numatomnames; i++)
free(atomnames[i]);
free(atomnames);
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) atom type indices...\n");
#endif
/* read in atom types */
fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
if (js->reverseendian)
swap2_aligned(shortbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
strcpy(atoms[i].type, atomtypes[shortbuf[i]]);
}
for (i=0; i<numatomtypes; i++)
free(atomtypes[i]);
free(atomtypes);
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) residue name indices...\n");
#endif
/* read in resnames */
fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
if (js->reverseendian)
swap2_aligned(shortbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
strcpy(atoms[i].resname, resnames[shortbuf[i]]);
}
for (i=0; i<numresnames; i++)
free(resnames[i]);
free(resnames);
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) segment name indices...\n");
#endif
/* read in segids */
fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
if (js->reverseendian)
swap2_aligned(shortbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
strcpy(atoms[i].segid, segids[shortbuf[i]]);
}
for (i=0; i<numsegids; i++)
free(segids[i]);
free(segids);
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) chain name indices...\n");
#endif
/* read in chains */
fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
if (js->reverseendian)
swap2_aligned(shortbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
strcpy(atoms[i].chain, chains[shortbuf[i]]);
}
for (i=0; i<numchains; i++)
free(chains[i]);
free(chains);
if (shortbuf != NULL) {
free(shortbuf);
shortbuf=NULL;
}
/*
* read in integer data blocks
*/
intbuf = (int *) malloc(js->natoms * sizeof(int));
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) residue indices...\n");
#endif
/* read in resid */
fio_fread(intbuf, js->natoms * sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(intbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
atoms[i].resid = intbuf[i];
}
if (intbuf != NULL) {
free(intbuf);
intbuf = NULL;
}
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) reading optional per-atom tables...\n");
#endif
/*
* read in optional single-precision float data blocks
*/
if (js->optflags & (JSOPT_OCCUPANCY | JSOPT_BFACTOR |
JSOPT_MASS | JSOPT_RADIUS | JSOPT_CHARGE))
fltbuf = (float *) malloc(js->natoms * sizeof(float));
/* read in optional data if it exists */
if (js->optflags & JSOPT_OCCUPANCY) {
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) occupancy...\n");
#endif
*optflags |= MOLFILE_OCCUPANCY;
fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
if (js->reverseendian)
swap4_aligned(fltbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
atoms[i].occupancy = fltbuf[i];
}
}
if (js->optflags & JSOPT_BFACTOR) {
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) bfactor...\n");
#endif
*optflags |= MOLFILE_BFACTOR;
fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
if (js->reverseendian)
swap4_aligned(fltbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
atoms[i].bfactor = fltbuf[i];
}
}
if (js->optflags & JSOPT_MASS) {
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) mass...\n");
#endif
*optflags |= MOLFILE_MASS;
fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
if (js->reverseendian)
swap4_aligned(fltbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
atoms[i].mass = fltbuf[i];
}
}
if (js->optflags & JSOPT_CHARGE) {
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) charge...\n");
#endif
*optflags |= MOLFILE_CHARGE;
fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
if (js->reverseendian)
swap4_aligned(fltbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
atoms[i].charge = fltbuf[i];
}
}
if (js->optflags & JSOPT_RADIUS) {
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) radius...\n");
#endif
*optflags |= MOLFILE_RADIUS;
fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
if (js->reverseendian)
swap4_aligned(fltbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
atoms[i].radius = fltbuf[i];
}
}
if (fltbuf != NULL) {
free(fltbuf);
fltbuf=NULL;
}
/*
* read in optional integer data blocks
*/
if (js->optflags & JSOPT_ATOMICNUMBER)
intbuf = (int *) malloc(js->natoms * sizeof(int));
if (js->optflags & JSOPT_ATOMICNUMBER) {
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) atomic number...\n");
#endif
*optflags |= MOLFILE_ATOMICNUMBER;
fio_fread(intbuf, js->natoms * sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(intbuf, js->natoms);
for (i=0; i<js->natoms; i++) {
atoms[i].atomicnumber = intbuf[i];
}
}
if (intbuf != NULL) {
free(intbuf);
intbuf = NULL;
}
/*
* read in bonds and fractional bond orders
*/
if (js->optflags & JSOPT_BONDS) {
fio_fread(&js->nbonds, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->nbonds, 1);
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) %d bonds...\n", js->nbonds);
#endif
js->bondfrom = (int *) malloc(js->nbonds * sizeof(int));
js->bondto = (int *) malloc(js->nbonds * sizeof(int));
fio_fread(js->bondfrom, js->nbonds * sizeof(int), 1, js->fd);
fio_fread(js->bondto, js->nbonds * sizeof(int), 1, js->fd);
if (js->reverseendian) {
swap4_aligned(js->bondfrom, js->nbonds);
swap4_aligned(js->bondto, js->nbonds);
}
if (js->optflags & JSOPT_BONDORDERS) {
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) bond orders...\n");
#endif
js->bondorders = (float *) malloc(js->nbonds * sizeof(float));
fio_fread(js->bondorders, js->nbonds * sizeof(float), 1, js->fd);
if (js->reverseendian)
swap4_aligned(js->bondorders, js->nbonds);
}
}
if (js->optflags & JSOPT_ANGLES) {
fio_fread(&js->numangles, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->numangles, 1);
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) %d angles...\n", js->numangles);
#endif
js->angles = (int *) malloc(3L * js->numangles * sizeof(int));
fio_fread(js->angles, sizeof(int)*3L*js->numangles, 1, js->fd);
if (js->reverseendian)
swap4_aligned(js->angles, 3L*js->numangles);
fio_fread(&js->numdihedrals, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->numdihedrals, 1);
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) %d dihedrals...\n", js->numdihedrals);
#endif
js->dihedrals = (int *) malloc(4L * js->numdihedrals * sizeof(int));
fio_fread(js->dihedrals, sizeof(int)*4L*js->numdihedrals, 1, js->fd);
if (js->reverseendian)
swap4_aligned(js->dihedrals, 4L*js->numdihedrals);
fio_fread(&js->numimpropers, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->numimpropers, 1);
js->impropers = (int *) malloc(4L * js->numimpropers * sizeof(int));
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) %d impropers...\n", js->numimpropers);
#endif
fio_fread(js->impropers, sizeof(int)*4L*js->numimpropers, 1, js->fd);
if (js->reverseendian)
swap4_aligned(js->impropers, 4L*js->numimpropers);
}
if (js->optflags & JSOPT_CTERMS) {
fio_fread(&js->numcterms, sizeof(int), 1, js->fd);
if (js->reverseendian)
swap4_aligned(&js->numcterms, 1);
js->cterms = (int *) malloc(8L * js->numcterms * sizeof(int));
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) %d cterms...\n", js->numcterms);
#endif
fio_fread(js->cterms, sizeof(int)*8L*js->numcterms, 1, js->fd);
if (js->reverseendian)
swap4_aligned(js->cterms, 8L*js->numcterms);
}
#if defined(INFOMSGS)
if (js->verbose) {
printf("jsplugin) final optflags: %08x\n", *optflags);
printf("jsplugin) structure information complete\n");
}
#endif
/* record the file offset for the first timestep */
js_calc_timestep_blocking_info(js);
return MOLFILE_SUCCESS;
}
#if defined(INFOMSGS)
if (js->verbose)
printf("jsplugin) no structure information available\n");
#endif
/* record the file offset for the first timestep */
js_calc_timestep_blocking_info(js);
/* else, we have no structure information */
return MOLFILE_NOSTRUCTUREDATA;
}