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

edmplugin.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: edmplugin.C,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.25 $       $Date: 2006/02/23 19:36:44 $
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);    // go on to next line
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; // this EDM file contains only one data set
00060 
00061   // read in EDM file header information
00062   eatline(edm->fd);               // skip first header line 
00063 
00064   convcnt = fscanf(edm->fd, "%d", &ntitle); // read number of title lines
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);               // go on to next line
00074 
00075   // skip past title and comment lines in header
00076   for (i=0; i<ntitle; i++) {
00077     eatline(edm->fd);             // skip a line
00078   }
00079 
00080   // read in the box dimensions and grid spacing deltas
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);               // go on to next line
00092   
00093   // calculate number of samples in each dimension
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   // read in 6 values for unit cell box orientation 
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);               // go on to next line
00113 
00114   // find box coordinates 
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   // convert degrees to radians
00122   alpha1 = 3.14159265358979323846 * alpha / 180.0;
00123   beta1  = 3.14159265358979323846 *  beta / 180.0;
00124   gamma1 = 3.14159265358979323846 * gamma / 180.0;
00125 
00126   // calculate non-orthogonal unit cell coordinates
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   // Check that the EDM file is stored in the "ZYX" format we expect,
00159   // and return NULL if it is not a supported file type.
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);               // go on to next line
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   // number of lines of text per slice
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);                // Eat the Z-plane index and throw away
00214 
00215 #if 1
00216     // read one plane of data, once cell at a time
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; // bad file format encountered
00223       }
00224       cell++;
00225     }
00226     eatline(edm->fd);                // go on to next line
00227 #else
00228     for (l=1; l<nlines; l++) {
00229       for (c=0; c<6; c++) {
00230         fgets(readbuf, 13, edm->fd); // read in 12 chars (fgets reads N-1)
00231         convcnt = sscanf(readbuf, "%f", cell); // convert ascii to float
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; // bad file format encountered
00236         }
00237         cell++;
00238       }
00239       eatline(edm->fd);              // go on to next line
00240     }
00241 
00242     // read any remaining partial line of text for this plane.
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; // bad file format encountered
00250         }
00251         cell++;
00252       }
00253     } 
00254 #endif
00255   }
00256 
00257   // read the -9999 end-of-file sentinel record
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     // return MOLFILE_ERROR; // bad file format encountered, no sentinel record
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  * Initialization stuff here
00279  */
00280 static molfile_plugin_t plugin = {
00281   vmdplugin_ABIVERSION,         // ABI version
00282   MOLFILE_PLUGIN_TYPE,          // plugin type
00283   "edm",                        // file format description
00284   "XPLOR Electron Density Map", // file format description
00285   "John E. Stone",              // author(s)
00286   0,                            // major version
00287   4,                            // minor version
00288   VMDPLUGIN_THREADSAFE,         // is reentrant
00289   "edm"                         // filename extension
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     // try loading the EDM metadata now
00322     if (read_edm_metadata(v, &nsets, &meta)) {
00323       return 1; // failed to load edm file
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       // try loading the EDM data sets now
00342       if (read_edm_data(v, set, voldata, coldata)) {
00343         return 1; // failed to load edm file
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 

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