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 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <ctype.h>
00037 #include <string.h>
00038
00039 #if defined(_AIX)
00040 #include <strings.h>
00041 #endif
00042
00043 #if defined(WIN32) || defined(WIN64)
00044 #define strcasecmp stricmp
00045 #define strncasecmp strnicmp
00046 #endif
00047
00048 #include "molfile_plugin.h"
00049
00050 #define LINESIZE 256
00051
00052 typedef struct {
00053 char filename[256];
00054 int filetype, skip, offset, stride;
00055 } datasource_t;
00056
00057 typedef struct {
00058 int nsets;
00059 molfile_volumetric_t *vol;
00060 datasource_t *data;
00061 } avsfield_t;
00062
00063 enum {NONE, ASCII, BINARY, UNFORMATTED};
00064 enum {UNIFORM, IRREGULAR, RECTILINEAR};
00065 enum {AVSFLOAT};
00066
00067
00068
00069
00070
00071 static char *get_string(char *s, int n, FILE *stream) {
00072 do {
00073 if (fgets(s, n, stream) == NULL) {
00074 fprintf(stderr, "avsplugin) Error reading string.\n");
00075 return NULL;
00076 }
00077 } while (s[0] == '#');
00078 return s;
00079 }
00080
00081
00082
00083
00084 static int read_datasource(char *s, datasource_t *data) {
00085 char *src, *tok, *value;
00086 src = strdup(s);
00087 tok = strtok(src, " \t\n");
00088
00089
00090 data->skip = 0;
00091 data->offset = 0;
00092 data->stride = 1;
00093
00094
00095 data->filename[0] = '\0';
00096 data->filetype = NONE;
00097
00098
00099 if ( (strcasecmp(tok, "coord") != 0) && (strcasecmp(tok, "variable") != 0) ) {
00100 fprintf(stderr, "avsplugin) Improperly formatted header: expected coord or variable.\n");
00101 free(src);
00102 return 1;
00103 }
00104
00105
00106 tok = strtok(NULL, " \t\n");
00107 if (!isdigit(*tok)) {
00108 fprintf(stderr, "avsplugin) Improperly formatted header: expected ID.\n");
00109 free(src);
00110 return 1;
00111 }
00112
00113
00114 tok = strtok(NULL, " \t\n");
00115 while(tok) {
00116 value = strchr(tok, '=');
00117 if (!value) {
00118 fprintf(stderr, "avsplugin) Error reading value.\n");
00119 free(src);
00120 return 1;
00121 }
00122 value++;
00123
00124 if (strncasecmp(tok, "file=", value - tok) == 0) {
00125
00126 strcpy(data->filename, value);
00127 }
00128 else if (strncasecmp(tok, "filetype=", value - tok) == 0) {
00129
00130
00131
00132
00133 if (strcasecmp(value, "ascii") == 0) {
00134 data->filetype = ASCII;
00135 }
00136 else {
00137 fprintf(stderr, "avsplugin) Non-ASCII files are not supported.\n");
00138 free(src);
00139 return 1;
00140 }
00141 }
00142 else if (strncasecmp(tok, "skip=", value - tok) == 0) {
00143
00144 data->skip = atoi(value);
00145 }
00146 else if (strncasecmp(tok, "offset=", value - tok) == 0) {
00147
00148 data->offset = atoi(value);
00149 }
00150 else if (strncasecmp(tok, "stride=", value - tok) == 0) {
00151
00152
00153 data->stride = atoi(value);
00154 }
00155 else {
00156
00157
00158
00159 fprintf(stderr, "avsplugin) Unrecognized argument.\n");
00160 free(src);
00161 return 1;
00162 }
00163
00164 tok = strtok(NULL, " \t\n");
00165 }
00166
00167 free(src);
00168
00169
00170 if ((data->filename[0] == '\0') || (data->filetype == NONE)) {
00171 fprintf(stderr, "avsplugin) Filename not set in options.\n");
00172 return 1;
00173 }
00174
00175 return 0;
00176 }
00177
00178 static void *open_avsfield_read(const char *filepath, const char *filetype, int *natoms) {
00179 avsfield_t *avsfield;
00180 FILE *fd;
00181 char inbuf[LINESIZE], current_file[256];
00182 int ndim, nspace, veclen, xsize, ysize, zsize,
00183 index, i, coord_count, var_count;
00184 float value, origin[3], gridlength[3];
00185 datasource_t *coord = NULL, *variable = NULL;
00186
00187 fd = fopen(filepath, "rb");
00188 if (!fd) {
00189 fprintf(stderr, "avsplugin) Error opening file.\n");
00190 return NULL;
00191 }
00192
00193
00194 if (fgets(inbuf, LINESIZE, fd) == NULL) {
00195 fclose(fd);
00196 fprintf(stderr, "avsplugin) Error reading line.\n");
00197 return NULL;
00198 }
00199 if (strncmp(inbuf, "# AVS", 5) != 0) {
00200 fclose(fd);
00201 fprintf(stderr, "avsplugin) Improperly formatted header.\n");
00202 return NULL;
00203 }
00204
00205
00206 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00207 fclose(fd);
00208 return NULL;
00209 }
00210 if (sscanf(inbuf, "ndim=%d", &ndim) != 1) {
00211 fprintf(stderr, "avsplugin) Error reading ndim.\n");
00212 fclose(fd);
00213 return NULL;
00214 }
00215 if (ndim != 3) {
00216 fprintf(stderr, "avsplugin) Error: ndim must be 3.\n");
00217 fclose(fd);
00218 return NULL;
00219 }
00220
00221
00222 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00223 fclose(fd);
00224 return NULL;
00225 }
00226 if (sscanf(inbuf, "dim1=%d", &xsize) != 1) {
00227 fprintf(stderr, "avsplugin) Error reading dim1.\n");
00228 fclose(fd);
00229 return NULL;
00230 }
00231 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00232 fclose(fd);
00233 return NULL;
00234 }
00235 if (sscanf(inbuf, "dim2=%d", &ysize) != 1) {
00236 fprintf(stderr, "avsplugin) Error reading dim2.\n");
00237 fclose(fd);
00238 return NULL;
00239 }
00240 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00241 fclose(fd);
00242 return NULL;
00243 }
00244 if (sscanf(inbuf, "dim3=%d", &zsize) != 1) {
00245 fprintf(stderr, "avsplugin) Error reading dim3.\n");
00246 fclose(fd);
00247 return NULL;
00248 }
00249
00250
00251 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00252 fclose(fd);
00253 return NULL;
00254 }
00255 if (sscanf(inbuf, "nspace=%d", &nspace) != 1) {
00256 fprintf(stderr, "avsplugin) Error reading nspace.\n");
00257 fclose(fd);
00258 return NULL;
00259 }
00260 if (nspace != 3) {
00261 fprintf(stderr, "avsplugin) Error: nspace must be 3.\n");
00262 fclose(fd);
00263 return NULL;
00264 }
00265
00266
00267
00268 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00269 fclose(fd);
00270 return NULL;
00271 }
00272 if (sscanf(inbuf, "veclen=%d", &veclen) != 1) {
00273 fprintf(stderr, "avsplugin) Error reading veclen.\n");
00274 fclose(fd);
00275 return NULL;
00276 }
00277
00278
00279 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00280 fclose(fd);
00281 return NULL;
00282 }
00283 if (strncmp(inbuf, "data=float", 10) != 0) {
00284 fprintf(stderr, "avsplugin) Error reading data type.\n");
00285 fclose(fd);
00286 return NULL;
00287 }
00288
00289
00290 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00291 fclose(fd);
00292 return NULL;
00293 }
00294 if (strncmp(inbuf, "field=uniform", 13) != 0) {
00295 fprintf(stderr, "avsplugin) Error reading field type.\n");
00296 fclose(fd);
00297 return NULL;
00298 }
00299
00300
00301
00302
00303
00304 coord = new datasource_t[ndim];
00305 variable = new datasource_t[veclen];
00306
00307
00308 for (i = 0; i < ndim; i++) {
00309 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00310 delete[] coord;
00311 fclose(fd);
00312 return NULL;
00313 }
00314 if ( (sscanf(inbuf, "coord %d", &coord_count) != 1) || (coord_count != i+1) ) {
00315 fprintf(stderr, "avsplugin) Error reading coord count.\n");
00316 delete[] coord;
00317 fclose(fd);
00318 return NULL;
00319 }
00320 if (read_datasource(inbuf, &coord[i])) {
00321 delete[] coord;
00322 fclose(fd);
00323 return NULL;
00324 }
00325 }
00326
00327
00328 for (i = 0; i < veclen; i++) {
00329 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00330 delete[] coord;
00331 fclose(fd);
00332 return NULL;
00333 }
00334 }
00335
00336
00337 for (i = 0; i < veclen; i++) {
00338 if (get_string(inbuf, LINESIZE, fd) == NULL) {
00339 delete[] coord;
00340 fclose(fd);
00341 return NULL;
00342 }
00343 if ( (sscanf(inbuf, "variable %d", &var_count) != 1) || (var_count != i+1) ) {
00344 fprintf(stderr, "avsplugin) Error reading variable count.\n");
00345 delete[] coord;
00346 fclose(fd);
00347 return NULL;
00348 }
00349 if (read_datasource(inbuf, &variable[i])) {
00350 delete[] coord;
00351 fclose(fd);
00352 return NULL;
00353 }
00354 }
00355
00356
00357 fclose(fd);
00358 fd = NULL;
00359
00360
00361
00362
00363 for (i = 0; i < ndim; i++) {
00364 if (strcmp(current_file, coord[i].filename) != 0) {
00365
00366 if (fd) {
00367 fclose(fd);
00368 fd = NULL;
00369 }
00370 strcpy(current_file, coord[i].filename);
00371 fd = fopen(current_file, "rb");
00372 if (!fd) {
00373 fprintf(stderr, "avsplugin) Error opening file.\n");
00374 delete[] coord;
00375 return NULL;
00376 }
00377 }
00378 else {
00379
00380 rewind(fd);
00381 }
00382
00383
00384 for (index = 0; index < coord[i].skip; index++) {
00385 if (fgets(inbuf, LINESIZE, fd) == NULL) {
00386 fprintf(stderr, "avsplugin) Error reading line.\n");
00387 fclose(fd);
00388 delete[] coord;
00389 return NULL;
00390 }
00391 }
00392
00393
00394 for (index = 0; index < coord[i].offset; index++) {
00395 if (fscanf(fd, " %f", &value) != 1) {
00396 fprintf(stderr, "avsplugin) Error skipping offset.\n");
00397 fclose(fd);
00398 delete[] coord;
00399 return NULL;
00400 }
00401 }
00402
00403
00404 if (fscanf(fd, " %f", &value) != 1) {
00405 fprintf(stderr, "avsplugin) Error reading origin.\n");
00406 fclose(fd);
00407 delete[] coord;
00408 return NULL;
00409 }
00410 origin[i] = value;
00411 for (index = 0; index < coord[i].stride; index++) {
00412 if (fscanf(fd, " %f", &value) != 1) {
00413 fprintf(stderr, "avsplugin) Error skipping stride.\n");
00414 fclose(fd);
00415 delete[] coord;
00416 return NULL;
00417 }
00418 }
00419 gridlength[i] = value - origin[i];
00420 }
00421
00422
00423 delete[] coord;
00424 coord = NULL;
00425 fclose(fd);
00426
00427
00428 avsfield = new avsfield_t;
00429 avsfield->vol = NULL;
00430 *natoms = MOLFILE_NUMATOMS_NONE;
00431
00432
00433 avsfield->nsets = veclen;
00434 avsfield->vol = new molfile_volumetric_t[veclen];
00435 avsfield->data = variable;
00436
00437 for (i = 0; i < veclen; i++) {
00438
00439 sprintf(avsfield->vol[i].dataname, "AVS Field: %d", i);
00440
00441 avsfield->vol[i].origin[0] = origin[0];
00442 avsfield->vol[i].origin[1] = origin[1];
00443 avsfield->vol[i].origin[2] = origin[2];
00444
00445 avsfield->vol[i].xaxis[0] = gridlength[0];
00446 avsfield->vol[i].xaxis[1] = 0;
00447 avsfield->vol[i].xaxis[2] = 0;
00448
00449 avsfield->vol[i].yaxis[0] = 0;
00450 avsfield->vol[i].yaxis[1] = gridlength[1];
00451 avsfield->vol[i].yaxis[2] = 0;
00452
00453 avsfield->vol[i].zaxis[0] = 0;
00454 avsfield->vol[i].zaxis[1] = 0;
00455 avsfield->vol[i].zaxis[2] = gridlength[2];
00456
00457 avsfield->vol[i].xsize = xsize;
00458 avsfield->vol[i].ysize = ysize;
00459 avsfield->vol[i].zsize = zsize;
00460
00461 avsfield->vol[i].has_color = 0;
00462 }
00463
00464 return avsfield;
00465 }
00466
00467 static int read_avsfield_metadata(void *v, int *nsets,
00468 molfile_volumetric_t **metadata) {
00469 avsfield_t *avsfield = (avsfield_t *)v;
00470 *nsets = avsfield->nsets;
00471 *metadata = avsfield->vol;
00472
00473 return MOLFILE_SUCCESS;
00474 }
00475
00476 static int read_avsfield_data(void *v, int set, float *datablock,
00477 float *colorblock) {
00478 avsfield_t *avsfield = (avsfield_t *)v;
00479 int skip, offset, stride, count, ndata, index;
00480 float value, *cellIndex = datablock;
00481 char inbuf[LINESIZE];
00482 FILE *fd;
00483
00484 fd = fopen(avsfield->data[set].filename, "rb");
00485 if (!fd) {
00486 fprintf(stderr, "avsplugin) Error opening file.\n");
00487 return MOLFILE_ERROR;
00488 }
00489
00490 skip = avsfield->data[set].skip;
00491 offset = avsfield->data[set].offset;
00492 stride = avsfield->data[set].stride;
00493
00494 count = 0;
00495 ndata = avsfield->vol[0].xsize * avsfield->vol[0].ysize * avsfield->vol[0].zsize;
00496
00497
00498 for (index = 0; index < skip; index++) {
00499 if (fgets(inbuf, LINESIZE, fd) == NULL) {
00500 fprintf(stderr, "avsplugin) Error skipping lines.\n");
00501 fclose(fd);
00502 return MOLFILE_ERROR;
00503 }
00504 }
00505
00506
00507 for (index = 0; index < offset; index++) {
00508 if (fscanf(fd, " %f", &value) != 1) {
00509 fprintf(stderr, "avsplugin) Error skipping offset.\n");
00510 fclose(fd);
00511 return MOLFILE_ERROR;
00512 }
00513 }
00514
00515 while (count < ndata) {
00516
00517 if (fscanf(fd, " %f", &value) != 1) {
00518 fprintf(stderr, "avsplugin) Error reading data.\n");
00519 fclose(fd);
00520 return MOLFILE_ERROR;
00521 }
00522 *cellIndex = value;
00523 cellIndex++;
00524 count++;
00525
00526 for (index = 0; index < stride-1; index++) {
00527 if (fscanf(fd, " %f", &value) != 1) {
00528 fprintf(stderr, "avsplugin) Error skipping stride.\n");
00529 fclose(fd);
00530 return MOLFILE_ERROR;
00531 }
00532 }
00533 }
00534
00535 fclose(fd);
00536 return MOLFILE_SUCCESS;
00537 }
00538
00539 static void close_avsfield_read(void *v) {
00540 avsfield_t *avsfield = (avsfield_t *)v;
00541
00542 if (avsfield->vol != NULL)
00543 delete [] avsfield->vol;
00544 if (avsfield->data != NULL)
00545 delete [] avsfield->data;
00546 delete avsfield;
00547 }
00548
00549
00550
00551
00552 static molfile_plugin_t plugin;
00553
00554 VMDPLUGIN_API int VMDPLUGIN_init(void) {
00555 memset(&plugin, 0, sizeof(plugin));
00556 plugin.abiversion = vmdplugin_ABIVERSION;
00557 plugin.type = MOLFILE_PLUGIN_TYPE;
00558 plugin.name = "fld";
00559 plugin.prettyname = "AVS Field";
00560 plugin.author = "Eamon Caddigan";
00561 plugin.majorv = 0;
00562 plugin.minorv = 5;
00563 plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
00564 plugin.filename_extension = "fld";
00565 plugin.open_file_read = open_avsfield_read;
00566 plugin.read_volumetric_metadata = read_avsfield_metadata;
00567 plugin.read_volumetric_data = read_avsfield_data;
00568 plugin.close_file_read = close_avsfield_read;
00569
00570 return VMDPLUGIN_SUCCESS;
00571 }
00572
00573 VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
00574
00575 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00576 (*cb)(v, (vmdplugin_t *)&plugin);
00577 return VMDPLUGIN_SUCCESS;
00578 }
00579