Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

dxplugin.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2006 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: dxplugin.C,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.21 $       $Date: 2006/02/23 19:36:44 $
00015  *
00016  ***************************************************************************/
00017 
00018 /* 
00019  * DX potential maps
00020  *
00021  * Format of the file is:
00022  * # Comments
00023  * .
00024  * .
00025  * .
00026  * object 1 class gridpositions counts xn yn zn
00027  * origin xorg yorg zorg
00028  * delta xdel 0 0
00029  * delta 0 ydel 0
00030  * delta 0 0 zdel
00031  * object 2 class gridconnections counts xn yn zn
00032  * object 3 class array type double rank 0 items [ xn*yn*zn ] data follows
00033  * f1 f2 f3
00034  * f4 f5 f6
00035  * .
00036  * .
00037  * .
00038  * object "Dataset name" class field
00039  
00040  * Where xn, yn, and zn are the number of data points along each axis;
00041  * xorg, yorg, and zorg is the origin of the grid, in angstroms;
00042  * xdel, ydel, and zdel are the scaling factors to convert grid units to
00043  * angstroms.
00044  * Grid data follows, with three values per line, ordered z fast, y medium,
00045  * and x slow.
00046  *
00047  * Note: this plugin was written to read the OpenDX files created by the
00048  * APBS program, and may not support all of the features in the file format.
00049  *
00050  */
00051 
00052 #include <stdlib.h>
00053 #include <stdio.h>
00054 #include <ctype.h>
00055 #include <math.h>
00056 #include <string.h>
00057 
00058 #if defined(_AIX)
00059 #include <strings.h>
00060 #endif
00061 
00062 #if defined(WIN32) || defined(WIN64)
00063 #define strcasecmp  stricmp
00064 #define strncasecmp strnicmp
00065 #endif
00066 
00067 #include "molfile_plugin.h"
00068 
00069 #define LINESIZE 85
00070 
00071 typedef struct {
00072   FILE *fd;
00073   int nsets;
00074   molfile_volumetric_t *vol;
00075 } dx_t;
00076 
00077 
00078 // Get a string from a stream, printing any errors that occur
00079 static char *dxgets(char *s, int n, FILE *stream) {
00080   char *returnVal;
00081 
00082   if (feof(stream)) {
00083     fprintf(stderr, "Unexpected end-of-file.\n");
00084     return NULL;
00085   } else if (ferror(stream)) {
00086     fprintf(stderr, "Error reading file.\n");
00087     return NULL;
00088   } else {
00089     returnVal = fgets(s, n, stream);
00090     if (returnVal == NULL) {
00091       fprintf(stderr, "Error reading line.\n");
00092     }
00093   }
00094 
00095   return returnVal;
00096 }
00097 
00098 
00099 static void *open_dx_read(const char *filepath, const char *filetype,
00100     int *natoms) {
00101   FILE *fd;
00102   dx_t *dx;
00103   char inbuf[LINESIZE];
00104   int xsize, ysize, zsize;
00105   float orig[3], xdelta[3], ydelta[3], zdelta[3];
00106   
00107   fd = fopen(filepath, "rb");
00108   if (!fd) {
00109     fprintf(stderr, "Error opening file.\n");
00110     return NULL;
00111   }
00112 
00113   /* skip comments */
00114   do {
00115     if (dxgets(inbuf, LINESIZE, fd) == NULL) 
00116       return NULL;
00117   } while (inbuf[0] == '#');
00118 
00119   /* get the number of grid points */
00120   if (sscanf(inbuf, "object 1 class gridpositions counts %d %d %d", &xsize, &ysize, &zsize) != 3) {
00121     fprintf(stderr, "Error reading grid dimensions.\n");
00122     return NULL;
00123   }
00124 
00125   /* get the cell origin */
00126   if (dxgets(inbuf, LINESIZE, fd) == NULL) {
00127     return NULL;
00128   }
00129   if (sscanf(inbuf, "origin %e %e %e", orig, orig+1, orig+2) != 3) {
00130     fprintf(stderr, "Error reading grid origin.\n");
00131     return NULL;
00132   }
00133 
00134   /* get the cell dimensions */
00135   if (dxgets(inbuf, LINESIZE, fd) == NULL) {
00136     return NULL;
00137   }
00138   if (sscanf(inbuf, "delta %e %e %e", xdelta, xdelta+1, xdelta+2) != 3) {
00139     fprintf(stderr, "Error reading cell x-dimension.\n");
00140     return NULL;
00141   }
00142 
00143   if (dxgets(inbuf, LINESIZE, fd) == NULL) {
00144     return NULL;
00145   }
00146   if (sscanf(inbuf, "delta %e %e %e", ydelta, ydelta+1, ydelta+2) != 3) {
00147     fprintf(stderr, "Error reading cell y-dimension.\n");
00148     return NULL;
00149   }
00150 
00151   if (dxgets(inbuf, LINESIZE, fd) == NULL) {
00152     return NULL;
00153   }
00154   if (sscanf(inbuf, "delta %e %e %e", zdelta, zdelta+1, zdelta+2) != 3) {
00155     fprintf(stderr, "Error reading cell z-dimension.\n");
00156     return NULL;
00157   }
00158 
00159   /* skip the last two lines of the header (described at the beginning of
00160    * the code), which aren't utilized by APBS-produced DX files.  */
00161   if (dxgets(inbuf, LINESIZE, fd) == NULL) 
00162     return NULL;
00163   if (dxgets(inbuf, LINESIZE, fd) == NULL)
00164     return NULL;
00165  
00166   /* allocate and initialize the dx structure */
00167   dx = new dx_t;
00168   dx->fd = fd;
00169   dx->vol = NULL;
00170   *natoms = MOLFILE_NUMATOMS_NONE;
00171   dx->nsets = 1; /* this file contains only one data set */
00172 
00173   dx->vol = new molfile_volumetric_t[1];
00174   strcpy(dx->vol[0].dataname, "DX map");
00175 
00176   /* Set the unit cell origin and basis vectors */
00177   for (int i=0; i<3; i++) {
00178     dx->vol[0].origin[i] = orig[i];
00179     dx->vol[0].xaxis[i] = xdelta[i] * (xsize-1);
00180     dx->vol[0].yaxis[i] = ydelta[i] * (ysize-1);
00181     dx->vol[0].zaxis[i] = zdelta[i] * (zsize-1);
00182   }
00183 
00184   dx->vol[0].xsize = xsize;
00185   dx->vol[0].ysize = ysize;
00186   dx->vol[0].zsize = zsize;
00187 
00188   /* DX files contain no color information. Taken from edmplugin.C */
00189   dx->vol[0].has_color = 0;
00190 
00191   return dx;
00192 }
00193 
00194 static int read_dx_metadata(void *v, int *nsets, 
00195   molfile_volumetric_t **metadata) {
00196   dx_t *dx = (dx_t *)v;
00197   *nsets = dx->nsets; 
00198   *metadata = dx->vol;  
00199 
00200   return MOLFILE_SUCCESS;
00201 }
00202 
00203 static int read_dx_data(void *v, int set, float *datablock,
00204                          float *colorblock) {
00205   dx_t *dx = (dx_t *)v;
00206   FILE *fd = dx->fd;
00207   char inbuf[LINESIZE];
00208   float grid[3];
00209   int x, y, z, xsize, ysize, zsize, xysize, count, total, i;
00210 
00211   xsize = dx->vol[0].xsize;
00212   ysize = dx->vol[0].ysize;
00213   zsize = dx->vol[0].zsize;
00214   xysize = xsize * ysize;
00215   total = xysize * zsize;
00216 
00217   /* Read the values from the file */
00218   x = y = z = 0;
00219   for (count = 0; count < total/3; count++) {
00220     if (dxgets(inbuf, LINESIZE, fd) == NULL )
00221       return MOLFILE_ERROR;
00222     if (sscanf(inbuf, "%e %e %e", &grid[0], &grid[1], &grid[2]) != 3) {
00223       fprintf(stderr, "Error reading grid data.\n");
00224       return MOLFILE_ERROR;
00225     }
00226 
00227     for (i = 0; i < 3; i++) { 
00228       datablock[x + y*xsize + z*xysize] = grid[i];
00229       z++;
00230       if (z >= zsize) {
00231         z = 0;
00232         y++;
00233         if (y >= ysize) {
00234           y = 0;
00235           x++;
00236         }
00237       }
00238     }
00239   }
00240 
00241   if ((total%3) != 0) {
00242     if (dxgets(inbuf, LINESIZE, fd) == NULL )
00243       return MOLFILE_ERROR;
00244 
00245     count = sscanf(inbuf, "%e %e %e", &grid[0], &grid[1], &grid[2]);
00246     if (count != (total%3)) {
00247       fprintf(stderr, "Error: incorrect number of data points.\n");
00248       return MOLFILE_ERROR;
00249     }
00250 
00251     for (i = 0; i < count; i++) {
00252       datablock[x + y*xsize + z*xysize] = grid[i];
00253       z++;
00254     }
00255   }
00256   
00257   char dxname[256];
00258   while (dxgets(inbuf, LINESIZE, dx->fd)) {
00259     if (sscanf(inbuf, "object \"%[^\"]\" class field", dxname) == 1) {
00260       // a dataset name has been found; override the default
00261       strcpy(dx->vol[0].dataname, dxname);
00262       break;
00263     }
00264   }
00265 
00266   return MOLFILE_SUCCESS;
00267 }
00268 
00269 static void close_dx_read(void *v) {
00270   dx_t *dx = (dx_t *)v;
00271   
00272   fclose(dx->fd);
00273   if (dx->vol != NULL)
00274     delete [] dx->vol; 
00275   delete dx;
00276 }
00277 
00278 /*
00279  * Initialization stuff here
00280  */
00281 static molfile_plugin_t plugin = {
00282   vmdplugin_ABIVERSION,   /* ABI version */
00283   MOLFILE_PLUGIN_TYPE,    /* plugin type */
00284   "dx",                   /* short file format description */
00285   "DX",                   /* pretty file format description */
00286   "Eamon Caddigan",       /* author(s) */
00287   0,                      /* major version */
00288   6,                      /* minor version */
00289   VMDPLUGIN_THREADSAFE,   /* is reentrant */
00290   "dx"                    /* filename extension */
00291 };
00292 
00293 VMDPLUGIN_API int VMDPLUGIN_init(void) { return VMDPLUGIN_SUCCESS; }
00294 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00295 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00296   plugin.open_file_read = open_dx_read;
00297   plugin.read_volumetric_metadata = read_dx_metadata;
00298   plugin.read_volumetric_data = read_dx_data;
00299   plugin.close_file_read = close_dx_read;
00300   (*cb)(v, (vmdplugin_t *)&plugin);
00301   return VMDPLUGIN_SUCCESS;
00302 }
00303 

Generated on Wed Mar 22 13:15:29 2006 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002