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.20 $       $Date: 2006/06/19 18:19: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 
00209 VMDPLUGIN_API int VMDPLUGIN_init() {
00210   memset(&plugin, 0, sizeof(molfile_plugin_t));
00211   plugin.abiversion = vmdplugin_ABIVERSION;
00212   plugin.type = MOLFILE_PLUGIN_TYPE;
00213   plugin.name = "namdbin";
00214   plugin.prettyname = "NAMD Binary Coordinates";
00215   plugin.author = "James Phillips, Justin Gullingsrud";
00216   plugin.majorv = 0;
00217   plugin.minorv = 2;
00218   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00219   plugin.filename_extension = "coor";
00220   plugin.open_file_read = open_namdbin_read;
00221   plugin.read_next_timestep = read_next_timestep;
00222   plugin.close_file_read = close_file_read;
00223   plugin.open_file_write = open_namdbin_write;
00224   plugin.write_timestep = write_timestep;
00225   plugin.close_file_write = close_file_write;
00226   return VMDPLUGIN_SUCCESS;
00227 }
00228 
00229 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00230   (*cb)(v, (vmdplugin_t *)&plugin);
00231   return VMDPLUGIN_SUCCESS;
00232 }
00233 
00234 VMDPLUGIN_API int VMDPLUGIN_fini() {
00235   return VMDPLUGIN_SUCCESS;
00236 }
00237 
00238   
00239 #ifdef TEST_NAMDBINPLUGIN
00240 
00241 int main(int argc, char *argv[]) {
00242   molfile_header_t header;
00243   molfile_timestep_t timestep;
00244   void *v;
00245   int i;
00246 
00247   while (--argc) {
00248     ++argv; 
00249     v = open_namdbin_read(*argv, &header);
00250     if (!v) {
00251       fprintf(stderr, "open_namdbin_read failed for file %s\n", *argv);
00252       return 1;
00253     }
00254     timestep.coords = (float *)malloc(3*sizeof(float)*header.numatoms);
00255     for (i=0; i<header.numsteps; i++) {
00256       int rc = read_next_timestep(v, &timestep);
00257       if (rc) {
00258         fprintf(stderr, "error in read_next_timestep\n");
00259         return 1;
00260       }
00261     }
00262     close_file_read(v);
00263   }
00264   return 0;
00265 }
00266  
00267       
00268 #endif  
00269 

Generated on Sun Sep 7 01:39:32 2008 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002