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 #include "fastio.h"
00051 #include "endianswap.h"
00052
00053 #include "molfile_plugin.h"
00054
00055 #ifndef M_PI_2
00056 #define M_PI_2 1.57079632679489661922
00057 #endif
00058
00059 #define JSHEADERSTRING "JS Binary Trajectory File Format"
00060 #define JSMAGICNUMBER 0x31337
00061 #define JSENDIANISM 0x12345678
00062 #define JSMAJORVERSION 1
00063 #define JSMINORVERSION 0
00064
00065 #define JSNFRAMESOFFSET (strlen(JSHEADERSTRING) + 20)
00066
00067 #define JSNOERR 0
00068 #define JSBADFILE 1
00069 #define JSBADFORMAT 2
00070
00071 typedef struct {
00072 fio_fd fd;
00073 int natoms;
00074 int nframes;
00075 double tsdelta;
00076 int reverse;
00077 int with_unitcell;
00078 } jshandle;
00079
00080 static void *open_js_read(const char *path, const char *filetype, int *natoms) {
00081 jshandle *js;
00082 int jsmagicnumber, jsendianism, jsmajorversion, jsminorversion;
00083 struct stat stbuf;
00084 char strbuf[1024];
00085 int rc = 0;
00086
00087 if (!path) return NULL;
00088
00089
00090 memset(&stbuf, 0, sizeof(struct stat));
00091 if (stat(path, &stbuf)) {
00092 fprintf(stderr, "Could not access file '%s'.\n", path);
00093 return NULL;
00094 }
00095
00096 js = (jshandle *)malloc(sizeof(jshandle));
00097 memset(js, 0, sizeof(jshandle));
00098 if (fio_open(path, FIO_READ, &js->fd) < 0) {
00099 fprintf(stderr, "Could not open file '%s' for reading.\n", path);
00100 free(js);
00101 return NULL;
00102 }
00103
00104
00105 fio_fread(strbuf, strlen(JSHEADERSTRING), 1, js->fd);
00106 strbuf[strlen(JSHEADERSTRING)] = '\0';
00107 if (strcmp(strbuf, JSHEADERSTRING)) {
00108 fprintf(stderr, "Bad trajectory header!\n");
00109 fprintf(stderr, "Read string: %s\n", strbuf);
00110 return NULL;
00111 }
00112
00113 fio_read_int32(js->fd, &jsmagicnumber);
00114 fio_read_int32(js->fd, &jsendianism);
00115 fio_read_int32(js->fd, &jsmajorversion);
00116 fio_read_int32(js->fd, &jsminorversion);
00117 fio_read_int32(js->fd, &js->natoms);
00118 fio_read_int32(js->fd, &js->nframes);
00119
00120 if ((jsmagicnumber != JSMAGICNUMBER) || (jsendianism != JSENDIANISM)) {
00121 fprintf(stderr, "Opposite endianism trajectory file, enabling byte swapping\n");
00122 js->reverse = 1;
00123 swap4_aligned(&jsmagicnumber, 1);
00124 swap4_aligned(&jsendianism, 1);
00125 swap4_aligned(&jsmajorversion, 1);
00126 swap4_aligned(&jsminorversion, 1);
00127 swap4_aligned(&js->natoms, 1);
00128 swap4_aligned(&js->nframes, 1);
00129 }
00130
00131 if ((jsmagicnumber != JSMAGICNUMBER) || (jsendianism != JSENDIANISM)) {
00132 fprintf(stderr, "read_jsreader returned %d\n", rc);
00133 fio_fclose(js->fd);
00134 free(js);
00135 return NULL;
00136 }
00137
00138 *natoms = js->natoms;
00139 return js;
00140 }
00141
00142
00143 static int read_js_timestep(void *v, int natoms, molfile_timestep_t *ts) {
00144 jshandle *js = (jshandle *)v;
00145 int framelen = (natoms * 3 * sizeof(float)) + (6 * sizeof(double));;
00146
00147
00148 if (ts != NULL) {
00149 int readlen;
00150 fio_iovec iov[2];
00151 double unitcell[6];
00152 unitcell[0] = unitcell[2] = unitcell[5] = 1.0f;
00153 unitcell[1] = unitcell[3] = unitcell[4] = 90.0f;
00154
00155
00156 iov[0].iov_base = (fio_caddr_t) ts->coords;
00157 iov[0].iov_len = natoms * 3 * sizeof(float);
00158 iov[1].iov_base = (fio_caddr_t) &unitcell[0];
00159 iov[1].iov_len = 6 * sizeof(double);
00160
00161
00162
00163
00164 readlen = fio_readv(js->fd, &iov[0], 2);
00165
00166
00167 if (readlen != framelen)
00168 return MOLFILE_EOF;
00169
00170
00171 if (js->reverse) {
00172 swap4_aligned(ts->coords, natoms * 3);
00173 swap8_aligned(unitcell, 6);
00174 }
00175
00176
00177 ts->A = unitcell[0];
00178 ts->B = unitcell[1];
00179 ts->C = unitcell[2];
00180 ts->alpha = 90.0 - asin(unitcell[3]) * 90.0 / M_PI_2;
00181 ts->beta = 90.0 - asin(unitcell[4]) * 90.0 / M_PI_2;
00182 ts->gamma = 90.0 - asin(unitcell[5]) * 90.0 / M_PI_2;
00183 } else {
00184
00185 if (fio_fseek(js->fd, framelen, FIO_SEEK_CUR))
00186 return MOLFILE_EOF;
00187 }
00188
00189 return MOLFILE_SUCCESS;
00190 }
00191
00192
00193 static void close_js_read(void *v) {
00194 jshandle *js = (jshandle *)v;
00195 fio_fclose(js->fd);
00196 free(js);
00197 }
00198
00199
00200 static void *open_js_write(const char *path, const char *filetype, int natoms) {
00201 jshandle *js;
00202
00203 js = (jshandle *)malloc(sizeof(jshandle));
00204 memset(js, 0, sizeof(jshandle));
00205 if (fio_open(path, FIO_WRITE, &js->fd) < 0) {
00206 fprintf(stderr, "Could not open file %s for writing\n", path);
00207 free(js);
00208 return NULL;
00209 }
00210
00211 js->natoms = natoms;
00212 js->with_unitcell = 1;
00213
00214
00215 fio_write_str(js->fd, JSHEADERSTRING);
00216 fio_write_int32(js->fd, JSMAGICNUMBER);
00217 fio_write_int32(js->fd, JSENDIANISM);
00218 fio_write_int32(js->fd, JSMAJORVERSION);
00219 fio_write_int32(js->fd, JSMINORVERSION);
00220
00221
00222 fio_write_int32(js->fd, natoms);
00223
00224
00225 js->nframes = 0;
00226 fio_write_int32(js->fd, js->nframes);
00227
00228 return js;
00229 }
00230
00231 static int write_js_timestep(void *v, const molfile_timestep_t *ts) {
00232 jshandle *js = (jshandle *)v;
00233 double unitcell[6];
00234
00235 js->nframes++;
00236
00237 unitcell[0] = ts->A;
00238 unitcell[1] = ts->B;
00239 unitcell[2] = ts->C;
00240 unitcell[3] = sin((M_PI_2 / 90.0) * (90.0 - ts->alpha));
00241 unitcell[4] = sin((M_PI_2 / 90.0) * (90.0 - ts->beta));
00242 unitcell[5] = sin((M_PI_2 / 90.0) * (90.0 - ts->gamma));
00243
00244
00245 fio_fwrite(ts->coords, js->natoms * 3 * sizeof(float), 1, js->fd);
00246
00247
00248 fio_fwrite(&unitcell[0], 6 * sizeof(double), 1, js->fd);
00249
00250 return MOLFILE_SUCCESS;
00251 }
00252
00253 static void close_js_write(void *v) {
00254 jshandle *js = (jshandle *)v;
00255
00256
00257 fio_fseek(js->fd, JSNFRAMESOFFSET, FIO_SEEK_SET);
00258 fio_write_int32(js->fd, js->nframes);
00259 fio_fseek(js->fd, 0, FIO_SEEK_END);
00260
00261 fio_fclose(js->fd);
00262 free(js);
00263 }
00264
00265
00266
00267
00268
00269 static molfile_plugin_t jsplugin = {
00270 vmdplugin_ABIVERSION,
00271 MOLFILE_PLUGIN_TYPE,
00272 "js",
00273 "js",
00274 "John Stone",
00275 0,
00276 8,
00277 VMDPLUGIN_THREADSAFE,
00278 "js",
00279 open_js_read,
00280 0,
00281 0,
00282 read_js_timestep,
00283 close_js_read,
00284 open_js_write,
00285 0,
00286 write_js_timestep,
00287 close_js_write,
00288 0,
00289 0,
00290 0
00291 };
00292
00293 VMDPLUGIN_API int VMDPLUGIN_init() {
00294 return VMDPLUGIN_SUCCESS;
00295 }
00296
00297 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00298 (*cb)(v, (vmdplugin_t *)&jsplugin);
00299 return VMDPLUGIN_SUCCESS;
00300 }
00301
00302 VMDPLUGIN_API int VMDPLUGIN_fini() {
00303 return VMDPLUGIN_SUCCESS;
00304 }
00305
00306
00307 #ifdef TEST_JSPLUGIN
00308
00309 #include <sys/time.h>
00310
00311
00312 double time_of_day(void) {
00313 #if defined(_MSC_VER)
00314 double t;
00315
00316 t = GetTickCount();
00317 t = t / 1000.0;
00318
00319 return t;
00320 #else
00321 struct timeval tm;
00322 struct timezone tz;
00323
00324 gettimeofday(&tm, &tz);
00325 return((double)(tm.tv_sec) + (double)(tm.tv_usec)/1000000.0);
00326 #endif
00327 }
00328
00329 int main(int argc, char *argv[]) {
00330 molfile_timestep_t timestep;
00331 void *v;
00332 jshandle *js;
00333 int i, natoms;
00334 float sizeMB =0.0, totalMB = 0.0;
00335 double starttime, endtime, totaltime = 0.0;
00336
00337 while (--argc) {
00338 ++argv;
00339 natoms = 0;
00340 v = open_js_read(*argv, "js", &natoms);
00341 if (!v) {
00342 fprintf(stderr, "open_js_read failed for file %s\n", *argv);
00343 return 1;
00344 }
00345 js = (jshandle *)v;
00346 sizeMB = ((natoms * 3.0) * js->nframes * 4.0) / (1024.0 * 1024.0);
00347 totalMB += sizeMB;
00348 printf("file: %s\n", *argv);
00349 printf(" %d atoms, %d frames, size: %6.1fMB\n", natoms, js->nframes, sizeMB);
00350
00351 starttime = time_of_day();
00352 timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
00353 for (i=0; i<js->nframes; i++) {
00354 int rc = read_js_timestep(v, natoms, ×tep);
00355 if (rc) {
00356 fprintf(stderr, "error in read_js_timestep on frame %d\n", i);
00357 return 1;
00358 }
00359 }
00360 endtime = time_of_day();
00361 close_js_read(v);
00362 totaltime += endtime - starttime;
00363 printf(" Time: %5.1f seconds\n", endtime - starttime);
00364 printf(" Speed: %5.1f MB/sec, %5.1f timesteps/sec\n", sizeMB / (endtime - starttime), (js->nframes / (endtime - starttime)));
00365 }
00366 printf("Overall Size: %6.1f MB\n", totalMB);
00367 printf("Overall Time: %6.1f seconds\n", totaltime);
00368 printf("Overall Speed: %5.1f MB/sec\n", totalMB / totaltime);
00369 return 0;
00370 }
00371
00372 #endif
00373