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

dlpolyplugin.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: dlpolyplugin.c,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.13 $       $Date: 2006/02/23 19:36:44 $
00015  *
00016  ***************************************************************************/
00017 
00018 /*
00019  * DLPOLY formatted history file format:
00020  *   http://www.cse.clrc.ac.uk/msi/software/DL_POLY/MANUALS/USRMAN3/node141.html
00021  *   http://hidra.iqfr.csic.es/man/dlpoly/USRMAN/node156.html
00022  *
00023  */
00024 
00025 #include "largefiles.h"   /* platform dependent 64-bit file I/O defines */
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <ctype.h>
00031 #include "molfile_plugin.h"
00032 
00033 #ifndef M_PI_2
00034 #define M_PI_2 1.57079632679489661922
00035 #endif
00036 
00037 typedef struct {
00038   FILE *file;
00039   int numatoms;
00040   char *file_name;
00041   molfile_atom_t *atomlist;
00042   int cellwarnflag;
00043 } dlpolydata;
00044  
00045 static void *open_dlpoly_read(const char *filename, const char *filetype, 
00046                            int *natoms) {
00047   FILE *fd;
00048   dlpolydata *data;
00049   char fbuffer[1025], buf[1025];
00050   int scancount, nstep, keytrj, atomcount;
00051 
00052   fd = fopen(filename, "rb");
00053   if (!fd) return NULL;
00054 
00055   if (NULL == fgets(fbuffer, 1024, fd))  
00056     return NULL;
00057  
00058   /* check to see if the first line is a "timestep" record */ 
00059   scancount = sscanf(fbuffer, "%s %d %d", buf, &nstep, natoms);
00060   if (scancount != 3 || strcmp(buf, "timestep") != 0) {
00061     /* if not a timestep, it might have the normal header on it      */
00062     /* in which case we'll skip the first line, and parse the second */
00063     if (NULL == fgets(fbuffer, 1024, fd))  
00064       return NULL;
00065     scancount = sscanf(fbuffer, "%d %d %d", &keytrj, &nstep, natoms);
00066     if (scancount != 3) {
00067       printf("open_dlpoly_read) unrecognized header record\n");
00068       return NULL;
00069     } 
00070 
00071     /* now check the first timestep record for safety */
00072     if (NULL == fgets(fbuffer, 1024, fd))  
00073       return NULL;
00074     scancount = sscanf(fbuffer, "%s %d %d", buf, &nstep, &atomcount);
00075     if (scancount != 3 || strcmp(buf, "timestep") != 0) {
00076       printf("open_dlpoly_read) unrecognized timestep record\n");
00077       return NULL;
00078     }
00079 
00080     if (atomcount != *natoms) {
00081       printf("open_dlpoly_read) mismatched atom count\n");
00082       return NULL;
00083     }
00084   }
00085  
00086   data = (dlpolydata *)malloc(sizeof(dlpolydata));
00087   data->file = fd;
00088   data->file_name = strdup(filename);
00089   data->numatoms= *natoms;
00090   data->cellwarnflag = 0;
00091 
00092   rewind(data->file); /* prepare for first read_timestep call */
00093 
00094   return data;
00095 }
00096 
00097 static int read_dlpoly_structure(void *mydata, int *optflags,
00098                               molfile_atom_t *atoms) {
00099   int i;
00100   char fbuffer[1025], buf[1025];
00101   float x, y, z;
00102   float alpha, beta, gamma, a, b, c;
00103   int nstep, atomcount, keytrj, imcon, scancount, atomid, atomcount2;
00104   float tstep, mass, charge;
00105   molfile_atom_t *atom;
00106   
00107   dlpolydata *data = (dlpolydata *)mydata;
00108 
00109   /* if we get nothing, assume we hit end of file */
00110   if (NULL == fgets(fbuffer, 1024, data->file))  
00111     return MOLFILE_EOF;
00112 
00113   /* check to see if the first line is a "timestep" record */
00114   scancount = sscanf(fbuffer, "%s %d %d %d %d %f", buf, 
00115                      &nstep, &atomcount, &keytrj, &imcon, &tstep);
00116   if (scancount != 6 || strcmp(buf, "timestep") != 0) {
00117     /* if not a timestep, it might have the normal header on it      */
00118     /* in which case we'll skip the first line, and parse the second */
00119     if (NULL == fgets(fbuffer, 1024, data->file))
00120       return MOLFILE_EOF;
00121     scancount = sscanf(fbuffer, "%d %d %d", &keytrj, &nstep, &atomcount);
00122     if (scancount != 3) {
00123       printf("dlpoly structure) unrecognized header record\n");
00124       return MOLFILE_ERROR;
00125     } 
00126 
00127     /* now check the first timestep record for safety */
00128     if (NULL == fgets(fbuffer, 1024, data->file))
00129       return MOLFILE_EOF;
00130     scancount = sscanf(fbuffer, "%s %d %d %d %d %f", buf, 
00131                        &nstep, &atomcount2, &keytrj, &imcon, &tstep);
00132     if (scancount != 6 || strcmp(buf, "timestep") != 0) {
00133       printf("dlpoly structure) unrecognized timestep record\n");
00134       return MOLFILE_ERROR;
00135     }
00136 
00137     /* check atom count */
00138     if (atomcount != atomcount2) {
00139       printf("dlpoly structure) header/timestep mismatched atom count\n");
00140       return MOLFILE_ERROR;
00141     }
00142   }
00143 
00144   /* check atom count */
00145   if (atomcount != data->numatoms) {
00146     printf("dlpoly structure) mismatched atom count\n");
00147     return MOLFILE_ERROR;
00148   }
00149 
00150   /* read periodic cell vectors */
00151   if (imcon > 0) {
00152     float xaxis[3];
00153     float yaxis[3];
00154     float zaxis[3];
00155 
00156     /* eat the data but don't use it for anything */
00157     fscanf(data->file, "%f %f %f\n", &xaxis[0], &xaxis[1], &xaxis[2]);
00158     fscanf(data->file, "%f %f %f\n", &yaxis[0], &yaxis[1], &yaxis[2]);
00159     fscanf(data->file, "%f %f %f\n", &zaxis[0], &zaxis[1], &zaxis[2]);
00160   }
00161 
00162   for (i=0; i<data->numatoms; i++) {
00163     molfile_atom_t *atom = atoms + i;
00164 
00165     /* read the coordinates */
00166     fscanf(data->file, "%s %d %f %f %f %f %f",
00167            buf, &atomid, &mass, &charge, &x, &y, &z);
00168 
00169     /* read the velocities */
00170     if (keytrj > 0) {
00171       float xv, yv, zv;
00172       fscanf(data->file, "%f %f %f", &xv, &yv, &zv);
00173     }
00174 
00175     /* read the forces */
00176     if (keytrj > 1) {
00177       float xf, yf, zf;
00178       fscanf(data->file, "%f %f %f", &xf, &yf, &zf);
00179     }
00180 
00181     strncpy(atom->name, buf, sizeof(atom->name));
00182     strncpy(atom->type, atom->name, sizeof(atom->type));
00183     atom->resname[0] = '\0';
00184     atom->resid = 1;
00185     atom->chain[0] = '\0';
00186     atom->segid[0] = '\0';
00187   }
00188 
00189   rewind(data->file);
00190   return MOLFILE_SUCCESS;
00191 }
00192 
00193 static int read_dlpoly_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
00194   int i;
00195   char fbuffer[1025], buf[1025];
00196   float x, y, z;
00197   int nstep, atomcount, keytrj, imcon, scancount, atomid, atomcount2;
00198   float tstep, mass, charge;
00199   
00200   dlpolydata *data = (dlpolydata *)mydata;
00201 
00202   /* if we get nothing, assume we hit end of file */
00203   if (NULL == fgets(fbuffer, 1024, data->file))  
00204     return MOLFILE_EOF;
00205 
00206   scancount = sscanf(fbuffer, "%s %d %d %d %d %f", buf, 
00207                      &nstep, &atomcount, &keytrj, &imcon, &tstep);
00208   if (scancount != 6 || strcmp(buf, "timestep") != 0) {
00209     /* if not a timestep, it might have the normal header on it      */
00210     /* in which case we'll skip the first line, and parse the second */
00211     if (NULL == fgets(fbuffer, 1024, data->file))
00212       return MOLFILE_EOF;
00213     scancount = sscanf(fbuffer, "%d %d %d", &keytrj, &nstep, &atomcount);
00214     if (scancount != 3) {
00215       printf("dlpoly timestep) unrecognized header record\n");
00216       return MOLFILE_ERROR;
00217     } 
00218 
00219     /* now check the first timestep record for safety */
00220     if (NULL == fgets(fbuffer, 1024, data->file))
00221       return MOLFILE_EOF;
00222     scancount = sscanf(fbuffer, "%s %d %d %d %d %f", buf, 
00223                        &nstep, &atomcount2, &keytrj, &imcon, &tstep);
00224     if (scancount != 6 || strcmp(buf, "timestep") != 0) {
00225       printf("dlpoly timestep) unrecognized timestep record\n");
00226       return MOLFILE_ERROR;
00227     }
00228 
00229     /* check atom count */
00230     if (atomcount != atomcount2) {
00231       printf("dlpoly timestep) header/timestep mismatched atom count\n");
00232       return MOLFILE_ERROR;
00233     }
00234   }
00235 
00236   /* check atom count */
00237   if (atomcount != natoms) {
00238     printf("dlpoly timestep) mismatched atom count\n");
00239     return MOLFILE_ERROR;
00240   }
00241 
00242   /* read periodic cell vectors */
00243   if (imcon > 0) {
00244     float xaxis[3];
00245     float yaxis[3];
00246     float zaxis[3];
00247 
00248     fscanf(data->file, "%f %f %f\n", &xaxis[0], &xaxis[1], &xaxis[2]);
00249     fscanf(data->file, "%f %f %f\n", &yaxis[0], &yaxis[1], &yaxis[2]);
00250     fscanf(data->file, "%f %f %f\n", &zaxis[0], &zaxis[1], &zaxis[2]);
00251 
00252     if (xaxis[1] != 0.0 || xaxis[2] != 0.0 || 
00253         yaxis[0] != 0.0 || yaxis[2] != 0.0 || 
00254         zaxis[0] != 0.0 || xaxis[1] != 0.0) {
00255       if (data->cellwarnflag != 1)
00256         printf("dlpoly timestep) non-orthogonal DLPOLY periodic cell data unsupported\n");
00257       data->cellwarnflag = 1;
00258     } else {
00259       ts->A = xaxis[0];
00260       ts->B = yaxis[1];
00261       ts->C = zaxis[2];
00262       if (data->cellwarnflag != 2)
00263         printf("dlpoly timestep) converting DLPOLY periodic cell data\n");
00264       data->cellwarnflag = 2;
00265     }
00266   }
00267 
00268   /* read all per-atom data */
00269   for (i=0; i<natoms; i++) {
00270     /* read the coordinates */
00271     fscanf(data->file, "%s %d %f %f %f %f %f",
00272            buf, &atomid, &mass, &charge, &x, &y, &z);
00273 
00274     /* read the velocities */
00275     if (keytrj > 0) {
00276       float xv, yv, zv;
00277       fscanf(data->file, "%f %f %f", &xv, &yv, &zv);
00278     }
00279 
00280     /* read the forces */
00281     if (keytrj > 1) {
00282       float xf, yf, zf;
00283       fscanf(data->file, "%f %f %f", &xf, &yf, &zf);
00284     }
00285 
00286     /* only save coords if we're given a timestep pointer, */
00287     /* otherwise assume that VMD wants us to skip past it. */
00288     if (ts != NULL) { 
00289       if (atomid > 0 && atomid <= natoms) {
00290         int addr = 3 * (atomid - 1);
00291         ts->coords[addr    ] = x;
00292         ts->coords[addr + 1] = y;
00293         ts->coords[addr + 2] = z;
00294       } else {
00295         fprintf(stderr, "dlpoly timestep) ignoring illegal atom index %d\n", atomid);
00296       }
00297     } 
00298   }
00299 
00300   /* eat LF character */
00301   fgetc(data->file);
00302 
00303   return MOLFILE_SUCCESS;
00304 }
00305     
00306 static void close_dlpoly_read(void *mydata) {
00307   dlpolydata *data = (dlpolydata *)mydata;
00308   fclose(data->file);
00309   free(data->file_name);
00310   free(data);
00311 }
00312 
00313 
00314 /* registration stuff */
00315 static molfile_plugin_t dlpolyplugin = {
00316   vmdplugin_ABIVERSION,
00317   MOLFILE_PLUGIN_TYPE,                         /* type */
00318   "dlpolyhist",                                /* short name */
00319   "DLPOLY History",                            /* pretty name */
00320   "John E. Stone",                             /* author */
00321   0,                                           /* major version */
00322   3,                                           /* minor version */
00323   VMDPLUGIN_THREADSAFE,                        /* is reentrant */
00324   "dlpolyhist",
00325   open_dlpoly_read,
00326   read_dlpoly_structure,
00327   0,
00328   read_dlpoly_timestep,
00329   close_dlpoly_read,
00330   0,                            /* write... */
00331   0,
00332   0,
00333   0,
00334   0,                            /* read_volumetric_metadata */
00335   0,                            /* read_volumetric_data */
00336   0                             /* read_rawgraphics */
00337 };
00338 
00339 VMDPLUGIN_API int VMDPLUGIN_init() {
00340   return VMDPLUGIN_SUCCESS;
00341 }
00342 
00343 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00344   (*cb)(v, (vmdplugin_t *)&dlpolyplugin);
00345   return VMDPLUGIN_SUCCESS;
00346 }
00347 
00348 VMDPLUGIN_API int VMDPLUGIN_fini() {
00349   return VMDPLUGIN_SUCCESS;
00350 }
00351 
00352 
00353 #ifdef TEST_PLUGIN
00354 
00355 int main(int argc, char *argv[]) {
00356   molfile_timestep_t timestep;
00357   void *v;
00358   int natoms;
00359   int i, nsets, set;
00360 
00361   while (--argc) {
00362     ++argv;
00363     v = open_dlpoly_read(*argv, "dlpoly", &natoms);
00364     if (!v) {
00365       fprintf(stderr, "open_dlpoly_read failed for file %s\n", *argv);
00366       return 1;
00367     }
00368     fprintf(stderr, "open_dlpoly_read succeeded for file %s\n", *argv);
00369     fprintf(stderr, "number of atoms: %d\n", natoms);
00370 
00371     i = 0;
00372     timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
00373     while (!read_dlpoly_timestep(v, natoms, &timestep)) {
00374       i++;
00375     }
00376     fprintf(stderr, "ended read_next_timestep on frame %d\n", i);
00377 
00378     close_dlpoly_read(v);
00379   }
00380   return 0;
00381 }
00382 
00383 #endif
00384 

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