Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

spiderplugin.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2016 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.17 $       $Date: 2016/11/28 05:01:54 $
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 
00084   /* file header buffer union */ 
00085   union buffer {
00086     float fbuf[256];  
00087     char  cbuf[1024];
00088   } h;
00089  
00090   fd = fopen(filepath, "rb");
00091   if (!fd) {
00092     fprintf(stderr, "spiderplugin) Error opening file.\n");
00093     return NULL;
00094   }
00095 
00096   /* allocate and initialize the spider structure */
00097   vol = new spider_t;
00098   vol->fd = fd;
00099   vol->vol = NULL;
00100   vol->byteswap = 0;
00101   *natoms = MOLFILE_NUMATOMS_NONE;
00102   vol->nsets = 1; /* this file contains only one data set */
00103 
00104   vol->vol = new molfile_volumetric_t[1];
00105   strcpy(vol->vol[0].dataname, "SPIDER map");
00106 
00107   // read SPIDER file header
00108   if (fread(&h.cbuf, 1024, 1, fd) < 1) {
00109     printf("spiderplugin) failed to read file header\n");
00110     return NULL; 
00111   } 
00112 
00113   // perform sanity checks on header values to see if we 
00114   // need to do byte swapping, or abort.
00115   vol->nslice   = (h.fbuf[0] < 0) ? -h.fbuf[0] : h.fbuf[0];
00116   vol->nrow     = h.fbuf[1];
00117   vol->nsam     = h.fbuf[11];
00118   total = vol->nslice * vol->nrow * vol->nsam;
00119 
00120   if (total <= 0 || 
00121       vol->nsam   <= 0 || vol->nsam   > 100000 ||
00122       vol->nrow   <= 0 || vol->nrow   > 100000 ||
00123       vol->nslice <= 0 || vol->nslice > 100000) { 
00124 
00125     printf("spiderplugin) Non-native endianness or unusual file detected\n");
00126 
00127     // byte swap the entire header in hopes of making sense of this gibberish
00128     vol->byteswap = 1;
00129     swap4_aligned(&h.fbuf, 256);
00130 
00131     vol->nslice   = (h.fbuf[0] < 0) ? -h.fbuf[0] : h.fbuf[0];
00132     vol->nrow     = h.fbuf[1];
00133     vol->nsam     = h.fbuf[11];
00134     total = vol->nslice * vol->nrow * vol->nsam;
00135 
00136     // check to see if we still have gibberish or not, bail out if we do.
00137     if (total <= 0 || 
00138       vol->nsam   <= 0 || vol->nsam   > 100000 ||
00139       vol->nrow   <= 0 || vol->nrow   > 100000 ||
00140       vol->nslice <= 0 || vol->nslice > 100000) { 
00141       printf("spiderplugin) bad header values in file fail sanity checks\n");
00142       delete [] vol->vol;
00143       delete vol;
00144       return NULL;
00145     }
00146   }
00147   if (vol->byteswap) {
00148     printf("spiderplugin) Enabling byte swapping\n");
00149   }
00150 
00151   vol->nlabel   = h.fbuf[3];
00152   vol->iform    = h.fbuf[4];
00153   vol->imami    = h.fbuf[5];
00154   vol->fmax     = h.fbuf[6];
00155   vol->fmin     = h.fbuf[7];
00156   vol->av       = h.fbuf[8];
00157   vol->sig      = h.fbuf[9];
00158   vol->headrec  = h.fbuf[12];
00159   vol->iangle   = h.fbuf[13];
00160   vol->phi      = h.fbuf[14];
00161   vol->theta    = h.fbuf[15];
00162   vol->gamma    = h.fbuf[16];
00163   vol->xoffset  = h.fbuf[17];
00164   vol->yoffset  = h.fbuf[18];
00165   vol->zoffset  = h.fbuf[19];
00166   vol->scale    = h.fbuf[20];
00167   vol->headbyt  = h.fbuf[21];
00168   vol->reclen   = h.fbuf[22];
00169   vol->nstack   = h.fbuf[23];
00170   vol->inuse    = h.fbuf[24];
00171   vol->maxim    = h.fbuf[25];
00172 
00173 printf("spider  nslice: %d\n", vol->nslice);
00174 printf("spider    nrow: %d\n", vol->nrow);
00175 printf("spider    nsam: %d\n", vol->nsam);
00176 printf("spider   iform: %d\n", vol->iform);
00177 printf("spider   scale: %f\n", vol->scale);
00178 printf("spider xoffset: %f\n", vol->xoffset);
00179 printf("spider yoffset: %f\n", vol->yoffset);
00180 printf("spider zoffset: %f\n", vol->zoffset);
00181 printf("spider     phi: %f\n", vol->phi);
00182 printf("spider   theta: %f\n", vol->theta);
00183 printf("spider   gamma: %f\n", vol->gamma);
00184 
00185   /* correct bad headbyt and reclen SPIDER files */
00186   if (vol->iform < 4 && (vol->reclen < (vol->nsam * 4)))
00187     vol->reclen = vol->nsam * 4; 
00188 
00189   int headrec = 1024 / vol->reclen;
00190   if (vol->reclen < 1024 && (1024 % (vol->reclen)) != 0)
00191      headrec++;
00192   int headbyt = headrec * vol->reclen;
00193  
00194   if (vol->iform < 4 && (vol->headbyt < headbyt))
00195     vol->headbyt = headbyt;
00196 
00197 printf("spider headbyt: %d\n", vol->headbyt);
00198 
00199   /* seek to data offset */
00200   fseek(fd, vol->headbyt, SEEK_SET);
00201 
00202   /* SPIDER files contain no color information */
00203   vol->vol[0].has_color = 0;
00204 
00205   vol->vol[0].xsize = vol->nsam;
00206   vol->vol[0].ysize = vol->nrow;
00207   vol->vol[0].zsize = vol->nslice;
00208 
00209   /* Set the unit cell origin and basis vectors */
00210   float vz[3] = {0.0, 0.0, 0.0};
00211   memcpy(vol->vol[0].xaxis, &vz, sizeof(vz));
00212   memcpy(vol->vol[0].yaxis, &vz, sizeof(vz));
00213   memcpy(vol->vol[0].zaxis, &vz, sizeof(vz));
00214 
00215   /* the scale value may be zero, if so, just reset to 1.0 */
00216   float vscale = vol->scale;
00217   if (vscale == 0.0) 
00218     vscale = 1.0;
00219 
00220   /* the data is stored in y/x/-z order and coordinate handedness  */
00221   /* we should probably rewrite the loader loop to shuffle x/y     */
00222   /* so that future conversions to other formats don't leave it in */
00223   /* an unusual packing order.  For now this works however         */
00224 
00225   float xlen = vscale * (vol->vol[0].ysize-1);
00226   float ylen = vscale * (vol->vol[0].xsize-1);
00227   float zlen = vscale * (vol->vol[0].zsize-1);
00228 
00229   vol->vol[0].xaxis[1] =  xlen;
00230   vol->vol[0].yaxis[0] =  ylen;
00231   vol->vol[0].zaxis[2] = -zlen;
00232 
00233   vol->vol[0].origin[0] = vol->yoffset - (0.5 * ylen);
00234   vol->vol[0].origin[1] = vol->xoffset - (0.5 * xlen);
00235   vol->vol[0].origin[2] = vol->zoffset + (0.5 * zlen);
00236 
00237 printf("spider final offset: (%f, %f, %f)\n",
00238   vol->vol[0].origin[0], vol->vol[0].origin[1], vol->vol[0].origin[2]);
00239 
00240 printf("spider final axes:\n");
00241 printf("  X (%f, %f, %f)\n",
00242   vol->vol[0].xaxis[0], 
00243   vol->vol[0].xaxis[1], 
00244   vol->vol[0].xaxis[2]);
00245 
00246 printf("  Y (%f, %f, %f)\n",
00247   vol->vol[0].yaxis[0], 
00248   vol->vol[0].yaxis[1], 
00249   vol->vol[0].yaxis[2]);
00250 
00251 printf("  Z (%f, %f, %f)\n",
00252   vol->vol[0].zaxis[0], 
00253   vol->vol[0].zaxis[1], 
00254   vol->vol[0].zaxis[2]);
00255 
00256   return vol;
00257 }
00258 
00259 static int read_spider_metadata(void *v, int *nsets, 
00260   molfile_volumetric_t **metadata) {
00261   spider_t *vol = (spider_t *)v;
00262   *nsets = vol->nsets;
00263   *metadata = vol->vol;  
00264 
00265   return MOLFILE_SUCCESS;
00266 }
00267 
00268 static int read_spider_data(void *v, int set, float *datablock,
00269                          float *colorblock) {
00270   spider_t *vol = (spider_t *)v;
00271   FILE *fd = vol->fd;
00272   int xsize, ysize, zsize, xysize, total;
00273 
00274   xsize = vol->vol[0].xsize;
00275   ysize = vol->vol[0].ysize;
00276   zsize = vol->vol[0].zsize;
00277   xysize = xsize * ysize;
00278   total = xysize * zsize;
00279 
00280   // Read the values from the file
00281   fread(datablock, total * sizeof(float), 1, fd);
00282 
00283   // perform byte swapping if necessary
00284   if (vol->byteswap) 
00285     swap4_aligned(datablock, total);
00286 
00287   return MOLFILE_SUCCESS;
00288 }
00289 
00290 static void close_spider_read(void *v) {
00291   spider_t *vol = (spider_t *)v;
00292   
00293   fclose(vol->fd);
00294   if (vol->vol != NULL)
00295     delete [] vol->vol; 
00296   delete vol;
00297 }
00298 
00299 /*
00300  * Initialization stuff here
00301  */
00302 static molfile_plugin_t plugin;
00303 
00304 VMDPLUGIN_API int VMDPLUGIN_init(void) {
00305   memset(&plugin, 0, sizeof(molfile_plugin_t));
00306   plugin.abiversion = vmdplugin_ABIVERSION;
00307   plugin.type = MOLFILE_PLUGIN_TYPE;
00308   plugin.name = "spider";
00309   plugin.prettyname = "SPIDER Density Map";
00310   plugin.author = "John Stone";
00311   plugin.majorv = 0;
00312   plugin.minorv = 7;
00313   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00314   plugin.filename_extension = "spi,spider";
00315   plugin.open_file_read = open_spider_read;
00316   plugin.read_volumetric_metadata = read_spider_metadata;
00317   plugin.read_volumetric_data = read_spider_data;
00318   plugin.close_file_read = close_spider_read;
00319   return VMDPLUGIN_SUCCESS;
00320 }
00321 
00322 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00323   (*cb)(v, (vmdplugin_t *)&plugin);
00324   return VMDPLUGIN_SUCCESS;
00325 }
00326 
00327 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00328 

Generated on Sat Aug 15 03:07:03 2020 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002