00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <math.h>
00021 #include <string.h>
00022
00023 #include "molfile_plugin.h"
00024
00025 typedef struct {
00026 FILE *fd;
00027 int nsets;
00028 molfile_volumetric_t *vol;
00029 } edm_t;
00030
00031 static void eatline(FILE * fd) {
00032 char readbuf[1025];
00033 fgets(readbuf, 1024, fd);
00034 }
00035
00036 static void *open_edm_read(const char *filepath, const char *filetype,
00037 int *natoms) {
00038 FILE *fd;
00039 edm_t *edm;
00040 int ntitle, na, nb, nc, xsize, ysize, zsize;
00041 int amin, amax, bmin, bmax, cmin, cmax;
00042 float a, b, c, alpha, beta, gamma;
00043 float xdelta, ydelta, zdelta;
00044 float alpha1, beta1, gamma1;
00045 float xaxis[3], yaxis[3], zaxis[3], z1, z2, z3;
00046 int i, convcnt;
00047
00048 fd = fopen(filepath, "rb");
00049 if (!fd)
00050 return NULL;
00051
00052 edm = new edm_t;
00053 edm->fd = fd;
00054 edm->vol = NULL;
00055 *natoms = MOLFILE_NUMATOMS_NONE;
00056
00057 edm->vol = new molfile_volumetric_t[1];
00058
00059 edm->nsets = 1;
00060
00061
00062 eatline(edm->fd);
00063
00064 convcnt = fscanf(edm->fd, "%d", &ntitle);
00065 if (convcnt != 1) {
00066 printf("edmplugin: failed to read in title line count\n");
00067 fclose(edm->fd);
00068 delete [] edm->vol;
00069 delete edm;
00070 return NULL;
00071 }
00072
00073 eatline(edm->fd);
00074
00075
00076 for (i=0; i<ntitle; i++) {
00077 eatline(edm->fd);
00078 }
00079
00080
00081 convcnt = fscanf(edm->fd, "%d %d %d %d %d %d %d %d %d",
00082 &na, &amin, &amax, &nb, &bmin, &bmax, &nc, &cmin, &cmax);
00083 if (convcnt != 9) {
00084 printf("edmplugin: failed to read in box dimensions\n");
00085 fclose(edm->fd);
00086 delete [] edm->vol;
00087 delete edm;
00088 return NULL;
00089 }
00090
00091 eatline(edm->fd);
00092
00093
00094 xsize = amax - amin + 1;
00095 ysize = bmax - bmin + 1;
00096 zsize = cmax - cmin + 1;
00097 edm->vol[0].xsize = xsize;
00098 edm->vol[0].ysize = ysize;
00099 edm->vol[0].zsize = zsize;
00100 edm->vol[0].has_color = 0;
00101
00102
00103 convcnt = fscanf(edm->fd, "%f %f %f %f %f %f",
00104 &a, &b, &c, &alpha, &beta, &gamma);
00105 if (convcnt != 6) {
00106 printf("edmplugin: failed to read in box lengths and angles\n");
00107 fclose(edm->fd);
00108 delete [] edm->vol;
00109 delete edm;
00110 return NULL;
00111 }
00112 eatline(edm->fd);
00113
00114
00115 xdelta = a / (float) na;
00116 ydelta = b / (float) nb;
00117 zdelta = c / (float) nc;
00118
00119 strcpy(edm->vol[0].dataname, "X-PLOR Electron Density Map");
00120
00121
00122 alpha1 = 3.14159265358979323846 * alpha / 180.0;
00123 beta1 = 3.14159265358979323846 * beta / 180.0;
00124 gamma1 = 3.14159265358979323846 * gamma / 180.0;
00125
00126
00127 xaxis[0] = xdelta;
00128 xaxis[1] = 0;
00129 xaxis[2] = 0;
00130
00131 yaxis[0] = cos(gamma1) * ydelta;
00132 yaxis[1] = sin(gamma1) * ydelta;
00133 yaxis[2] = 0;
00134
00135 z1 = cos(beta1);
00136 z2 = (cos(alpha1) - cos(beta1)*cos(gamma1)) / sin(gamma1);
00137 z3 = sqrt(1.0 - z1*z1 - z2*z2);
00138 zaxis[0] = z1 * zdelta;
00139 zaxis[1] = z2 * zdelta;
00140 zaxis[2] = z3 * zdelta;
00141
00142 edm->vol[0].origin[0] = xaxis[0] * amin + yaxis[0] * bmin + zaxis[0] * cmin;
00143 edm->vol[0].origin[1] = yaxis[1] * bmin + zaxis[1] * cmin;
00144 edm->vol[0].origin[2] = zaxis[2] * cmin;
00145
00146 edm->vol[0].xaxis[0] = xaxis[0] * xsize;
00147 edm->vol[0].xaxis[1] = 0;
00148 edm->vol[0].xaxis[2] = 0;
00149
00150 edm->vol[0].yaxis[0] = yaxis[0] * ysize;
00151 edm->vol[0].yaxis[1] = yaxis[1] * ysize;
00152 edm->vol[0].yaxis[2] = 0;
00153
00154 edm->vol[0].zaxis[0] = zaxis[0] * zsize;
00155 edm->vol[0].zaxis[1] = zaxis[1] * zsize;
00156 edm->vol[0].zaxis[2] = zaxis[2] * zsize;
00157
00158
00159
00160 char planeorder[4];
00161 memset(planeorder, 0, sizeof(planeorder));
00162 convcnt = fscanf(edm->fd, "%3s", planeorder);
00163 if (convcnt != 1) {
00164 printf("edmplugin: failed to read in plane order\n");
00165 fclose(edm->fd);
00166 delete [] edm->vol;
00167 delete edm;
00168 return NULL;
00169 }
00170
00171 if (strcmp(planeorder, "ZYX")) {
00172 printf("edmplugin: unsupported plane ordering %s\n", planeorder);
00173 fclose(edm->fd);
00174 delete [] edm->vol;
00175 delete edm;
00176 return NULL;
00177 }
00178 eatline(edm->fd);
00179
00180 return edm;
00181 }
00182
00183 static int read_edm_metadata(void *v, int *nsets,
00184 molfile_volumetric_t **metadata) {
00185 edm_t *edm = (edm_t *)v;
00186 *nsets = edm->nsets;
00187 *metadata = edm->vol;
00188
00189 return MOLFILE_SUCCESS;
00190 }
00191
00192 static int read_edm_data(void *v, int set, float *datablock,
00193 float *colorblock) {
00194 edm_t *edm = (edm_t *)v;
00195 float * cell = datablock;
00196 int z, l, sentinel, convcnt;
00197 char readbuf[16];
00198
00199 int xsize = edm->vol[0].xsize;
00200 int ysize = edm->vol[0].ysize;
00201 int zsize = edm->vol[0].zsize;
00202
00203
00204 int nperslice = xsize * ysize;
00205 int nlines = (int)(nperslice / 6.0);
00206 if ((nlines * 6) < nperslice) {
00207 nlines++;
00208 }
00209 int leftover = (nperslice - (nlines - 1) * 6);
00210
00211 for (z=0; z<zsize; z++) {
00212 int c;
00213 eatline(edm->fd);
00214
00215 #if 1
00216
00217 for (c=0; c<nperslice; c++) {
00218 convcnt = fscanf(edm->fd, "%f", cell);
00219 if (convcnt != 1) {
00220 printf("edmplugin: failed reading cell data\n");
00221 printf("edmplugin: cell %d of %d, slice %d\n", c, nperslice, z);
00222 return MOLFILE_ERROR;
00223 }
00224 cell++;
00225 }
00226 eatline(edm->fd);
00227 #else
00228 for (l=1; l<nlines; l++) {
00229 for (c=0; c<6; c++) {
00230 fgets(readbuf, 13, edm->fd);
00231 convcnt = sscanf(readbuf, "%f", cell);
00232 if (convcnt != 1) {
00233 printf("edmplugin: failed reading cell data\n");
00234 printf("edmplugin: cell on line %d cell %d, of %d lines\n", l, c, nlines);
00235 return MOLFILE_ERROR;
00236 }
00237 cell++;
00238 }
00239 eatline(edm->fd);
00240 }
00241
00242
00243 if (leftover > 0) {
00244 for (c=0; c<leftover; c++) {
00245 fgets(readbuf, 13, edm->fd);
00246 convcnt = sscanf(readbuf, "%f", cell);
00247 if (convcnt != 1) {
00248 printf("edmplugin: failed reading partial line cell data\n");
00249 return MOLFILE_ERROR;
00250 }
00251 cell++;
00252 }
00253 }
00254 #endif
00255 }
00256
00257
00258 sentinel = 0;
00259 fgets(readbuf, 13, edm->fd);
00260 sscanf(readbuf, "%d", &sentinel);
00261 if (sentinel != -9999) {
00262 printf("edmplugin: EOF sentinel != -9999\n");
00263
00264 }
00265
00266 return MOLFILE_SUCCESS;
00267 }
00268
00269 static void close_edm_read(void *v) {
00270 edm_t *edm = (edm_t *)v;
00271
00272 fclose(edm->fd);
00273 delete [] edm->vol;
00274 delete edm;
00275 }
00276
00277
00278
00279
00280 static molfile_plugin_t plugin = {
00281 vmdplugin_ABIVERSION,
00282 MOLFILE_PLUGIN_TYPE,
00283 "edm",
00284 "XPLOR Electron Density Map",
00285 "John E. Stone",
00286 0,
00287 4,
00288 VMDPLUGIN_THREADSAFE,
00289 "edm"
00290 };
00291
00292 VMDPLUGIN_API int VMDPLUGIN_init(void) { return VMDPLUGIN_SUCCESS; }
00293 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00294 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00295 plugin.open_file_read = open_edm_read;
00296 plugin.read_volumetric_metadata = read_edm_metadata;
00297 plugin.read_volumetric_data = read_edm_data;
00298 plugin.close_file_read = close_edm_read;
00299 (*cb)(v, (vmdplugin_t *)&plugin);
00300 return VMDPLUGIN_SUCCESS;
00301 }
00302
00303
00304
00305 #ifdef TEST_EDMPLUGIN
00306
00307 int main(int argc, char *argv[]) {
00308 int natoms;
00309 void *v;
00310 int i, nsets, set;
00311 molfile_volumetric_t * meta;
00312
00313 while (--argc) {
00314 ++argv;
00315 v = open_edm_read(*argv, "edm", &natoms);
00316 if (!v) {
00317 fprintf(stderr, "open_edm_read failed for file %s\n", *argv);
00318 return 1;
00319 }
00320
00321
00322 if (read_edm_metadata(v, &nsets, &meta)) {
00323 return 1;
00324 }
00325
00326 for (set=0; set<nsets; set++) {
00327 printf("Loading volume set: %d\n", set);
00328
00329 int elements = meta[set].xsize * meta[set].ysize * meta[set].zsize;
00330 printf(" Grid Elements: %d\n", elements);
00331 printf(" Grid dimensions: X: %d Y: %d Z: %d\n",
00332 meta[set].xsize, meta[set].ysize, meta[set].zsize);
00333
00334 float * voldata = (float *) malloc(sizeof(float) * elements);
00335 float * coldata = NULL;
00336
00337 if (meta[set].has_color) {
00338 coldata = (float *) malloc(sizeof(float) * elements * 3);
00339 }
00340
00341
00342 if (read_edm_data(v, set, voldata, coldata)) {
00343 return 1;
00344 }
00345
00346 printf("First 6 elements:\n ");
00347 for (i=0; i<6; i++) {
00348 printf("%g, ", voldata[i]);
00349 }
00350 printf("\n");
00351
00352 printf("Last 6 elements:\n ");
00353 for (i=elements - 6; i<elements; i++) {
00354 printf("%g, ", voldata[i]);
00355 }
00356 printf("\n");
00357 }
00358
00359 close_edm_read(v);
00360 }
00361 return 0;
00362 }
00363
00364 #endif
00365
00366
00367
00368