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 int rc;
00084
00085
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
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;
00104
00105 vol->vol = new molfile_volumetric_t[1];
00106 strcpy(vol->vol[0].dataname, "SPIDER map");
00107
00108
00109 if (fread(&h.cbuf, 1024, 1, fd) < 1) {
00110 printf("spiderplugin) failed to read file header\n");
00111 return NULL;
00112 }
00113
00114
00115
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
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
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
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
00199 fseek(fd, vol->headbyt, SEEK_SET);
00200
00201
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
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
00215 float vscale = vol->scale;
00216 if (vscale == 0.0)
00217 vscale = 1.0;
00218
00219
00220
00221
00222
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
00280 fread(datablock, total * sizeof(float), 1, fd);
00281
00282
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
00300
00301 static molfile_plugin_t plugin = {
00302 vmdplugin_ABIVERSION,
00303 MOLFILE_PLUGIN_TYPE,
00304 "spider",
00305 "SPIDER Density Map",
00306 "John Stone",
00307 0,
00308 4,
00309 VMDPLUGIN_THREADSAFE,
00310 "spider"
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