00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
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;
00103
00104 vol->vol = new molfile_volumetric_t[1];
00105 strcpy(vol->vol[0].dataname, "SPIDER map");
00106
00107
00108 if (fread(&h.cbuf, 1024, 1, fd) < 1) {
00109 printf("spiderplugin) failed to read file header\n");
00110 return NULL;
00111 }
00112
00113
00114
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
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
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
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
00200 fseek(fd, vol->headbyt, SEEK_SET);
00201
00202
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
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
00216 float vscale = vol->scale;
00217 if (vscale == 0.0)
00218 vscale = 1.0;
00219
00220
00221
00222
00223
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
00281 fread(datablock, total * sizeof(float), 1, fd);
00282
00283
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
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