示例#1
0
文件: jsplugin.c 项目: Almad/pymol
static void close_js_write(void *v) {
  jshandle *js = (jshandle *)v;

  /* update the trajectory header information */
  fio_fseek(js->fd, JSNFRAMESOFFSET, FIO_SEEK_SET);
  fio_write_int32(js->fd, js->nframes);
  fio_fseek(js->fd, 0, FIO_SEEK_END);

  fio_fclose(js->fd);

#if JSMAJORVERSION > 1
  if (js->bondfrom)
    free(js->bondfrom);
  if (js->bondto)
    free(js->bondto);
  if (js->bondorders)
    free(js->bondorders);

  if (js->angles)
    free(js->angles);
  if (js->dihedrals)
    free(js->dihedrals);
  if (js->impropers)
    free(js->impropers);
  if (js->cterms)
    free(js->cterms);
#endif

  free(js);
}
示例#2
0
文件: dcdplugin.c 项目: Almad/pymol
/* 
 * Skip past a timestep.  If there are fixed atoms, this cannot be used with
 * the first timestep.  
 * Input: fd - a file struct from which the header has already been read
 *        natoms - number of atoms per timestep
 *        nfixed - number of fixed atoms
 *        charmm - charmm flags as returned by read_dcdheader
 * Output: 0 on success, negative error code on failure.
 * Side effects: One timestep will be skipped; fd will be positioned at the
 *               next timestep.
 */
static int skip_dcdstep(fio_fd fd, int natoms, int nfixed, int charmm) {
  
  int seekoffset = 0;
  int rec_scale;

  if (charmm & DCD_HAS_64BIT_REC) {
    rec_scale=RECSCALE64BIT;
  } else {
    rec_scale=RECSCALE32BIT;
  }

  /* Skip charmm extra block */
  if ((charmm & DCD_IS_CHARMM) && (charmm & DCD_HAS_EXTRA_BLOCK)) {
    seekoffset += 4*rec_scale + 48 + 4*rec_scale;
  }

  /* For each atom set, seek past an int, the free atoms, and another int. */
  seekoffset += 3 * (2*rec_scale + natoms - nfixed) * 4;

  /* Assume that charmm 4th dim is the same size as the other three. */
  if ((charmm & DCD_IS_CHARMM) && (charmm & DCD_HAS_4DIMS)) {
    seekoffset += (2*rec_scale + natoms - nfixed) * 4;
  }
 
  if (fio_fseek(fd, seekoffset, FIO_SEEK_CUR)) return DCD_BADEOF;

  return DCD_SUCCESS;
}
示例#3
0
文件: dcdplugin.c 项目: Almad/pymol
static int read_charmm_extrablock(fio_fd fd, int charmm, int reverseEndian,
                                  float *unitcell) {
  int i, input_integer[2], rec_scale;

  if (charmm & DCD_HAS_64BIT_REC) {
    rec_scale = RECSCALE64BIT;
  } else {
    rec_scale = RECSCALE32BIT;
  }

  if ((charmm & DCD_IS_CHARMM) && (charmm & DCD_HAS_EXTRA_BLOCK)) {
    /* Leading integer must be 48 */
    input_integer[1] = 0;
    if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale)
      return DCD_BADREAD; 
    if (reverseEndian) swap4_aligned(input_integer, rec_scale);
    if ((input_integer[0]+input_integer[1]) == 48) {
      double tmp[6];
      if (fio_fread(tmp, 48, 1, fd) != 1) return DCD_BADREAD;
      if (reverseEndian) 
        swap8_aligned(tmp, 6);
      for (i=0; i<6; i++) unitcell[i] = (float)tmp[i];
    } else {
      /* unrecognized block, just skip it */
      if (fio_fseek(fd, (input_integer[0]+input_integer[1]), FIO_SEEK_CUR)) return DCD_BADREAD;
    }
    if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale) return DCD_BADREAD; 
  } 

  return DCD_SUCCESS;
}
示例#4
0
文件: dcd.c 项目: alejob/mdanalysis
int jump_to_frame(dcdhandle *dcd, int frame)
{
  int rc;
  if (frame > dcd->nsets) {
    return -1;
  }
  // Calculate file offset
  {
    off_t extrablocksize, ndims, firstframesize, framesize;
    off_t pos;
    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;
    // Use zero indexing
    if (frame == 0) {
      pos = dcd->header_size;
      dcd->first = 1;
    }
    else {
      pos = dcd->header_size + firstframesize + framesize * (frame-1);
      dcd->first = 0;
    }
    rc = fio_fseek(dcd->fd, pos, FIO_SEEK_SET);
  }
  dcd->setsread = frame;
  return rc;
}
示例#5
0
文件: dcdplugin.c 项目: Almad/pymol
/* 
 * Write a timestep to a dcd file
 * Input: fd - a file struct for which a dcd header has already been written
 *       curframe: Count of frames written to this file, starting with 1.
 *       curstep: Count of timesteps elapsed = istart + curframe * nsavc.
 *        natoms - number of elements in x, y, z arrays
 *        x, y, z: pointers to atom coordinates
 * Output: 0 on success, negative error code on failure.
 * Side effects: coordinates are written to the dcd file.
 */
