static int read_binary_dx_data(dx_t *dx, int set, float *datablock) { int i, j, k; int xsize = dx->vol[0].xsize; int ysize = dx->vol[0].ysize; int zsize = dx->vol[0].zsize; int xysize = xsize * ysize; size_t total = xysize * zsize; float *tmp = (float *)malloc(total*sizeof(float)); if (fread(tmp, sizeof(float), total, dx->fd) != total) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Failed to read %d binary floats\n", total); free(tmp); return MOLFILE_ERROR; } // take the transpose - nasty int ind = 0; for (i=0; i<xsize; i++) { for (j=0; j<ysize; j++) { for (k=0; k<zsize; k++) { datablock[k * xysize + j*xsize + i] = tmp[ind++]; } } } free( tmp ); return MOLFILE_SUCCESS; }
static void *open_rst_write(const char *path, const char *filetype, int natoms) { char title[82]; rstdata *rst; FILE *fd; int len; fd = fopen(path, "wb"); if (!fd) { vmdcon_printf(VMDCON_ERROR, "rst7plugin) Could not open file %s for writing\n", path); return NULL; } /* write out fixed length fortran style string */ sprintf(title, "TITLE : Created by VMD with %d atoms",natoms); len = strlen(title); memset(title+len,(int)' ',82-len); title[80] = '\n'; title[81] = '\0'; fputs(title,fd); rst = (rstdata *)malloc(sizeof(rstdata)); rst->file = fd; rst->numatoms = natoms; rst->has_box = 1; return rst; }
// Get a string from a stream, printing any errors that occur static char *dxgets(char *s, int n, FILE *stream) { char *returnVal; if (feof(stream)) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Unexpected end-of-file.\n"); return NULL; } else if (ferror(stream)) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error reading file.\n"); return NULL; } else { returnVal = fgets(s, n, stream); if (returnVal == NULL) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error reading line.\n"); } } return returnVal; }
static void *open_dx_write(const char *filepath, const char *filetype, int natoms) { FILE *fd = fopen(filepath, "wb"); if (!fd) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Could not open path '%s' for writing.\n", filepath); } return fd; }
/* flush current message queue to a registered * console widget, if such a thing exists. * since vmdcon_append() allocates the storage, * for everything, we have to free the msg structs * and the strings. */ int vmdcon_purge(void) { struct vmdcon_msg *msg; const char *res; wkf_mutex_lock(&vmdcon_status_lock); /* purge message queue only if we have a working console window */ if ( ! ((vmdcon_status == VMDCON_UNDEF) || (vmdcon_status == VMDCON_NONE) || ((vmdcon_status == VMDCON_WIDGET) && ((vmdcon_interp == NULL) || (vmdcon_wpath == NULL))) ) ) { wkf_mutex_lock(&vmdcon_output_lock); while (vmdcon_pending != NULL) { msg=vmdcon_pending; switch (vmdcon_status) { case VMDCON_TEXT: fputs(msg->txt,stdout); break; case VMDCON_WIDGET: res = tcl_vmdcon_insert(vmdcon_interp, vmdcon_wpath, vmdcon_mark, msg->txt); /* handle errors writing to a tcl console window. * unregister widget, don't free current message * and append error message into holding buffer. */ if (res) { wkf_mutex_unlock(&vmdcon_status_lock); vmdcon_register(NULL, NULL, vmdcon_interp); wkf_mutex_unlock(&vmdcon_output_lock); vmdcon_printf(VMDCON_ERROR, "Problem writing to text widget: %s\n", res); return 1; } break; default: /* unknown console type */ return 1; } free(msg->txt); vmdcon_pending=msg->next; free(msg); } if (vmdcon_status == VMDCON_TEXT) fflush(stdout); wkf_mutex_unlock(&vmdcon_output_lock); } wkf_mutex_unlock(&vmdcon_status_lock); return 0; }
static int read_timestep_metadata(void *mydata, molfile_timestep_metadata_t *meta) { rstdata *data = (rstdata *)mydata; meta->count = -1; meta->has_velocities = data->ts_meta.has_velocities; if (meta->has_velocities) { vmdcon_printf(VMDCON_INFO, "rst7plugin) Importing velocities from restart file.\n"); } return MOLFILE_SUCCESS; }
static int read_dx_data(void *v, int set, float *datablock, float *colorblock) { dx_t *dx = (dx_t *)v; FILE *fd = dx->fd; char inbuf[LINESIZE]; char *p; float grid; int x, y, z, xsize, ysize, zsize, xysize, count, total, i, line; if (dx->isBinary) return read_binary_dx_data(dx, set, datablock); xsize = dx->vol[0].xsize; ysize = dx->vol[0].ysize; zsize = dx->vol[0].zsize; xysize = xsize * ysize; total = xysize * zsize; /* Read the values from the file */ x = y = z = line = 0; for (count = 0; count < total;) { ++line; p=dxgets(inbuf, LINESIZE, fd); if (p == NULL) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error reading grid data.\n"); vmdcon_printf(VMDCON_ERROR, "dxplugin) line: %d. item: %d/%d. last data: %s\n", line, count, total, inbuf); return MOLFILE_ERROR; } // chop line into whitespace separated tokens and parse them one by one. while (*p != '\n' && *p != '\0') { // skip over whitespace and try to parse non-blank as number while (*p != '\0' && (*p == ' ' || *p == '\t' || *p == '\n')) ++p; i = sscanf(p, "%e", &grid); if (i < 0) break; // end of line/string. get a new one. // a 0 return value means non-parsable as number. if (i == 0) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error parsing grid data.\n"); vmdcon_printf(VMDCON_ERROR, "dxplugin) line: %d. item: %d/%d. data %s\n", line, count, total, p); return MOLFILE_ERROR; } // success! add to dataset. if (i == 1) { ++count; datablock[x + y*xsize + z*xysize] = grid; z++; if (z >= zsize) { z = 0; y++; if (y >= ysize) { y = 0; x++; } } } // skip over the parsed text and search for next blank. while (*p != '\0' && *p != ' ' && *p != '\t' && *p != '\n') ++p; } } char dxname[256]; while (dxgets(inbuf, LINESIZE, dx->fd)) { if (sscanf(inbuf, "object \"%[^\"]\" class field", dxname) == 1) { // a dataset name has been found; override the default strcpy(dx->vol[0].dataname, dxname); break; } } return MOLFILE_SUCCESS; }
static void *open_dx_read(const char *filepath, const char *filetype, int *natoms) { FILE *fd; dx_t *dx; char inbuf[LINESIZE]; int xsize, ysize, zsize; float orig[3], xdelta[3], ydelta[3], zdelta[3]; int isBinary = 0; fd = fopen(filepath, "rb"); if (!fd) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error opening file.\n"); return NULL; } /* skip comments */ do { if (dxgets(inbuf, LINESIZE, fd) == NULL) return NULL; } while (inbuf[0] == '#'); /* get the number of grid points */ if (sscanf(inbuf, "object 1 class gridpositions counts %d %d %d", &xsize, &ysize, &zsize) != 3) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error reading grid dimensions.\n"); return NULL; } /* get the cell origin */ if (dxgets(inbuf, LINESIZE, fd) == NULL) { return NULL; } if (sscanf(inbuf, "origin %e %e %e", orig, orig+1, orig+2) != 3) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error reading grid origin.\n"); return NULL; } /* get the cell dimensions */ if (dxgets(inbuf, LINESIZE, fd) == NULL) { return NULL; } if (sscanf(inbuf, "delta %e %e %e", xdelta, xdelta+1, xdelta+2) != 3) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error reading cell x-dimension.\n"); return NULL; } if (dxgets(inbuf, LINESIZE, fd) == NULL) { return NULL; } if (sscanf(inbuf, "delta %e %e %e", ydelta, ydelta+1, ydelta+2) != 3) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error reading cell y-dimension.\n"); return NULL; } if (dxgets(inbuf, LINESIZE, fd) == NULL) { return NULL; } if (sscanf(inbuf, "delta %e %e %e", zdelta, zdelta+1, zdelta+2) != 3) { vmdcon_printf(VMDCON_ERROR, "dxplugin) Error reading cell z-dimension.\n"); return NULL; } /* skip the next line of the header (described at the beginning of * the code), which aren't utilized by APBS-produced DX files. */ if (dxgets(inbuf, LINESIZE, fd) == NULL) return NULL; /* The next line tells us whether to expect ascii or binary format. * We scan for the word 'binary' somewhere in the line, and if it's found * we assume binary. */ if (dxgets(inbuf, LINESIZE, fd) == NULL) return NULL; if (strstr(inbuf, "binary")) { isBinary = 1; } /* allocate and initialize the dx structure */ dx = new dx_t; dx->fd = fd; dx->vol = NULL; dx->isBinary = isBinary; *natoms = MOLFILE_NUMATOMS_NONE; dx->nsets = 1; /* this file contains only one data set */ dx->vol = new molfile_volumetric_t[1]; strcpy(dx->vol[0].dataname, "DX map"); /* Set the unit cell origin and basis vectors */ for (int i=0; i<3; i++) { dx->vol[0].origin[i] = orig[i]; dx->vol[0].xaxis[i] = xdelta[i] * ((xsize-1 > 0) ? (xsize-1) : 1); dx->vol[0].yaxis[i] = ydelta[i] * ((ysize-1 > 0) ? (ysize-1) : 1); dx->vol[0].zaxis[i] = zdelta[i] * ((zsize-1 > 0) ? (zsize-1) : 1); } dx->vol[0].xsize = xsize; dx->vol[0].ysize = ysize; dx->vol[0].zsize = zsize; /* DX files contain no color information. Taken from edmplugin.C */ dx->vol[0].has_color = 0; return dx; }
static void *open_rst_read(const char *filename, const char *filetype,int *natoms) { FILE *fd; rstdata *data; int numats=0,i,j,point2,kkk=1; char title[82], *field; char line[82]; float x, y, z,a=0.0,b=0.0,c=0.0; double timesteprst; /* Amber 7'coord' restart files have a second introduction line with * possibly 2 entries only check for one now... * they include three 90.00 ter cards at the end * need to fix this, real crd files have atom record but no timestep and no * velocity info...arggggg */ fd = fopen(filename, "rb"); if (!fd) return NULL; /* failure */ data = (rstdata *)malloc(sizeof(rstdata)); memset(data, 0, sizeof(rstdata)); #if vmdplugin_ABIVERSION > 10 data->ts_meta.count = -1; data->ts_meta.has_velocities = 0; #endif fgets(title, 82, fd); vmdcon_printf(VMDCON_INFO, "rst7plugin) Title: %s\n",title); fgets(line, 82, fd); while (kkk==1) { /* try to read first field */ field = strtok(line, " \t"); if (field==NULL) { continue; /* no fields at all on this line */ } numats = atoi(field); /* try to read second field will be null if not there */ field = strtok(NULL, " \t"); if (field==NULL) { kkk=0; vmdcon_printf(VMDCON_INFO, "rst7plugin) This file has no velocity info.\n"); data->has_vels=0; } else { timesteprst = strtod(field, NULL); vmdcon_printf(VMDCON_INFO, "rst7plugin) This file contains velocity info.\n"); data->has_vels=1; #if vmdplugin_ABIVERSION > 10 data->ts_meta.has_velocities = 1; #endif kkk=0; } } point2=ftell(fd); data->file = fd; vmdcon_printf(VMDCON_INFO, "rst7plugin) The Restartcrd has %d atoms.\n",numats); /* skip over coordinate data */ for (i=0; i<numats; i++) { j = fscanf(fd, "%f%f%f", &x, &y, &z); } /* skip over velocity data, if present */ if (data->has_vels) { for (i=0; i<numats; i++) { j = fscanf(fd, "%f%f%f", &x, &y, &z); } } j = fscanf(fd, "%f%f%f%f%f%f", &x, &y, &z,&a,&b,&c); if (j != EOF) { vmdcon_printf(VMDCON_INFO, "rst7plugin) This restartcrd file has box info.\n"); data->has_box=1; vmdcon_printf(VMDCON_INFO, "rst7plugin) Box Dimensions are %f %f %f %f %f %f\n",x,y,z,a,b,c); } *natoms=numats; data->numatoms=numats; data->rstfile=1; fseek(fd,point2,SEEK_SET); return data; }
static int read_rst_timestep(void *mydata, int natoms, molfile_timestep_t *ts) { rstdata *rst= (rstdata *)mydata; int i, j; float x, y, z, a, b, c; /* check for rst and first read through already taken place */ if(rst->count==1 && rst->rstfile==1) return MOLFILE_ERROR; ts->A = ts->B = ts->C = 0.0f; ts->alpha = ts->beta = ts->gamma = 90.0f; for (i=0; i<rst->numatoms; i++) { /* changed to i=1 BB */ j = fscanf(rst->file, "%f%f%f", &x, &y, &z); if (j == EOF) { return MOLFILE_ERROR; } else if (j <= 0) { vmdcon_printf(VMDCON_ERROR, "rst7plugin) Problem reading CRD file\n"); return MOLFILE_ERROR; } ts->coords[3*i] = x; ts->coords[3*i+1] = y; ts->coords[3*i+2] = z; } if (rst->has_vels) { /* Read in optional velocity data. Units are Angstroms per 1/20.455ps. */ for (i=0; i<rst->numatoms; i++) { j = fscanf(rst->file, "%f%f%f", &x, &y, &z); if (j == EOF) { return MOLFILE_ERROR; } else if (j <= 0) { vmdcon_printf(VMDCON_ERROR, "rst7plugin) Problem reading velocities\n"); return MOLFILE_ERROR; } #if vmdplugin_ABIVERSION > 10 if (ts->velocities != NULL) { ts->velocities[3*i] = x; ts->velocities[3*i+1] = y; ts->velocities[3*i+2] = z; } #endif } } if (rst->has_box) { j = fscanf(rst->file, "%f%f%f%f%f%f", &x, &y, &z, &a, &b, &c); if (j == EOF) { vmdcon_printf(VMDCON_ERROR, "rst7plugin) Problem reading box data\n"); return MOLFILE_ERROR; } ts->A = x; ts->B = y; ts->C = z; ts->alpha = a; ts->beta = b; ts->gamma = c; } rst->count++; /* printf("rst->count: %d\n",rst->count); */ return MOLFILE_SUCCESS; }