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

moldenplugin.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: moldenplugin.c,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.12 $       $Date: 2006/02/23 19:36:45 $
00015  *
00016  ***************************************************************************/
00017 
00018 /* This is a plugin that will read input from a MOLDEN
00019 ** generated output file 
00020 ** some more details will go here soon 
00021 ** NOTE: The current version of the plugin relies
00022 ** on the fact that the [Atom] field comes before
00023 ** the [Geometries] field */
00024 
00025 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <ctype.h>
00030 #include "molfile_plugin.h"
00031 
00032 
00033 
00034 typedef struct {
00035   FILE *file;
00036   int trajectory;
00037   int numatoms;
00038   char *file_name;
00039   molfile_atom_t *atomlist;
00040 } moldendata;
00041 
00042 /* this will skip one line at a time */
00043 
00044 static void eatline(FILE * fd)
00045 {
00046   char readbuf[1025];
00047   fgets(readbuf, 1024, fd);
00048 }
00049 
00050  
00051 static void *open_molden_read(const char *filename, const char *filetype, int *natoms) {
00052 
00053   FILE *fd;
00054   moldendata *data;
00055   char moldentest1[7];
00056   char moldentest2[7];
00057   char buffer[1024];
00058   char tester[20];
00059   int i;
00060   char *s;
00061 
00062   fd = fopen(filename, "rb");
00063   if (!fd) return NULL;
00064   
00065   data = (moldendata *)malloc(sizeof(moldendata));
00066   data->file = fd;
00067   data->file_name = strdup(filename);
00068 
00069 /* check if the file is MOLDEN format */
00070 
00071   fscanf(data->file, "%s %s",moldentest1,moldentest2);
00072   if (!strcmp(moldentest1,"[Molden") && \
00073       !strcmp(moldentest2,"Format]"))
00074   {
00075     printf("Detected MOLDEN file format!\n");
00076   }
00077   else
00078   {
00079     printf("The file does not seem to be in MOLDEN format!\n");
00080     return NULL;
00081   }
00082 
00083 /* Unfortunately the molden file format has two possibilities:
00084 ** either there is a [ATOMS] section which provides the atom
00085 ** name, charges and coordinates or there is only a 
00086 ** XYZ style [GEOMETRIES] section, which still provides atom
00087 ** type and geometry information, hence I have to check which
00088 ** case I have */
00089   
00090 /* check if there is an [ATOMS] section */
00091 
00092   do
00093   {
00094     i=fscanf(data->file, "%s",tester); 
00095     if (!strcmp(tester,"[Atoms]"))
00096     {
00097 /* start counting the atoms; 
00098 ** read until I hit the first line that starts with a "["
00099 ** bracket */
00100 
00101       eatline(fd); 
00102       (*natoms)=0; 
00103       s=fgets(buffer,1024,fd);
00104 
00105 /* Here I assume that the [Atoms] section goes
00106 ** on until another section starts, i.e. ther is
00107 ** a "[" or I encounter EOF */
00108 
00109       while ((buffer[0]!='[') && (s != NULL))
00110       {
00111         (*natoms)++;     
00112         s=fgets(buffer,1024,fd);
00113       }
00114       data->numatoms=*natoms;
00115       rewind(fd);
00116       data->trajectory = 0;
00117       return data;
00118     }
00119     else if (!strcmp(tester,"[GEOMETRIES]"))
00120     {
00121       printf("Found [Geometry] section ...\n");
00122       data->trajectory = 1;         
00123        
00124 /* In this case I am lucky because the first line
00125 ** of the XYZ type [GEOMETRIES] input contains the
00126 ** number of atoms, i.e. skip to this line and the
00127 ** read this entry */
00128 
00129       eatline(fd);
00130 
00131       i=fscanf(data->file, "%d",natoms);
00132       if (i!=1)
00133       {
00134         printf("The [GEOMTRIES] output does not have \n");
00135         printf("the number of atoms in line number one !! \n");
00136       }
00137 
00138       data->numatoms=*natoms;
00139      
00140 /* skip the next two lines, so the file can be parsed in the 
00141 ** structure section */      
00142 
00143       eatline(fd);
00144       eatline(fd);
00145 
00146       return data; 
00147     }
00148    } while (i>0);
00149   
00150   return NULL;
00151 }
00152 
00153 static int read_molden_structure(void *mydata, int *optflags, 
00154     molfile_atom_t *atoms) 
00155  {
00156   int i;
00157   char atname[1024];
00158   char buffer[1024];
00159   char geotest[11];
00160   int num,charge;
00161   float x,y,z;
00162   molfile_atom_t *atom;
00163   moldendata *data = (moldendata *)mydata;
00164 
00165   *optflags = MOLFILE_NOOPTIONS; /* no optional data */
00166 
00167 /* here I have two possibilities, either there is an
00168 ** [Atoms] section (i.e. data->trajectory=0) and I can
00169 ** read there structure information right there,
00170 ** or I have to extract it from the [GEOMETRIES]
00171 ** output (i.e. data->trajectory=1) */
00172 
00173   if(data->trajectory==0)
00174   { 
00175 
00176 /* Skip the first three lines */
00177 
00178     eatline(data->file);
00179     eatline(data->file);
00180 
00181 /* Now read in the atom types, names, charges as well
00182 ** as x,y,z coordinates */
00183 
00184     for(i=0;i<data->numatoms;i++) 
00185     {
00186       atom = atoms+i;
00187       fgets(buffer,1024,data->file);    
00188       sscanf(buffer,"%s %d %d %f %f %f",atname,&num,&charge,\
00189           &x,&y,&z);
00190       strncpy(atom->name,atname,sizeof(atom->name)); 
00191       strncpy(atom->type, atom->name, sizeof(atom->type));
00192       atom->resname[0] = '\0';
00193       atom->resid = 1;
00194       atom->chain[0] = '\0';
00195       atom->segid[0] = '\0';
00196     }
00197 
00198 
00199 /* finally and important skip the the beginning of the xyz
00200 ** section */
00201 
00202     do 
00203     {
00204       fscanf(data->file, "%s",geotest);   
00205     } while (strcmp(geotest,"[GEOMETRIES]")!=0);
00206   
00207      printf("Found Geometry Section\n");
00208 
00209   /* advance to the beginning of the XYZ list */
00210 
00211     eatline(data->file);
00212     eatline(data->file);
00213     eatline(data->file); 
00214 
00215 /* time to go back */
00216 
00217     return MOLFILE_SUCCESS; 
00218   }
00219   else if(data->trajectory==1)
00220   {
00221     
00222 /* in the read section I already forwarded to the correct
00223 ** location in the file hence I can start reading right
00224 ** away */
00225 
00226 
00227     for(i=0;i<data->numatoms;i++) 
00228     {
00229       atom = atoms+i;
00230       fgets(buffer,1024,data->file);    
00231       sscanf(buffer,"%s %f %f %f",atname,&x,&y,&z);
00232       strncpy(atom->name,atname,sizeof(atom->name)); 
00233       strncpy(atom->type, atom->name, sizeof(atom->type));
00234       atom->resname[0] = '\0';
00235       atom->resid = 1;
00236       atom->chain[0] = '\0';
00237       atom->segid[0] = '\0';
00238     }
00239 
00240 /* now rewind the file and go back to the [GEOMETRIES]
00241 ** section */
00242 
00243     rewind(data->file);
00244     
00245     do 
00246     {
00247       fscanf(data->file, "%s",geotest);   
00248     } while (strcmp(geotest,"[GEOMETRIES]")!=0);
00249   
00250      printf("Found Geometry Section\n");
00251 
00252 /* advance to the beginning of the XYZ list */
00253 
00254      eatline(data->file);
00255      eatline(data->file);
00256      eatline(data->file);
00257 
00258 /* time to go back */
00259 
00260      return MOLFILE_SUCCESS;
00261 
00262    }
00263 
00264   printf("Sorry, could not obtain structure information \n");
00265   printf("from either the [Atoms] or [GEOMETRIES] section! \n");
00266   printf("Please check your MOLDEN output file! \n"); 
00267   return MOLFILE_ERROR; 
00268 }
00269 
00270 
00271 static int read_next_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
00272 
00273   int i;
00274   char *k;
00275   char atname[1024];
00276   char buffer[1024];
00277   float x, y, z;
00278   
00279   moldendata *data = (moldendata *)mydata;
00280   
00281 /* read the coordinates */
00282 
00283   for(i=0;i<data->numatoms;i++) 
00284   {
00285       k=fgets(buffer,1024,data->file);
00286       sscanf(buffer,"%s %f %f %f",atname,&x,&y,&z);
00287 
00288 /* save coordinates only if given a timestep pointer
00289 ** otherwise assume that VMD would like to skip past
00290 ** it */
00291 
00292 /* if I don't check for EOF file I get stuck in
00293 ** an infinite loop */
00294 
00295       if ( k==NULL)
00296       {
00297         return MOLFILE_ERROR;
00298       }
00299       
00300       if (ts!=NULL) 
00301       {
00302        ts->coords[3*i  ] = x;
00303        ts->coords[3*i+1] = y;
00304        ts->coords[3*i+2] = z;     
00305       } 
00306   }     
00307 
00308 /* skip the two comment lines, which separate
00309 ** the individual coordinate entries 
00310 ** (for now, cause contains useful information
00311 ** like energies) */
00312 
00313   eatline(data->file);
00314   eatline(data->file); 
00315 
00316 /* done and go back */
00317 
00318   return MOLFILE_SUCCESS;
00319 }
00320   
00321 
00322 static void close_molden_read(void *mydata) {
00323   moldendata *data = (moldendata *)mydata;
00324   fclose(data->file);
00325   free(data->file_name);
00326   free(data);
00327 }
00328 
00329 
00330 /* registration stuff */
00331 static molfile_plugin_t moldenplugin = {
00332   vmdplugin_ABIVERSION,
00333   MOLFILE_PLUGIN_TYPE,                         /* type */
00334   "molden",                                    /* short name */
00335   "Molden",                                    /* pretty name */
00336   "Markus Dittrich",                           /* author */
00337   0,                                           /* major version */
00338   1,                                           /* minor version */
00339   VMDPLUGIN_THREADSAFE,                        /* is reentrant */
00340   "molden",
00341   open_molden_read,
00342   read_molden_structure,
00343   0,
00344   read_next_timestep, 
00345   close_molden_read,
00346   0,
00347   0,
00348   0, 
00349   0,
00350 };
00351 
00352 VMDPLUGIN_API int VMDPLUGIN_init() {
00353   return VMDPLUGIN_SUCCESS;
00354 }
00355 
00356 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00357   (*cb)(v, (vmdplugin_t *)&moldenplugin);
00358   return VMDPLUGIN_SUCCESS;
00359 }
00360 
00361 VMDPLUGIN_API int VMDPLUGIN_fini() {
00362   return VMDPLUGIN_SUCCESS;
00363 }
00364 

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