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.30 $       $Date: 2008/01/09 20:23:48 $
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-1);
00147   edm->vol[0].xaxis[1] = 0;
00148   edm->vol[0].xaxis[2] = 0;
00149 
00150   edm->vol[0].yaxis[0] = yaxis[0] * (ysize-1);
00151   edm->vol[0].yaxis[1] = yaxis[1] * (ysize-1);
00152   edm->vol[0].yaxis[2] = 0;
00153 
00154   edm->vol[0].zaxis[0] = zaxis[0] * (zsize-1);
00155   edm->vol[0].zaxis[1] = zaxis[1] * (zsize-1);
00156   edm->vol[0].zaxis[2] = zaxis[2] * (zsize-1);
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 
00282 VMDPLUGIN_API int VMDPLUGIN_init(void) { 
00283   memset(&plugin, 0, sizeof(molfile_plugin_t));
00284   plugin.abiversion = vmdplugin_ABIVERSION;
00285   plugin.type = MOLFILE_PLUGIN_TYPE;
00286   plugin.name = "edm";
00287   plugin.prettyname = "XPLOR Electron Density Map";
00288   plugin.author = "John Stone";
00289   plugin.majorv = 0;
00290   plugin.minorv = 7;
00291   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00292   plugin.filename_extension = "cns,edm,xplor";
00293   plugin.open_file_read = open_edm_read;
00294   plugin.read_volumetric_metadata = read_edm_metadata;
00295   plugin.read_volumetric_data = read_edm_data;
00296   plugin.close_file_read = close_edm_read;
00297   return VMDPLUGIN_SUCCESS; 
00298 }
00299 
00300 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00301   (*cb)(v, (vmdplugin_t *)&plugin);
00302   return VMDPLUGIN_SUCCESS;
00303 }
00304 
00305 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00306 
00307 
00308 
00309 #ifdef TEST_EDMPLUGIN
00310 
00311 int main(int argc, char *argv[]) {
00312   int natoms;
00313   void *v;
00314   int i, nsets, set;
00315   molfile_volumetric_t * meta;
00316 
00317   while (--argc) {
00318     ++argv;
00319     v = open_edm_read(*argv, "edm", &natoms);
00320     if (!v) {
00321       fprintf(stderr, "open_edm_read failed for file %s\n", *argv);
00322       return 1;
00323     }
00324 
00325     // try loading the EDM metadata now
00326     if (read_edm_metadata(v, &nsets, &meta)) {
00327       return 1; // failed to load edm file
00328     }
00329 
00330     for (set=0; set<nsets; set++) {
00331       printf("Loading volume set: %d\n", set);   
00332       
00333       int elements = meta[set].xsize * meta[set].ysize * meta[set].zsize;
00334       printf("   Grid Elements: %d\n", elements);
00335       printf(" Grid dimensions: X: %d Y: %d Z: %d\n", 
00336              meta[set].xsize, meta[set].ysize, meta[set].zsize);
00337 
00338       float * voldata = (float *) malloc(sizeof(float) * elements);
00339       float * coldata = NULL;
00340 
00341       if (meta[set].has_color) {
00342         coldata = (float *) malloc(sizeof(float) * elements * 3);
00343       }
00344 
00345       // try loading the EDM data sets now
00346       if (read_edm_data(v, set, voldata, coldata)) {
00347         return 1; // failed to load edm file
00348       }
00349 
00350       printf("First 6 elements:\n   ");
00351       for (i=0; i<6; i++) {
00352         printf("%g, ", voldata[i]);
00353       }
00354       printf("\n"); 
00355 
00356       printf("Last 6 elements:\n   ");
00357       for (i=elements - 6; i<elements; i++) {
00358         printf("%g, ", voldata[i]);
00359       }
00360       printf("\n"); 
00361     }
00362 
00363     close_edm_read(v);
00364   }
00365   return 0;
00366 }
00367 
00368 #endif
00369 
00370 
00371 
00372 

Generated on Sun Sep 7 01:39:29 2008 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002