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
00038
00039
00040
00041 #include "largefiles.h"
00042
00043 #include <sys/stat.h>
00044 #include <sys/types.h>
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048 #include <math.h>
00049
00050 #define VMDPLUGIN_STATIC
00051 #include "hash.h"
00052 #include "fastio.h"
00053 #include "endianswap.h"
00054 #include "molfile_plugin.h"
00055
00056 #ifndef M_PI_2
00057 #define M_PI_2 1.57079632679489661922
00058 #endif
00059
00060 #define JSHEADERSTRING "JS Binary Structure and Trajectory File Format"
00061 #define JSMAGICNUMBER 0x31337
00062 #define JSENDIANISM 0x12345678
00063 #if 0
00064 #define JSMAJORVERSION 2
00065 #define JSMINORVERSION 0
00066 #else
00067 #define JSMAJORVERSION 1
00068 #define JSMINORVERSION 0
00069 #endif
00070
00071 #define JSNFRAMESOFFSET (strlen(JSHEADERSTRING) + 20)
00072
00073 #define JSNOERR 0
00074 #define JSBADFILE 1
00075 #define JSBADFORMAT 2
00076
00077
00078 #define JSOPT_NOOPTIONS 0x0000
00079 #define JSOPT_STRUCTURE 0x0001
00080 #define JSOPT_BONDS 0x0002
00081 #define JSOPT_BONDORDERS 0x0004
00082 #define JSOPT_OCCUPANCY 0x0008
00083 #define JSOPT_BFACTOR 0x0010
00084 #define JSOPT_MASS 0x0020
00085 #define JSOPT_CHARGE 0x0040
00086 #define JSOPT_RADIUS 0x0080
00087 #define JSOPT_ATOMICNUMBER 0x0100
00088
00089 typedef struct {
00090 fio_fd fd;
00091 int natoms;
00092
00093 #if JSMAJORVERSION > 1
00094
00095 int optflags;
00096 molfile_atom_t *atomlist;
00097 molfile_metadata_t *meta;
00098 int nbonds;
00099 int *bondfrom;
00100 int *bondto;
00101 float *bondorders;
00102 #endif
00103
00104
00105 int nframes;
00106 double tsdelta;
00107 int reverseendian;
00108 int with_unitcell;
00109
00110 } jshandle;
00111
00112 static void *open_js_read(const char *path, const char *filetype, int *natoms) {
00113 jshandle *js;
00114 int jsmagicnumber, jsendianism, jsmajorversion, jsminorversion;
00115 struct stat stbuf;
00116 char strbuf[1024];
00117 int rc = 0;
00118
00119 if (!path) return NULL;
00120
00121
00122 memset(&stbuf, 0, sizeof(struct stat));
00123 if (stat(path, &stbuf)) {
00124 printf("jsplugin) Could not access file '%s'.\n", path);
00125 return NULL;
00126 }
00127
00128 js = (jshandle *)malloc(sizeof(jshandle));
00129 memset(js, 0, sizeof(jshandle));
00130 if (fio_open(path, FIO_READ, &js->fd) < 0) {
00131 printf("jsplugin) Could not open file '%s' for reading.\n", path);
00132 free(js);
00133 return NULL;
00134 }
00135
00136
00137 fio_fread(strbuf, strlen(JSHEADERSTRING), 1, js->fd);
00138 strbuf[strlen(JSHEADERSTRING)] = '\0';
00139 if (strcmp(strbuf, JSHEADERSTRING)) {
00140 printf("jsplugin) Bad trajectory header!\n");
00141 printf("jsplugin) Read string: %s\n", strbuf);
00142 return NULL;
00143 }
00144
00145 fio_read_int32(js->fd, &jsmagicnumber);
00146 fio_read_int32(js->fd, &jsendianism);
00147 fio_read_int32(js->fd, &jsmajorversion);
00148 fio_read_int32(js->fd, &jsminorversion);
00149 fio_read_int32(js->fd, &js->natoms);
00150 fio_read_int32(js->fd, &js->nframes);
00151 if ((jsmagicnumber != JSMAGICNUMBER) || (jsendianism != JSENDIANISM)) {
00152 printf("jsplugin) opposite endianism trajectory file, enabling byte swapping\n");
00153 js->reverseendian = 1;
00154 swap4_aligned(&jsmagicnumber, 1);
00155 swap4_aligned(&jsendianism, 1);
00156 swap4_aligned(&jsmajorversion, 1);
00157 swap4_aligned(&jsminorversion, 1);
00158 swap4_aligned(&js->natoms, 1);
00159 swap4_aligned(&js->nframes, 1);
00160 }
00161
00162 if ((jsmagicnumber != JSMAGICNUMBER) || (jsendianism != JSENDIANISM)) {
00163 printf("jsplugin) read_jsreader returned %d\n", rc);
00164 fio_fclose(js->fd);
00165 free(js);
00166 return NULL;
00167 }
00168
00169 *natoms = js->natoms;
00170 return js;
00171 }
00172
00173
00174 #if JSMAJORVERSION > 1
00175
00176 static int read_js_structure(void *mydata, int *optflags,
00177 molfile_atom_t *atoms) {
00178 jshandle *js = (jshandle *) mydata;
00179 int i;
00180
00181 *optflags = MOLFILE_NOOPTIONS;
00182
00183
00184 fio_read_int32(js->fd, &js->optflags);
00185 if (js->reverseendian)
00186 swap4_aligned(&js->optflags, 1);
00187 printf("jsplugin) read option flags: %0x08x\n", js->optflags);
00188
00189
00190 if (js->optflags & JSOPT_STRUCTURE) {
00191 int numatomnames, numatomtypes, numresnames, numsegids, numchains;
00192 char **atomnames = NULL;
00193 char **atomtypes = NULL;
00194 char **resnames = NULL;
00195 char **segids = NULL;
00196 char **chains = NULL;
00197 short *shortbuf = NULL;
00198 int *intbuf = NULL;
00199 float *fltbuf = NULL;
00200
00201
00202 fio_read_int32(js->fd, &numatomnames);
00203 fio_read_int32(js->fd, &numatomtypes);
00204 fio_read_int32(js->fd, &numresnames);
00205 fio_read_int32(js->fd, &numsegids);
00206 fio_read_int32(js->fd, &numchains);
00207 if (js->reverseendian) {
00208 swap4_aligned(&numatomnames, js->natoms);
00209 swap4_aligned(&numatomtypes, js->natoms);
00210 swap4_aligned(&numresnames, js->natoms);
00211 swap4_aligned(&numsegids, js->natoms);
00212 swap4_aligned(&numchains, js->natoms);
00213 }
00214
00215 printf("jsplugin) reading string tables...\n");
00216 printf("jsplugin) %d %d %d %d %d\n",
00217 numatomnames, numatomtypes, numresnames, numsegids, numchains);
00218
00219
00220 atomnames = (char **) malloc(numatomnames * sizeof(char *));
00221 atomtypes = (char **) malloc(numatomtypes * sizeof(char *));
00222 resnames = (char **) malloc(numresnames * sizeof(char *));
00223 segids = (char **) malloc(numsegids * sizeof(char *));
00224 chains = (char **) malloc(numchains * sizeof(char *));
00225
00226 printf("jsplugin) atom names...\n");
00227
00228 for (i=0; i<numatomnames; i++) {
00229 atomnames[i] = (char *) malloc(16 * sizeof(char));
00230 fio_fread(atomnames[i], 16 * sizeof(char), 1, js->fd);
00231 }
00232
00233 printf("jsplugin) atom types...\n");
00234 for (i=0; i<numatomtypes; i++) {
00235 atomtypes[i] = (char *) malloc(16 * sizeof(char));
00236 fio_fread(atomtypes[i], 16 * sizeof(char), 1, js->fd);
00237 }
00238
00239 printf("jsplugin) residue names...\n");
00240 for (i=0; i<numresnames; i++) {
00241 resnames[i] = (char *) malloc(8 * sizeof(char));
00242 fio_fread(resnames[i], 8 * sizeof(char), 1, js->fd);
00243 }
00244
00245 printf("jsplugin) segment names...\n");
00246 for (i=0; i<numsegids; i++) {
00247 segids[i] = (char *) malloc(8 * sizeof(char));
00248 fio_fread(segids[i], 8 * sizeof(char), 1, js->fd);
00249 }
00250
00251 printf("jsplugin) chain names...\n");
00252 for (i=0; i<numchains; i++) {
00253 chains[i] = (char *) malloc(2 * sizeof(char));
00254 fio_fread(chains[i], 2 * sizeof(char), 1, js->fd);
00255 }
00256
00257 printf("jsplugin) reading numeric field tables...\n");
00258
00259 shortbuf = (void *) malloc(js->natoms * sizeof(short));
00260
00261 printf("jsplugin) atom name indices...\n");
00262
00263 fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00264 if (js->reverseendian)
00265 swap2_aligned(shortbuf, js->natoms);
00266 for (i=0; i<js->natoms; i++) {
00267 strcpy(atoms[i].name, atomnames[shortbuf[i]]);
00268 }
00269
00270 printf("jsplugin) atom type indices...\n");
00271
00272 fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00273 if (js->reverseendian)
00274 swap2_aligned(shortbuf, js->natoms);
00275 for (i=0; i<js->natoms; i++) {
00276 strcpy(atoms[i].type, atomtypes[shortbuf[i]]);
00277 }
00278
00279 printf("jsplugin) residue name indices...\n");
00280
00281 fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00282 if (js->reverseendian)
00283 swap2_aligned(shortbuf, js->natoms);
00284 for (i=0; i<js->natoms; i++) {
00285 strcpy(atoms[i].resname, resnames[shortbuf[i]]);
00286 }
00287
00288 printf("jsplugin) segment name indices...\n");
00289
00290 fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00291 if (js->reverseendian)
00292 swap2_aligned(shortbuf, js->natoms);
00293 for (i=0; i<js->natoms; i++) {
00294 strcpy(atoms[i].segid, segids[shortbuf[i]]);
00295 }
00296
00297 printf("jsplugin) chain name indices...\n");
00298
00299 fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00300 if (js->reverseendian)
00301 swap2_aligned(shortbuf, js->natoms);
00302 for (i=0; i<js->natoms; i++) {
00303 strcpy(atoms[i].chain, chains[shortbuf[i]]);
00304 }
00305
00306 if (shortbuf != NULL) {
00307 free(shortbuf);
00308 shortbuf=NULL;
00309 }
00310
00311
00312
00313
00314 intbuf = (int *) malloc(js->natoms * sizeof(int));
00315
00316 printf("jsplugin) residue indices...\n");
00317
00318 fio_fread(intbuf, js->natoms * sizeof(int), 1, js->fd);
00319 if (js->reverseendian)
00320 swap4_aligned(intbuf, js->natoms);
00321 for (i=0; i<js->natoms; i++) {
00322 atoms[i].resid = intbuf[i];
00323 }
00324
00325 if (intbuf != NULL) {
00326 free(intbuf);
00327 intbuf = NULL;
00328 }
00329
00330
00331 printf("jsplugin) reading optional per-atom tables...\n");
00332
00333
00334
00335 if (js->optflags & (JSOPT_OCCUPANCY | JSOPT_BFACTOR |
00336 JSOPT_MASS | JSOPT_RADIUS | JSOPT_CHARGE))
00337 fltbuf = (void *) malloc(js->natoms * sizeof(float));
00338
00339
00340 if (js->optflags & JSOPT_OCCUPANCY) {
00341 printf("jsplugin) occupancy...\n");
00342 *optflags |= MOLFILE_OCCUPANCY;
00343 fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00344 if (js->reverseendian)
00345 swap4_aligned(fltbuf, js->natoms);
00346 for (i=0; i<js->natoms; i++) {
00347 atoms[i].occupancy = fltbuf[i];
00348 }
00349 }
00350
00351 if (js->optflags & JSOPT_BFACTOR) {
00352 printf("jsplugin) bfactor...\n");
00353 *optflags |= MOLFILE_BFACTOR;
00354 fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00355 if (js->reverseendian)
00356 swap4_aligned(fltbuf, js->natoms);
00357 for (i=0; i<js->natoms; i++) {
00358 atoms[i].bfactor = fltbuf[i];
00359 }
00360 }
00361
00362 if (js->optflags & JSOPT_MASS) {
00363 printf("jsplugin) mass...\n");
00364 *optflags |= MOLFILE_MASS;
00365 fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00366 if (js->reverseendian)
00367 swap4_aligned(fltbuf, js->natoms);
00368 for (i=0; i<js->natoms; i++) {
00369 atoms[i].mass = fltbuf[i];
00370 }
00371 }
00372
00373 if (js->optflags & JSOPT_CHARGE) {
00374 printf("jsplugin) charge...\n");
00375 *optflags |= MOLFILE_CHARGE;
00376 fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00377 if (js->reverseendian)
00378 swap4_aligned(fltbuf, js->natoms);
00379 for (i=0; i<js->natoms; i++) {
00380 atoms[i].charge = fltbuf[i];
00381 }
00382 }
00383
00384 if (js->optflags & JSOPT_RADIUS) {
00385 printf("jsplugin) radius...\n");
00386 *optflags |= MOLFILE_RADIUS;
00387 fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00388 if (js->reverseendian)
00389 swap4_aligned(fltbuf, js->natoms);
00390 for (i=0; i<js->natoms; i++) {
00391 atoms[i].radius = fltbuf[i];
00392 }
00393 }
00394
00395 if (fltbuf != NULL) {
00396 free(fltbuf);
00397 fltbuf=NULL;
00398 }
00399
00400
00401
00402
00403 if (js->optflags & JSOPT_ATOMICNUMBER)
00404 intbuf = (void *) malloc(js->natoms * sizeof(int));
00405
00406 if (js->optflags & JSOPT_ATOMICNUMBER) {
00407 printf("jsplugin) atomic number...\n");
00408 *optflags |= MOLFILE_ATOMICNUMBER;
00409 fio_fread(intbuf, js->natoms * sizeof(int), 1, js->fd);
00410 if (js->reverseendian)
00411 swap4_aligned(intbuf, js->natoms);
00412 for (i=0; i<js->natoms; i++) {
00413 atoms[i].atomicnumber = intbuf[i];
00414 }
00415 }
00416
00417 if (intbuf != NULL) {
00418 free(intbuf);
00419 intbuf = NULL;
00420 }
00421
00422
00423
00424
00425
00426 if (js->optflags & JSOPT_BONDS) {
00427 fio_fread(&js->nbonds, sizeof(int), 1, js->fd);
00428 if (js->reverseendian)
00429 swap4_aligned(&js->nbonds, 1);
00430 printf("jsplugin) %d bonds...\n", js->nbonds);
00431
00432 js->bondfrom = (void *) malloc(js->nbonds * sizeof(int));
00433 js->bondto = (void *) malloc(js->nbonds * sizeof(int));
00434 fio_fread(js->bondfrom, js->nbonds * sizeof(int), 1, js->fd);
00435 fio_fread(js->bondto, js->nbonds * sizeof(int), 1, js->fd);
00436 if (js->reverseendian) {
00437 swap4_aligned(js->bondfrom, js->nbonds);
00438 swap4_aligned(js->bondto, js->nbonds);
00439 }
00440
00441 if (js->optflags & JSOPT_BONDORDERS) {
00442 printf("jsplugin) bond orders...\n");
00443 js->bondorders = (void *) malloc(js->nbonds * sizeof(float));
00444 fio_fread(js->bondorders, js->nbonds * sizeof(float), 1, js->fd);
00445 if (js->reverseendian)
00446 swap4_aligned(js->bondorders, js->nbonds);
00447 }
00448 }
00449
00450 printf("jsplugin) final optflags: %08x\n", *optflags);
00451 printf("jsplugin) structure information complete\n");
00452
00453 return MOLFILE_SUCCESS;
00454 }
00455
00456 printf("jsplugin) no structure information available\n");
00457
00458
00459 return MOLFILE_NOSTRUCTUREDATA;
00460 }
00461
00462 static int read_js_bonds(void *v, int *nbonds, int **fromptr, int **toptr, float **bondorder) {
00463 jshandle *js = (jshandle *)v;
00464
00465 *nbonds = 0;
00466 *fromptr = NULL;
00467 *toptr = NULL;
00468 *bondorder = NULL;
00469
00470 if (js->optflags & JSOPT_BONDS) {
00471
00472 *nbonds = js->nbonds;
00473 *fromptr = js->bondfrom;
00474 *toptr = js->bondto;
00475
00476 if (js->optflags & JSOPT_BONDORDERS) {
00477 *bondorder = js->bondorders;
00478 }
00479 }
00480
00481 return MOLFILE_SUCCESS;
00482 }
00483
00484 #endif
00485
00486
00487
00488
00489
00490
00491 static int read_js_timestep(void *v, int natoms, molfile_timestep_t *ts) {
00492 jshandle *js = (jshandle *)v;
00493 int framelen = (natoms * 3 * sizeof(float)) + (6 * sizeof(double));;
00494
00495
00496 if (ts != NULL) {
00497 int readlen;
00498 fio_iovec iov[2];
00499 double unitcell[6];
00500 unitcell[0] = unitcell[2] = unitcell[5] = 1.0f;
00501 unitcell[1] = unitcell[3] = unitcell[4] = 90.0f;
00502
00503
00504 iov[0].iov_base = (fio_caddr_t) ts->coords;
00505 iov[0].iov_len = natoms * 3 * sizeof(float);
00506 iov[1].iov_base = (fio_caddr_t) &unitcell[0];
00507 iov[1].iov_len = 6 * sizeof(double);
00508
00509
00510
00511
00512 readlen = fio_readv(js->fd, &iov[0], 2);
00513
00514
00515 if (readlen != framelen)
00516 return MOLFILE_EOF;
00517
00518
00519 if (js->reverseendian) {
00520 swap4_aligned(ts->coords, natoms * 3);
00521 swap8_aligned(unitcell, 6);
00522 }
00523
00524
00525 ts->A = unitcell[0];
00526 ts->B = unitcell[1];
00527 ts->C = unitcell[2];
00528 ts->alpha = 90.0 - asin(unitcell[3]) * 90.0 / M_PI_2;
00529 ts->beta = 90.0 - asin(unitcell[4]) * 90.0 / M_PI_2;
00530 ts->gamma = 90.0 - asin(unitcell[5]) * 90.0 / M_PI_2;
00531 } else {
00532
00533 if (fio_fseek(js->fd, framelen, FIO_SEEK_CUR))
00534 return MOLFILE_EOF;
00535 }
00536
00537 return MOLFILE_SUCCESS;
00538 }
00539
00540
00541 static void close_js_read(void *v) {
00542 jshandle *js = (jshandle *)v;
00543 fio_fclose(js->fd);
00544
00545 #if JSMAJORVERSION > 1
00546 if (js->bondfrom)
00547 free(js->bondfrom);
00548 if (js->bondto)
00549 free(js->bondto);
00550 if (js->bondorders)
00551 free(js->bondorders);
00552 #endif
00553
00554 free(js);
00555 }
00556
00557
00558 static void *open_js_write(const char *path, const char *filetype, int natoms) {
00559 jshandle *js;
00560
00561 js = (jshandle *)malloc(sizeof(jshandle));
00562 memset(js, 0, sizeof(jshandle));
00563 if (fio_open(path, FIO_WRITE, &js->fd) < 0) {
00564 printf("jsplugin) Could not open file %s for writing\n", path);
00565 free(js);
00566 return NULL;
00567 }
00568
00569 js->natoms = natoms;
00570 js->with_unitcell = 1;
00571
00572
00573 fio_write_str(js->fd, JSHEADERSTRING);
00574 fio_write_int32(js->fd, JSMAGICNUMBER);
00575 fio_write_int32(js->fd, JSENDIANISM);
00576 fio_write_int32(js->fd, JSMAJORVERSION);
00577 fio_write_int32(js->fd, JSMINORVERSION);
00578
00579
00580 fio_write_int32(js->fd, natoms);
00581
00582
00583 js->nframes = 0;
00584 fio_write_int32(js->fd, js->nframes);
00585
00586 return js;
00587 }
00588
00589
00590 #if JSMAJORVERSION > 1
00591
00592 static int write_js_structure(void *mydata, int optflags,
00593 const molfile_atom_t *atoms) {
00594 jshandle *js = (jshandle *) mydata;
00595 int i;
00596
00597 js->optflags |= JSOPT_STRUCTURE;
00598
00599 if (optflags & MOLFILE_OCCUPANCY)
00600 js->optflags |= JSOPT_OCCUPANCY;
00601
00602 if (optflags & MOLFILE_BFACTOR)
00603 js->optflags |= JSOPT_BFACTOR;
00604
00605 if (optflags & MOLFILE_BFACTOR)
00606 js->optflags |= JSOPT_BFACTOR;
00607
00608 if (optflags & MOLFILE_MASS)
00609 js->optflags |= JSOPT_MASS;
00610
00611 if (optflags & MOLFILE_CHARGE)
00612 js->optflags |= JSOPT_CHARGE;
00613
00614 if (optflags & MOLFILE_RADIUS)
00615 js->optflags |= JSOPT_RADIUS;
00616
00617 if (optflags & MOLFILE_ATOMICNUMBER)
00618 js->optflags |= JSOPT_ATOMICNUMBER;
00619
00620
00621 fio_write_int32(js->fd, js->optflags);
00622 printf("jsplugin) writing option flags: %0x08x\n", js->optflags);
00623
00624 printf("jsplugin) writing structure...\n");
00625
00626 if (js->optflags & JSOPT_STRUCTURE) {
00627 int numatomnames, numatomtypes, numresnames, numsegids, numchains;
00628 char **atomnames = NULL;
00629 char **atomtypes = NULL;
00630 char **resnames = NULL;
00631 char **segids = NULL;
00632 char **chains = NULL;
00633 short *shortbuf = NULL;
00634 int *intbuf = NULL;
00635 float *fltbuf = NULL;
00636
00637 hash_t tmphash;
00638 hash_t atomnamehash;
00639 hash_t atomtypehash;
00640 hash_t resnamehash;
00641 hash_t segidhash;
00642 hash_t chainhash;
00643 int hashcnt;
00644
00645
00646 printf("jsplugin) counting atom names, types, etc...\n");
00647
00648 hash_init(&tmphash, 127);
00649 for (i=0; i<js->natoms; i++)
00650 hash_insert(&tmphash, atoms[i].name, 0);
00651 numatomnames = tmphash.entries;
00652 hash_destroy(&tmphash);
00653
00654 hash_init(&tmphash, 127);
00655 for (i=0; i<js->natoms; i++)
00656 hash_insert(&tmphash, atoms[i].type, 0);
00657 numatomtypes = tmphash.entries;
00658 hash_destroy(&tmphash);
00659
00660 hash_init(&tmphash, 127);
00661 for (i=0; i<js->natoms; i++)
00662 hash_insert(&tmphash, atoms[i].resname, 0);
00663 numresnames = tmphash.entries;
00664 hash_destroy(&tmphash);
00665
00666 hash_init(&tmphash, 127);
00667 for (i=0; i<js->natoms; i++)
00668 hash_insert(&tmphash, atoms[i].segid, 0);
00669 numsegids = tmphash.entries;
00670 hash_destroy(&tmphash);
00671
00672 hash_init(&tmphash, 127);
00673 for (i=0; i<js->natoms; i++)
00674 hash_insert(&tmphash, atoms[i].chain, 0);
00675 numchains = tmphash.entries;
00676 hash_destroy(&tmphash);
00677
00678 printf("jsplugin) writing unique string counts...\n");
00679 printf("jsplugin) %d %d %d %d %d\n",
00680 numatomnames, numatomtypes, numresnames, numsegids, numchains);
00681
00682
00683 fio_write_int32(js->fd, numatomnames);
00684 fio_write_int32(js->fd, numatomtypes);
00685 fio_write_int32(js->fd, numresnames);
00686 fio_write_int32(js->fd, numsegids);
00687 fio_write_int32(js->fd, numchains);
00688
00689 printf("jsplugin) writing string tables...\n");
00690
00691 atomnames = (char **) malloc(numatomnames * sizeof(char *));
00692 atomtypes = (char **) malloc(numatomtypes * sizeof(char *));
00693 resnames = (char **) malloc(numresnames * sizeof(char *));
00694 segids = (char **) malloc(numsegids * sizeof(char *));
00695 chains = (char **) malloc(numchains * sizeof(char *));
00696
00697 printf("jsplugin) atom names...\n");
00698
00699 hash_init(&atomnamehash, 127);
00700 for (hashcnt=0,i=0; i<js->natoms; i++) {
00701
00702 if (hash_insert(&atomnamehash, atoms[i].name, hashcnt) == HASH_FAIL) {
00703 atomnames[hashcnt] = (char *) malloc(16 * sizeof(char));
00704 strcpy(atomnames[hashcnt], atoms[i].name);
00705 hashcnt++;
00706 }
00707 }
00708 for (i=0; i<numatomnames; i++) {
00709 fio_fwrite(atomnames[i], 16 * sizeof(char), 1, js->fd);
00710 }
00711
00712
00713 printf("jsplugin) atom types...\n");
00714 hash_init(&atomtypehash, 127);
00715 for (hashcnt=0,i=0; i<js->natoms; i++) {
00716
00717 if (hash_insert(&atomtypehash, atoms[i].type, hashcnt) == HASH_FAIL) {
00718 atomtypes[hashcnt] = (char *) malloc(16 * sizeof(char));
00719 strcpy(atomtypes[hashcnt], atoms[i].type);
00720 hashcnt++;
00721 }
00722 }
00723 for (i=0; i<numatomtypes; i++) {
00724 fio_fwrite(atomtypes[i], 16 * sizeof(char), 1, js->fd);
00725 }
00726
00727
00728 printf("jsplugin) residue names...\n");
00729 hash_init(&resnamehash, 127);
00730 for (hashcnt=0,i=0; i<js->natoms; i++) {
00731
00732 if (hash_insert(&resnamehash, atoms[i].resname, hashcnt) == HASH_FAIL) {
00733 resnames[hashcnt] = (char *) malloc(8 * sizeof(char));
00734 strcpy(resnames[hashcnt], atoms[i].resname);
00735 hashcnt++;
00736 }
00737 }
00738 for (i=0; i<numresnames; i++) {
00739 fio_fwrite(resnames[i], 8 * sizeof(char), 1, js->fd);
00740 }
00741
00742
00743 printf("jsplugin) segment names...\n");
00744 hash_init(&segidhash, 127);
00745 for (hashcnt=0,i=0; i<js->natoms; i++) {
00746
00747 if (hash_insert(&segidhash, atoms[i].segid, hashcnt) == HASH_FAIL) {
00748 segids[hashcnt] = (char *) malloc(8 * sizeof(char));
00749 strcpy(segids[hashcnt], atoms[i].segid);
00750 hashcnt++;
00751 }
00752 }
00753 for (i=0; i<numsegids; i++) {
00754 fio_fwrite(segids[i], 8 * sizeof(char), 1, js->fd);
00755 }
00756
00757
00758 printf("jsplugin) chain names...\n");
00759 hash_init(&chainhash, 127);
00760 for (hashcnt=0,i=0; i<js->natoms; i++) {
00761
00762 if (hash_insert(&chainhash, atoms[i].chain, hashcnt) == HASH_FAIL) {
00763 chains[hashcnt] = (char *) malloc(2 * sizeof(char));
00764 strcpy(chains[hashcnt], atoms[i].chain);
00765 hashcnt++;
00766 }
00767 }
00768 for (i=0; i<numchains; i++) {
00769 fio_fwrite(chains[i], 2 * sizeof(char), 1, js->fd);
00770 }
00771
00772
00773 printf("jsplugin) writing numeric field tables...\n");
00774
00775 shortbuf = (void *) malloc(js->natoms * sizeof(short));
00776
00777
00778 for (i=0; i<js->natoms; i++) {
00779 shortbuf[i] = hash_lookup(&atomnamehash, atoms[i].name);
00780 }
00781 fio_fwrite(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00782
00783
00784 for (i=0; i<js->natoms; i++) {
00785 shortbuf[i] = hash_lookup(&atomtypehash, atoms[i].type);
00786 }
00787 fio_fwrite(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00788
00789
00790 for (i=0; i<js->natoms; i++) {
00791 shortbuf[i] = hash_lookup(&resnamehash, atoms[i].resname);
00792 }
00793 fio_fwrite(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00794
00795
00796 for (i=0; i<js->natoms; i++) {
00797 shortbuf[i] = hash_lookup(&segidhash, atoms[i].segid);
00798 }
00799 fio_fwrite(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00800
00801
00802 for (i=0; i<js->natoms; i++) {
00803 shortbuf[i] = hash_lookup(&chainhash, atoms[i].chain);
00804 }
00805 fio_fwrite(shortbuf, js->natoms * sizeof(short), 1, js->fd);
00806
00807 if (shortbuf != NULL) {
00808 free(shortbuf);
00809 shortbuf=NULL;
00810 }
00811
00812
00813 hash_destroy(&atomnamehash);
00814 hash_destroy(&atomtypehash);
00815 hash_destroy(&resnamehash);
00816 hash_destroy(&segidhash);
00817 hash_destroy(&chainhash);
00818
00819
00820
00821
00822
00823 intbuf = (int *) malloc(js->natoms * sizeof(int));
00824
00825 printf("jsplugin) residue indices...\n");
00826
00827 for (i=0; i<js->natoms; i++) {
00828 intbuf[i] = atoms[i].resid;
00829 }
00830 fio_fwrite(intbuf, js->natoms * sizeof(int), 1, js->fd);
00831
00832 if (intbuf != NULL) {
00833 free(intbuf);
00834 intbuf = NULL;
00835 }
00836
00837 printf("jsplugin) writing optional per-atom tables...\n");
00838
00839
00840
00841 if (js->optflags & (JSOPT_OCCUPANCY | JSOPT_BFACTOR |
00842 JSOPT_MASS | JSOPT_RADIUS | JSOPT_CHARGE))
00843 fltbuf = (void *) malloc(js->natoms * sizeof(float));
00844
00845
00846
00847 if (js->optflags & JSOPT_OCCUPANCY) {
00848 printf("jsplugin) writing occupancy...\n");
00849 for (i=0; i<js->natoms; i++) {
00850 fltbuf[i] = atoms[i].occupancy;
00851 }
00852 fio_fwrite(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00853 }
00854
00855 if (js->optflags & JSOPT_BFACTOR) {
00856 printf("jsplugin) writing bfactor...\n");
00857 for (i=0; i<js->natoms; i++) {
00858 fltbuf[i] = atoms[i].bfactor;
00859 }
00860 fio_fwrite(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00861 }
00862
00863 if (js->optflags & JSOPT_MASS) {
00864 printf("jsplugin) writing mass...\n");
00865 for (i=0; i<js->natoms; i++) {
00866 fltbuf[i] = atoms[i].mass;
00867 }
00868 fio_fwrite(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00869 }
00870
00871 if (js->optflags & JSOPT_CHARGE) {
00872 printf("jsplugin) writing charge...\n");
00873 for (i=0; i<js->natoms; i++) {
00874 fltbuf[i] = atoms[i].charge;
00875 }
00876 fio_fwrite(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00877 }
00878
00879 if (js->optflags & JSOPT_RADIUS) {
00880 printf("jsplugin) writing radius...\n");
00881 for (i=0; i<js->natoms; i++) {
00882 fltbuf[i] = atoms[i].radius;
00883 }
00884 fio_fwrite(fltbuf, js->natoms * sizeof(float), 1, js->fd);
00885 }
00886
00887 if (fltbuf != NULL) {
00888 free(fltbuf);
00889 fltbuf=NULL;
00890 }
00891
00892
00893
00894
00895
00896 if (js->optflags & JSOPT_ATOMICNUMBER)
00897 intbuf = (void *) malloc(js->natoms * sizeof(int));
00898
00899 if (js->optflags & JSOPT_ATOMICNUMBER) {
00900 printf("jsplugin) writing atomic number...\n");
00901 for (i=0; i<js->natoms; i++) {
00902 intbuf[i] = atoms[i].atomicnumber;
00903 }
00904 fio_fwrite(intbuf, js->natoms * sizeof(int), 1, js->fd);
00905 }
00906
00907 if (intbuf != NULL) {
00908 free(intbuf);
00909 intbuf = NULL;
00910 }
00911
00912
00913
00914
00915
00916 if (js->optflags & JSOPT_BONDS) {
00917 printf("jsplugin) writing bonds...\n");
00918 fio_fwrite(&js->nbonds, sizeof(int), 1, js->fd);
00919 fio_fwrite(js->bondfrom, js->nbonds * sizeof(int), 1, js->fd);
00920 fio_fwrite(js->bondto, js->nbonds * sizeof(int), 1, js->fd);
00921
00922 if (js->optflags & JSOPT_BONDORDERS) {
00923 printf("jsplugin) writing bond orders...\n");
00924 fio_fwrite(js->bondorders, js->nbonds * sizeof(float), 1, js->fd);
00925 }
00926 }
00927
00928 return MOLFILE_SUCCESS;
00929 }
00930
00931
00932 return MOLFILE_NOSTRUCTUREDATA;
00933 }
00934
00935
00936 static int write_js_bonds(void *mydata, int nbonds, int *fromptr, int *toptr, float *bondorder) {
00937 jshandle *js = (jshandle *) mydata;
00938
00939 if (nbonds > 0 && fromptr != NULL && toptr != NULL) {
00940 js->optflags |= JSOPT_BONDS;
00941
00942
00943 js->nbonds = nbonds;
00944 js->bondfrom = (int *) malloc(nbonds * sizeof(int));
00945 memcpy(js->bondfrom, fromptr, nbonds * sizeof(int));
00946 js->bondto = (int *) malloc(nbonds * sizeof(int));
00947 memcpy(js->bondto, toptr, nbonds * sizeof(int));
00948
00949 if (bondorder != NULL) {
00950 js->optflags |= JSOPT_BONDORDERS;
00951 js->bondorders = (float *) malloc(nbonds * sizeof(float));
00952 memcpy(js->bondorders, bondorder, nbonds * sizeof(float));
00953 }
00954 }
00955
00956 return MOLFILE_SUCCESS;
00957 }
00958
00959 #endif
00960
00961 static int write_js_timestep(void *v, const molfile_timestep_t *ts) {
00962 jshandle *js = (jshandle *)v;
00963 double unitcell[6];
00964
00965 js->nframes++;
00966
00967 unitcell[0] = ts->A;
00968 unitcell[1] = ts->B;
00969 unitcell[2] = ts->C;
00970 unitcell[3] = sin((M_PI_2 / 90.0) * (90.0 - ts->alpha));
00971 unitcell[4] = sin((M_PI_2 / 90.0) * (90.0 - ts->beta));
00972 unitcell[5] = sin((M_PI_2 / 90.0) * (90.0 - ts->gamma));
00973
00974
00975 fio_fwrite(ts->coords, js->natoms * 3 * sizeof(float), 1, js->fd);
00976
00977
00978 fio_fwrite(&unitcell[0], 6 * sizeof(double), 1, js->fd);
00979
00980 return MOLFILE_SUCCESS;
00981 }
00982
00983 static void close_js_write(void *v) {
00984 jshandle *js = (jshandle *)v;
00985
00986
00987 fio_fseek(js->fd, JSNFRAMESOFFSET, FIO_SEEK_SET);
00988 fio_write_int32(js->fd, js->nframes);
00989 fio_fseek(js->fd, 0, FIO_SEEK_END);
00990
00991 fio_fclose(js->fd);
00992
00993 #if JSMAJORVERSION > 1
00994 if (js->bondfrom)
00995 free(js->bondfrom);
00996 if (js->bondto)
00997 free(js->bondto);
00998 if (js->bondorders)
00999 free(js->bondorders);
01000 #endif
01001
01002 free(js);
01003 }
01004
01005
01006
01007
01008
01009 static molfile_plugin_t plugin;
01010
01011 VMDPLUGIN_API int VMDPLUGIN_init() {
01012 memset(&plugin, 0, sizeof(molfile_plugin_t));
01013 plugin.abiversion = vmdplugin_ABIVERSION;
01014 plugin.type = MOLFILE_PLUGIN_TYPE;
01015 plugin.name = "js";
01016 plugin.prettyname = "js";
01017 plugin.author = "John Stone";
01018 plugin.majorv = 0;
01019 plugin.minorv = 9;
01020 plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
01021 plugin.filename_extension = "js";
01022 plugin.open_file_read = open_js_read;
01023 #if JSMAJORVERSION > 1
01024 plugin.read_structure = read_js_structure;
01025 plugin.read_bonds = read_js_bonds;
01026 #endif
01027 plugin.read_next_timestep = read_js_timestep;
01028 plugin.close_file_read = close_js_read;
01029 plugin.open_file_write = open_js_write;
01030 #if JSMAJORVERSION > 1
01031 plugin.write_structure = write_js_structure;
01032 plugin.write_bonds = write_js_bonds;
01033 #endif
01034 plugin.write_timestep = write_js_timestep;
01035 plugin.close_file_write = close_js_write;
01036 return VMDPLUGIN_SUCCESS;
01037 }
01038
01039 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
01040 (*cb)(v, (vmdplugin_t *)&plugin);
01041 return VMDPLUGIN_SUCCESS;
01042 }
01043
01044 VMDPLUGIN_API int VMDPLUGIN_fini() {
01045 return VMDPLUGIN_SUCCESS;
01046 }
01047
01048
01049 #ifdef TEST_JSPLUGIN
01050
01051 #include <sys/time.h>
01052
01053
01054 double time_of_day(void) {
01055 #if defined(_MSC_VER)
01056 double t;
01057
01058 t = GetTickCount();
01059 t = t / 1000.0;
01060
01061 return t;
01062 #else
01063 struct timeval tm;
01064 struct timezone tz;
01065
01066 gettimeofday(&tm, &tz);
01067 return((double)(tm.tv_sec) + (double)(tm.tv_usec)/1000000.0);
01068 #endif
01069 }
01070
01071 int main(int argc, char *argv[]) {
01072 molfile_timestep_t timestep;
01073 void *v;
01074 jshandle *js;
01075 int i, natoms;
01076 float sizeMB =0.0, totalMB = 0.0;
01077 double starttime, endtime, totaltime = 0.0;
01078
01079 while (--argc) {
01080 ++argv;
01081 natoms = 0;
01082 v = open_js_read(*argv, "js", &natoms);
01083 if (!v) {
01084 printf("jsplugin) open_js_read failed for file %s\n", *argv);
01085 return 1;
01086 }
01087 js = (jshandle *)v;
01088 sizeMB = ((natoms * 3.0) * js->nframes * 4.0) / (1024.0 * 1024.0);
01089 totalMB += sizeMB;
01090 printf("jsplugin) file: %s\n", *argv);
01091 printf("jsplugin) %d atoms, %d frames, size: %6.1fMB\n", natoms, js->nframes, sizeMB);
01092
01093 starttime = time_of_day();
01094 timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
01095 for (i=0; i<js->nframes; i++) {
01096 int rc = read_js_timestep(v, natoms, ×tep);
01097 if (rc) {
01098 printf("jsplugin) error in read_js_timestep on frame %d\n", i);
01099 return 1;
01100 }
01101 }
01102 endtime = time_of_day();
01103 close_js_read(v);
01104 totaltime += endtime - starttime;
01105 printf("jsplugin) Time: %5.1f seconds\n", endtime - starttime);
01106 printf("jsplugin) Speed: %5.1f MB/sec, %5.1f timesteps/sec\n", sizeMB / (endtime - starttime), (js->nframes / (endtime - starttime)));
01107 }
01108 printf("jsplugin) Overall Size: %6.1f MB\n", totalMB);
01109 printf("jsplugin) Overall Time: %6.1f seconds\n", totaltime);
01110 printf("jsplugin) Overall Speed: %5.1f MB/sec\n", totalMB / totaltime);
01111 return 0;
01112 }
01113
01114 #endif
01115