static int write_dcdstep(fio_fd fd, int curframe, int curstep, int N, 
                  const float *X, const float *Y, const float *Z, 
                  const double *unitcell, int charmm) {
  int out_integer;

  if (charmm) {
    /* write out optional unit cell */
    if (unitcell != NULL) {
      out_integer = 48; /* 48 bytes (6 floats) */
      fio_write_int32(fd, out_integer);
      WRITE(fd, unitcell, out_integer);
      fio_write_int32(fd, out_integer);
    }
  }

  /* write out coordinates */
  out_integer = N*4; /* N*4 bytes per X/Y/Z array (N floats per array) */
  fio_write_int32(fd, out_integer);
  if (fio_fwrite((void *) X, out_integer, 1, fd) != 1) return DCD_BADWRITE;
  fio_write_int32(fd, out_integer);
  fio_write_int32(fd, out_integer);
  if (fio_fwrite((void *) Y, out_integer, 1, fd) != 1) return DCD_BADWRITE;
  fio_write_int32(fd, out_integer);
  fio_write_int32(fd, out_integer);
  if (fio_fwrite((void *) Z, out_integer, 1, fd) != 1) return DCD_BADWRITE;
  fio_write_int32(fd, out_integer);

  /* update the DCD header information */
  fio_fseek(fd, NFILE_POS, FIO_SEEK_SET);
  fio_write_int32(fd, curframe);
  fio_fseek(fd, NSTEP_POS, FIO_SEEK_SET);
  fio_write_int32(fd, curstep);
  fio_fseek(fd, 0, FIO_SEEK_END);

  return DCD_SUCCESS;
}
示例#6
0
文件: jsplugin.c 项目: Almad/pymol
static int read_js_timestep(void *v, int natoms, molfile_timestep_t *ts) {
  jshandle *js = (jshandle *)v;
  int framelen = (natoms * 3 * sizeof(float)) + (6 * sizeof(double));;

  /* if we have a valid ts pointer, read the timestep, otherwise skip it */ 
  if (ts != NULL) {
    int readlen; 
    fio_iovec iov[2];
    double unitcell[6];
    unitcell[0] = unitcell[2] = unitcell[5] = 1.0f;
    unitcell[1] = unitcell[3] = unitcell[4] = 90.0f;
  
    /* setup the I/O vector */
    iov[0].iov_base = (fio_caddr_t) ts->coords;   /* read coordinates    */
    iov[0].iov_len  = natoms * 3 * sizeof(float);
    iov[1].iov_base = (fio_caddr_t) &unitcell[0]; /* read PBC unit cell  */
    iov[1].iov_len  = 6 * sizeof(double);

    /* Do all of the reads with a single syscall, for peak efficiency. */
    /* On smart kernels, readv() causes only one context switch, and   */
    /* can effeciently scatter the reads to the various buffers.       */
    readlen = fio_readv(js->fd, &iov[0], 2); 
  
    /* check the number of read bytes versus what we expected */
    if (readlen != framelen)
      return MOLFILE_EOF;

    /* perform byte swapping if necessary */
    if (js->reverseendian) {
      swap4_aligned(ts->coords, natoms * 3);
      swap8_aligned(unitcell, 6);
    }

    /* copy unit cell values into VMD */
    ts->A = unitcell[0];
    ts->B = unitcell[1];
    ts->C = unitcell[2];
    ts->alpha = 90.0 - asin(unitcell[3]) * 90.0 / M_PI_2;
    ts->beta  = 90.0 - asin(unitcell[4]) * 90.0 / M_PI_2;
    ts->gamma = 90.0 - asin(unitcell[5]) * 90.0 / M_PI_2;
  } else {
    /* skip this frame, seek to the next frame */
    if (fio_fseek(js->fd, framelen, FIO_SEEK_CUR)) 
      return MOLFILE_EOF;
  }
 
  return MOLFILE_SUCCESS;
}
示例#7
0
文件: dcdplugin.c 项目: Almad/pymol
static int read_charmm_4dim(fio_fd fd, int charmm, int reverseEndian) {
  int input_integer[2],rec_scale;

  if (charmm & DCD_HAS_64BIT_REC) {
    rec_scale=RECSCALE64BIT;
  } else {
    rec_scale=RECSCALE32BIT;
  }
    
  /* If this is a CHARMm file and contains a 4th dimension block, */
  /* we must skip past it to avoid problems                       */
  if ((charmm & DCD_IS_CHARMM) && (charmm & DCD_HAS_4DIMS)) {
    input_integer[1]=0;
    if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale) return DCD_BADREAD;  
    if (reverseEndian) swap4_aligned(input_integer, rec_scale);
    if (fio_fseek(fd, (input_integer[0]+input_integer[1]), FIO_SEEK_CUR)) return DCD_BADREAD;
    if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale) return DCD_BADREAD;  
  }

  return DCD_SUCCESS;
}
示例#8
0
文件: dcd.c 项目: alejob/mdanalysis
static PyObject *
__reset_dcd_read(PyObject *self, PyObject *args)
{
  PyObject* temp;
  dcdhandle *dcd;
  int rc;

  if (! self) {
    /* we were in fact called as a module function, try to retrieve
       a matching object from args */
    if( !PyArg_ParseTuple(args, "O", &self) )
      return NULL;
  } else {
    /* we were obviously called as an object method so args should
       only have the int value. */
    if( !PyArg_ParseTuple(args, "") )
      return NULL;
  }

  if ( !PyObject_HasAttrString(self, "_dcd_C_ptr") ) {
    // Raise exception
    PyErr_SetString(PyExc_AttributeError, "_dcd_C_ptr is not an attribute");
    return NULL;
  }

  if ((temp = PyObject_GetAttrString(self, "_dcd_C_ptr")) == NULL) { // This gives me a New Reference
    // Raise exception
    PyErr_SetString(PyExc_AttributeError, "_dcd_C_ptr is not an attribute");
    return NULL;
  }

  dcd = (dcdhandle*)PyCObject_AsVoidPtr(temp);
  rc = fio_fseek(dcd->fd, dcd->header_size, FIO_SEEK_SET);
  dcd->setsread = 0;
  dcd->first = 1;
  Py_DECREF(temp);
  Py_INCREF(Py_None);
  return Py_None;
}
示例#9
0
文件: dcdplugin.c 项目: Almad/pymol
static void *open_dcd_read(const char *path, const char *filetype, 
    int *natoms) {
  dcdhandle *dcd;
  fio_fd fd;
  int rc;
  struct stat stbuf;

  if (!path) return NULL;

  /* See if the file exists, and get its size */
  memset(&stbuf, 0, sizeof(struct stat));
  if (stat(path, &stbuf)) {
    printf("dcdplugin) Could not access file '%s'.\n", path);
    return NULL;
  }

  if (fio_open(path, FIO_READ, &fd) < 0) {
    printf("dcdplugin) Could not open file '%s' for reading.\n", path);
    return NULL;
  }

  dcd = (dcdhandle *)malloc(sizeof(dcdhandle));
  memset(dcd, 0, sizeof(dcdhandle));
  dcd->fd = fd;

  if ((rc = read_dcdheader(dcd->fd, &dcd->natoms, &dcd->nsets, &dcd->istart, 
         &dcd->nsavc, &dcd->delta, &dcd->nfixed, &dcd->freeind, 
         &dcd->fixedcoords, &dcd->reverse, &dcd->charmm))) {
    print_dcderror("read_dcdheader", rc);
    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.
   */
  {
    fio_size_t ndims, firstframesize, framesize, extrablocksize;
    fio_size_t trjsize, filesize, curpos;
    int newnsets;

    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.
     */

    curpos = fio_ftell(dcd->fd); /* save current offset (end of header) */

#if defined(_MSC_VER) && defined(FASTIO_NATIVEWIN32)
    /* the stat() call is not 64-bit savvy on Windows             */
    /* so we have to use the fastio fseek/ftell routines for this */
    /* until we add a portable filesize routine for this purpose  */
    fio_fseek(dcd->fd, 0, FIO_SEEK_END);       /* seek to end of file */
    filesize = fio_ftell(dcd->fd);
    fio_fseek(dcd->fd, curpos, FIO_SEEK_SET);  /* return to end of header */
#else
    filesize = stbuf.st_size; /* this works ok on Unix machines */
#endif
    trjsize = filesize - curpos - firstframesize;
    if (trjsize < 0) {
      printf("dcdplugin) file '%s' appears to contain no timesteps.\n", path);
      fio_fclose(dcd->fd);
      free(dcd);
      return NULL;
    }

    newnsets = trjsize / framesize + 1;

    if (dcd->nsets > 0 && newnsets != dcd->nsets) {
      printf("dcdplugin) Warning: DCD header claims %d frames, file size indicates there are actually %d frames\n", dcd->nsets, newnsets);
    }

    dcd->nsets = newnsets; 
    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) {
    printf("dcdplugin) Unable to allocate space for %d atoms.\n", dcd->natoms);
    if (dcd->x)
      free(dcd->x);
    if (dcd->y)
      free(dcd->y);
    if (dcd->z)
      free(dcd->z);
    fio_fclose(dcd->fd);
    free(dcd);
    return NULL;
  }
  *natoms = dcd->natoms;
  return dcd;
}
示例#10
0
文件: dcdplugin.c 项目: Almad/pymol
/*
 * Read the header information from a dcd file.
 * Input: fd - a file struct opened for binary reading.
 * Output: 0 on success, negative error code on failure.
 * Side effects: *natoms set to number of atoms per frame
 *               *nsets set to number of frames in dcd file
 *               *istart set to starting timestep of dcd file
 *               *nsavc set to timesteps between dcd saves
 *               *delta set to value of trajectory timestep
 *               *nfixed set to number of fixed atoms 
 *               *freeind may be set to heap-allocated space
 *               *reverse set to one if reverse-endian, zero if not.
 *               *charmm set to internal code for handling charmm data.
 */
static int read_dcdheader(fio_fd fd, int *N, int *NSET, int *ISTART, 
                   int *NSAVC, double *DELTA, int *NAMNF, 
                   int **FREEINDEXES, float **fixedcoords, int *reverseEndian, 
                   int *charmm)
{
  unsigned int input_integer[2];  /* buffer space */
  int i, ret_val, rec_scale;
  union hdrufb_union {
  char charvalue[84];    /* char buffer used to store header */
  int intvalue;
  } hdrbuf;
  int NTITLE;
  int dcdcordmagic;
  char *corp = (char *) &dcdcordmagic;

  /* coordinate dcd file magic string 'CORD' */
  corp[0] = 'C';
  corp[1] = 'O';
  corp[2] = 'R';
  corp[3] = 'D';

  /* First thing in the file should be an 84.
   * some 64-bit compiles have a 64-bit record length indicator,
   * so we have to read two ints and check in a more complicated 
   * way. :-( */
  ret_val = READ(fd, input_integer, 2*sizeof(unsigned int));
  CHECK_FREAD(ret_val, "reading first int from dcd file");
  CHECK_FEOF(ret_val, "reading first int from dcd file");

  /* Check magic number in file header and determine byte order*/
  if ((input_integer[0]+input_integer[1]) == 84) {
    *reverseEndian=0;
    rec_scale=RECSCALE64BIT;
    printf("dcdplugin) detected CHARMM -i8 64-bit DCD file of native endianness\n");
  } else if (input_integer[0] == 84 && input_integer[1] == dcdcordmagic) {
    *reverseEndian=0;
    rec_scale=RECSCALE32BIT;
    printf("dcdplugin) detected standard 32-bit DCD file of native endianness\n");
  } else {
    /* now try reverse endian */
    swap4_aligned(input_integer, 2); /* will have to unswap magic if 32-bit */
    if ((input_integer[0]+input_integer[1]) == 84) {
      *reverseEndian=1;
      rec_scale=RECSCALE64BIT;
      printf("dcdplugin) detected CHARMM -i8 64-bit DCD file of opposite endianness\n");
    } else {
      swap4_aligned(&input_integer[1], 1); /* unswap magic (see above) */
      if (input_integer[0] == 84 && input_integer[1] == dcdcordmagic) {
        *reverseEndian=1;
        rec_scale=RECSCALE32BIT;
        printf("dcdplugin) detected standard 32-bit DCD file of opposite endianness\n");
      } else {
        /* not simply reversed endianism or -i8, something rather more evil */
        printf("dcdplugin) unrecognized DCD header:\n");
        printf("dcdplugin)   [0]: %10d  [1]: %10d\n", input_integer[0], input_integer[1]);
        printf("dcdplugin)   [0]: 0x%08x  [1]: 0x%08x\n", input_integer[0], input_integer[1]);
        return DCD_BADFORMAT;

      }
    }
  }

  /* check for magic string, in case of long record markers */
  if (rec_scale == RECSCALE64BIT) { 
    ret_val = READ(fd, input_integer, sizeof(unsigned int));
    if (input_integer[0] != dcdcordmagic) {
      printf("dcdplugin) failed to find CORD magic in CHARMM -i8 64-bit DCD file\n");
      return DCD_BADFORMAT;
    }
  }

  /* Buffer the entire header for random access */
  ret_val = READ(fd, hdrbuf.charvalue, 80);
  CHECK_FREAD(ret_val, "buffering header");
  CHECK_FEOF(ret_val, "buffering header");

  /* CHARMm-genereate DCD files set the last integer in the     */
  /* header, which is unused by X-PLOR, to its version number.  */
  /* Checking if this is nonzero tells us this is a CHARMm file */
  /* and to look for other CHARMm flags.                        */
  if (*((int *) (hdrbuf.charvalue + 76)) != 0) {
    (*charmm) = DCD_IS_CHARMM;
    if (*((int *) (hdrbuf.charvalue + 40)) != 0)
      (*charmm) |= DCD_HAS_EXTRA_BLOCK;

    if (*((int *) (hdrbuf.charvalue + 44)) == 1)
      (*charmm) |= DCD_HAS_4DIMS;

    if (rec_scale == RECSCALE64BIT)
      (*charmm) |= DCD_HAS_64BIT_REC;
  
  } else {
    (*charmm) = DCD_IS_XPLOR; /* must be an X-PLOR format DCD file */
  }

  if (*charmm & DCD_IS_CHARMM) {
    /* CHARMM and NAMD versions 2.1b1 and later */
    printf("dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)\n");
  } else {
    /* CHARMM and NAMD versions prior to 2.1b1  */
    printf("dcdplugin) X-PLOR format DCD file (also NAMD 2.0 and earlier)\n");
  }

  /* Store the number of sets of coordinates (NSET) */
  (*NSET) = *((int *)(hdrbuf.charvalue)); 
  if (*reverseEndian) swap4_unaligned(NSET, 1);

  /* Store ISTART, the starting timestep */
  (*ISTART) = *((int *) (hdrbuf.charvalue + 4));
  if (*reverseEndian) swap4_unaligned(ISTART, 1);

  /* Store NSAVC, the number of timesteps between dcd saves */
  (*NSAVC) = *((int *) (hdrbuf.charvalue + 8));
  if (*reverseEndian) swap4_unaligned(NSAVC, 1);

  /* Store NAMNF, the number of fixed atoms */
  (*NAMNF) = *((int *) (hdrbuf.charvalue + 32));
  if (*reverseEndian) swap4_unaligned(NAMNF, 1);

  /* Read in the timestep, DELTA */
  /* Note: DELTA is stored as a double with X-PLOR but as a float with CHARMm */
  if ((*charmm) & DCD_IS_CHARMM) {
    float ftmp;
    ftmp = *((float *)(hdrbuf.charvalue+36)); /* is this safe on Alpha? */
    if (*reverseEndian)
      swap4_aligned(&ftmp, 1);

    *DELTA = (double)ftmp;
  } else {
    (*DELTA) = *((double *)(hdrbuf.charvalue + 36));
    if (*reverseEndian) swap8_unaligned(DELTA, 1);
  }

  /* Get the end size of the first block */
  ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
  CHECK_FREAD(ret_val, "reading second 84 from dcd file");
  CHECK_FEOF(ret_val, "reading second 84 from dcd file");
  if (*reverseEndian) swap4_aligned(input_integer, rec_scale);

  if (rec_scale == RECSCALE64BIT) {
    if ((input_integer[0]+input_integer[1]) != 84) {
      return DCD_BADFORMAT;
    }
  } else {
    if (input_integer[0] != 84) {
      return DCD_BADFORMAT;
    }
  }
  
  /* Read in the size of the next block */
  input_integer[1] = 0;
  ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
  CHECK_FREAD(ret_val, "reading size of title block");
  CHECK_FEOF(ret_val, "reading size of title block");
  if (*reverseEndian) swap4_aligned(input_integer, rec_scale);

  if ((((input_integer[0]+input_integer[1])-4) % 80) == 0) {
    /* Read NTITLE, the number of 80 character title strings there are */
    ret_val = READ(fd, &NTITLE, sizeof(int));
    CHECK_FREAD(ret_val, "reading NTITLE");
    CHECK_FEOF(ret_val, "reading NTITLE");
    if (*reverseEndian) swap4_aligned(&NTITLE, 1);

    for (i=0; i<NTITLE; i++) {
      fio_fseek(fd, 80, FIO_SEEK_CUR);
      CHECK_FEOF(ret_val, "reading TITLE");
    }

    /* Get the ending size for this block */
    ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
    CHECK_FREAD(ret_val, "reading size of title block");
    CHECK_FEOF(ret_val, "reading size of title block");
  } else {
    return DCD_BADFORMAT;
  }

  /* Read in an integer '4' */
  input_integer[1] = 0;
  ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
  
  CHECK_FREAD(ret_val, "reading a '4'");
  CHECK_FEOF(ret_val, "reading a '4'");
  if (*reverseEndian) swap4_aligned(input_integer, rec_scale);

  if ((input_integer[0]+input_integer[1]) != 4) {
    return DCD_BADFORMAT;
  }

  /* Read in the number of atoms */
  ret_val = READ(fd, N, sizeof(int));
  CHECK_FREAD(ret_val, "reading number of atoms");
  CHECK_FEOF(ret_val, "reading number of atoms");
  if (*reverseEndian) swap4_aligned(N, 1);

  /* Read in an integer '4' */
  input_integer[1] = 0;
  ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
  CHECK_FREAD(ret_val, "reading a '4'");
  CHECK_FEOF(ret_val, "reading a '4'");
  if (*reverseEndian) swap4_aligned(input_integer, rec_scale);

  if ((input_integer[0]+input_integer[1]) != 4) {
    return DCD_BADFORMAT;
  }

  *FREEINDEXES = NULL;
  *fixedcoords = NULL;
  if (*NAMNF != 0) {
    (*FREEINDEXES) = (int *) calloc(((*N)-(*NAMNF)), sizeof(int));
    if (*FREEINDEXES == NULL)
      return DCD_BADMALLOC;

    *fixedcoords = (float *) calloc((*N)*4 - (*NAMNF), sizeof(float));
    if (*fixedcoords == NULL)
      return DCD_BADMALLOC;

    /* Read in index array size */
    input_integer[1]=0;
    ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
    CHECK_FREAD(ret_val, "reading size of index array");
    CHECK_FEOF(ret_val, "reading size of index array");
    if (*reverseEndian) swap4_aligned(input_integer, rec_scale);

    if ((input_integer[0]+input_integer[1]) != ((*N)-(*NAMNF))*4) {
      return DCD_BADFORMAT;
    }

    ret_val = READ(fd, (*FREEINDEXES), ((*N)-(*NAMNF))*sizeof(int));
    CHECK_FREAD(ret_val, "reading size of index array");
    CHECK_FEOF(ret_val, "reading size of index array");

    if (*reverseEndian)
      swap4_aligned((*FREEINDEXES), ((*N)-(*NAMNF)));

    input_integer[1]=0;
    ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
    CHECK_FREAD(ret_val, "reading size of index array");
    CHECK_FEOF(ret_val, "reading size of index array");
    if (*reverseEndian) swap4_aligned(input_integer, rec_scale);

    if ((input_integer[0]+input_integer[1]) != ((*N)-(*NAMNF))*4) {
      return DCD_BADFORMAT;
    }
  }

  return DCD_SUCCESS;
}
示例#11
0
文件: dcd.c 项目: alejob/mdanalysis
static PyObject *
__read_timeseries(PyObject *self, PyObject *args)
{
   PyObject *temp = NULL;
   PyArrayObject *coord = NULL;
   PyListObject *atoms = NULL;
   int lowerb = 0, upperb = 0, range=0;
   float *tempX = NULL, *tempY = NULL, *tempZ = NULL;
   int rc;
   int i, j, index;
   int n_atoms = 0, n_frames = 0;

   /* Stop = -1 is incorrect and causes an error, look for a fix of this in line
   469 */
   int start = 0, stop = -1, step = 1, numskip = 0, remaining_frames=0;
   dcdhandle *dcd = NULL;
   int *atomlist = NULL;
   npy_intp dimensions[3];
   float unitcell[6];
   const char* format = "afc";

   if (!self) {
      /* we were in fact called as a module function, try to retrieve
      a matching object from args */
      if( !PyArg_ParseTuple(args, "OO!|iiis", &self, &PyList_Type, &atoms, &start, &stop, &step, &format) )
      return NULL;
   } else {
      /* we were obviously called as an object method so args should
      only have the int value. */
      if( !PyArg_ParseTuple(args, "O!|iiis", &PyList_Type, &atoms, &start, &stop, &step, &format) )
      return NULL;
   }

   if ((temp = PyObject_GetAttrString(self, "_dcd_C_ptr")) == NULL) { // This gives me a New Reference
      // Raise exception
      PyErr_SetString(PyExc_AttributeError, "_dcd_C_ptr is not an attribute");
      return NULL;
   }

   dcd = (dcdhandle*)PyCObject_AsVoidPtr(temp);
   Py_DECREF(temp);

   n_frames = ((stop-start) / step);
   if ((stop-start) % step > 0) { n_frames++; }
   //n_frames = dcd->nsets / skip;
   n_atoms = PyList_Size((PyObject*)atoms);
   if (n_atoms == 0) {
      PyErr_SetString(PyExc_Exception, "No atoms passed into _read_timeseries function");
      return NULL;
   }
   atomlist = (int*)malloc(sizeof(int)*n_atoms);
   memset(atomlist, 0, sizeof(int)*n_atoms);

   // Get the atom indexes
   for (i=0;i<n_atoms;i++) {
      temp = PyList_GetItem((PyObject*)atoms, i); // Borrowed Reference
      if (temp==NULL) goto error;
      // Make sure temp is an integer
      /* TODO: this is not the proper check but [OB] cannot figure out how
      to check if this is a numpy.int64 or similar; PyInt_Check would fail
      on those (Issue 18)
      */
      if (!PyArray_IsAnyScalar((PyObject*)temp)) {
         PyErr_SetString(PyExc_ValueError, "Atom number is not an integer");
         goto error;
      }
      atomlist[i] = PyInt_AsLong(temp);
   }

   lowerb = atomlist[0]; upperb = atomlist[n_atoms-1];
   range = upperb-lowerb+1;

   // Figure out the format string
   if (strncasecmp(format, "afc", 3) == 0) {
      dimensions[0] = n_atoms; dimensions[1] = n_frames; dimensions[2] = 3;
   } else if (strncasecmp(format, "acf", 3) == 0) {
      dimensions[0] = n_atoms; dimensions[1] = 3; dimensions[2] = n_frames;
   } else if (strncasecmp(format, "fac", 3) == 0) {
      dimensions[0] = n_frames; dimensions[1] = n_atoms; dimensions[2] = 3;
   } else if (strncasecmp(format, "fca", 3) == 0) {
      dimensions[0] = n_frames; dimensions[1] = 3; dimensions[2] = n_atoms;
   } else if (strncasecmp(format, "caf", 3) == 0) {
      dimensions[0] = 3; dimensions[1] = n_atoms; dimensions[2] = n_frames;
   } else if (strncasecmp(format, "cfa", 3) == 0) {
      dimensions[0] = 3; dimensions[1] = n_frames; dimensions[2] = n_atoms;
   }

   coord = (PyArrayObject*) PyArray_SimpleNew(3, dimensions, NPY_DOUBLE);
   if (coord == NULL) goto error;

   // Reset trajectory
   rc = fio_fseek(dcd->fd, dcd->header_size, FIO_SEEK_SET);
   dcd->setsread = 0;
   dcd->first = 1;

   // Jump to starting frame
   jump_to_frame(dcd, start);

   // Now read through trajectory and get the atom pos
   tempX = (float*)malloc(sizeof(float)*range);
   tempY = (float*)malloc(sizeof(float)*range);
   tempZ = (float*)malloc(sizeof(float)*range);
   if ((tempX == NULL) | (tempY == NULL) || (tempZ == NULL)) {
      PyErr_SetString(PyExc_MemoryError, "Can't allocate temporary space for coordinate arrays");
      goto error;
   }

   remaining_frames = stop-start;
   for (i=0;i<n_frames;i++) {
      if (step > 1 && i>0) {
         // Check if we have fixed atoms
         // XXX not done
         /* Figure out how many steps to step over, if step = n, np array
            slicing treats this as skip over n-1, read the nth. */
         numskip = step -1;
         /* If the number to skip is greater than the number of frames left
            to be jumped over, just take one more step to reflect np slicing
            if there is a remainder, guaranteed to have at least one more
            frame.
         */
         if(remaining_frames < numskip){
            numskip = 1;
         }
         rc = skip_dcdstep(dcd->fd, dcd->natoms, dcd->nfixed, dcd->charmm, numskip);
         if (rc < 0) {
            // return an exception
            PyErr_SetString(PyExc_IOError, "Error skipping frame from DCD file");
            goto error;
         }
      }
      // on first iteration, numskip == 0, first set is always read.
      dcd->setsread += numskip;
      //now read from subset
      rc = read_dcdsubset(dcd->fd, dcd->natoms, lowerb, upperb, tempX, tempY, tempZ,
         unitcell, dcd->nfixed, dcd->first, dcd->freeind, dcd->fixedcoords,
         dcd->reverse, dcd->charmm);
      dcd->first = 0;
      dcd->setsread++;
      remaining_frames = stop - dcd->setsread;
      if (rc < 0) {
         // return an exception
         PyErr_SetString(PyExc_IOError, "Error reading frame from DCD file");
         goto error;

         }


      // Copy into Numeric array only those atoms we are interested in
      for (j=0;j<n_atoms;j++) {
         index = atomlist[j]-lowerb;

         /*
         * coord[a][b][c] = *(float*)(coord->data + a*coord->strides[0] + b*coord->strides[1] + c*coord->strides[2])
         */
         if (strncasecmp(format, "afc", 3) == 0) {
            *(double*)(coord->data + j*coord->strides[0] + i*coord->strides[1] + 0*coord->strides[2]) = tempX[index];
            *(double*)(coord->data + j*coord->strides[0] + i*coord->strides[1] + 1*coord->strides[2]) = tempY[index];
            *(double*)(coord->data + j*coord->strides[0] + i*coord->strides[1] + 2*coord->strides[2]) = tempZ[index];
         } else if (strncasecmp(format, "acf", 3) == 0) {
            *(double*)(coord->data + j*coord->strides[0] + 0*coord->strides[1] + i*coord->strides[2]) = tempX[index];
            *(double*)(coord->data + j*coord->strides[0] + 1*coord->strides[1] + i*coord->strides[2]) = tempY[index];
            *(double*)(coord->data + j*coord->strides[0] + 2*coord->strides[1] + i*coord->strides[2]) = tempZ[index];
         } else if (strncasecmp(format, "fac", 3) == 0) {
            *(double*)(coord->data + i*coord->strides[0] + j*coord->strides[1] + 0*coord->strides[2]) = tempX[index];
            *(double*)(coord->data + i*coord->strides[0] + j*coord->strides[1] + 1*coord->strides[2]) = tempY[index];
            *(double*)(coord->data + i*coord->strides[0] + j*coord->strides[1] + 2*coord->strides[2]) = tempZ[index];
         } else if (strncasecmp(format, "fca", 3) == 0) {
            *(double*)(coord->data + i*coord->strides[0] + 0*coord->strides[1] + j*coord->strides[2]) = tempX[index];
            *(double*)(coord->data + i*coord->strides[0] + 1*coord->strides[1] + j*coord->strides[2]) = tempY[index];
            *(double*)(coord->data + i*coord->strides[0] + 2*coord->strides[1] + j*coord->strides[2]) = tempZ[index];
         } else if (strncasecmp(format, "caf", 3) == 0) {
            *(double*)(coord->data + 0*coord->strides[0] + j*coord->strides[1] + i*coord->strides[2]) = tempX[index];
            *(double*)(coord->data + 1*coord->strides[0] + j*coord->strides[1] + i*coord->strides[2]) = tempY[index];
            *(double*)(coord->data + 2*coord->strides[0] + j*coord->strides[1] + i*coord->strides[2]) = tempZ[index];
         } else if (strncasecmp(format, "cfa", 3) == 0) {
            *(double*)(coord->data + 0*coord->strides[0] + i*coord->strides[1] + j*coord->strides[2]) = tempX[index];
            *(double*)(coord->data + 1*coord->strides[0] + i*coord->strides[1] + j*coord->strides[2]) = tempY[index];
            *(double*)(coord->data + 2*coord->strides[0] + i*coord->strides[1] + j*coord->strides[2]) = tempZ[index];
         }
      }
      // Check if we've been interupted by the user
      if (PyErr_CheckSignals() == 1) goto error;
   }

   // Reset trajectory
   rc = fio_fseek(dcd->fd, dcd->header_size, FIO_SEEK_SET);
   dcd->setsread = 0;
   dcd->first = 1;
   free(atomlist);
   free(tempX);
   free(tempY);
   free(tempZ);
   return PyArray_Return(coord);

   error:
   // Reset trajectory
   rc = fio_fseek(dcd->fd, dcd->header_size, FIO_SEEK_SET);
   dcd->setsread = 0;
   dcd->first = 1;
   Py_XDECREF(coord);
   if (atomlist != NULL) free(atomlist);
   if (tempX != NULL) free(tempX);
   if (tempY != NULL) free(tempY);
   if (tempZ != NULL) free(tempZ);
   return NULL;
}