Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

namdbinplugin.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2016 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.23 $       $Date: 2016/11/28 05:01:54 $
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 #define BLOCK 500
00034 
00035 typedef struct {
00036   double xyz[3*BLOCK];
00037   FILE *fd;
00038   int numatoms;
00039   int wrongendian;
00040 } namdbinhandle;
00041 
00042 static void *open_namdbin_read(const char *path, const char *filetype, 
00043     int *natoms) {
00044   namdbinhandle *namdbin;
00045   FILE *fd;
00046   int numatoms;
00047   namdbin_int32 filen;
00048   char lenbuf[4];
00049   char tmpc;
00050 
00051   namdbin = (namdbinhandle *)malloc(sizeof(namdbinhandle));
00052   if (!namdbin) {
00053     fprintf(stderr, "Unable to allocate space for read buffer.\n");
00054     return NULL;
00055   }
00056   memset(namdbin, 0, sizeof(namdbinhandle));
00057 
00058   fd = fopen(path, "rb");
00059   if (!fd) {
00060     fprintf(stderr, "Could not open file '%s' for reading.\n", path);
00061     free(namdbin);
00062     return NULL;
00063   }
00064   fseek(fd,0,SEEK_END);
00065   numatoms = (ftell(fd)-4)/24;
00066   if (numatoms < 1) {
00067     fprintf(stderr, "File '%s' is too short.\n", path);
00068     fclose(fd);
00069     free(namdbin);
00070     return NULL;
00071   }
00072   fseek(fd,0,SEEK_SET);
00073   fread(&filen, sizeof(namdbin_int32), 1, fd);
00074   if (filen != numatoms) {
00075     namdbin->wrongendian = 1;
00076     memcpy(lenbuf, (const char *)&filen, 4);
00077     tmpc = lenbuf[0]; lenbuf[0] = lenbuf[3]; lenbuf[3] = tmpc;
00078     tmpc = lenbuf[1]; lenbuf[1] = lenbuf[2]; lenbuf[2] = tmpc;
00079     memcpy((char *)&filen, lenbuf, 4);
00080   }
00081   if (filen != numatoms) {
00082     fprintf(stderr, "Inconsistent atom count in file '%s'.\n", path);
00083     fclose(fd);
00084     free(namdbin);
00085     return NULL;
00086   }
00087   if ( namdbin->wrongendian ) {
00088     fprintf(stderr, "File '%s' appears to be other-endian.\n", path);
00089   }
00090   namdbin->fd = fd;
00091   namdbin->numatoms = numatoms;
00092   *natoms = namdbin->numatoms;
00093   return namdbin;
00094 }
00095 
00096 static int read_next_timestep(void *v, int natoms, molfile_timestep_t *ts) {
00097   namdbinhandle *namdbin;
00098   int i, numatoms;
00099   char *cdata;
00100 
00101   namdbin = (namdbinhandle *)v;
00102   if (!namdbin->fd) 
00103     return MOLFILE_ERROR;  /* Done reading frames */
00104 
00105   numatoms = namdbin->numatoms;
00106 
00107   for (i=0; i<namdbin->numatoms; i+=BLOCK) {
00108     int j, n;
00109     n = namdbin->numatoms - i;
00110     if ( n > BLOCK ) n = BLOCK;
00111 
00112     if (fread(namdbin->xyz, sizeof(double), 3*n, namdbin->fd) != (size_t)(3*n)) {
00113       fprintf(stderr, "Failure reading data from NAMD binary file.\n");
00114       return MOLFILE_ERROR;
00115     }
00116 
00117     if (namdbin->wrongendian) {
00118       if ( ! i ) fprintf(stderr, "Converting other-endian data from NAMD binary file.\n");
00119       cdata = (char *) namdbin->xyz;
00120       for ( j=0; j<3*n; ++j, cdata+=8 ) {
00121         char tmp0, tmp1, tmp2, tmp3;
00122         tmp0 = cdata[0]; tmp1 = cdata[1];
00123         tmp2 = cdata[2]; tmp3 = cdata[3];
00124         cdata[0] = cdata[7]; cdata[1] = cdata[6];
00125         cdata[2] = cdata[5]; cdata[3] = cdata[4];
00126         cdata[7] = tmp0; cdata[6] = tmp1;
00127         cdata[5] = tmp2; cdata[4] = tmp3;
00128       }
00129     }
00130 
00131     if (ts) {
00132       for (j=0; j<n; ++j) {
00133         ts->coords[3L*(i+j)  ] = namdbin->xyz[3*j  ];
00134         ts->coords[3L*(i+j)+1] = namdbin->xyz[3*j+1];
00135         ts->coords[3L*(i+j)+2] = namdbin->xyz[3*j+2];
00136       }
00137     }
00138 
00139   }
00140   /*
00141    * Close the file handle and set to NULL so we know we're done reading 
00142    */
00143   fclose(namdbin->fd);
00144   namdbin->fd = NULL;
00145 
00146   return MOLFILE_SUCCESS;
00147 }
00148  
00149 static void close_file_read(void *v) {
00150   namdbinhandle *namdbin = (namdbinhandle *)v;
00151   if (namdbin->fd)
00152     fclose(namdbin->fd);
00153   free(namdbin);
00154 }
00155 
00156 static void *open_namdbin_write(const char *path, const char *filetype, 
00157     int natoms) {
00158   namdbinhandle *namdbin;
00159   FILE *fd;
00160 
00161   namdbin = (namdbinhandle *)malloc(sizeof(namdbinhandle));
00162   if (!namdbin) {
00163     fprintf(stderr, "Unable to allocate space for write buffer.\n");
00164     return NULL;
00165   }
00166 
00167   fd = fopen(path, "wb");
00168   if (!fd) {
00169     fprintf(stderr, "Could not open file %s for writing\n", path);
00170     free(namdbin);
00171     return NULL;
00172   }
00173 
00174   namdbin->fd = fd;
00175   namdbin->numatoms = natoms;
00176   return namdbin;
00177 }
00178 
00179 static int write_timestep(void *v, const molfile_timestep_t *ts) {
00180   
00181   int i;
00182   namdbin_int32 myint;
00183   namdbinhandle *namdbin = (namdbinhandle *)v;
00184   
00185   if (!namdbin->fd)
00186     return MOLFILE_ERROR;
00187   
00188   myint = (namdbin_int32)namdbin->numatoms;
00189   fwrite(&myint, 4, 1, namdbin->fd);
00190 
00191   for (i=0; i<namdbin->numatoms; i+=BLOCK) {
00192     double *tmp = namdbin->xyz;
00193     int j, n;
00194     n = namdbin->numatoms - i;
00195     if ( n > BLOCK ) n = BLOCK;
00196     for (j=0; j<n; ++j) {
00197       tmp[3*j  ] = ts->coords[3L*(i+j)  ];
00198       tmp[3*j+1] = ts->coords[3L*(i+j)+1];
00199       tmp[3*j+2] = ts->coords[3L*(i+j)+2];
00200     }
00201     if (fwrite(tmp, sizeof(double), 3*n, namdbin->fd) != 3*n) {
00202       fprintf(stderr, "Error writing namd binary file\n");
00203       return MOLFILE_ERROR;
00204     }
00205   }
00206   
00207   /*
00208    * Close and NULLify the file handle so we don't write any more frames.
00209    */
00210   fclose(namdbin->fd);
00211   namdbin->fd = NULL;
00212 
00213   return MOLFILE_SUCCESS;
00214 }
00215        
00216 static void close_file_write(void *v) {
00217   namdbinhandle *namdbin = (namdbinhandle *)v;
00218   if (namdbin->fd)
00219     fclose(namdbin->fd);
00220   free(namdbin);
00221 }
00222 
00223 /*
00224  * Initialization stuff here
00225  */
00226 
00227 static molfile_plugin_t plugin;
00228 
00229 VMDPLUGIN_API int VMDPLUGIN_init() {
00230   memset(&plugin, 0, sizeof(molfile_plugin_t));
00231   plugin.abiversion = vmdplugin_ABIVERSION;
00232   plugin.type = MOLFILE_PLUGIN_TYPE;
00233   plugin.name = "namdbin";
00234   plugin.prettyname = "NAMD Binary Coordinates";
00235   plugin.author = "James Phillips, Justin Gullingsrud";
00236   plugin.majorv = 0;
00237   plugin.minorv = 2;
00238   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00239   plugin.filename_extension = "coor";
00240   plugin.open_file_read = open_namdbin_read;
00241   plugin.read_next_timestep = read_next_timestep;
00242   plugin.close_file_read = close_file_read;
00243   plugin.open_file_write = open_namdbin_write;
00244   plugin.write_timestep = write_timestep;
00245   plugin.close_file_write = close_file_write;
00246   return VMDPLUGIN_SUCCESS;
00247 }
00248 
00249 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00250   (*cb)(v, (vmdplugin_t *)&plugin);
00251   return VMDPLUGIN_SUCCESS;
00252 }
00253 
00254 VMDPLUGIN_API int VMDPLUGIN_fini() {
00255   return VMDPLUGIN_SUCCESS;
00256 }
00257 
00258   
00259 #ifdef TEST_NAMDBINPLUGIN
00260 
00261 int main(int argc, char *argv[]) {
00262   molfile_header_t header;
00263   molfile_timestep_t timestep;
00264   void *v;
00265   int i;
00266 
00267   while (--argc) {
00268     ++argv; 
00269     v = open_namdbin_read(*argv, &header);
00270     if (!v) {
00271       fprintf(stderr, "open_namdbin_read failed for file %s\n", *argv);
00272       return 1;
00273     }
00274     timestep.coords = (float *)malloc(3*sizeof(float)*header.numatoms);
00275     for (i=0; i<header.numsteps; i++) {
00276       int rc = read_next_timestep(v, &timestep);
00277       if (rc) {
00278         fprintf(stderr, "error in read_next_timestep\n");
00279         return 1;
00280       }
00281     }
00282     close_file_read(v);
00283   }
00284   return 0;
00285 }
00286  
00287       
00288 #endif  
00289 

Generated on Tue Aug 11 03:06:37 2020 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002