00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
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
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
00114 do {
00115 if (dxgets(inbuf, LINESIZE, fd) == NULL)
00116 return NULL;
00117 } while (inbuf[0] == '#');
00118
00119
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
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
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
00160
00161 if (dxgets(inbuf, LINESIZE, fd) == NULL)
00162 return NULL;
00163 if (dxgets(inbuf, LINESIZE, fd) == NULL)
00164 return NULL;
00165
00166
00167 dx = new dx_t;
00168 dx->fd = fd;
00169 dx->vol = NULL;
00170 *natoms = MOLFILE_NUMATOMS_NONE;
00171 dx->nsets = 1;
00172
00173 dx->vol = new molfile_volumetric_t[1];
00174 strcpy(dx->vol[0].dataname, "DX map");
00175
00176
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
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
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
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
00280
00281 static molfile_plugin_t plugin = {
00282 vmdplugin_ABIVERSION,
00283 MOLFILE_PLUGIN_TYPE,
00284 "dx",
00285 "DX",
00286 "Eamon Caddigan",
00287 0,
00288 6,
00289 VMDPLUGIN_THREADSAFE,
00290 "dx"
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