📄 dcdplugin.c
字号:
fio_fclose(dcd->fd); free(dcd); return NULL; } /* * Check that the file is big enough to really hold the number of sets * it claims to have. Then we'll use nsets to keep track of where EOF * should be. */ { off_t ndims, firstframesize, framesize, extrablocksize; off_t filesize; extrablocksize = dcd->charmm & DCD_HAS_EXTRA_BLOCK ? 48 + 8 : 0; ndims = dcd->charmm & DCD_HAS_4DIMS ? 4 : 3; firstframesize = (dcd->natoms+2) * ndims * sizeof(float) + extrablocksize; framesize = (dcd->natoms-dcd->nfixed+2) * ndims * sizeof(float) + extrablocksize; /* * It's safe to use ftell, even though ftell returns a long, because the * header size is < 4GB. */ filesize = stbuf.st_size - fio_ftell(dcd->fd) - firstframesize; if (filesize < 0) { fprintf(stderr, "DCD file '%s' appears to contain no timesteps.\n", path); fio_fclose(dcd->fd); free(dcd); return NULL; } dcd->nsets = filesize / framesize + 1; dcd->setsread = 0; } dcd->first = 1; dcd->x = (float *)malloc(dcd->natoms * sizeof(float)); dcd->y = (float *)malloc(dcd->natoms * sizeof(float)); dcd->z = (float *)malloc(dcd->natoms * sizeof(float)); if (!dcd->x || !dcd->y || !dcd->z) { fprintf(stderr, "Unable to allocate space for %d atoms.\n", dcd->natoms); free(dcd->x); free(dcd->y); free(dcd->z); fio_fclose(dcd->fd); free(dcd); return NULL; } *natoms = dcd->natoms; return dcd;}static int read_next_timestep(void *v, int natoms, molfile_timestep_t *ts) { dcdhandle *dcd; int i, j, rc; float unitcell[6]; unitcell[0] = unitcell[2] = unitcell[5] = 1.0f; unitcell[1] = unitcell[3] = unitcell[4] = 90.0f; dcd = (dcdhandle *)v; /* Check for EOF here; that way all EOF's encountered later must be errors */ if (dcd->setsread == dcd->nsets) return MOLFILE_EOF; dcd->setsread++; if (!ts) { if (dcd->first && dcd->nfixed) { /* We can't just skip it because we need the fixed atom coordinates */ rc = read_dcdstep(dcd->fd, dcd->natoms, dcd->x, dcd->y, dcd->z, unitcell, dcd->nfixed, dcd->first, dcd->freeind, dcd->fixedcoords, dcd->reverse, dcd->charmm); dcd->first = 0; return rc; /* XXX this needs to be updated */ } dcd->first = 0; /* XXX this needs to be changed */ return skip_dcdstep(dcd->fd, dcd->natoms, dcd->nfixed, dcd->charmm); } rc = read_dcdstep(dcd->fd, dcd->natoms, dcd->x, dcd->y, dcd->z, unitcell, dcd->nfixed, dcd->first, dcd->freeind, dcd->fixedcoords, dcd->reverse, dcd->charmm); dcd->first = 0; if (rc < 0) { fprintf(stderr, "read_dcdstep returned %d\n", rc); return MOLFILE_ERROR; } /* copy timestep data from plugin-local buffers to VMD's buffer */ /* XXX * This code is still the root of all evil. Just doing this extra copy * cuts the I/O rate of the DCD reader from 728 MB/sec down to * 394 MB/sec when reading from a ram filesystem. * For a physical disk filesystem, the I/O rate goes from * 187 MB/sec down to 122 MB/sec. Clearly this extra copy has to go. */ { int natoms = dcd->natoms; float *nts = ts->coords; const float *bufx = dcd->x; const float *bufy = dcd->y; const float *bufz = dcd->z; for (i=0, j=0; i<natoms; i++, j+=3) { nts[j ] = bufx[i]; nts[j + 1] = bufy[i]; nts[j + 2] = bufz[i]; } } ts->A = unitcell[0]; ts->B = unitcell[2]; ts->C = unitcell[5]; if (unitcell[1] >= -1.0 && unitcell[1] <= 1.0 && unitcell[3] >= -1.0 && unitcell[3] <= 1.0 && unitcell[4] >= -1.0 && unitcell[4] <= 1.0) { /* This file was generated by Charmm, or by NAMD > 2.5, with the angle */ /* cosines of the periodic cell angles written to the DCD file. */ /* This formulation improves rounding behavior for orthogonal cells */ /* so that the angles end up at precisely 90 degrees, unlike acos(). */ ts->alpha = 90.0 - asin(unitcell[4]) * 90.0 / M_PI_2; /* cosBC */ ts->beta = 90.0 - asin(unitcell[3]) * 90.0 / M_PI_2; /* cosAC */ ts->gamma = 90.0 - asin(unitcell[1]) * 90.0 / M_PI_2; /* cosAB */ } else { /* This file was likely generated by NAMD 2.5 and the periodic cell */ /* angles are specified in degrees rather than angle cosines. */ ts->alpha = unitcell[4]; /* angle between B and C */ ts->beta = unitcell[3]; /* angle between A and C */ ts->gamma = unitcell[1]; /* angle between A and B */ } return MOLFILE_SUCCESS;} static void close_file_read(void *v) { dcdhandle *dcd = (dcdhandle *)v; close_dcd_read(dcd->freeind, dcd->fixedcoords); fio_fclose(dcd->fd); free(dcd->x); free(dcd->y); free(dcd->z); free(dcd); }static void *open_dcd_write(const char *path, const char *filetype, int natoms) { dcdhandle *dcd; fio_fd fd; int rc; int istart, nsavc; double delta; int with_unitcell; int charmm; if (fio_open(path, FIO_WRITE, &fd) < 0) { fprintf(stderr, "Could not open file %s for writing\n", path); return NULL; } dcd = (dcdhandle *)malloc(sizeof(dcdhandle)); memset(dcd, 0, sizeof(dcdhandle)); dcd->fd = fd; istart = 0; /* starting timestep of DCD file */ nsavc = 1; /* number of timesteps between written DCD frames */ delta = 1.0; /* length of a timestep */ with_unitcell = 1; /* contains unit cell information (charmm format) */ charmm = DCD_IS_CHARMM; /* charmm-formatted DCD file */ if (with_unitcell) charmm |= DCD_HAS_EXTRA_BLOCK; rc = write_dcdheader(dcd->fd, "Created by DCD plugin", natoms, istart, nsavc, delta, with_unitcell, charmm); if (rc < 0) { fprintf(stderr, "write_dcdheader returned %d\n", rc); fio_fclose(dcd->fd); free(dcd); return NULL; } dcd->natoms = natoms; dcd->nsets = 0; dcd->istart = istart; dcd->nsavc = nsavc; dcd->with_unitcell = with_unitcell; dcd->charmm = charmm; dcd->x = (float *)malloc(natoms * sizeof(float)); dcd->y = (float *)malloc(natoms * sizeof(float)); dcd->z = (float *)malloc(natoms * sizeof(float)); return dcd;}static int write_timestep(void *v, const molfile_timestep_t *ts) { dcdhandle *dcd = (dcdhandle *)v; int i, rc, curstep; float *pos = ts->coords; double unitcell[6]; unitcell[0] = unitcell[2] = unitcell[5] = 1.0f; unitcell[1] = unitcell[3] = unitcell[4] = 90.0f; /* copy atom coords into separate X/Y/Z arrays for writing */ for (i=0; i<dcd->natoms; i++) { dcd->x[i] = *(pos++); dcd->y[i] = *(pos++); dcd->z[i] = *(pos++); } dcd->nsets++; curstep = dcd->istart + dcd->nsets * dcd->nsavc; unitcell[0] = ts->A; unitcell[2] = ts->B; unitcell[5] = ts->C; unitcell[1] = sin((M_PI_2 / 90.0) * (90.0 - ts->gamma)); /* cosAB */ unitcell[3] = sin((M_PI_2 / 90.0) * (90.0 - ts->beta)); /* cosAC */ unitcell[4] = sin((M_PI_2 / 90.0) * (90.0 - ts->alpha)); /* cosBC */ rc = write_dcdstep(dcd->fd, dcd->nsets, curstep, dcd->natoms, dcd->x, dcd->y, dcd->z, dcd->with_unitcell ? unitcell : NULL, dcd->charmm); if (rc < 0) { fprintf(stderr, "write_dcdstep returned %d\n", rc); return MOLFILE_ERROR; } return MOLFILE_SUCCESS;}static void close_file_write(void *v) { dcdhandle *dcd = (dcdhandle *)v; fio_fclose(dcd->fd); free(dcd->x); free(dcd->y); free(dcd->z); free(dcd);}/* * Initialization stuff here */static molfile_plugin_t dcdplugin = { vmdplugin_ABIVERSION, /* ABI version */ MOLFILE_PLUGIN_TYPE, /* type */ "dcd", /* short name */ "CHARMM,NAMD,XPLOR DCD Trajectory", /* pretty name */ "Justin Gullingsrud, John Stone", /* author */ 1, /* major version */ 2, /* minor version */ VMDPLUGIN_THREADSAFE, /* is reentrant */ "dcd", /* filename extension */ open_dcd_read, 0, 0, read_next_timestep, close_file_read, open_dcd_write, 0, write_timestep, close_file_write};int VMDPLUGIN_init() { return VMDPLUGIN_SUCCESS;}int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) { (*cb)(v, (vmdplugin_t *)&dcdplugin); return VMDPLUGIN_SUCCESS;}int VMDPLUGIN_fini() { return VMDPLUGIN_SUCCESS;} #ifdef TEST_DCDPLUGIN#include <sys/time.h>/* get the time of day from the system clock, and store it (in seconds) */double time_of_day(void) {#if defined(_MSC_VER) double t; t = GetTickCount(); t = t / 1000.0; return t;#else struct timeval tm; struct timezone tz; gettimeofday(&tm, &tz); return((double)(tm.tv_sec) + (double)(tm.tv_usec)/1000000.0);#endif}int main(int argc, char *argv[]) { molfile_timestep_t timestep; void *v; dcdhandle *dcd; int i, natoms; float sizeMB =0.0, totalMB = 0.0; double starttime, endtime, totaltime = 0.0; while (--argc) { ++argv; natoms = 0; v = open_dcd_read(*argv, "dcd", &natoms); if (!v) { fprintf(stderr, "open_dcd_read failed for file %s\n", *argv); return 1; } dcd = (dcdhandle *)v; sizeMB = ((natoms * 3.0) * dcd->nsets * 4.0) / (1024.0 * 1024.0); totalMB += sizeMB; printf("file: %s\n", *argv); printf(" %d atoms, %d frames, size: %6.1fMB\n", natoms, dcd->nsets, sizeMB); starttime = time_of_day(); timestep.coords = (float *)malloc(3*sizeof(float)*natoms); for (i=0; i<dcd->nsets; i++) { int rc = read_next_timestep(v, natoms, ×tep); if (rc) { fprintf(stderr, "error in read_next_timestep on frame %d\n", i); return 1; } } endtime = time_of_day(); close_file_read(v); totaltime += endtime - starttime; printf(" Time: %5.1f seconds\n", endtime - starttime); printf(" Speed: %5.1f MB/sec, %5.1f timesteps/sec\n", sizeMB / (endtime - starttime), (dcd->nsets / (endtime - starttime))); } printf("Overall Size: %6.1f MB\n", totalMB); printf("Overall Time: %6.1f seconds\n", totaltime); printf("Overall Speed: %5.1f MB/sec\n", totalMB / totaltime); return 0;} #endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -