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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <stdlib.h>
00038 #include <stdio.h>
00039 #include <ctype.h>
00040 #include <math.h>
00041 #include <string.h>
00042
00043 #if defined(_AIX)
00044 #include <strings.h>
00045 #endif
00046
00047 #include "molfile_plugin.h"
00048 #include "endianswap.h"
00049
00050 typedef struct {
00051 FILE *fd;
00052 int nsets;
00053 int ndata;
00054 int nclx;
00055 int ncly;
00056 int nclz;
00057 int swap;
00058 molfile_volumetric_t *vol;
00059 } pbeq_t;
00060
00061
00062 static void *open_pbeq_read(const char *filepath, const char *filetype,
00063 int *natoms) {
00064 FILE *fd;
00065 pbeq_t *pbeq;
00066 int nclx, ncly, nclz;
00067 int trash, length;
00068 double dcel;
00069 double xbcen, ybcen, zbcen;
00070 double epsw, epsp, conc, tmemb, zmemb, epsm;
00071 int swap=0;
00072
00073 fd = fopen(filepath, "rb");
00074 if (!fd) {
00075 printf("pbeqplugin) Error opening file %s.\n", filepath);
00076 return NULL;
00077 }
00078
00079
00080
00081 if (fread(&length, 4, 1, fd) != 1)
00082 return NULL;
00083
00084 if (fread(&nclx, 4, 1, fd) != 1)
00085 return NULL;
00086 if (fread(&ncly, 4, 1, fd) != 1)
00087 return NULL;
00088 if (fread(&nclz, 4, 1, fd) != 1)
00089 return NULL;
00090
00091
00092 if (length != 44) {
00093 swap = 1;
00094 swap4_aligned(&length, 1);
00095 if (length != 44) {
00096 printf("pbeqplugin) length record != 44, unrecognized format (length: %d)\n", length);
00097 return NULL;
00098 }
00099 }
00100
00101 if (swap) {
00102 swap4_aligned(&nclx, 1);
00103 swap4_aligned(&ncly, 1);
00104 swap4_aligned(&nclz, 1);
00105 }
00106
00107
00108
00109
00110
00111 if ((nclx > 4000 && ncly > 4000 && nclz > 4000) ||
00112 (nclx * ncly * nclz < 0)) {
00113 printf("pbeqplugin) inconclusive byte ordering, bailing out\n");
00114 return NULL;
00115 }
00116
00117
00118 if (fread(&dcel, 8, 1, fd) != 1)
00119 return NULL;
00120 if (fread(&xbcen, 8, 1, fd) != 1)
00121 return NULL;
00122 if (fread(&ybcen, 8, 1, fd) != 1)
00123 return NULL;
00124 if (fread(&zbcen, 8, 1, fd) != 1)
00125 return NULL;
00126
00127
00128
00129 if (fread(&trash, 4, 1, fd) != 1)
00130 return NULL;
00131
00132
00133
00134 if (fread(&trash, 4, 1, fd) != 1)
00135 return NULL;
00136
00137 if (fread(&epsw, 8, 1, fd) != 1)
00138 return NULL;
00139 if (fread(&epsp, 8, 1, fd) != 1)
00140 return NULL;
00141 if (fread(&conc, 8, 1, fd) != 1)
00142 return NULL;
00143 if (fread(&tmemb, 8, 1, fd) != 1)
00144 return NULL;
00145 if (fread(&zmemb, 8, 1, fd) != 1)
00146 return NULL;
00147 if (fread(&epsm, 8, 1, fd) != 1)
00148 return NULL;
00149
00150
00151
00152 if (fread(&trash, 4, 1, fd) != 1)
00153 return NULL;
00154
00155
00156 if (swap) {
00157 swap8_aligned(&dcel, 1);
00158 swap8_aligned(&xbcen, 1);
00159 swap8_aligned(&ybcen, 1);
00160 swap8_aligned(&zbcen, 1);
00161 swap8_aligned(&epsw, 1);
00162 swap8_aligned(&epsp, 1);
00163 swap8_aligned(&conc, 1);
00164 swap8_aligned(&tmemb, 1);
00165 swap8_aligned(&zmemb, 1);
00166 swap8_aligned(&epsm, 1);
00167 }
00168
00169 #if 0
00170
00171 printf("pbeqplugin) nclx:%d nxly:%d nclz:%d\n", nclx, ncly, nclz);
00172 printf("pbeqplugin) dcel: %f\n", dcel);
00173 printf("pbeqplugin) x/y/zbcen: %g %g %g\n", xbcen, ybcen, zbcen);
00174 printf("pbeqplugin) epsw/p: %g %g conc: %g tmemb: %g zmemb: %g epsm: %g\n",
00175 epsw, epsp, conc, tmemb, zmemb, epsm);
00176 #endif
00177
00178
00179 pbeq = new pbeq_t;
00180 pbeq->fd = fd;
00181 pbeq->vol = NULL;
00182 *natoms = MOLFILE_NUMATOMS_NONE;
00183 pbeq->nsets = 1;
00184 pbeq->ndata = nclx*ncly*nclz;
00185 pbeq->nclx = nclx;
00186 pbeq->ncly = ncly;
00187 pbeq->nclz = nclz;
00188 pbeq->swap = swap;
00189
00190 pbeq->vol = new molfile_volumetric_t[1];
00191 strcpy(pbeq->vol[0].dataname, "CHARMM PBEQ Potential Map");
00192
00193 pbeq->vol[0].origin[0] = -0.5*((nclx-1) * dcel) + xbcen;
00194 pbeq->vol[0].origin[1] = -0.5*((ncly-1) * dcel) + ybcen;
00195 pbeq->vol[0].origin[2] = -0.5*((nclz-1) * dcel) + zbcen;
00196
00197
00198 printf("pbeqplugin) box LL origin: %g %g %g\n",
00199 pbeq->vol[0].origin[0],
00200 pbeq->vol[0].origin[1],
00201 pbeq->vol[0].origin[2]);
00202
00203 pbeq->vol[0].xaxis[0] = (nclx-1) * dcel;
00204 pbeq->vol[0].xaxis[1] = 0;
00205 pbeq->vol[0].xaxis[2] = 0;
00206
00207 pbeq->vol[0].yaxis[0] = 0;
00208 pbeq->vol[0].yaxis[1] = (ncly-1) * dcel;
00209 pbeq->vol[0].yaxis[2] = 0;
00210
00211 pbeq->vol[0].zaxis[0] = 0;
00212 pbeq->vol[0].zaxis[1] = 0;
00213 pbeq->vol[0].zaxis[2] = (nclz-1) * dcel;
00214
00215 pbeq->vol[0].xsize = nclx;
00216 pbeq->vol[0].ysize = ncly;
00217 pbeq->vol[0].zsize = nclz;
00218
00219 pbeq->vol[0].has_color = 0;
00220
00221 return pbeq;
00222 }
00223
00224 static int read_pbeq_metadata(void *v, int *nsets,
00225 molfile_volumetric_t **metadata) {
00226 pbeq_t *pbeq = (pbeq_t *)v;
00227 *nsets = pbeq->nsets;
00228 *metadata = pbeq->vol;
00229
00230 return MOLFILE_SUCCESS;
00231 }
00232
00233 static int read_pbeq_data(void *v, int set, float *datablock,
00234 float *colorblock) {
00235 pbeq_t *pbeq = (pbeq_t *)v;
00236 int ndata = pbeq->ndata;
00237 int nclx = pbeq->nclx;
00238 int ncly = pbeq->ncly;
00239 int nclz = pbeq->nclz;
00240 FILE *fd = pbeq->fd;
00241 int trash;
00242
00243
00244
00245 if (fread(&trash, 4, 1, fd) != 1)
00246 return MOLFILE_ERROR;
00247
00248
00249 int x, y, z;
00250 int count=0;
00251 for (x=0; x<nclx; x++) {
00252 for (y=0; y<ncly; y++) {
00253 for (z=0; z<nclz; z++) {
00254 int addr = z*nclx*ncly + y*nclx + x;
00255 if (fread(datablock + addr, 4, 1, fd) != 1) {
00256 printf("pbeqplugin) Error reading potential map cell: %d,%d,%d\n", x, y, z);
00257 printf("pbeqplugin) offset: %d\n", (int) ftell(fd));
00258 return MOLFILE_ERROR;
00259 }
00260 count++;
00261 }
00262 }
00263 }
00264
00265
00266 #if 0
00267
00268
00269 if (fread(&trash, 4, 1, fd) != 1)
00270 return NULL;
00271
00272
00273 printf("pbeqplugin) read %d phi values from block\n", count);
00274 for (x=0; x<1000000; x++) {
00275 int trash;
00276 if (fread(&trash, 4, 1, fd) != 1) {
00277 printf("pbeqplugin) read %d extra phi values past the end of the block\n", x);
00278 break;
00279 }
00280 }
00281 #endif
00282
00283 if (pbeq->swap) {
00284 swap4_aligned(datablock, ndata);
00285 }
00286
00287 return MOLFILE_SUCCESS;
00288 }
00289
00290 static void close_pbeq_read(void *v) {
00291 pbeq_t *pbeq = (pbeq_t *)v;
00292
00293 fclose(pbeq->fd);
00294 if (pbeq->vol != NULL)
00295 delete [] pbeq->vol;
00296 delete pbeq;
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 = "pbeq";
00309 plugin.prettyname = "CHARMM PBEQ Binary Potential Map";
00310 plugin.author = "John Stone";
00311 plugin.majorv = 0;
00312 plugin.minorv = 4;
00313 plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00314 plugin.filename_extension = "pbeq, phi80";
00315 plugin.open_file_read = open_pbeq_read;
00316 plugin.read_volumetric_metadata = read_pbeq_metadata;
00317 plugin.read_volumetric_data = read_pbeq_data;
00318 plugin.close_file_read = close_pbeq_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