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

spiderplugin.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: spiderplugin.C,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.9 $       $Date: 2006/03/21 08:19:25 $
00015  *
00016  ***************************************************************************/
00017 
00018 /* 
00019  * SPIDER volumetric image datasets
00020  *   http://www.wadsworth.org/spider_doc/spider/docs/image_doc.html
00021  *
00022  * TODO:
00023  *  - Add code to determine axis scaling factors, axis angles, offsets, etc
00024  */
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <ctype.h>
00029 #include <math.h>
00030 #include <string.h>
00031 #include "endianswap.h"
00032 
00033 #if defined(_AIX)
00034 #include <strings.h>
00035 #endif
00036 
00037 #if defined(WIN32) || defined(WIN64)
00038 #define strcasecmp  stricmp
00039 #define strncasecmp strnicmp
00040 #endif
00041 
00042 #include "molfile_plugin.h"
00043 
00044 #define LINESIZE 85
00045 
00046 typedef struct {
00047   FILE *fd;
00048   int nsets;
00049   molfile_volumetric_t *vol;
00050   int byteswap;
00051   int nslice;
00052   int nrow;
00053   int nlabel;
00054   int iform;
00055   int imami;
00056   float fmax;
00057   float fmin;
00058   float av;
00059   float sig;
00060   int nsam;
00061   int headrec;
00062   int iangle;
00063   float phi;
00064   float theta;
00065   float gamma;
00066   float xoffset;
00067   float yoffset;
00068   float zoffset;
00069   float scale;
00070   int headbyt;
00071   int reclen;
00072   int nstack;
00073   int inuse;
00074   int maxim; 
00075 } spider_t;
00076 
00077 
00078 static void *open_spider_read(const char *filepath, const char *filetype,
00079     int *natoms) {
00080   FILE *fd;
00081   spider_t *vol;
00082   int total;
00083   int rc;
00084 
00085   /* file header buffer union */ 
00086   union buffer {
00087     float fbuf[256];  
00088     char  cbuf[1024];
00089   } h;
00090  
00091   fd = fopen(filepath, "rb");
00092   if (!fd) {
00093     fprintf(stderr, "Error opening file.\n");
00094     return NULL;
00095   }
00096 
00097   /* allocate and initialize the spider structure */
00098   vol = new spider_t;
00099   vol->fd = fd;
00100   vol->vol = NULL;
00101   vol->byteswap = 0;
00102   *natoms = MOLFILE_NUMATOMS_NONE;
00103   vol->nsets = 1; /* this file contains only one data set */
00104 
00105   vol->vol = new molfile_volumetric_t[1];
00106   strcpy(vol->vol[0].dataname, "SPIDER map");
00107 
00108   // read SPIDER file header
00109   if (fread(&h.cbuf, 1024, 1, fd) < 1) {
00110     printf("spiderplugin) failed to read file header\n");
00111     return NULL; 
00112   } 
00113 
00114   // perform sanity checks on header values to see if we 
00115   // need to do byte swapping, or abort.
00116   vol->nslice   = (h.fbuf[0] < 0) ? -h.fbuf[0] : h.fbuf[0];
00117   vol->nrow     = h.fbuf[1];
00118   vol->nsam     = h.fbuf[11];
00119   total = vol->nslice * vol->nrow * vol->nsam;
00120 
00121   if (total <= 0 || 
00122       vol->nsam   <= 0 || vol->nsam   > 100000 ||
00123       vol->nrow   <= 0 || vol->nrow   > 100000 ||
00124       vol->nslice <= 0 || vol->nslice > 100000) { 
00125 
00126     printf("spiderplugin) Non-native endianness or unusual file detected\n");
00127 
00128     // byte swap the entire header in hopes of making sense of this gibberish
00129     vol->byteswap = 1;
00130     swap4_aligned(&h.fbuf, 256);
00131 
00132     vol->nslice   = (h.fbuf[0] < 0) ? -h.fbuf[0] : h.fbuf[0];
00133     vol->nrow     = h.fbuf[1];
00134     vol->nsam     = h.fbuf[11];
00135     total = vol->nslice * vol->nrow * vol->nsam;
00136 
00137     // check to see if we still have gibberish or not, bail out if we do.
00138     if (total <= 0 || 
00139       vol->nsam   <= 0 || vol->nsam   > 100000 ||
00140       vol->nrow   <= 0 || vol->nrow   > 100000 ||
00141       vol->nslice <= 0 || vol->nslice > 100000) { 
00142       printf("spiderplugin) bad header values in file fail sanity checks\n");
00143       delete [] vol->vol;
00144       delete vol;
00145       return NULL;
00146     }
00147   }
00148   if (vol->byteswap) {
00149     printf("spiderplugin) Enabling byte swapping\n");
00150   }
00151 
00152   vol->nlabel   = h.fbuf[3];
00153   vol->iform    = h.fbuf[4];
00154   vol->imami    = h.fbuf[5];
00155   vol->fmax     = h.fbuf[6];
00156   vol->fmin     = h.fbuf[7];
00157   vol->av       = h.fbuf[8];
00158   vol->sig      = h.fbuf[9];
00159   vol->headrec  = h.fbuf[12];
00160   vol->iangle   = h.fbuf[13];
00161   vol->phi      = h.fbuf[14];
00162   vol->theta    = h.fbuf[15];
00163   vol->gamma    = h.fbuf[16];
00164   vol->xoffset  = h.fbuf[17];
00165   vol->yoffset  = h.fbuf[18];
00166   vol->zoffset  = h.fbuf[19];
00167   vol->scale    = h.fbuf[20];
00168   vol->headbyt  = h.fbuf[21];
00169   vol->reclen   = h.fbuf[22];
00170   vol->nstack   = h.fbuf[23];
00171   vol->inuse    = h.fbuf[24];
00172   vol->maxim    = h.fbuf[25];
00173 
00174 printf("spider  nslice: %d\n", vol->nslice);
00175 printf("spider    nrow: %d\n", vol->nrow);
00176 printf("spider    nsam: %d\n", vol->nsam);
00177 printf("spider   iform: %d\n", vol->iform);
00178 printf("spider   scale: %f\n", vol->scale);
00179 printf("spider xoffset: %f\n", vol->xoffset);
00180 printf("spider yoffset: %f\n", vol->yoffset);
00181 printf("spider zoffset: %f\n", vol->zoffset);
00182 printf("spider    phi: %f\n", vol->phi);
00183 printf("spider  theta: %f\n", vol->theta);
00184 printf("spider  gamma: %f\n", vol->gamma);
00185 
00186   /* correct bad headbyt and reclen SPIDER files */
00187   if (vol->iform < 4 && (vol->reclen < (vol->nsam * 4)))
00188     vol->reclen = vol->nsam * 4; 
00189 
00190   int headrec = 1024 / vol->reclen;
00191   if (vol->reclen < 1024 && (1024 % (vol->reclen)) != 0)
00192      headrec++;
00193   int headbyt = headrec * vol->reclen;
00194  
00195   if (vol->iform < 4 && (vol->headbyt < headbyt))
00196     vol->headbyt = headbyt;
00197 
00198   /* seek to data offset */
00199   fseek(fd, vol->headbyt, SEEK_SET);
00200 
00201   /* SPIDER files contain no color information */
00202   vol->vol[0].has_color = 0;
00203 
00204   vol->vol[0].xsize = vol->nsam;
00205   vol->vol[0].ysize = vol->nrow;
00206   vol->vol[0].zsize = vol->nslice;
00207 
00208   /* Set the unit cell origin and basis vectors */
00209   float vz[3] = {0.0, 0.0, 0.0};
00210   memcpy(vol->vol[0].xaxis, &vz, sizeof(vz));
00211   memcpy(vol->vol[0].yaxis, &vz, sizeof(vz));
00212   memcpy(vol->vol[0].zaxis, &vz, sizeof(vz));
00213 
00214   /* the scale value may be zero, if so, just reset to 1.0 */
00215   float vscale = vol->scale;
00216   if (vscale == 0.0) 
00217     vscale = 1.0;
00218 
00219   /* the data is stored in y/x/-z order and coordinate handedness  */
00220   /* we should probably rewrite the loader loop to shuffle x/y     */
00221   /* so that future conversions to other formats don't leave it in */
00222   /* an unusual packing order.  For now this works however         */
00223 
00224   float xlen = vscale * (vol->vol[0].ysize-1);
00225   float ylen = vscale * (vol->vol[0].xsize-1);
00226   float zlen = vscale * (vol->vol[0].zsize-1);
00227 
00228   vol->vol[0].xaxis[1] =  xlen;
00229   vol->vol[0].yaxis[0] =  ylen;
00230   vol->vol[0].zaxis[2] = -zlen;
00231 
00232   vol->vol[0].origin[0] = vol->yoffset - (0.5 * ylen);
00233   vol->vol[0].origin[1] = vol->xoffset - (0.5 * xlen);
00234   vol->vol[0].origin[2] = vol->zoffset + (0.5 * zlen);
00235 
00236 printf("spider final offset: (%f, %f, %f)\n",
00237   vol->vol[0].origin[0], vol->vol[0].origin[1], vol->vol[0].origin[2]);
00238 
00239 printf("spider final axes:\n");
00240 printf("  X (%f, %f, %f)\n",
00241   vol->vol[0].xaxis[0], 
00242   vol->vol[0].xaxis[1], 
00243   vol->vol[0].xaxis[2]);
00244 
00245 printf("  Y (%f, %f, %f)\n",
00246   vol->vol[0].yaxis[0], 
00247   vol->vol[0].yaxis[1], 
00248   vol->vol[0].yaxis[2]);
00249 
00250 printf("  Z (%f, %f, %f)\n",
00251   vol->vol[0].zaxis[0], 
00252   vol->vol[0].zaxis[1], 
00253   vol->vol[0].zaxis[2]);
00254 
00255   return vol;
00256 }
00257 
00258 static int read_spider_metadata(void *v, int *nsets, 
00259   molfile_volumetric_t **metadata) {
00260   spider_t *vol = (spider_t *)v;
00261   *nsets = vol->nsets;
00262   *metadata = vol->vol;  
00263 
00264   return MOLFILE_SUCCESS;
00265 }
00266 
00267 static int read_spider_data(void *v, int set, float *datablock,
00268                          float *colorblock) {
00269   spider_t *vol = (spider_t *)v;
00270   FILE *fd = vol->fd;
00271   int x, y, z, xsize, ysize, zsize, xysize, total;
00272 
00273   xsize = vol->vol[0].xsize;
00274   ysize = vol->vol[0].ysize;
00275   zsize = vol->vol[0].zsize;
00276   xysize = xsize * ysize;
00277   total = xysize * zsize;
00278 
00279   // Read the values from the file
00280   fread(datablock, total * sizeof(float), 1, fd);
00281 
00282   // perform byte swapping if necessary
00283   if (vol->byteswap) 
00284     swap4_aligned(datablock, total);
00285 
00286   return MOLFILE_SUCCESS;
00287 }
00288 
00289 static void close_spider_read(void *v) {
00290   spider_t *vol = (spider_t *)v;
00291   
00292   fclose(vol->fd);
00293   if (vol->vol != NULL)
00294     delete [] vol->vol; 
00295   delete vol;
00296 }
00297 
00298 /*
00299  * Initialization stuff here
00300  */
00301 static molfile_plugin_t plugin = {
00302   vmdplugin_ABIVERSION,   /* ABI version */
00303   MOLFILE_PLUGIN_TYPE,    /* plugin type */
00304   "spider",               /* short file format description */
00305   "SPIDER Density Map",   /* pretty file format description */
00306   "John Stone",           /* author(s) */
00307   0,                      /* major version */
00308   4,                      /* minor version */
00309   VMDPLUGIN_THREADSAFE,   /* is reentrant */
00310   "spider"                /* filename extension */
00311 };
00312 
00313 VMDPLUGIN_API int VMDPLUGIN_init(void) { return VMDPLUGIN_SUCCESS; }
00314 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00315 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00316   plugin.open_file_read = open_spider_read;
00317   plugin.read_volumetric_metadata = read_spider_metadata;
00318   plugin.read_volumetric_data = read_spider_data;
00319   plugin.close_file_read = close_spider_read;
00320   (*cb)(v, (vmdplugin_t *)&plugin);
00321   return VMDPLUGIN_SUCCESS;
00322 }
00323 

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