Exemplo n.º 1
0
static int read_fixed_atoms(fio_fd fd, int N, int num_free, const int *indexes,
                            int reverseEndian, const float *fixedcoords, 
                            float *freeatoms, float *pos, int charmm) {
  int i, input_integer[2], rec_scale;
  
  if(charmm & DCD_HAS_64BIT_REC) {
    rec_scale=RECSCALE64BIT;
  } else {
    rec_scale=RECSCALE32BIT;
  }
  
  /* Read leading integer */
  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]) != 4*num_free) return DCD_BADFORMAT;
  
  /* Read free atom coordinates */
  if (fio_fread(freeatoms, 4*num_free, 1, fd) != 1) return DCD_BADREAD;
  if (reverseEndian)
    swap4_aligned(freeatoms, num_free);

  /* Copy fixed and free atom coordinates into position buffer */
  memcpy(pos, fixedcoords, 4*N);
  for (i=0; i<num_free; i++)
    pos[indexes[i]-1] = freeatoms[i];

  /* Read trailing integer */ 
  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]) != 4*num_free) return DCD_BADFORMAT;

  return DCD_SUCCESS;
}
Exemplo n.º 2
0
void IMDSimBlocking::send_forces(int num, int *ind, float *forces) {
  // Total data sent will be one int and three floats for each atom 
  if (!isConnected()) return;
  if (need2flip) {
    swap4_aligned(ind, num);
    swap4_aligned(forces, 3*num);
  }
  if (imd_send_mdcomm(sock, num, ind, forces)) {
    msgErr << "Error sending MDComm indices+forces" << sendmsg;
    disconnect();
  }
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
void IMDSimBlocking::process_energies(int32 /* length */) {
  if (imd_recv_energies(sock, &imdEnergies)) {
    msgErr << "Error reading energies!" << sendmsg;
    disconnect();   
  }
  else {
    if (need2flip) swap4_aligned(&imdEnergies, sizeof(imdEnergies) / 4);
  }
}
Exemplo n.º 5
0
static int read_pbeq_data(void *v, int set, float *datablock,
                         float *colorblock) {
  pbeq_t *pbeq = (pbeq_t *)v;
  int ndata = pbeq->ndata;
  int nclx = pbeq->nclx;
  int ncly = pbeq->ncly;
  int nclz = pbeq->nclz;
  FILE *fd = pbeq->fd;
  int trash;

  // skip first Fortran length record for 
  // WRITE(UNIT)(PHI(I),I=1,NCLX*NCLY*NCLZ)
  if (fread(&trash, 4, 1, fd) != 1)
    return MOLFILE_ERROR;

  /* Read the densities. Order for file is z fast, y medium, x slow */
  int x, y, z;
  int count=0;
  for (x=0; x<nclx; x++) {
    for (y=0; y<ncly; y++) {
      for (z=0; z<nclz; z++) {
        int addr = z*nclx*ncly + y*nclx + x;
        if (fread(datablock + addr, 4, 1, fd) != 1) {
          printf("pbeqplugin) Error reading potential map cell: %d,%d,%d\n", x, y, z);
          printf("pbeqplugin) offset: %d\n", ftell(fd));
          return MOLFILE_ERROR;
        }
        count++;
      }
    }
  }


#if 0
  // skip last Fortran length record for 
  // WRITE(UNIT)(PHI(I),I=1,NCLX*NCLY*NCLZ)
  if (fread(&trash, 4, 1, fd) != 1)
    return NULL;

  // print debugging info for early versions
  printf("pbeqplugin) read %d phi values from block\n", count);
  for (x=0; x<1000000; x++) {
    int trash;
    if (fread(&trash, 4, 1, fd) != 1) {
      printf("pbeqplugin) read %d extra phi values past the end of the block\n", x);
      break;
    }
  }   
#endif

  if (pbeq->swap) {
    swap4_aligned(datablock, ndata);
  }

  return MOLFILE_SUCCESS;
}
Exemplo n.º 6
0
static int read_ccp4_data(void *v, int set, float *datablock,
                         float *colorblock) {
  ccp4_t *ccp4 = (ccp4_t *)v;
  float *rowdata;
  int x, y, z, xSize, ySize, zSize, xySize, extent[3], coord[3];
  FILE *fd = ccp4->fd;

  xSize = ccp4->vol[0].xsize;
  ySize = ccp4->vol[0].ysize;
  zSize = ccp4->vol[0].zsize;
  xySize = xSize * ySize;

  // coord = <col, row, sec>
  // extent = <colSize, rowSize, secSize>
  extent[ccp4->xyz2crs[0]] = xSize;
  extent[ccp4->xyz2crs[1]] = ySize;
  extent[ccp4->xyz2crs[2]] = zSize;

  rowdata = new float[extent[0]];

  fseek(fd, ccp4->dataOffset, SEEK_SET);

  for (coord[2] = 0; coord[2] < extent[2]; coord[2]++) {
    for (coord[1] = 0; coord[1] < extent[1]; coord[1]++) {
      // Read an entire row of data from the file, then write it into the
      // datablock with the correct slice ordering.
      if (feof(fd)) {
        printf("ccp4plugin) Unexpected end-of-file.\n");
        return MOLFILE_ERROR;
      }
      if (ferror(fd)) {
        printf("ccp4plugin) Problem reading the file.\n");
        return MOLFILE_ERROR;
      }
      if ( fread(rowdata, sizeof(float), extent[0], fd) != extent[0] ) {
        printf("ccp4plugin) Error reading data row.\n");
        return MOLFILE_ERROR;
      }

      for (coord[0] = 0; coord[0] < extent[0]; coord[0]++) {
        x = coord[ccp4->xyz2crs[0]];
        y = coord[ccp4->xyz2crs[1]];
        z = coord[ccp4->xyz2crs[2]];
        datablock[x + y*xSize + z*xySize] = rowdata[coord[0]];
      }
    }
  }

  if (ccp4->swap == 1)
    swap4_aligned(datablock, xySize * zSize);

  delete [] rowdata;

  return MOLFILE_SUCCESS;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
static int read_plt_data(void *v, int set, float *datablock,
                         float *colorblock) {
  plt_t *plt = (plt_t *)v;
  int swap, ndata;
  FILE *fd = plt->fd;

  swap = plt->swap;
  ndata = plt->vol[0].xsize * plt->vol[0].ysize * plt->vol[0].zsize;

  // Read the densities. Order for file is x fast, y medium, z slow
  if ( fread(datablock, sizeof(float), ndata, fd) != ndata ) {
    fprintf(stderr, "pltplugin) Error reading data, not enough values read.\n");
    return MOLFILE_ERROR;
  }

  if (swap) 
    swap4_aligned(datablock, ndata);

  return MOLFILE_SUCCESS;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
static int read_spider_data(void *v, int set, float *datablock,
                         float *colorblock) {
  spider_t *vol = (spider_t *)v;
  FILE *fd = vol->fd;
  int xsize, ysize, zsize, xysize, total;

  xsize = vol->vol[0].xsize;
  ysize = vol->vol[0].ysize;
  zsize = vol->vol[0].zsize;
  xysize = xsize * ysize;
  total = xysize * zsize;

  // Read the values from the file
  fread(datablock, total * sizeof(float), 1, fd);

  // perform byte swapping if necessary
  if (vol->byteswap) 
    swap4_aligned(datablock, total);

  return MOLFILE_SUCCESS;
}
Exemplo n.º 11
0
static void *open_plt_read(const char *filepath, const char *filetype,
    int *natoms) {
  FILE *fd;
  plt_t *plt;
  int swap=0;
  // File header data:
  int intHeader[5];
  float floatHeader[6];
  
  fd = fopen(filepath, "rb");
  if (!fd) {
    fprintf(stderr, "pltplugin) Error opening file.\n");
    return NULL;
  }

  // Integer header info: rank (always 3), surface type, z length, y length, 
  // x length.
  fread(intHeader, sizeof(int), 5, fd);
  if (intHeader[0] != 3) {
    // check if the bytes need to be swapped
    swap4_aligned(intHeader, 5);
    if (intHeader[0] == 3) 
      swap = 1;
    else {
      fprintf(stderr, "pltplugin) Incorrect header.\n");
      return NULL;
    }
  }

  // Float header info: z min, z max, y min, y max, xmin, x max.
  fread(floatHeader, sizeof(float), 6, fd);
  if (swap)
    swap4_aligned(floatHeader, 6);

  // Allocate and initialize the plt structure
  plt = new plt_t;
  plt->fd = fd;
  plt->vol = NULL;
  *natoms = MOLFILE_NUMATOMS_NONE;
  plt->nsets = 1; // this file contains only one data set
  plt->swap = swap;

  plt->vol = new molfile_volumetric_t[1];
  strcpy(plt->vol[0].dataname, "PLT Electron Density Map");

  // Best guesses for unit cell information, as none is included in the plt
  // file format.
  plt->vol[0].origin[0] = floatHeader[4];
  plt->vol[0].origin[1] = floatHeader[2];
  plt->vol[0].origin[2] = floatHeader[0];

  plt->vol[0].xaxis[0] = floatHeader[5] - floatHeader[4];
  plt->vol[0].xaxis[1] = 0;
  plt->vol[0].xaxis[2] = 0;

  plt->vol[0].yaxis[0] = 0;
  plt->vol[0].yaxis[1] = floatHeader[3] - floatHeader[2];
  plt->vol[0].yaxis[2] = 0;
  
  plt->vol[0].zaxis[0] = 0;
  plt->vol[0].zaxis[1] = 0;
  plt->vol[0].zaxis[2] = floatHeader[1] - floatHeader[0];

  plt->vol[0].xsize = intHeader[4];
  plt->vol[0].ysize = intHeader[3];
  plt->vol[0].zsize = intHeader[2];

  plt->vol[0].has_color = 0;

  return plt;
}
Exemplo n.º 12
0
/*
 * 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;
}
Exemplo n.º 13
0
void cMRC<T>::readHeader(const std::string& fileName, cMapHeader& header)
{
    const std::string   funcName("void cMRC::readHeader("
                                    "const std::string& fileName, "
                                    "cMapHeader& header)");

    checkExtension(fileName);

    std::ifstream       fileHandle;

    fileHandle.open(fileName.c_str(), std::ifstream::binary);
    assure(fileHandle, fileName.c_str());

    int             map_dim[3], data_mode, origin[3], cell_grid[3], axes_order[3];
    float           cell_dim[3], cell_angle[3];
    float           density_min, density_max, density_mean;
    int             spacegroup, sym_byte;
    char            mapStamp[] = "    ";

    fileHandle.read((char*) map_dim,       3*sizeof(int));         // NX, NY, NZ
    fileHandle.read((char*) &data_mode,      sizeof(int));         // MODE
    fileHandle.read((char*) origin,        3*sizeof(int));         // NXSTART, NYSTART, NZSTART
    fileHandle.read((char*) cell_grid,     3*sizeof(int));         // MX, MY, MZ
    fileHandle.read((char*) cell_dim,      3*sizeof(float));       // CELLA
    fileHandle.read((char*) cell_angle,    3*sizeof(float));       // CELLB
    fileHandle.read((char*) axes_order,    3*sizeof(int));         // MAPC, MAPR, MAPS
    fileHandle.read((char*) &density_min,    sizeof(float));       // DMIN
    fileHandle.read((char*) &density_max,    sizeof(float));       // DMAX
    fileHandle.read((char*) &density_mean,   sizeof(float));       // DMEAN
    fileHandle.read((char*) &spacegroup,     sizeof(int));         // ISPG
    fileHandle.read((char*) &sym_byte,       sizeof(int));         // NSYMBT

    fileHandle.seekg(208, std::ios::beg);
    fileHandle.read((char*) mapStamp,      4*sizeof(char));        // MAP

    // check for the need of byte swapping
    header.edian_swap = false;
    if (map_dim[0] < 0 || map_dim[0] > 100000 ||
        map_dim[1] < 0 || map_dim[1] > 100000 ||
        map_dim[2] < 0 || map_dim[2] > 100000) {
        header.edian_swap = true;
    }

    if (header.edian_swap) {
        swap4_aligned(map_dim, 3);
        swap4_aligned(&data_mode, 1);
        swap4_aligned(origin, 3);
        swap4_aligned(cell_grid, 3);
        swap4_aligned(cell_dim, 3);
        swap4_aligned(cell_angle, 3);
        swap4_aligned(axes_order, 3);
        swap4_aligned(&density_min, 1);
        swap4_aligned(&density_max, 1);
        swap4_aligned(&density_mean, 1);
        swap4_aligned(&spacegroup, 1);
        swap4_aligned(&sym_byte, 1);
        swap4_aligned(mapStamp, 1);
    }

    // check data mode and 'MAP' stamp
    require(data_mode >=0 || data_mode <= 2,
            funcName + ": non-supported data type (data_mode != 0,1,2) in" + fileName);
    if (map_dim[2] != 1) {
        require(strcmp(mapStamp, "MAP ") == 0,
                funcName + ": cannot detect the 'MAP' string in " + fileName);
    }

    // check symmetry validity
    size_t      fileSize, dataOffset,
                nelement = (size_t) map_dim[0] * (size_t) map_dim[1] * (size_t) map_dim[2];

    fileHandle.seekg(0, std::ios::end);
    fileSize   = fileHandle.tellg();

    switch (data_mode) {
        case 0:            // int8
            dataOffset = fileSize - 1 * nelement;
            break;
        case 1:            // int16
            dataOffset = fileSize - 2 * nelement;
            break;
        case 2:            // float32
            dataOffset = fileSize - 4 * nelement;
            break;
        case 6:            // uint16
            dataOffset = fileSize - 2 * nelement;
            break;
        default:
            ERROR(funcName, "unsupported data mode in reading " + fileName);
    }

    if ((int) dataOffset != (CCP4_HEADER_SIZE + sym_byte)) {
        if (dataOffset < CCP4_HEADER_SIZE) {
            ERROR(funcName, "file " + fileName + " has size smaller than expected");
        }
        else if (dataOffset == CCP4_HEADER_SIZE) {
            ERROR(funcName, "the symmetry record in " + fileName + " is bogus");
        }
        else {
            ERROR(funcName, "file " + fileName + " has size larger than expected");
        }
    }

    // save header information
    header.file_name = fileName;

    header.data_mode  = data_mode;
    header.spacegroup = spacegroup;
    header.sym_byte   = sym_byte;

    header.cell_dim[0] = cell_dim[0];
    header.cell_dim[1] = cell_dim[1];
    header.cell_dim[2] = cell_dim[2];

    header.cell_angle[0] = cell_angle[0];
    header.cell_angle[1] = cell_angle[1];
    header.cell_angle[2] = cell_angle[2];

    header.map_dim[0] = map_dim[0];
    header.map_dim[1] = map_dim[1];
    header.map_dim[2] = map_dim[2];

    header.origin[0] = origin[0];
    header.origin[1] = origin[1];
    header.origin[2] = origin[2];

    header.cell_grid[0] = cell_grid[0];
    header.cell_grid[1] = cell_grid[1];
    header.cell_grid[2] = cell_grid[2];

    header.axes_order[0] = axes_order[0];
    header.axes_order[1] = axes_order[1];
    header.axes_order[2] = axes_order[2];

    header.min  = density_min;
    header.max  = density_max;
    header.mean = density_mean;

    fileHandle.close();
}
Exemplo n.º 14
0
void cMRC<T>::readData(const std::string& fileName, cData3<T>& object, cMapHeader& header)
{
    const std::string   funcName("void cMRC::readData(const std::string& fileName, "
                                    "cData3<T>& object, cMapHeader& header)");

    checkExtension(fileName);

    std::ifstream       fileHandle;

    fileHandle.open(fileName.c_str(), std::ifstream::binary);
    assure(fileHandle, fileName.c_str());

    // allocate new memory
    object.memReAlloc(cVector3<size_t>((size_t) header.map_dim[0],
                                       (size_t) header.map_dim[1],
                                       (size_t) header.map_dim[2]));

    // seek to data starting point
    fileHandle.seekg(CCP4_HEADER_SIZE + header.sym_byte, std::ios::beg);

    unsigned char*      bufferData   = NULL;
    size_t              bufferLength = (size_t) std::pow(2,header.data_mode) * header.getNelement();

    array_new(bufferData, bufferLength);
    fileHandle.read((char*) bufferData, bufferLength);

    switch (header.data_mode) {
        case 0:            // int8
            array_index_col2row((int8_t*) bufferData, object.getAddrData(),
                                object.getNrow(), object.getNcol(), object.getNsec());

            break;
        case 1:            // int16
            if (header.edian_swap) { swap2_aligned(bufferData, header.getNelement()); }

            array_index_col2row((int16_t*) bufferData, object.getAddrData(),
                                object.getNrow(), object.getNcol(), object.getNsec());

            break;
        case 2:            // float32
            if (header.edian_swap) { swap4_aligned(bufferData, header.getNelement()); }

            array_index_col2row((float*) bufferData, object.getAddrData(),
                                object.getNrow(), object.getNcol(), object.getNsec());

            break;
        case 6:            // uint16
            if (header.edian_swap) { swap2_aligned(bufferData, header.getNelement()); }

            array_index_col2row((uint16_t*) bufferData, object.getAddrData(),
                                object.getNrow(), object.getNcol(), object.getNsec());

            break;
        default:
            ERROR(funcName, "unsupported data mode in reading " + fileName);
    }

    array_delete(bufferData);

    fileHandle.close();
}
Exemplo n.º 15
0
static void *open_pbeq_read(const char *filepath, const char *filetype,
    int *natoms) {
  FILE *fd;
  pbeq_t *pbeq;
  int nclx, ncly, nclz;
  int trash, length;
  double dcel; 
  double xbcen, ybcen, zbcen;
  double epsw, epsp, conc, tmemb, zmemb, epsm;
  int swap=0; 

  fd = fopen(filepath, "rb");
  if (!fd) {
    printf("pbeqplugin) Error opening file %s.\n", filepath);
    return NULL;
  }

  // skip first Fortran length record for
  // WRITE(UNIT) NCLX,NCLY,NCLZ,DCEL,XBCEN,YBCEN,ZBCEN
  if (fread(&length, 4, 1, fd) != 1)
    return NULL;

  if (fread(&nclx, 4, 1, fd) != 1)
    return NULL;
  if (fread(&ncly, 4, 1, fd) != 1)
    return NULL;
  if (fread(&nclz, 4, 1, fd) != 1)
    return NULL;

  // test endianness first
  if (length != 44) {
    swap = 1;
    swap4_aligned(&length, 1);
    if (length != 44) {
      printf("pbeqplugin) length record != 44, unrecognized format (length: %d)\n", length);
      return NULL;
    }
  }

  if (swap) {
    swap4_aligned(&nclx, 1);
    swap4_aligned(&ncly, 1);
    swap4_aligned(&nclz, 1);
  } 

  // this is a risky strategy for detecting endianness, 
  // but it works so far, and the charmm potential maps don't
  // have version numbers, magic numbers, or anything else that we
  // might otherwise use for this purpose.
  if ((nclx > 4000 && ncly > 4000 && nclz > 4000) ||
      (nclx * ncly * nclz < 0)) {
    printf("pbeqplugin) inconclusive byte ordering, bailing out\n");
    return NULL;
  }

  // read the rest of the header
  if (fread(&dcel, 8, 1, fd) != 1) 
    return NULL;
  if (fread(&xbcen, 8, 1, fd) != 1) 
    return NULL;
  if (fread(&ybcen, 8, 1, fd) != 1) 
    return NULL;
  if (fread(&zbcen, 8, 1, fd) != 1) 
    return NULL;

  // skip second Fortran length record for
  // WRITE(UNIT) NCLX,NCLY,NCLZ,DCEL,XBCEN,YBCEN,ZBCEN
  if (fread(&trash, 4, 1, fd) != 1)
    return NULL;

  // skip first Fortran length record for 
  // WRITE(UNIT) EPSW,EPSP,CONC,TMEMB,ZMEMB,EPSM
  if (fread(&trash, 4, 1, fd) != 1)
    return NULL;

  if (fread(&epsw, 8, 1, fd) != 1) 
    return NULL;
  if (fread(&epsp, 8, 1, fd) != 1) 
    return NULL;
  if (fread(&conc, 8, 1, fd) != 1) 
    return NULL;
  if (fread(&tmemb, 8, 1, fd) != 1) 
    return NULL;
  if (fread(&zmemb, 8, 1, fd) != 1) 
    return NULL;
  if (fread(&epsm, 8, 1, fd) != 1) 
    return NULL;

  // skip second Fortran length record for 
  // WRITE(UNIT) EPSW,EPSP,CONC,TMEMB,ZMEMB,EPSM
  if (fread(&trash, 4, 1, fd) != 1)
    return NULL;

  // byte swap the header data if necessary
  if (swap) {
    swap8_aligned(&dcel, 1);
    swap8_aligned(&xbcen, 1);
    swap8_aligned(&ybcen, 1);
    swap8_aligned(&zbcen, 1);
    swap8_aligned(&epsw, 1);
    swap8_aligned(&epsp, 1);
    swap8_aligned(&conc, 1);
    swap8_aligned(&tmemb, 1);
    swap8_aligned(&zmemb, 1);
    swap8_aligned(&epsm, 1);
  }

#if 0
  // print header info for debugging of early versions
  printf("pbeqplugin) nclx:%d nxly:%d nclz:%d\n", nclx, ncly, nclz);
  printf("pbeqplugin) dcel: %f\n", dcel); 
  printf("pbeqplugin) x/y/zbcen: %g %g %g\n", xbcen, ybcen, zbcen); 
  printf("pbeqplugin) epsw/p: %g %g  conc: %g  tmemb: %g zmemb: %g  epsm: %g\n",
         epsw, epsp, conc, tmemb, zmemb, epsm);
#endif

  /* Allocate and initialize the pbeq structure */
  pbeq = new pbeq_t;
  pbeq->fd = fd;
  pbeq->vol = NULL;
  *natoms = MOLFILE_NUMATOMS_NONE;
  pbeq->nsets = 1; /* this file contains only one data set */
  pbeq->ndata = nclx*ncly*nclz;
  pbeq->nclx = nclx;
  pbeq->ncly = ncly;
  pbeq->nclz = nclz;
  pbeq->swap = swap;

  pbeq->vol = new molfile_volumetric_t[1];
  strcpy(pbeq->vol[0].dataname, "CHARMM PBEQ Potential Map");

  pbeq->vol[0].origin[0] = -0.5*((nclx-1) * dcel) + xbcen;
  pbeq->vol[0].origin[1] = -0.5*((ncly-1) * dcel) + ybcen;
  pbeq->vol[0].origin[2] = -0.5*((nclz-1) * dcel) + zbcen;

  // print origin info, for debuggin of early versions
  printf("pbeqplugin) box LL origin: %g %g %g\n", 
         pbeq->vol[0].origin[0],
         pbeq->vol[0].origin[1],
         pbeq->vol[0].origin[2]);

  pbeq->vol[0].xaxis[0] = (nclx-1) * dcel;
  pbeq->vol[0].xaxis[1] = 0;
  pbeq->vol[0].xaxis[2] = 0;

  pbeq->vol[0].yaxis[0] = 0;
  pbeq->vol[0].yaxis[1] = (ncly-1) * dcel;
  pbeq->vol[0].yaxis[2] = 0;

  pbeq->vol[0].zaxis[0] = 0;
  pbeq->vol[0].zaxis[1] = 0;
  pbeq->vol[0].zaxis[2] = (nclz-1) * dcel;

  pbeq->vol[0].xsize = nclx;
  pbeq->vol[0].ysize = ncly;
  pbeq->vol[0].zsize = nclz;

  pbeq->vol[0].has_color = 0;

  return pbeq;
}
Exemplo n.º 16
0
static void *open_spider_read(const char *filepath, const char *filetype,
    int *natoms) {
  FILE *fd;
  spider_t *vol;
  int total;

  /* file header buffer union */ 
  union buffer {
    float fbuf[256];  
    char  cbuf[1024];
  } h;
 
  fd = fopen(filepath, "rb");
  if (!fd) {
    fprintf(stderr, "spiderplugin) Error opening file.\n");
    return NULL;
  }

  /* allocate and initialize the spider structure */
  vol = new spider_t;
  vol->fd = fd;
  vol->vol = NULL;
  vol->byteswap = 0;
  *natoms = MOLFILE_NUMATOMS_NONE;
  vol->nsets = 1; /* this file contains only one data set */

  vol->vol = new molfile_volumetric_t[1];
  strcpy(vol->vol[0].dataname, "SPIDER map");

  // read SPIDER file header
  if (fread(&h.cbuf, 1024, 1, fd) < 1) {
    printf("spiderplugin) failed to read file header\n");
    return NULL; 
  } 

  // perform sanity checks on header values to see if we 
  // need to do byte swapping, or abort.
  vol->nslice   = (h.fbuf[0] < 0) ? -h.fbuf[0] : h.fbuf[0];
  vol->nrow     = h.fbuf[1];
  vol->nsam     = h.fbuf[11];
  total = vol->nslice * vol->nrow * vol->nsam;

  if (total <= 0 || 
      vol->nsam   <= 0 || vol->nsam   > 100000 ||
      vol->nrow   <= 0 || vol->nrow   > 100000 ||
      vol->nslice <= 0 || vol->nslice > 100000) { 

    printf("spiderplugin) Non-native endianness or unusual file detected\n");

    // byte swap the entire header in hopes of making sense of this gibberish
    vol->byteswap = 1;
    swap4_aligned(&h.fbuf, 256);

    vol->nslice   = (h.fbuf[0] < 0) ? -h.fbuf[0] : h.fbuf[0];
    vol->nrow     = h.fbuf[1];
    vol->nsam     = h.fbuf[11];
    total = vol->nslice * vol->nrow * vol->nsam;

    // check to see if we still have gibberish or not, bail out if we do.
    if (total <= 0 || 
      vol->nsam   <= 0 || vol->nsam   > 100000 ||
      vol->nrow   <= 0 || vol->nrow   > 100000 ||
      vol->nslice <= 0 || vol->nslice > 100000) { 
      printf("spiderplugin) bad header values in file fail sanity checks\n");
      delete [] vol->vol;
      delete vol;
      return NULL;
    }
  }
  if (vol->byteswap) {
    printf("spiderplugin) Enabling byte swapping\n");
  }

  vol->nlabel   = h.fbuf[3];
  vol->iform    = h.fbuf[4];
  vol->imami    = h.fbuf[5];
  vol->fmax     = h.fbuf[6];
  vol->fmin     = h.fbuf[7];
  vol->av       = h.fbuf[8];
  vol->sig      = h.fbuf[9];
  vol->headrec  = h.fbuf[12];
  vol->iangle   = h.fbuf[13];
  vol->phi      = h.fbuf[14];
  vol->theta    = h.fbuf[15];
  vol->gamma    = h.fbuf[16];
  vol->xoffset  = h.fbuf[17];
  vol->yoffset  = h.fbuf[18];
  vol->zoffset  = h.fbuf[19];
  vol->scale    = h.fbuf[20];
  vol->headbyt  = h.fbuf[21];
  vol->reclen   = h.fbuf[22];
  vol->nstack   = h.fbuf[23];
  vol->inuse    = h.fbuf[24];
  vol->maxim    = h.fbuf[25];

printf("spider  nslice: %d\n", vol->nslice);
printf("spider    nrow: %d\n", vol->nrow);
printf("spider    nsam: %d\n", vol->nsam);
printf("spider   iform: %d\n", vol->iform);
printf("spider   scale: %f\n", vol->scale);
printf("spider xoffset: %f\n", vol->xoffset);
printf("spider yoffset: %f\n", vol->yoffset);
printf("spider zoffset: %f\n", vol->zoffset);
printf("spider     phi: %f\n", vol->phi);
printf("spider   theta: %f\n", vol->theta);
printf("spider   gamma: %f\n", vol->gamma);

  /* correct bad headbyt and reclen SPIDER files */
  if (vol->iform < 4 && (vol->reclen < (vol->nsam * 4)))
    vol->reclen = vol->nsam * 4; 

  int headrec = 1024 / vol->reclen;
  if (vol->reclen < 1024 && (1024 % (vol->reclen)) != 0)
     headrec++;
  int headbyt = headrec * vol->reclen;
 
  if (vol->iform < 4 && (vol->headbyt < headbyt))
    vol->headbyt = headbyt;

printf("spider headbyt: %d\n", vol->headbyt);

  /* seek to data offset */
  fseek(fd, vol->headbyt, SEEK_SET);

  /* SPIDER files contain no color information */
  vol->vol[0].has_color = 0;

  vol->vol[0].xsize = vol->nsam;
  vol->vol[0].ysize = vol->nrow;
  vol->vol[0].zsize = vol->nslice;

  /* Set the unit cell origin and basis vectors */
  float vz[3] = {0.0, 0.0, 0.0};
  memcpy(vol->vol[0].xaxis, &vz, sizeof(vz));
  memcpy(vol->vol[0].yaxis, &vz, sizeof(vz));
  memcpy(vol->vol[0].zaxis, &vz, sizeof(vz));

  /* the scale value may be zero, if so, just reset to 1.0 */
  float vscale = vol->scale;
  if (vscale == 0.0) 
    vscale = 1.0;

  /* the data is stored in y/x/-z order and coordinate handedness  */
  /* we should probably rewrite the loader loop to shuffle x/y     */
  /* so that future conversions to other formats don't leave it in */
  /* an unusual packing order.  For now this works however         */

  float xlen = vscale * (vol->vol[0].ysize-1);
  float ylen = vscale * (vol->vol[0].xsize-1);
  float zlen = vscale * (vol->vol[0].zsize-1);

  vol->vol[0].xaxis[1] =  xlen;
  vol->vol[0].yaxis[0] =  ylen;
  vol->vol[0].zaxis[2] = -zlen;

  vol->vol[0].origin[0] = vol->yoffset - (0.5 * ylen);
  vol->vol[0].origin[1] = vol->xoffset - (0.5 * xlen);
  vol->vol[0].origin[2] = vol->zoffset + (0.5 * zlen);

printf("spider final offset: (%f, %f, %f)\n",
  vol->vol[0].origin[0], vol->vol[0].origin[1], vol->vol[0].origin[2]);

printf("spider final axes:\n");
printf("  X (%f, %f, %f)\n",
  vol->vol[0].xaxis[0], 
  vol->vol[0].xaxis[1], 
  vol->vol[0].xaxis[2]);

printf("  Y (%f, %f, %f)\n",
  vol->vol[0].yaxis[0], 
  vol->vol[0].yaxis[1], 
  vol->vol[0].yaxis[2]);

printf("  Z (%f, %f, %f)\n",
  vol->vol[0].zaxis[0], 
  vol->vol[0].zaxis[1], 
  vol->vol[0].zaxis[2]);

  return vol;
}
Exemplo n.º 17
0
static int read_rawgraphics(void *v, int *nelem, 
    const molfile_graphics_t **data) {
  grasp_t *grasp = (grasp_t *)v;
  FILE *infile = grasp->fd;

  // Reverse engineering is your friend, and combined with FORTRAN code, voila!
  // od -c shows the header starts off:
  // \0  \0  \0   P   f   o   r   m   a   t   =   2
  // and according to ungrasp, this is a 1 for grasp versions 1.0
  // and 1.1, and 2 for grasp version 1.2
  // Also, the header lines are of length 80 characters + 4 header chars
  // + 4 trailer chars
  // The 4 bytes at the beginning/end are standard Fortran array trash

  /// Pointers grassp type
  GRASSP datax;
   
  char trash[4];
#define TRASH fread(trash, 4, 1, infile)
  char line[81];

  // FIRST LINE OF HEADER; contains format type
  TRASH; 
  fread(line, 1, 80, infile); 
  // make sure it says 'format='
  if (strncmp(line, "format=", 7) != 0) {
    printf("graspplugin) First characters of file don't look like a GRASP file\n");
    return MOLFILE_ERROR;
  }
  TRASH;

  // next char should be a 0 or 1
  char gfiletype = line[7];
  if (gfiletype == '1') {
    gfiletype = 1;
  } else if (gfiletype == '2') {
    gfiletype = 2;
  } else {
    printf("graspplugin) GRASP file is in format %c, but only '1' or '2' is supported\n", gfiletype);
    return MOLFILE_ERROR;
  }

  // SECOND LINE: contains "vertices,accessibles,normals,triangles"
  TRASH; 
  fread(line, 1, 80, infile); 
  TRASH;

  // THIRD LINE: contains (0 or more of)?
  //  "potentials,curvature,distances,gproperty,g2property,vertexcolor
  TRASH; 
  line3(infile, &datax);/// Reads line 3
  TRASH;

  // FOURTH LINE stores vertices, triangles, gridsize, lattice spacing
  int nvert, ntriangles, gridsize;
  float lattice;
  TRASH; 
  fread(line, 1, 80, infile); 
  TRASH;
  sscanf(line, "%d%d%d%f", &nvert, &ntriangles, &gridsize, &lattice);

  /// Stores color
  float *colores = new float [3*nvert];

  // FIFTH LINE stores the center (x,y,z) position
  float center[3];
  TRASH; 
  fread(line, 1, 80, infile); 
  TRASH;
  sscanf(line, "%f%f%f", center, center+1, center+2);

  float *vertex = new float[3 * nvert];
  float *access = new float[3 * nvert];
  float *normal = new float[3 * nvert];
  int *triangle = new int[3 * ntriangles];
  float *properties = new float[3* nvert];

  if (!vertex || !access || !normal || !triangle || !properties) {
    delete [] vertex;
    delete [] access;
    delete [] normal;
    delete [] triangle;
    delete [] properties;
    printf("graspplugin) Failed vertex/access/normal/triangle allocations.\n");
    return MOLFILE_ERROR;
  }

  // ungrasp says:
  //    if (filetype.eq.1) then integer*2
  //    if (filetype.eq.2) then integer*4

  // And read them in.  Who needs error checking?
  TRASH; 
  fread(vertex, 3 * sizeof(float), nvert, infile); 
  TRASH;
  TRASH; 
  fread(access, 3 * sizeof(float), nvert, infile); 
  TRASH;
  TRASH; 
  fread(normal, 3 * sizeof(float), nvert, infile); 
  TRASH;
 
  if (is_little_endian()) {
    swap4_aligned(vertex, 3*nvert);
    swap4_aligned(access, 3*nvert);
    swap4_aligned(normal, 3*nvert);
  }

  if (gfiletype == 2) {
    TRASH; 
    fread(triangle, 3 * sizeof(int), ntriangles, infile); 
    TRASH;
    TRASH;
    fread(properties, 3 * sizeof(float), nvert, infile);
    if (is_little_endian()) {
      swap4_aligned(triangle, 3*ntriangles);
      swap4_aligned(properties, 3*nvert);
    }
  } else {
#if 1
    int i;
    short *striangle = new short[3 * ntriangles];
    if (!striangle) {
      delete [] vertex;
      delete [] access;
      delete [] normal;
      delete [] triangle;
      delete [] properties;
      printf("graspplugin) Failed short triangle allocation.\n");
      return MOLFILE_ERROR;
    }

    TRASH;
    fread(striangle, sizeof(short), 3 * ntriangles, infile);
    TRASH;
    TRASH;
    fread(properties, sizeof(float), 3 * nvert, infile);
    
    if (is_little_endian()) {
    swap2_aligned(striangle, 3 * ntriangles);
    swap4_aligned(properties, 3*nvert);}
    
    for (i=0; i<3*ntriangles; i++) {
      triangle[i] = striangle[i];
    }
    delete [] striangle;  
    
#else
    // do it the slow way (converting from short to int)
    int i;
    short tmp[3];
    TRASH;
    for (i=0; i<ntriangles; i++) {
      fread(tmp, sizeof(short), 3, infile);
      if (is_little_endian()) swap2_aligned(tmp, 3);
      triangle[3*i+0] = tmp[0];
      triangle[3*i+1] = tmp[1];
      triangle[3*i+2] = tmp[2];
    }
    TRASH;
    TRASH;
    fread(properties, sizeof(float), 3 * nvert, infile);
      if (is_little_endian())
      swap4_aligned(properties, 3*nvert);

#endif
  }   
  
  /// Gets properties:  potentials, curvature, distances, gproperty, g2property or vertexcolor 
  Get_Property_Values(&datax, properties, colores, nvert);
  
  // And draw things
  grasp->graphics = new molfile_graphics_t[3*ntriangles];
  int vert1, vert2, vert3;

  for (int tri_count = 0; tri_count < ntriangles; tri_count++) {
    vert1 = triangle[3*tri_count+0] - 1;  // from 1-based FORTRAN
    vert2 = triangle[3*tri_count+1] - 1;  // to 0-based C++
    vert3 = triangle[3*tri_count+2] - 1;

    if (vert1 <      0 || vert2 <      0 || vert3 <      0 ||
        vert1 >= nvert || vert2 >= nvert || vert3 >= nvert) {
      printf("graspplugin) Error, out-of-range vertex index, aborting.\n"); 
      delete [] vertex;
      delete [] access;
      delete [] normal;
      delete [] triangle;
      delete [] properties;
      return MOLFILE_ERROR;
    }

    grasp->graphics[2*tri_count  ].type = MOLFILE_TRINORM;
    grasp->graphics[2*tri_count+1].type = MOLFILE_NORMS;
    grasp->graphics[2*tri_count+2].type = MOLFILE_COLOR;
    
    float *tridata =  grasp->graphics[2*tri_count  ].data;
    float *normdata = grasp->graphics[2*tri_count+1].data;
    float *colordata = grasp->graphics[2*tri_count+2].data;
        
    memcpy(tridata  , vertex+3*vert1, 3*sizeof(float));
    memcpy(tridata+3, vertex+3*vert2, 3*sizeof(float));
    memcpy(tridata+6, vertex+3*vert3, 3*sizeof(float));
    
    memcpy(normdata  , normal+3*vert1, 3*sizeof(float));
    memcpy(normdata+3, normal+3*vert2, 3*sizeof(float));
    memcpy(normdata+6, normal+3*vert3, 3*sizeof(float));
    
    memcpy(colordata  , properties+3*vert1, 3*sizeof(float));
    memcpy(colordata+3, properties+3*vert2, 3*sizeof(float));
    memcpy(colordata+6, properties+3*vert3, 3*sizeof(float));
  } 

  *nelem = 2*ntriangles;
  *data = grasp->graphics;

  delete [] triangle;
  delete [] normal;
  delete [] access;
  delete [] vertex;
  delete [] properties;

  return MOLFILE_SUCCESS;
}
Exemplo n.º 18
0
static int read_js_structure(void *mydata, int *optflags,
                             molfile_atom_t *atoms) {
  jshandle *js = (jshandle *) mydata;
  int i;

  *optflags = MOLFILE_NOOPTIONS; /* set to no options until we read them */

  /* write flags data to the file */
  fio_read_int32(js->fd, &js->optflags); 
  if (js->reverseendian)
    swap4_aligned(&js->optflags, 1);
printf("jsplugin) read option flags: %0x08x\n", js->optflags);

  /* determine whether or not this file contains structure info or not */
  if (js->optflags & JSOPT_STRUCTURE) {
    int numatomnames, numatomtypes, numresnames, numsegids, numchains;
    char **atomnames = NULL;
    char **atomtypes = NULL;
    char **resnames = NULL;
    char **segids = NULL;
    char **chains = NULL;
    short *shortbuf = NULL; /* temp buf for decoding atom records */
    int *intbuf = NULL;     /* temp buf for decoding atom records */
    float *fltbuf = NULL;   /* temp buf for decoding atom records */
 
    /* read in block of name string table sizes */
    fio_read_int32(js->fd, &numatomnames); 
    fio_read_int32(js->fd, &numatomtypes); 
    fio_read_int32(js->fd, &numresnames);
    fio_read_int32(js->fd, &numsegids);
    fio_read_int32(js->fd, &numchains); 
    if (js->reverseendian) {
      swap4_aligned(&numatomnames, js->natoms);
      swap4_aligned(&numatomtypes, js->natoms);
      swap4_aligned(&numresnames, js->natoms);
      swap4_aligned(&numsegids, js->natoms);
      swap4_aligned(&numchains, js->natoms);
    }

printf("jsplugin) reading string tables...\n");
printf("jsplugin) %d %d %d %d %d\n",
       numatomnames, numatomtypes, numresnames, numsegids, numchains);

    /* allocate string tables */
    atomnames = (char **) malloc(numatomnames * sizeof(char *));
    atomtypes = (char **) malloc(numatomtypes * sizeof(char *));
    resnames  = (char **) malloc(numresnames  * sizeof(char *));
    segids    = (char **) malloc(numsegids    * sizeof(char *));
    chains    = (char **) malloc(numchains    * sizeof(char *));

printf("jsplugin)   atom names...\n");
    /* read in the string tables */
    for (i=0; i<numatomnames; i++) {
      atomnames[i] = (char *) malloc(16 * sizeof(char));
      fio_fread(atomnames[i], 16 * sizeof(char), 1, js->fd);
    }

printf("jsplugin)   atom types...\n");
    for (i=0; i<numatomtypes; i++) {
      atomtypes[i] = (char *) malloc(16 * sizeof(char));
      fio_fread(atomtypes[i], 16 * sizeof(char), 1, js->fd);
    }

printf("jsplugin)   residue names...\n");
    for (i=0; i<numresnames; i++) {
      resnames[i] = (char *) malloc(8 * sizeof(char));
      fio_fread(resnames[i], 8 * sizeof(char), 1, js->fd);
    }

printf("jsplugin)   segment names...\n");
    for (i=0; i<numsegids; i++) {
      segids[i] = (char *) malloc(8 * sizeof(char));
      fio_fread(segids[i], 8 * sizeof(char), 1, js->fd);
    }

printf("jsplugin)   chain names...\n");
    for (i=0; i<numchains; i++) {
      chains[i] = (char *) malloc(2 * sizeof(char));
      fio_fread(chains[i], 2 * sizeof(char), 1, js->fd);
    }

printf("jsplugin) reading numeric field tables...\n");
    /* read in all of the atom fields */
    shortbuf = (void *) malloc(js->natoms * sizeof(short));

printf("jsplugin)   atom name indices...\n");
    /* read in atom names */
    fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
    if (js->reverseendian)
      swap2_aligned(shortbuf, js->natoms);
    for (i=0; i<js->natoms; i++) {
      strcpy(atoms[i].name, atomnames[shortbuf[i]]);
    }    

printf("jsplugin)   atom type indices...\n");
    /* read in atom types */
    fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
    if (js->reverseendian)
      swap2_aligned(shortbuf, js->natoms);
    for (i=0; i<js->natoms; i++) {
      strcpy(atoms[i].type, atomtypes[shortbuf[i]]);
    }    

printf("jsplugin)   residue name indices...\n");
    /* read in resnames */
    fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
    if (js->reverseendian)
      swap2_aligned(shortbuf, js->natoms);
    for (i=0; i<js->natoms; i++) {
      strcpy(atoms[i].resname, resnames[shortbuf[i]]);
    }    
    
printf("jsplugin)   segment name indices...\n");
    /* read in segids */
    fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
    if (js->reverseendian)
      swap2_aligned(shortbuf, js->natoms);
    for (i=0; i<js->natoms; i++) {
      strcpy(atoms[i].segid, segids[shortbuf[i]]);
    }    

printf("jsplugin)   chain name indices...\n");
    /* read in chains */
    fio_fread(shortbuf, js->natoms * sizeof(short), 1, js->fd);
    if (js->reverseendian)
      swap2_aligned(shortbuf, js->natoms);
    for (i=0; i<js->natoms; i++) {
      strcpy(atoms[i].chain, chains[shortbuf[i]]);
    }    

    if (shortbuf != NULL) {
      free(shortbuf);
      shortbuf=NULL;
    }

    /* 
     * read in integer data blocks 
     */
    intbuf = (int *) malloc(js->natoms * sizeof(int));

printf("jsplugin)   residue indices...\n");
    /* read in resid */
    fio_fread(intbuf, js->natoms * sizeof(int), 1, js->fd);
    if (js->reverseendian)
      swap4_aligned(intbuf, js->natoms);
    for (i=0; i<js->natoms; i++) {
      atoms[i].resid = intbuf[i];
    }    
     
    if (intbuf != NULL) {
      free(intbuf);
      intbuf = NULL;
    }


printf("jsplugin) reading optional per-atom tables...\n");
    /*
     * read in optional single-precision float data blocks
     */ 
    if (js->optflags & (JSOPT_OCCUPANCY | JSOPT_BFACTOR | 
        JSOPT_MASS | JSOPT_RADIUS | JSOPT_CHARGE)) 
      fltbuf = (void *) malloc(js->natoms * sizeof(float));

    /* read in optional data if it exists */
    if (js->optflags & JSOPT_OCCUPANCY) {
printf("jsplugin)   occupancy...\n");
      *optflags |= MOLFILE_OCCUPANCY;
      fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(fltbuf, js->natoms);
      for (i=0; i<js->natoms; i++) {
        atoms[i].occupancy = fltbuf[i];
      }    
    }

    if (js->optflags & JSOPT_BFACTOR) {
printf("jsplugin)   bfactor...\n");
      *optflags |= MOLFILE_BFACTOR;
      fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(fltbuf, js->natoms);
      for (i=0; i<js->natoms; i++) {
        atoms[i].bfactor = fltbuf[i];
      }    
    }

    if (js->optflags & JSOPT_MASS) { 
printf("jsplugin)   mass...\n");
      *optflags |= MOLFILE_MASS;
      fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(fltbuf, js->natoms);
      for (i=0; i<js->natoms; i++) {
        atoms[i].mass = fltbuf[i];
      }    
    }

    if (js->optflags & JSOPT_CHARGE) { 
printf("jsplugin)   charge...\n");
      *optflags |= MOLFILE_CHARGE;
      fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(fltbuf, js->natoms);
      for (i=0; i<js->natoms; i++) {
        atoms[i].charge = fltbuf[i];
      }    
    }

    if (js->optflags & JSOPT_RADIUS) { 
printf("jsplugin)   radius...\n");
      *optflags |= MOLFILE_RADIUS;
      fio_fread(fltbuf, js->natoms * sizeof(float), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(fltbuf, js->natoms);
      for (i=0; i<js->natoms; i++) {
        atoms[i].radius = fltbuf[i];
      }    
    }

    if (fltbuf != NULL) {
      free(fltbuf);
      fltbuf=NULL;
    }

    /*
     * read in optional integer data blocks
     */ 
    if (js->optflags & JSOPT_ATOMICNUMBER)
      intbuf = (void *) malloc(js->natoms * sizeof(int));

    if (js->optflags & JSOPT_ATOMICNUMBER) { 
printf("jsplugin)   atomic number...\n");
      *optflags |= MOLFILE_ATOMICNUMBER;
      fio_fread(intbuf, js->natoms * sizeof(int), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(intbuf, js->natoms);
      for (i=0; i<js->natoms; i++) {
        atoms[i].atomicnumber = intbuf[i];
      }    
    }

    if (intbuf != NULL) {
      free(intbuf);
      intbuf = NULL;
    }


    /*
     * read in bonds and fractional bond orders
     */ 
    if (js->optflags & JSOPT_BONDS) {
      fio_fread(&js->nbonds, sizeof(int), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->nbonds, 1);
printf("jsplugin)   %d bonds...\n", js->nbonds);

      js->bondfrom = (int *) malloc(js->nbonds * sizeof(int));
      js->bondto = (int *) malloc(js->nbonds * sizeof(int));
      fio_fread(js->bondfrom, js->nbonds * sizeof(int), 1, js->fd);
      fio_fread(js->bondto, js->nbonds * sizeof(int), 1, js->fd);
      if (js->reverseendian) {
        swap4_aligned(js->bondfrom, js->nbonds);
        swap4_aligned(js->bondto, js->nbonds);
      }

      if (js->optflags & JSOPT_BONDORDERS) {
printf("jsplugin)   bond orders...\n");
        js->bondorders = (void *) malloc(js->nbonds * sizeof(float));
        fio_fread(js->bondorders, js->nbonds * sizeof(float), 1, js->fd);
        if (js->reverseendian)
          swap4_aligned(js->bondorders, js->nbonds);
      }
    }

    if (js->optflags & JSOPT_ANGLES) {
      fio_fread(&js->numangles, sizeof(int), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->numangles, 1);
printf("jsplugin)   %d angles...\n", js->numangles);
      js->angles = (int *) malloc(3 * js->numangles * sizeof(int));
      fio_fread(js->angles, sizeof(int)*3*js->numangles, 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->angles, 3*js->numangles);

      fio_fread(&js->numdihedrals, sizeof(int), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->numdihedrals, 1);
printf("jsplugin)   %d dihedrals...\n", js->numdihedrals);
      js->dihedrals = (int *) malloc(4 * js->numdihedrals * sizeof(int));
      fio_fread(js->dihedrals, sizeof(int)*4*js->numdihedrals, 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->dihedrals, 4*js->numdihedrals);

      fio_fread(&js->numimpropers, sizeof(int), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->numimpropers, 1);
      js->impropers = (int *) malloc(4 * js->numimpropers * sizeof(int));
printf("jsplugin)   %d impropers...\n", js->numimpropers);
      fio_fread(js->impropers, sizeof(int)*4*js->numimpropers, 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->impropers, 4*js->numimpropers);
    }
    if (js->optflags & JSOPT_CTERMS) {
      fio_fread(&js->numcterms, sizeof(int), 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->numcterms, 1);
      js->cterms = (int *) malloc(8 * js->numcterms * sizeof(int));
printf("jsplugin)   %d cterms...\n", js->numcterms);
      fio_fread(js->cterms, sizeof(int)*8*js->numcterms, 1, js->fd);
      if (js->reverseendian)
        swap4_aligned(&js->cterms, 8*js->numcterms);
    }

printf("jsplugin) final optflags: %08x\n", *optflags);
printf("jsplugin) structure information complete\n");

    return MOLFILE_SUCCESS;
  }

printf("jsplugin) no structure information available\n");

  /* else, we have no structure information */
  return MOLFILE_NOSTRUCTUREDATA;
}
Exemplo n.º 19
0
static void *open_js_read(const char *path, const char *filetype, int *natoms) {
  jshandle *js;
  int jsmagicnumber, jsendianism, jsmajorversion, jsminorversion;
  struct stat stbuf;
  char strbuf[1024];
  int rc = 0;

  if (!path) return NULL;

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

  js = (jshandle *)malloc(sizeof(jshandle));
  memset(js, 0, sizeof(jshandle));
  if (fio_open(path, FIO_READ, &js->fd) < 0) {
    printf("jsplugin) Could not open file '%s' for reading.\n", path);
    free(js);
    return NULL;
  }

  /* emit header information */
  fio_fread(strbuf, strlen(JSHEADERSTRING), 1, js->fd);
  strbuf[strlen(JSHEADERSTRING)] = '\0';
  if (strcmp(strbuf, JSHEADERSTRING)) {
    printf("jsplugin) Bad trajectory header!\n");
    printf("jsplugin) Read string: %s\n", strbuf);
    return NULL;
  }

  fio_read_int32(js->fd, &jsmagicnumber);
  fio_read_int32(js->fd, &jsendianism);
  fio_read_int32(js->fd, &jsmajorversion);
  fio_read_int32(js->fd, &jsminorversion);
  fio_read_int32(js->fd, &js->natoms);
  fio_read_int32(js->fd, &js->nframes);
  if ((jsmagicnumber != JSMAGICNUMBER) || (jsendianism != JSENDIANISM)) {
    printf("jsplugin) opposite endianism file, enabling byte swapping\n");
    js->reverseendian = 1;
    swap4_aligned(&jsmagicnumber, 1);
    swap4_aligned(&jsendianism, 1);
    swap4_aligned(&jsmajorversion, 1);
    swap4_aligned(&jsminorversion, 1);
    swap4_aligned(&js->natoms, 1);
    swap4_aligned(&js->nframes, 1);
  } else {
    printf("jsplugin) native endianism file\n");
  }

  if ((jsmagicnumber != JSMAGICNUMBER) || (jsendianism != JSENDIANISM)) {
    printf("jsplugin) read_jsreader returned %d\n", rc);
    fio_fclose(js->fd);
    free(js);
    return NULL;
  }
 
  if (jsmajorversion != JSMAJORVERSION) {
    printf("jsplugin) major version mismatch\n");
    printf("jsplugin)   file version: %d\n", jsmajorversion);
    printf("jsplugin)   plugin version: %d\n", JSMAJORVERSION);
    fio_fclose(js->fd);
    free(js);
    return NULL;
  }
 
  *natoms = js->natoms;
  return js;
}
Exemplo n.º 20
0
static void *open_ccp4_read(const char *filepath, const char *filetype,
                            int *natoms) {
  FILE *fd;
  ccp4_t *ccp4;
  char mapString[4], symData[81];
  int nxyzstart[3], extent[3], grid[3], crs2xyz[3], voxtype, symBytes;
  float origin2k[3];
  int swap, i, xIndex, yIndex, zIndex;
  long dataOffset, filesize;
  float cellDimensions[3], cellAngles[3], xaxis[3], yaxis[3], zaxis[3];
  float alpha, beta, gamma, xScale, yScale, zScale, z1, z2, z3;
  float amin, amax, amean;
  int dataflags=0,imodstamp=0,imodflags=0;
  
  fd = fopen(filepath, "rb");
  if (!fd) {
    printf("ccp4plugin) Error opening file %s\n", filepath);
    return NULL;
  }

  if ((fread(extent, sizeof(int), 3, fd) != 3) ||
      (fread(&voxtype, sizeof(int), 1, fd) != 1) ||
      (fread(nxyzstart, sizeof(int), 3, fd) != 3) ||
      (fread(grid, sizeof(int), 3, fd) != 3) ||
      (fread(cellDimensions, sizeof(float), 3, fd) != 3) ||
      (fread(cellAngles, sizeof(float), 3, fd) != 3) ||
      (fread(crs2xyz, sizeof(int), 3, fd) != 3) ||
      (fread(&amin, sizeof(float), 1, fd) != 1) || 
      (fread(&amax, sizeof(float), 1, fd) != 1) || 
      (fread(&amean, sizeof(float), 1, fd) != 1)) {
    printf("ccp4plugin) Error: Improperly formatted line.\n");
    return NULL;
  }

  // Check the number of bytes used for storing symmetry operators
  // (word 23, byte 92)
  fseek(fd, 23 * 4, SEEK_SET);
  if ((fread(&symBytes, sizeof(int), 1, fd) != 1) ) {
    printf("ccp4plugin) Error: Failed reading symmetry bytes record.\n");
    return NULL;
  }

  // read MRC2000 Origin record at word 49, byte 196, and use it if necessary
  // http://www2.mrc-lmb.cam.ac.uk/image2000.html
  fseek(fd, 49 * 4, SEEK_SET);
  if (fread(origin2k, sizeof(float), 3, fd) != 3) {
    printf("ccp4plugin) Error: unable to read ORIGIN records at offset 196.\n");
  }

  // Check for IMOD stamp at offset 152, indicating an IMOD file 
  fseek(fd, 152, SEEK_SET);
  if (fread(&imodstamp, sizeof(int), 1, fd) != 1) {
    printf("ccp4plugin) Error: failed to read IMOD stamp from MRC file.\n");
    return NULL;
  }
  if (fread(&imodflags, sizeof(int), 1, fd) != 1) {
    printf("ccp4plugin) Error: failed to read IMOD flags from MRC file.\n");
    return NULL;
  }

  // Check file endianism using some heuristics
  swap = 0;
  int tmp[3];
  memcpy(tmp, extent, 3*sizeof(int));
  if (tmp[0] > 65536 || tmp[1] > 65536 || tmp[2] > 65536) {
    swap4_aligned(tmp, 3);
    if (tmp[0] > 65536 || tmp[1] > 65536 || tmp[2] > 65536) {
      swap = 0;
      printf("ccp4plugin) Guessing file endianism: native\n");
    } else {
      swap = 1;
      printf("ccp4plugin) Guessing file endianism: swapped\n");
    }
  }
  if (voxtype > 16 && swap == 0) {
    tmp[0] = voxtype;
    swap4_aligned(tmp, 1);
    if (tmp[0] <= 16) {
      swap = 1;
      printf("ccp4plugin) Guessing file endianism: swapped\n");
    }
  }

  // Byte-swap header information if needed
  if (swap == 1) {
    swap4_aligned(extent, 3);
    swap4_aligned(&voxtype, 1);
    swap4_aligned(nxyzstart, 3);
    swap4_aligned(origin2k, 3);
    swap4_aligned(grid, 3);
    swap4_aligned(cellDimensions, 3);
    swap4_aligned(cellAngles, 3);
    swap4_aligned(crs2xyz, 3);
    swap4_aligned(&amin, 1);
    swap4_aligned(&amax, 1);
    swap4_aligned(&amean, 1);
    swap4_aligned(&symBytes, 1);
    swap4_aligned(&imodstamp, 1);
    swap4_aligned(&imodflags, 1);
  }

  // Check for the string "MAP" at word 52 byte 208, indicating a CCP4 file.
  fseek(fd, 52 * 4, SEEK_SET);
  if (fgets(mapString, 4, fd) == NULL) {
    printf("ccp4plugin) Error: unable to read 'MAP' string, not a valid CCP4/IMOD MRC file.\n");
    return NULL;
  }

  if ((strcmp(mapString, "MAP") != 0) && (imodstamp != IMOD_MAGIC_STAMP)) {
    // Older versions of IMOD (2.6.19 or below) do not have the "MAP " string.
    // If the IMOD stamp is there its probably a valid MRC file
    printf("ccp4plugin) Warning: 'MAP' string missing!\n");
    printf("ccp4plugin) This usually indicates an invalid IMOD file,\n");
    printf("ccp4plugin) but some old IMOD versions did not specify 'MAP'.\n");
    printf("ccp4plugin) File loading will proceed but may ultimately fail.\n");
  }

  // Check if we found an IMOD file or not
  if (imodstamp == IMOD_MAGIC_STAMP) {
    printf("ccp4plugin) MRC file generated by IMOD-compatible program.\n");

    dataflags |= DATA_FLAG_IMOD_FORMAT; // mark that this file came from IMOD

    if (imodflags & IMOD_FLAG_SIGNED) {
      dataflags |= DATA_FLAG_SIGNED;
      printf("ccp4plugin) IMOD flag: data uses signed-bytes\n");
    } else {
      printf("ccp4plugin) IMOD flag: data uses unsigned-bytes\n");
    }

    if (imodflags & IMOD_FLAG_HEADER_SPACING)
      printf("ccp4plugin) IMOD flag: pixel spacing set in extended header\n");

    if (imodflags & IMOD_FLAG_ORIGIN_INVERTED_SIGN)
      printf("ccp4plugin) IMOD flag: origin sign is inverted.\n");
  } else {
    imodflags = 0;
    printf("ccp4plugin) No IMOD stamp found.\n");

    if (amin < 0) {
      printf("ccp4plugin) Note: amin < 0, signed voxels are implied\n");
      dataflags |= DATA_FLAG_SIGNED;
    } else {
      printf("ccp4plugin) Note: amin >= 0, unsigned voxels are implied\n");
    }
  }

  // Check the data type of the file.
  switch (voxtype) {
    case MRC_TYPE_BYTE:
      printf("ccp4plugin) voxel type: byte\n");
      break;

    case MRC_TYPE_SHORT:
      printf("ccp4plugin) voxel type: short (16-bit signed int)\n");
      break;

    case MRC_TYPE_FLOAT:
      printf("ccp4plugin) voxel type: float (32-bit real)\n");
      break;

    case MRC_TYPE_SHORT2:
      printf("ccp4plugin) voxel type: short2 (2x 16-bit signed int)\n");
      printf("ccp4plugin) Error: unimplemented voxel format\n");
      return NULL;

    case MRC_TYPE_FLOAT2:
      printf("ccp4plugin) voxel type: float2 (2x 32-bit real)\n");
      printf("ccp4plugin) Error: unimplemented voxel format\n");
      return NULL;

    case MRC_TYPE_USHORT:
      printf("ccp4plugin) voxel type: ushort (16-bit unsigned int)\n");
      break;

    case MRC_TYPE_UCHAR3:
      printf("ccp4plugin) voxel type: uchar3 (3x unsigned char)\n");
      break;

    default:
      printf("ccp4plugin) Error: Only byte, short (16-bit integer) or float (32-bit real) data types are supported.\n");
      return NULL;
  }

#if 1
  printf("ccp4plugin)    extent: %d x %d x %d\n",
         extent[0], extent[1], extent[2]);
  printf("ccp4plugin) nxyzstart: %d, %d, %d\n", 
         nxyzstart[0], nxyzstart[1], nxyzstart[2]);
  printf("ccp4plugin)  origin2k: %f, %f, %f\n", 
         origin2k[0], origin2k[1], origin2k[2]);
  printf("ccp4plugin)      grid: %d x %d x %d\n", grid[0], grid[1], grid[2]);
  printf("ccp4plugin)   celldim: %f x %f x %f\n", 
         cellDimensions[0], cellDimensions[1], cellDimensions[2]);
  printf("cpp4plugin)cellangles: %f, %f, %f\n", 
         cellAngles[0], cellAngles[1], cellAngles[2]);
  printf("ccp4plugin)   crs2xyz: %d %d %d\n", 
         crs2xyz[0], crs2xyz[1], crs2xyz[2]);
  printf("ccp4plugin)      amin: %g  amax: %g  amean: %g\n", amin, amax, amean);
  printf("ccp4plugin)  symBytes: %d\n", symBytes);
#endif

  // Check the dataOffset: this fixes the problem caused by files claiming
  // to have symmetry records when they do not.
  fseek(fd, 0, SEEK_END);
  filesize = ftell(fd);

  // compute data offset using file size and voxel type info
  long voxcount = long(extent[0]) * long(extent[1]) * long(extent[2]);
  if (voxtype == MRC_TYPE_BYTE) {
    dataOffset = filesize - sizeof(char)*voxcount;
  } else if (voxtype == MRC_TYPE_FLOAT) {
    dataOffset = filesize - sizeof(float)*voxcount;
  } else if (voxtype == MRC_TYPE_SHORT || voxtype == MRC_TYPE_USHORT) {
    dataOffset = filesize - sizeof(short)*voxcount;
  } else if (voxtype == MRC_TYPE_UCHAR3) {
    dataOffset = filesize - sizeof(uchar3)*voxcount;
  } else {
    printf("ccp4plugin) unimplemented voxel type!\n");
  }

  if (dataOffset != (CCP4HDSIZE + symBytes)) {
    if (dataOffset == CCP4HDSIZE) {
      // Bogus symmetry record information
      printf("ccp4plugin) Warning: file contains bogus symmetry record.\n");
      symBytes = 0;
    } else if (dataOffset < CCP4HDSIZE) {
      printf("ccp4plugin) Error: File appears truncated and doesn't match header.\n");
      return NULL;
    } else if ((dataOffset > CCP4HDSIZE) && (dataOffset < (1024*1024))) {
      // Fix for loading SPIDER files which are larger than usual
      // In this specific case, we must absolutely trust the symBytes record
      dataOffset = CCP4HDSIZE + symBytes; 
      printf("ccp4plugin) Warning: File is larger than expected and doesn't match header.\n");
      printf("ccp4plugin) Warning: Continuing file load, good luck!\n");
    } else {
      printf("ccp4plugin) Error: File is MUCH larger than expected and doesn't match header.\n");
      return NULL;
    }
  }

  // Read symmetry records -- organized as 80-byte lines of text.
  if (symBytes != 0) {
    printf("ccp4plugin) Symmetry records found:\n");
    fseek(fd, CCP4HDSIZE, SEEK_SET);
    for (i = 0; i < symBytes/80; i++) {
      fgets(symData, 81, fd);
      printf("ccp4plugin) %s\n", symData);
    }
  }

  // check extent and grid interval counts
  if (grid[0] == 0 && extent[0] > 0) {
    grid[0] = extent[0] - 1;
    printf("ccp4plugin) Warning: Fixed X interval count\n");
  }
  if (grid[1] == 0 && extent[1] > 0) {
    grid[1] = extent[1] - 1;
    printf("ccp4plugin) Warning: Fixed Y interval count\n");
  }
  if (grid[2] == 0 && extent[2] > 0) {
    grid[2] = extent[2] - 1;
    printf("ccp4plugin) Warning: Fixed Z interval count\n");
  }

  // Allocate and initialize the ccp4 structure
  ccp4 = new ccp4_t;
  memset(ccp4, 0, sizeof(ccp4_t));
  ccp4->fd = fd;
  ccp4->vol = NULL;
  *natoms = MOLFILE_NUMATOMS_NONE;
  ccp4->nsets = 1; // this EDM file contains only one data set
  ccp4->voxtype = voxtype;
  ccp4->voxcount = voxcount;
  ccp4->dataflags = dataflags;
  ccp4->imodstamp = imodstamp;
  ccp4->imodflags = imodflags;
  ccp4->swap = swap;
  ccp4->dataOffset = dataOffset;
  ccp4->amin = amin;
  ccp4->amax = amax;
  ccp4->amean = amean;

  ccp4->vol = new molfile_volumetric_t[1];
  memset(ccp4->vol, 0, sizeof(molfile_volumetric_t));
  strcpy(ccp4->vol[0].dataname, "CCP4 Electron Density Map");

  // Mapping between CCP4 column, row, section and VMD x, y, z.
  if (crs2xyz[0] == 0 && crs2xyz[1] == 0 && crs2xyz[2] == 0) {
    printf("ccp4plugin) Warning: All crs2xyz records are zero.\n");
    printf("ccp4plugin) Warning: Setting crs2xyz to 1, 2, 3\n");
    crs2xyz[0] = 1;
    crs2xyz[0] = 2;
    crs2xyz[0] = 3;
  }

  ccp4->xyz2crs[crs2xyz[0]-1] = 0;
  ccp4->xyz2crs[crs2xyz[1]-1] = 1;
  ccp4->xyz2crs[crs2xyz[2]-1] = 2;
  xIndex = ccp4->xyz2crs[0];
  yIndex = ccp4->xyz2crs[1];
  zIndex = ccp4->xyz2crs[2];

  // calculate non-orthogonal unit cell coordinates
  alpha = (M_PI / 180.0) * cellAngles[0];
  beta = (M_PI / 180.0) * cellAngles[1];
  gamma = (M_PI / 180.0) * cellAngles[2];

  if (cellDimensions[0] == 0.0 && 
      cellDimensions[1] == 0.0 &&
      cellDimensions[2] == 0.0) {
    printf("ccp4plugin) Warning: Cell dimensions are all zero.\n");
    printf("ccp4plugin) Warning: Setting to 1.0, 1.0, 1.0 for viewing.\n");
    printf("ccp4plugin) Warning: Map file will not align with other structures.\n");
    cellDimensions[0] = 1.0;
    cellDimensions[1] = 1.0;
    cellDimensions[2] = 1.0;
  } 

  xScale = cellDimensions[0] / grid[0];
  yScale = cellDimensions[1] / grid[1];
  zScale = cellDimensions[2] / grid[2];

  if ((alpha == 0) || (beta == 0) || (gamma == 0)) {
    printf("ccp4plugin) orthorhombic unit cell axes\n");
    xaxis[0] = xScale;
    xaxis[1] = 0;
    xaxis[2] = 0;

    yaxis[0] = 0;
    yaxis[1] = yScale;
    yaxis[2] = 0;

    zaxis[0] = 0;
    zaxis[1] = 0;
    zaxis[2] = zScale;
  } else {
    // calculate non-orthogonal unit cell coordinates
    printf("ccp4plugin) computing non-orthorhombic unit cell axes\n");
    xaxis[0] = xScale;
    xaxis[1] = 0;
    xaxis[2] = 0;

    yaxis[0] = cos(gamma) * yScale;
    yaxis[1] = sin(gamma) * yScale;
    yaxis[2] = 0;

    z1 = cos(beta);
    z2 = (cos(alpha) - cos(beta)*cos(gamma)) / sin(gamma);
    z3 = sqrt(1.0 - z1*z1 - z2*z2);
    zaxis[0] = z1 * zScale;
    zaxis[1] = z2 * zScale;
    zaxis[2] = z3 * zScale;
  }


#if 0
  printf("ccp4plugin)  scale: %g %g %g\n", xScale, yScale, zScale);
  printf("ccp4plugin)    xax: %g %g %g\n", xaxis[0], xaxis[1], xaxis[2]);
  printf("ccp4plugin)    yax: %g %g %g\n", yaxis[0], yaxis[1], yaxis[2]);
  printf("ccp4plugin)    zax: %g %g %g\n", zaxis[0], zaxis[1], zaxis[2]);
#endif

#if 1
  // Handle both MRC-2000 and older format maps
  if (origin2k[0] == 0.0f && origin2k[1] == 0.0f && origin2k[2] == 0.0f) {
    printf("ccp4plugin) using CCP4 n[xyz]start origin\n");
    ccp4->vol[0].origin[0] = xaxis[0] * nxyzstart[xIndex] + 
                             yaxis[0] * nxyzstart[yIndex] +
                             zaxis[0] * nxyzstart[zIndex];
    ccp4->vol[0].origin[1] = yaxis[1] * nxyzstart[yIndex] +
                             zaxis[1] * nxyzstart[zIndex];
    ccp4->vol[0].origin[2] = zaxis[2] * nxyzstart[zIndex];
  } else {
    // Use ORIGIN records rather than old n[xyz]start records
    //   http://www2.mrc-lmb.cam.ac.uk/image2000.html
    // XXX the ORIGIN field is only used by the EM community, and
    //     has undefined meaning for non-orthogonal maps and/or
    //     non-cubic voxels, etc.
    printf("ccp4plugin) using MRC2000 origin\n");
    ccp4->vol[0].origin[0] = origin2k[xIndex];
    ccp4->vol[0].origin[1] = origin2k[yIndex];
    ccp4->vol[0].origin[2] = origin2k[zIndex];
  }
#else
  // old code that only pays attention to old MRC nxstart/nystart/nzstart
  ccp4->vol[0].origin[0] = xaxis[0] * nxyzstart[xIndex] + 
                           yaxis[0] * nxyzstart[yIndex] +
                           zaxis[0] * nxyzstart[zIndex];
  ccp4->vol[0].origin[1] = yaxis[1] * nxyzstart[yIndex] +
                           zaxis[1] * nxyzstart[zIndex];
  ccp4->vol[0].origin[2] = zaxis[2] * nxyzstart[zIndex];
#endif

  ccp4->vol[0].xaxis[0] = xaxis[0] * (extent[xIndex]-1);
  ccp4->vol[0].xaxis[1] = 0;
  ccp4->vol[0].xaxis[2] = 0;

  ccp4->vol[0].yaxis[0] = yaxis[0] * (extent[yIndex]-1);
  ccp4->vol[0].yaxis[1] = yaxis[1] * (extent[yIndex]-1);
  ccp4->vol[0].yaxis[2] = 0;

  ccp4->vol[0].zaxis[0] = zaxis[0] * (extent[zIndex]-1);
  ccp4->vol[0].zaxis[1] = zaxis[1] * (extent[zIndex]-1);
  ccp4->vol[0].zaxis[2] = zaxis[2] * (extent[zIndex]-1);

  ccp4->vol[0].xsize = extent[xIndex];
  ccp4->vol[0].ysize = extent[yIndex];
  ccp4->vol[0].zsize = extent[zIndex];

  ccp4->vol[0].has_color = 0;

#if 0
  printf("ccp4plugin) origin: %.3f %.3f %.3f\n",
         ccp4->vol[0].origin[0],
         ccp4->vol[0].origin[1],
         ccp4->vol[0].origin[2]);

  printf("ccp4plugin)   xax': %g %g %g\n",
         ccp4->vol[0].xaxis[0], ccp4->vol[0].xaxis[1], ccp4->vol[0].xaxis[2]);
  printf("ccp4plugin)   yax': %g %g %g\n",
         ccp4->vol[0].yaxis[0], ccp4->vol[0].yaxis[1], ccp4->vol[0].yaxis[2]);
  printf("ccp4plugin)   zax': %g %g %g\n",
         ccp4->vol[0].zaxis[0], ccp4->vol[0].zaxis[1], ccp4->vol[0].zaxis[2]);

  printf("ccp4plugin)     sz: %d %d %d\n",
         ccp4->vol[0].xsize, ccp4->vol[0].ysize, ccp4->vol[0].zsize);
#endif


  return ccp4;
}
Exemplo n.º 21
0
static void *open_fs4_read(const char *filepath, const char *filetype,
    int *natoms) {
  fs4_t *fs4;
  FILE *fd;
  float header[32], scale, fmsCellSize[3], alpha, beta, gamma, z1, z2, z3;
  int dataBegin, blocksize, geom[16], fmsGridSize[3], norn, swap=0;

  fd = fopen(filepath, "rb");
  if (!fd) {
    fprintf(stderr, "fs4plugin) Error opening file.\n");
    return NULL;
  }

  // Use the first four-byte integer in the file to determine the file's
  // byte-order
  fread(&dataBegin, sizeof(int), 1, fd);
  if (dataBegin > 255) {
    // check if the bytes need to be swapped
    swap4_aligned(&dataBegin, 1);
    if (dataBegin <= 255) {
      swap = 1;
    } else {
      fprintf(stderr, "fs4plugin) Cannot read file: header block is too large.\n");
      return NULL;
    }
  }

  // Read the header
  rewind(fd);
  blocksize = fortread_4(header, 32, swap, fd);

  // Handle files produced by old versions of (cns|ccp)2fsfour
  if (blocksize == 28) {
    printf("fs4plugin) Recognized %s cns2fsfour map.\n", 
        swap ? "opposite-endian" : "same-endian");

    // Read the geometry block
    blocksize = fortread_4(geom, 16, swap, fd);
    if (blocksize != 7) {
      fprintf(stderr, "fs4plugin) Incorrect size for geometry block.\n");
      return NULL;
    }

    fmsGridSize[0] = geom[0];
    fmsGridSize[1] = geom[1];
    fmsGridSize[2] = geom[2];
    norn = geom[4];

    // Warn about assumptions
    printf("fs4plugin) Warning: file does not contain unit cell lengths or angles.\n");

    scale = 50.0;
    fmsCellSize[0] = 1.0;
    fmsCellSize[1] = 1.0;
    fmsCellSize[2] = 1.0;
    alpha = 90.0;
    beta = 90.0;
    gamma = 90.0;
  }

  // Handle standard fsfour files
  else if (blocksize == 31) {
    printf("fs4plugin) Recognize standard fsfour map.\n");

    fmsCellSize[0] = header[21];
    fmsCellSize[1] = header[22];
    fmsCellSize[2] = header[23];
    alpha = header[24];
    beta = header[25];
    gamma = header[26];
    
    // Skip the symmetry block if one present
    blocksize = fortread_4(geom, 16, swap, fd);
    if (blocksize == 9) {
      printf("fs4plugin) Skipping symmetry block.\n");
      blocksize = fortread_4(geom, 16, swap, fd);
    }

    // Read the geometry block
    if (blocksize != 13) {
      fprintf(stderr, "fs4plugin) Incorrect size for geometry block.\n");
      return NULL;
    }

    fmsGridSize[0] = geom[0];
    fmsGridSize[1] = geom[1];
    fmsGridSize[2] = geom[2];

    scale = *((float *) geom + 3);
    if (scale == 0) {
      scale = 50;
    }

    norn = geom[4];
    if ((norn < 0) || (norn > 2)) {
      fprintf(stderr, "fs4plugin) norn out of range.\n");
      return NULL;
    }
  }

  // Unrecognized format
  else {
    fprintf(stderr, "fs4plugin) Unrecognized map format.\n");
    return NULL;
  }

  // Convert degrees to radians
  alpha *= M_PI / 180.0;
  beta  *= M_PI / 180.0;
  gamma *= M_PI / 180.0;

  // Warn about assumptions
  printf("fs4plugin) Warning: file does not contain molecule center.\nCentering at <0, 0, 0>\n");

  // Allocate and initialize the fs4 structure
  fs4 = new fs4_t;
  fs4->fd = fd;
  fs4->vol = NULL;
  *natoms = MOLFILE_NUMATOMS_NONE;
  fs4->nsets = 1; // this file contains only one data set
  fs4->swap = swap;
  fs4->scale = scale;
  if (norn == 0) {
    // x fast, z medium, y slow
    fs4->x = 0;
    fs4->y = 2;
    fs4->z = 1;
    fs4->f = 0;
    fs4->m = 2;
    fs4->s = 1;
  }
  else if (norn == 1) {
    // y fast, z medium, x slow
    fs4->x = 2;
    fs4->y = 0;
    fs4->z = 1;
    fs4->f = 1;
    fs4->m = 2;
    fs4->s = 0;
  }
  else { // norn ==2
    // x fast, y medium, z slow
    fs4->x = 0;
    fs4->y = 1;
    fs4->z = 2;
    fs4->f = 0;
    fs4->m = 1;
    fs4->s = 2;
  }

  fs4->vol = new molfile_volumetric_t[1];
  strcpy(fs4->vol[0].dataname, "Fsfour Electron Density Map");

  // Place the origin at {0 0 0}
  fs4->vol[0].origin[0] = 0.0;
  fs4->vol[0].origin[1] = 0.0;
  fs4->vol[0].origin[2] = 0.0;

  fs4->vol[0].xaxis[0] = fmsCellSize[0];
  fs4->vol[0].xaxis[1] = 0.0;
  fs4->vol[0].xaxis[2] = 0.0;

  fs4->vol[0].yaxis[0] = cos(gamma) * fmsCellSize[1];
  fs4->vol[0].yaxis[1] = sin(gamma) * fmsCellSize[1];
  fs4->vol[0].yaxis[2] = 0.0;
 
  z1 = cos(beta);
  z2 = (cos(alpha) - cos(beta)*cos(gamma)) / sin(gamma);
  z3 = sqrt(1.0 - z1*z1 - z2*z2);
  fs4->vol[0].zaxis[0] = z1 * fmsCellSize[2];
  fs4->vol[0].zaxis[1] = z2 * fmsCellSize[2];
  fs4->vol[0].zaxis[2] = z3 * fmsCellSize[2];

  fs4->vol[0].xsize = fmsGridSize[fs4->x];
  fs4->vol[0].ysize = fmsGridSize[fs4->y];
  fs4->vol[0].zsize = fmsGridSize[fs4->z];

  fs4->vol[0].has_color = 0;

  return fs4;
}
Exemplo n.º 22
0
static int read_uhbd_data(void *v, int set, float *datablock,
                         float *colorblock) {
  uhbd_t *uhbd = (uhbd_t *)v;
  FILE *fd = uhbd->fd;
  char inbuf[LINESIZE];
  float grid[6];
  int z, xsize, ysize, zsize, xysize, count, count2, total, i;

  xsize = uhbd->vol[0].xsize;
  ysize = uhbd->vol[0].ysize;
  zsize = uhbd->vol[0].zsize;
  xysize = xsize * ysize;
  total = xysize * zsize;

  if (uhbd->scale) {
    int headerblock[6];
    // The binary data is written one z-slice at a time.  First, a 
    // block of three ints indicating which slice is next, of the form
    // kk, im, jm, where kk is the on-based slice index, and im and jm
    // are the x and y dimensions.  We just read past them and also read the
    // start of the next block, which is the actual data.
    for (z=0; z<zsize; z++) {
      if (fread(headerblock, sizeof(int), 6, fd) != 6) {
        fprintf(stderr, "uhbdplugin) Error reading header block in binary uhbd file\n");
        return MOLFILE_ERROR;
      }
      // TODO: some sanity checks on the header block.
      if (fread(datablock + z*xysize, sizeof(float), xysize, fd) != xysize) {
        fprintf(stderr, "uhbdplugin) Error reading data block in binary uhbd file\n");
        return MOLFILE_ERROR;
      }
      // read the trailing block delimiter
      fseek(fd, 4, SEEK_CUR);
    }
    if (uhbd->doswap) {
      swap4_aligned(datablock, total);
    }
    return MOLFILE_SUCCESS;
  }

  /* Read the values from the file */
  for (z = 0; z < zsize; z++) {
    // read header
    if (uhbdgets(inbuf, LINESIZE, fd, 
        "uhbdplugin) error while getting density plane indices\n") == NULL)
      return MOLFILE_ERROR;

    // read data
    for (count = 0; count < xysize/6; count++) {
      if (uhbdgets(inbuf, LINESIZE, fd,
          "uhbdplugin) error while getting density values\n") == NULL)
        return MOLFILE_ERROR;

      if (sscanf(inbuf, "%e %e %e %e %e %e", &grid[0], &grid[1], &grid[2], &grid[3], &grid[4], &grid[5]) != 6) {
        printf("uhbdplugin) Error reading grid data.\n");
        return MOLFILE_ERROR;
      }
    
      for (i = 0; i < 6; i++) { 
        datablock[i + count*6 + z*xysize] = grid[i];
      }
    }

    if ((xysize%6) != 0) {
      if (uhbdgets(inbuf, LINESIZE, fd, 
          "uhbdplugin) error reading data elements modulo 6\n") == NULL)
        return MOLFILE_ERROR;

      count2 = sscanf(inbuf, "%e %e %e %e %e %e", &grid[0], &grid[1], &grid[2], &grid[3], &grid[4], &grid[5]);
      if (count2 != (xysize%6)) {
        printf("uhbdplugin) Error: incorrect number of data points.\n");
        return MOLFILE_ERROR;
      }

      for (i = 0; i < count2; i++) {
        datablock[i + (count+1)*6 + z*xysize] = grid[i];
      }
    }
  }

  return MOLFILE_SUCCESS;
}
Exemplo n.º 23
0
static void *open_ccp4_read(const char *filepath, const char *filetype,
    int *natoms) {
  FILE *fd;
  ccp4_t *ccp4;
  char mapString[4], symData[81];
  int nxyzstart[3], extent[3], grid[3], crs2xyz[3], mode, symBytes;
  float origin2k[3];
  int swap, i, xIndex, yIndex, zIndex;
  long dataOffset, filesize;
  float cellDimensions[3], cellAngles[3], xaxis[3], yaxis[3], zaxis[3];
  float alpha, beta, gamma, xScale, yScale, zScale, z1, z2, z3;
  
  fd = fopen(filepath, "rb");
  if (!fd) {
    printf("ccp4plugin) Error opening file %s\n", filepath);
    return NULL;
  }

  if ( (fread(extent, sizeof(int), 3, fd) != 3) ||
       (fread(&mode, sizeof(int), 1, fd) != 1) ||
       (fread(nxyzstart, sizeof(int), 3, fd) != 3) ||
       (fread(grid, sizeof(int), 3, fd) != 3) ||
       (fread(cellDimensions, sizeof(float), 3, fd) != 3) ||
       (fread(cellAngles, sizeof(float), 3, fd) != 3) ||
       (fread(crs2xyz, sizeof(int), 3, fd) != 3) ) {
    printf("ccp4plugin) Error: Improperly formatted line.\n");
    return NULL;
  }

  // Check the number of bytes used for storing symmetry operators
  // (word 23, byte 92)
  fseek(fd, 23 * 4, SEEK_SET);
  if ((fread(&symBytes, sizeof(int), 1, fd) != 1) ) {
    printf("ccp4plugin) Error: Failed reading symmetry bytes record.\n");
    return NULL;
  }

  // read MRC2000 Origin record at word 49, byte 196, and use it if necessary
  // http://www2.mrc-lmb.cam.ac.uk/image2000.html
  fseek(fd, 49 * 4, SEEK_SET);
  if (fread(origin2k, sizeof(float), 3, fd) != 3) {
    printf("ccp4plugin) Error: unable to read ORIGIN records at offset 196.\n");
  }

  // Check for the string "MAP" at word 52 byte 208, indicating a CCP4 file.
  fseek(fd, 52 * 4, SEEK_SET);
  if ( (fgets(mapString, 4, fd) == NULL) ||
       (strcmp(mapString, "MAP") != 0) ) {
    printf("ccp4plugin) Error: 'MAP' string missing, not a valid CCP4 file.\n");
    return NULL;
  }

  swap = 0;
  // Check the data type of the file.
  if (mode != 2) {
    // Check if the byte-order is flipped
    swap4_aligned(&mode, 1);
    if (mode != 2) {
      printf("ccp4plugin) Error: Non-real (32-bit float) data types are unsupported.\n");
      return NULL;
    } else {
      swap = 1; // enable byte swapping
    }
  }

  // Swap all the information obtained from the header
  if (swap == 1) {
    swap4_aligned(extent, 3);
    swap4_aligned(nxyzstart, 3);
    swap4_aligned(origin2k, 3);
    swap4_aligned(grid, 3);
    swap4_aligned(cellDimensions, 3);
    swap4_aligned(cellAngles, 3);
    swap4_aligned(crs2xyz, 3);
    swap4_aligned(&symBytes, 1);
  }


#if 1
  printf("ccp4plugin)    extent: %d x %d x %d\n",
         extent[0], extent[1], extent[2]);
  printf("ccp4plugin) nxyzstart: %d x %d x %d\n", 
         nxyzstart[0], nxyzstart[1], nxyzstart[2]);
  printf("ccp4plugin)  origin2k: %f x %f x %f\n", 
         origin2k[0], origin2k[1], origin2k[2]);
  printf("ccp4plugin)      grid: %d x %d x %d\n", grid[0], grid[1], grid[2]);
  printf("ccp4plugin)   celldim: %f x %f x %f\n", 
         cellDimensions[0], cellDimensions[1], cellDimensions[2]);
  printf("cpp4plugin)cellangles: %f, %f, %f\n", 
         cellAngles[0], cellAngles[1], cellAngles[2]);
  printf("ccp4plugin)   crs2xyz: %d %d %d\n", 
         crs2xyz[0], crs2xyz[1], crs2xyz[2]);
  printf("ccp4plugin)  symBytes: %d\n", symBytes);
#endif


  // Check the dataOffset: this fixes the problem caused by files claiming
  // to have symmetry records when they do not.
  fseek(fd, 0, SEEK_END);
  filesize = ftell(fd);
  dataOffset = filesize - 4*(extent[0]*extent[1]*extent[2]);
  if (dataOffset != (CCP4HDSIZE + symBytes)) {
    if (dataOffset == CCP4HDSIZE) {
      // Bogus symmetry record information
      printf("ccp4plugin) Warning: file contains bogus symmetry record.\n");
      symBytes = 0;
    } else if (dataOffset < CCP4HDSIZE) {
      printf("ccp4plugin) Error: File appears truncated and doesn't match header.\n");
      return NULL;
    } else if ((dataOffset > CCP4HDSIZE) && (dataOffset < (1024*1024))) {
      // Fix for loading SPIDER files which are larger than usual
      // In this specific case, we must absolutely trust the symBytes record
      dataOffset = CCP4HDSIZE + symBytes; 
      printf("ccp4plugin) Warning: File is larger than expected and doesn't match header.\n");
      printf("ccp4plugin) Warning: Continuing file load, good luck!\n");
    } else {
      printf("ccp4plugin) Error: File is MUCH larger than expected and doesn't match header.\n");
      return NULL;
    }
  }

  // Read symmetry records -- organized as 80-byte lines of text.
  if (symBytes != 0) {
    printf("ccp4plugin) Symmetry records found:\n");
    fseek(fd, CCP4HDSIZE, SEEK_SET);
    for (i = 0; i < symBytes/80; i++) {
      fgets(symData, 81, fd);
      printf("ccp4plugin) %s\n", symData);
    }
  }

  // check extent and grid interval counts
  if (grid[0] == 0 && extent[0] > 0) {
    grid[0] = extent[0] - 1;
    printf("ccp4plugin) Warning: Fixed X interval count\n");
  }
  if (grid[1] == 0 && extent[1] > 0) {
    grid[1] = extent[1] - 1;
    printf("ccp4plugin) Warning: Fixed Y interval count\n");
  }
  if (grid[2] == 0 && extent[2] > 0) {
    grid[2] = extent[2] - 1;
    printf("ccp4plugin) Warning: Fixed Z interval count\n");
  }
 

  // Allocate and initialize the ccp4 structure
  ccp4 = new ccp4_t;
  ccp4->fd = fd;
  ccp4->vol = NULL;
  *natoms = MOLFILE_NUMATOMS_NONE;
  ccp4->nsets = 1; // this EDM file contains only one data set
  ccp4->swap = swap;
  ccp4->dataOffset = dataOffset;

  ccp4->vol = new molfile_volumetric_t[1];
  strcpy(ccp4->vol[0].dataname, "CCP4 Electron Density Map");

  // Mapping between CCP4 column, row, section and VMD x, y, z.
  if (crs2xyz[0] == 0 && crs2xyz[1] == 0 && crs2xyz[2] == 0) {
    printf("ccp4plugin) Warning: All crs2xyz records are zero.\n");
    printf("ccp4plugin) Warning: Setting crs2xyz to 1, 2, 3\n");
    crs2xyz[0] = 1;
    crs2xyz[0] = 2;
    crs2xyz[0] = 3;
  }

  ccp4->xyz2crs[crs2xyz[0]-1] = 0;
  ccp4->xyz2crs[crs2xyz[1]-1] = 1;
  ccp4->xyz2crs[crs2xyz[2]-1] = 2;
  xIndex = ccp4->xyz2crs[0];
  yIndex = ccp4->xyz2crs[1];
  zIndex = ccp4->xyz2crs[2];

  // calculate non-orthogonal unit cell coordinates
  alpha = (M_PI / 180.0) * cellAngles[0];
  beta = (M_PI / 180.0) * cellAngles[1];
  gamma = (M_PI / 180.0) * cellAngles[2];

  if (cellDimensions[0] == 0.0 && 
      cellDimensions[1] == 0.0 &&
      cellDimensions[2] == 0.0) {
    printf("ccp4plugin) Warning: Cell dimensions are all zero.\n");
    printf("ccp4plugin) Warning: Setting to 1.0, 1.0, 1.0 for viewing.\n");
    printf("ccp4plugin) Warning: Map file will not align with other structures.\n");
    cellDimensions[0] = 1.0;
    cellDimensions[1] = 1.0;
    cellDimensions[2] = 1.0;
  } 


  xScale = cellDimensions[0] / grid[0];
  yScale = cellDimensions[1] / grid[1];
  zScale = cellDimensions[2] / grid[2];

  // calculate non-orthogonal unit cell coordinates
  xaxis[0] = xScale;
  xaxis[1] = 0;
  xaxis[2] = 0;

  yaxis[0] = cos(gamma) * yScale;
  yaxis[1] = sin(gamma) * yScale;
  yaxis[2] = 0;

  z1 = cos(beta);
  z2 = (cos(alpha) - cos(beta)*cos(gamma)) / sin(gamma);
  z3 = sqrt(1.0 - z1*z1 - z2*z2);
  zaxis[0] = z1 * zScale;
  zaxis[1] = z2 * zScale;
  zaxis[2] = z3 * zScale;

#if 1
  // Handle both MRC-2000 and older format maps
  if (origin2k[0] == 0.0f && origin2k[1] == 0.0f && origin2k[2] == 0.0f) {
    printf("ccp4plugin) using CCP4 n[xyz]start origin\n");
    ccp4->vol[0].origin[0] = xaxis[0] * nxyzstart[xIndex] + 
                             yaxis[0] * nxyzstart[yIndex] +
                             zaxis[0] * nxyzstart[zIndex];
    ccp4->vol[0].origin[1] = yaxis[1] * nxyzstart[yIndex] +
                             zaxis[1] * nxyzstart[zIndex];
    ccp4->vol[0].origin[2] = zaxis[2] * nxyzstart[zIndex];
  } else {
    // Use ORIGIN records rather than old n[xyz]start records
    //   http://www2.mrc-lmb.cam.ac.uk/image2000.html
    // XXX the ORIGIN field is only used by the EM community, and
    //     has undefined meaning for non-orthogonal maps and/or
    //     non-cubic voxels, etc.
    printf("ccp4plugin) using MRC2000 origin\n");
    ccp4->vol[0].origin[0] = origin2k[xIndex];
    ccp4->vol[0].origin[1] = origin2k[yIndex];
    ccp4->vol[0].origin[2] = origin2k[zIndex];
  }
#else
  // old code that only pays attention to old MRC nxstart/nystart/nzstart
  ccp4->vol[0].origin[0] = xaxis[0] * nxyzstart[xIndex] + 
                           yaxis[0] * nxyzstart[yIndex] +
                           zaxis[0] * nxyzstart[zIndex];
  ccp4->vol[0].origin[1] = yaxis[1] * nxyzstart[yIndex] +
                           zaxis[1] * nxyzstart[zIndex];
  ccp4->vol[0].origin[2] = zaxis[2] * nxyzstart[zIndex];
#endif

#if 0
  printf("ccp4plugin) origin: %.3f %.3f %.3f\n",
         ccp4->vol[0].origin[0],
         ccp4->vol[0].origin[1],
         ccp4->vol[0].origin[2]);
#endif

  ccp4->vol[0].xaxis[0] = xaxis[0] * (extent[xIndex]-1);
  ccp4->vol[0].xaxis[1] = 0;
  ccp4->vol[0].xaxis[2] = 0;

  ccp4->vol[0].yaxis[0] = yaxis[0] * (extent[yIndex]-1);
  ccp4->vol[0].yaxis[1] = yaxis[1] * (extent[yIndex]-1);
  ccp4->vol[0].yaxis[2] = 0;

  ccp4->vol[0].zaxis[0] = zaxis[0] * (extent[zIndex]-1);
  ccp4->vol[0].zaxis[1] = zaxis[1] * (extent[zIndex]-1);
  ccp4->vol[0].zaxis[2] = zaxis[2] * (extent[zIndex]-1);

  ccp4->vol[0].xsize = extent[xIndex];
  ccp4->vol[0].ysize = extent[yIndex];
  ccp4->vol[0].zsize = extent[zIndex];

  ccp4->vol[0].has_color = 0;

  return ccp4;
}
Exemplo n.º 24
0
void IMDSimBlocking::get_next_ts(float *pos, IMDEnergies *buf) {
  new_coords_ready = 0;
  memcpy(pos, curpos, 3*numcoords*sizeof(float));
  memcpy(buf, &imdEnergies, sizeof(IMDEnergies));
  if (need2flip) swap4_aligned(pos, 3*numcoords);
}
Exemplo n.º 25
0
/* 
 * Read a dcd timestep from a dcd file
 * Input: fd - a file struct opened for binary reading, from which the 
 *             header information has already been read.
 *        natoms, nfixed, first, *freeind, reverse, charmm - the corresponding 
 *             items as set by read_dcdheader
 *        first - true if this is the first frame we are reading.
 *        x, y, z: space for natoms each of floats.
 *        unitcell - space for six floats to hold the unit cell data.  
 *                   Not set if no unit cell data is present.
 * Output: 0 on success, negative error code on failure.
 * Side effects: x, y, z contain the coordinates for the timestep read.
 *               unitcell holds unit cell data if present.
 */
static int read_dcdstep(fio_fd fd, int N, float *X, float *Y, float *Z, 
                        float *unitcell, int num_fixed,
                        int first, int *indexes, float *fixedcoords, 
                        int reverseEndian, int charmm) {
  int ret_val, rec_scale;   /* Return value from read */
  
  if (charmm & DCD_HAS_64BIT_REC) {
    rec_scale=RECSCALE64BIT;
  } else {
    rec_scale=RECSCALE32BIT;
  }
  
  if ((num_fixed==0) || first) {
    /* temp storage for reading formatting info */
    /* note: has to be max size we'll ever use  */
    int tmpbuf[6*RECSCALEMAX]; 

    fio_iovec iov[7];   /* I/O vector for fio_readv() call          */
    fio_size_t readlen; /* number of bytes actually read            */
    int i;

    /* if there are no fixed atoms or this is the first timestep read */
    /* then we read all coordinates normally.                         */

    /* read the charmm periodic cell information */
    /* XXX this too should be read together with the other items in a */
    /*     single fio_readv() call in order to prevent lots of extra  */
    /*     kernel/user context switches.                              */
    ret_val = read_charmm_extrablock(fd, charmm, reverseEndian, unitcell);
    if (ret_val) return ret_val;

    /* setup the I/O vector for the call to fio_readv() */
    iov[0].iov_base = (fio_caddr_t) &tmpbuf[0]; /* read format integer    */
    iov[0].iov_len  = rec_scale*sizeof(int);

    iov[1].iov_base = (fio_caddr_t) X;          /* read X coordinates     */
    iov[1].iov_len  = sizeof(float)*N;

    iov[2].iov_base = (fio_caddr_t) &tmpbuf[1*rec_scale]; /* read 2 format integers */
    iov[2].iov_len  = rec_scale*sizeof(int) * 2;

    iov[3].iov_base = (fio_caddr_t) Y;          /* read Y coordinates     */
    iov[3].iov_len  = sizeof(float)*N;

    iov[4].iov_base = (fio_caddr_t) &tmpbuf[3*rec_scale]; /* read 2 format integers */
    iov[4].iov_len  = rec_scale*sizeof(int) * 2;

    iov[5].iov_base = (fio_caddr_t) Z;          /* read Y coordinates     */
    iov[5].iov_len  = sizeof(float)*N;

    iov[6].iov_base = (fio_caddr_t) &tmpbuf[5*rec_scale]; /* read format integer    */
    iov[6].iov_len  = rec_scale*sizeof(int);

    readlen = fio_readv(fd, &iov[0], 7);

    if (readlen != (rec_scale*6*sizeof(int) + 3*N*sizeof(float)))
      return DCD_BADREAD;

    /* convert endianism if necessary */
    if (reverseEndian) {
      swap4_aligned(&tmpbuf[0], rec_scale*6);
      swap4_aligned(X, N);
      swap4_aligned(Y, N);
      swap4_aligned(Z, N);
    }

    /* double-check the fortran format size values for safety */
    if(rec_scale == 1) {
      for (i=0; i<6; i++) {
        if (tmpbuf[i] != sizeof(float)*N) return DCD_BADFORMAT;
      }
    } else {
      for (i=0; i<6; i++) {
          if ((tmpbuf[2*i]+tmpbuf[2*i+1]) != sizeof(float)*N) return DCD_BADFORMAT;
      }
    }

    /* copy fixed atom coordinates into fixedcoords array if this was the */
    /* first timestep, to be used from now on.  We just copy all atoms.   */
    if (num_fixed && first) {
      memcpy(fixedcoords, X, N*sizeof(float));
      memcpy(fixedcoords+N, Y, N*sizeof(float));
      memcpy(fixedcoords+2*N, Z, N*sizeof(float));
    }

    /* read in the optional charmm 4th array */
    /* XXX this too should be read together with the other items in a */
    /*     single fio_readv() call in order to prevent lots of extra  */
    /*     kernel/user context switches.                              */
    ret_val = read_charmm_4dim(fd, charmm, reverseEndian);
    if (ret_val) return ret_val;
  } else {
    /* if there are fixed atoms, and this isn't the first frame, then we */
    /* only read in the non-fixed atoms for all subsequent timesteps.    */
    ret_val = read_charmm_extrablock(fd, charmm, reverseEndian, unitcell);
    if (ret_val) return ret_val;
    ret_val = read_fixed_atoms(fd, N, N-num_fixed, indexes, reverseEndian,
                               fixedcoords, fixedcoords+3*N, X, charmm);
    if (ret_val) return ret_val;
    ret_val = read_fixed_atoms(fd, N, N-num_fixed, indexes, reverseEndian,
                               fixedcoords+N, fixedcoords+3*N, Y, charmm);
    if (ret_val) return ret_val;
    ret_val = read_fixed_atoms(fd, N, N-num_fixed, indexes, reverseEndian,
                               fixedcoords+2*N, fixedcoords+3*N, Z, charmm);
    if (ret_val) return ret_val;
    ret_val = read_charmm_4dim(fd, charmm, reverseEndian);
    if (ret_val) return ret_val;
  }

  return DCD_SUCCESS;
}
Exemplo n.º 26
0
static int read_ccp4_data(void *v, int set, float *datablock,
                         float *colorblock) {
  ccp4_t *ccp4 = (ccp4_t *)v;
  int x, y, z, xSize, ySize, zSize, extent[3], coord[3];
  long xySize;
  FILE *fd = ccp4->fd;

  xSize = ccp4->vol[0].xsize;
  ySize = ccp4->vol[0].ysize;
  zSize = ccp4->vol[0].zsize;
  xySize = xSize * ySize;

  // coord = <col, row, sec>
  // extent = <colSize, rowSize, secSize>
  extent[ccp4->xyz2crs[0]] = xSize;
  extent[ccp4->xyz2crs[1]] = ySize;
  extent[ccp4->xyz2crs[2]] = zSize;

  fseek(fd, ccp4->dataOffset, SEEK_SET);

  // Read entire rows of data from the file, then write into the
  // datablock with the correct slice ordering.
  if ((ccp4->voxtype == MRC_TYPE_BYTE) && (ccp4->dataflags & DATA_FLAG_SIGNED)) {
    printf("ccp4plugin) reading signed-byte voxel data\n");
    signed char *rowdata = new signed char[extent[0]];
    for (coord[2] = 0; coord[2] < extent[2]; coord[2]++) {
      for (coord[1] = 0; coord[1] < extent[1]; coord[1]++) {
        if (feof(fd)) {
          printf("ccp4plugin) Unexpected end-of-file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (ferror(fd)) {
          printf("ccp4plugin) Problem reading the file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if ( fread(rowdata, sizeof(char), extent[0], fd) != extent[0] ) {
          printf("ccp4plugin) Error reading data row.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }

        for (coord[0] = 0; coord[0] < extent[0]; coord[0]++) {
          x = coord[ccp4->xyz2crs[0]];
          y = coord[ccp4->xyz2crs[1]];
          z = coord[ccp4->xyz2crs[2]];
          datablock[x + long(y*xSize) + long(z*xySize)] = rowdata[coord[0]];
        }
      }
    }
    delete [] rowdata;
  } else if ((ccp4->voxtype == MRC_TYPE_BYTE) && !(ccp4->dataflags & DATA_FLAG_SIGNED)) {
    printf("ccp4plugin) reading unsigned-byte voxel data\n");
    unsigned char *rowdata = new unsigned char[extent[0]];
    for (coord[2] = 0; coord[2] < extent[2]; coord[2]++) {
      for (coord[1] = 0; coord[1] < extent[1]; coord[1]++) {
        if (feof(fd)) {
          printf("ccp4plugin) Unexpected end-of-file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (ferror(fd)) {
          printf("ccp4plugin) Problem reading the file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if ( fread(rowdata, sizeof(unsigned char), extent[0], fd) != extent[0] ) {
          printf("ccp4plugin) Error reading data row.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }

        for (coord[0] = 0; coord[0] < extent[0]; coord[0]++) {
          x = coord[ccp4->xyz2crs[0]];
          y = coord[ccp4->xyz2crs[1]];
          z = coord[ccp4->xyz2crs[2]];
          datablock[x + long(y*xSize) + long(z*xySize)] = rowdata[coord[0]];
        }
      }
    }
    delete [] rowdata;
  } else if (ccp4->voxtype == MRC_TYPE_FLOAT) {
    printf("ccp4plugin) reading float (32-bit real) voxel data\n");
    float *rowdata = new float[extent[0]];
    int x, y, z;
    for (coord[2] = 0; coord[2] < extent[2]; coord[2]++) {
      for (coord[1] = 0; coord[1] < extent[1]; coord[1]++) {
        if (feof(fd)) {
          printf("ccp4plugin) Unexpected end-of-file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (ferror(fd)) {
          printf("ccp4plugin) Problem reading the file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (fread(rowdata, sizeof(float), extent[0], fd) != extent[0] ) {
          printf("ccp4plugin) Error reading data row.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }

        for (coord[0] = 0; coord[0] < extent[0]; coord[0]++) {
          x = coord[ccp4->xyz2crs[0]];
          y = coord[ccp4->xyz2crs[1]];
          z = coord[ccp4->xyz2crs[2]];
          datablock[x + long(y*xSize) + long(z*xySize)] = rowdata[coord[0]];
        }
      }
    }
    delete [] rowdata;
    if (ccp4->swap == 1)
      swap4_aligned(datablock, xySize * zSize);
  } else if (ccp4->voxtype == MRC_TYPE_SHORT) {
    printf("ccp4plugin) reading short (16-bit int) voxel data\n");
    short *rowdata = new short[extent[0]];
    for (coord[2] = 0; coord[2] < extent[2]; coord[2]++) {
      for (coord[1] = 0; coord[1] < extent[1]; coord[1]++) {
        if (feof(fd)) {
          printf("ccp4plugin) Unexpected end-of-file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (ferror(fd)) {
          printf("ccp4plugin) Problem reading the file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (fread(rowdata, sizeof(short), extent[0], fd) != extent[0] ) {
          printf("ccp4plugin) Error reading data row.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (ccp4->swap == 1)
          swap2_aligned(rowdata, extent[0]);
        for (coord[0] = 0; coord[0] < extent[0]; coord[0]++) {
          x = coord[ccp4->xyz2crs[0]];
          y = coord[ccp4->xyz2crs[1]];
          z = coord[ccp4->xyz2crs[2]];
          datablock[x + long(y*xSize) + long(z*xySize)] = rowdata[coord[0]];
        }
      }
    }
    delete [] rowdata;
  } else if (ccp4->voxtype == MRC_TYPE_SHORT2) {
    /* IMOD developers said that this is not used anymore and not worth our time to implement */
    printf("TYPE_SHORT2 not implemented yet...\n");
    return MOLFILE_ERROR;
  } else if (ccp4->voxtype == MRC_TYPE_USHORT) {
    printf("ccp4plugin) reading unsigned short (16-bit int) voxel data\n");
    unsigned short *rowdata = new unsigned short[extent[0]];
    for (coord[2] = 0; coord[2] < extent[2]; coord[2]++) {
      for (coord[1] = 0; coord[1] < extent[1]; coord[1]++) {
        if (feof(fd)) {
          printf("ccp4plugin) Unexpected end-of-file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (ferror(fd)) {
          printf("ccp4plugin) Problem reading the file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (fread(rowdata, sizeof(unsigned short), extent[0], fd) != extent[0] ) {
          printf("ccp4plugin) Error reading data row.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (ccp4->swap == 1)
          swap2_aligned(rowdata, extent[0]);
        for (coord[0] = 0; coord[0] < extent[0]; coord[0]++) {
          x = coord[ccp4->xyz2crs[0]];
          y = coord[ccp4->xyz2crs[1]];
          z = coord[ccp4->xyz2crs[2]];
          datablock[x + long(y*xSize) + long(z*xySize)] = rowdata[coord[0]];
        }
      }
    }
    delete [] rowdata;
  } else if (ccp4->voxtype == MRC_TYPE_UCHAR3) {
    printf("ccp4plugin) reading unsigned char * 3 (8-bit uchar * 3) voxel data\n");
    uchar3 *rowdata = new uchar3[extent[0]];
    float grayscale;
    for (coord[2] = 0; coord[2] < extent[2]; coord[2]++) {
      for (coord[1] = 0; coord[1] < extent[1]; coord[1]++) {
        if (feof(fd)) {
          printf("ccp4plugin) Unexpected end-of-file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if (ferror(fd)) {
          printf("ccp4plugin) Problem reading the file.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        if ( fread(rowdata, sizeof(uchar3), extent[0], fd) != extent[0] ) {
          printf("ccp4plugin) Error reading data row.\n");
          delete [] rowdata;
          return MOLFILE_ERROR;
        }
        for (coord[0] = 0; coord[0] < extent[0]; coord[0]++) {
          x = coord[ccp4->xyz2crs[0]];
          y = coord[ccp4->xyz2crs[1]];
          z = coord[ccp4->xyz2crs[2]];
          grayscale = rowdata[coord[0]].red + rowdata[coord[0]].blue + rowdata[coord[0]].green;
          datablock[x + long(y*xSize) + long(z*xySize)] = grayscale/3.0;
        }
      }
    }
    delete [] rowdata;
  }
  return MOLFILE_SUCCESS;
}