Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

namdbinplugin.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2006 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: namdbinplugin.c,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.19 $       $Date: 2006/02/23 19:36:45 $
00015  *
00016  ***************************************************************************/
00017 
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <string.h>
00021 #include <limits.h>
00022 
00023 #include "molfile_plugin.h"
00024 
00025 #if INT_MAX == 2147483647
00026   typedef int namdbin_int32;
00027 #elif SHRT_MAX == 2147483647
00028   typedef short namdbin_int32;
00029 #elif LONG_MAX == 2147483647
00030   typedef long namdbin_int32;
00031 #endif
00032 
00033 typedef struct {
00034   FILE *fd;
00035   int numatoms;
00036   int wrongendian;
00037   double *xyz;
00038 } namdbinhandle;
00039 
00040 static void *open_namdbin_read(const char *path, const char *filetype, 
00041     int *natoms) {
00042   namdbinhandle *namdbin;
00043   FILE *fd;
00044   int numatoms;
00045   namdbin_int32 filen;
00046   char lenbuf[4];
00047   char tmpc;
00048 
00049   fd = fopen(path, "rb");
00050   if (!fd) {
00051     fprintf(stderr, "Could not open file '%s' for reading.\n", path);
00052     return NULL;
00053   }
00054   namdbin = (namdbinhandle *)malloc(sizeof(namdbinhandle));
00055   memset(namdbin, 0, sizeof(namdbinhandle));
00056   fseek(fd,0,SEEK_END);
00057   numatoms = (ftell(fd)-4)/24;
00058   if (numatoms < 1) {
00059     fprintf(stderr, "File '%s' is too short.\n", path);
00060     fclose(fd);
00061     free(namdbin);
00062     return NULL;
00063   }
00064   fseek(fd,0,SEEK_SET);
00065   fread(&filen, sizeof(namdbin_int32), 1, fd);
00066   if (filen != numatoms) {
00067     namdbin->wrongendian = 1;
00068     memcpy(lenbuf, (const char *)&filen, 4);
00069     tmpc = lenbuf[0]; lenbuf[0] = lenbuf[3]; lenbuf[3] = tmpc;
00070     tmpc = lenbuf[1]; lenbuf[1] = lenbuf[2]; lenbuf[2] = tmpc;
00071     memcpy((char *)&filen, lenbuf, 4);
00072   }
00073   if (filen != numatoms) {
00074     fprintf(stderr, "Inconsistent atom count in file '%s'.\n", path);
00075     fclose(fd);
00076     free(namdbin);
00077     return NULL;
00078   }
00079   if ( namdbin->wrongendian ) {
00080     fprintf(stderr, "File '%s' appears to be other-endian.\n", path);
00081   }
00082   namdbin->fd = fd;
00083   namdbin->numatoms = numatoms;
00084   namdbin->xyz = (double *)malloc(3 * namdbin->numatoms * sizeof(double));
00085   if (!namdbin->xyz) {
00086     fprintf(stderr, "Unable to allocate space for %d atoms.\n", namdbin->numatoms);
00087     fclose(fd);
00088     free(namdbin);
00089     return NULL;
00090   }
00091   *natoms = namdbin->numatoms;
00092   return namdbin;
00093 }
00094 
00095 static int read_next_timestep(void *v, int natoms, molfile_timestep_t *ts) {
00096   namdbinhandle *namdbin;
00097   int i, numatoms;
00098   char *cdata;
00099   char tmp0, tmp1, tmp2, tmp3;
00100 
00101   namdbin = (namdbinhandle *)v;
00102   if (!namdbin->fd) 
00103     return MOLFILE_ERROR;  /* Done reading frames */
00104 
00105   numatoms = namdbin->numatoms;
00106 
00107   if (fread(namdbin->xyz, sizeof(double), 3 * numatoms, namdbin->fd)
00108                                  != (size_t)(3 * numatoms)) {
00109     fprintf(stderr, "Failure reading data from NAMD binary file.\n");
00110     return MOLFILE_ERROR;
00111   }
00112 
00113   if (namdbin->wrongendian) {
00114     fprintf(stderr, "Converting other-endian data from NAMD binary file.\n");
00115     cdata = (char *) namdbin->xyz;
00116     for ( i=0; i<3*numatoms; ++i, cdata+=8 ) {
00117       tmp0 = cdata[0]; tmp1 = cdata[1];
00118       tmp2 = cdata[2]; tmp3 = cdata[3];
00119       cdata[0] = cdata[7]; cdata[1] = cdata[6];
00120       cdata[2] = cdata[5]; cdata[3] = cdata[4];
00121       cdata[7] = tmp0; cdata[6] = tmp1;
00122       cdata[5] = tmp2; cdata[4] = tmp3;
00123     }
00124   }
00125 
00126   if (ts) {
00127     for ( i=0; i<numatoms; ++i) {
00128       ts->coords[3*i] = namdbin->xyz[3*i];
00129       ts->coords[3*i+1] = namdbin->xyz[3*i+1];
00130       ts->coords[3*i+2] = namdbin->xyz[3*i+2];
00131     }
00132   }
00133   /*
00134    * Close the file handle and set to NULL so we know we're done reading 
00135    */
00136   fclose(namdbin->fd);
00137   namdbin->fd = NULL;
00138 
00139   return MOLFILE_SUCCESS;
00140 }
00141  
00142 static void close_file_read(void *v) {
00143   namdbinhandle *namdbin = (namdbinhandle *)v;
00144   if (namdbin->fd)
00145     fclose(namdbin->fd);
00146   free(namdbin->xyz);
00147   free(namdbin);
00148 }
00149 
00150 static void *open_namdbin_write(const char *path, const char *filetype, 
00151     int natoms) {
00152   namdbinhandle *namdbin;
00153   FILE *fd;
00154 
00155   fd = fopen(path, "wb");
00156   if (!fd) {
00157     fprintf(stderr, "Could not open file %s for writing\n", path);
00158     return NULL;
00159   }
00160 
00161   namdbin = (namdbinhandle *)malloc(sizeof(namdbinhandle));
00162   namdbin->fd = fd;
00163   namdbin->numatoms = natoms;
00164   return namdbin;
00165 }
00166 
00167 static int write_timestep(void *v, const molfile_timestep_t *ts) {
00168   
00169   int i;
00170   namdbin_int32 myint;
00171   namdbinhandle *namdbin = (namdbinhandle *)v;
00172   
00173   if (!namdbin->fd)
00174     return MOLFILE_ERROR;
00175   
00176   myint = (namdbin_int32)namdbin->numatoms;
00177   fwrite(&myint, 4, 1, namdbin->fd);
00178 
00179   for (i=0; i<3*namdbin->numatoms; i++) {
00180     double tmp = ts->coords[i];
00181     if (fwrite(&tmp, sizeof(double), 1, namdbin->fd) != 1) {
00182       fprintf(stderr, "Error writing namd binary file\n");
00183       return MOLFILE_ERROR;
00184     }
00185   }
00186   
00187   /*
00188    * Close and NULLify the file handle so we don't write any more frames.
00189    */
00190   fclose(namdbin->fd);
00191   namdbin->fd = NULL;
00192 
00193   return MOLFILE_SUCCESS;
00194 }
00195        
00196 static void close_file_write(void *v) {
00197   namdbinhandle *namdbin = (namdbinhandle *)v;
00198   if (namdbin->fd)
00199     fclose(namdbin->fd);
00200   free(namdbin);
00201 }
00202 
00203 /*
00204  * Initialization stuff here
00205  */
00206 
00207 static molfile_plugin_t plugin = {
00208   vmdplugin_ABIVERSION,         /* ABI verison */
00209   MOLFILE_PLUGIN_TYPE,          /* type of plugin */
00210   "namdbin",                    /* name of plugin */
00211   "NAMD Binary Coordinates",    /* name of plugin */
00212   "James Phillips, Justin Gullingsrud",  /* author */
00213   0,                            /* major version */
00214   1,                            /* minor version */
00215   VMDPLUGIN_THREADSAFE,         /* is reentrant */
00216   "coor",                       /* filename extension */
00217   open_namdbin_read,
00218   0,
00219   0,
00220   read_next_timestep,
00221   close_file_read,
00222   open_namdbin_write,
00223   0,
00224   write_timestep,
00225   close_file_write
00226 };
00227 
00228 VMDPLUGIN_API int VMDPLUGIN_init() {
00229   return VMDPLUGIN_SUCCESS;
00230 }
00231 
00232 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00233   (*cb)(v, (vmdplugin_t *)&plugin);
00234   return VMDPLUGIN_SUCCESS;
00235 }
00236 
00237 VMDPLUGIN_API int VMDPLUGIN_fini() {
00238   return VMDPLUGIN_SUCCESS;
00239 }
00240 
00241   
00242 #ifdef TEST_NAMDBINPLUGIN
00243 
00244 int main(int argc, char *argv[]) {
00245   molfile_header_t header;
00246   molfile_timestep_t timestep;
00247   void *v;
00248   int i;
00249 
00250   while (--argc) {
00251     ++argv; 
00252     v = open_namdbin_read(*argv, &header);
00253     if (!v) {
00254       fprintf(stderr, "open_namdbin_read failed for file %s\n", *argv);
00255       return 1;
00256     }
00257     timestep.coords = (float *)malloc(3*sizeof(float)*header.numatoms);
00258     for (i=0; i<header.numsteps; i++) {
00259       int rc = read_next_timestep(v, &timestep);
00260       if (rc) {
00261         fprintf(stderr, "error in read_next_timestep\n");
00262         return 1;
00263       }
00264     }
00265     close_file_read(v);
00266   }
00267   return 0;
00268 }
00269  
00270       
00271 #endif  
00272 

Generated on Wed Mar 22 13:15:30 2006 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002