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

ReadPARM7.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  * RCS INFORMATION:
00003  *
00004  *      $RCSfile: ReadPARM7.h,v $
00005  *      $Author: johns $        $Locker:  $                $State: Exp $
00006  *      $Revision: 1.22 $      $Date: 2006/02/16 20:34:41 $
00007  *
00008  ***************************************************************************
00009  * DESCRIPTION:
00010  * NOTE:: Significant modifications were made to the VMD version of 
00011  *        Bill Ross's original code in order to make it easy to hook 
00012  *        into VMD plugin structures.  
00013  *        Further modifications were made to the VMD code to 
00014  *        read amber 7 parm files, courtesy of Brian Bennion
00015  * Here is what has changed:
00016  *     Functions became Class Methods, data became instance variables
00017  *     The Code to check for compressed files before opening was disabled
00018  *     Methods get_parm7_atom, get_parm7_bond, get_hydrogen_bond,
00019  *     get_parm7_natoms, get_parm7_nbonds, get_parm7_boxInfo were added in 
00020  *     order to convert from prm.c parlance to VMD conventions.
00021  ***************************************************************************/
00022 
00023 /*
00024  * COPYRIGHT 1992, REGENTS OF THE UNIVERSITY OF CALIFORNIA
00025  *
00026  *  prm.c - read information from an amber PARM topology file:
00027  *      atom/residue/bond/charge info, plus force field data.
00028  *      This file and the accompanying prm.h may be distributed
00029  *      provided this notice is retained unmodified and provided
00030  *      that any modifications to the rest of the file are noted
00031  *      in comments.
00032  *
00033  *      Bill Ross, UCSF 1994
00034  */
00035 
00036 #ifndef READPARM7_H
00037 #define READPARM7_H
00038 
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <ctype.h>
00042 #include <sys/types.h>
00043 #include <sys/stat.h>
00044 #include <errno.h>
00045 #include <string.h>
00046 #include "molfile_plugin.h"  // needed for molfile return codes etc
00047 
00048 #if 0 
00049 #define _REAL           double
00050 #define DBLFMT          "%lf"
00051 #else
00052 #define _REAL           float
00053 #define DBLFMT          "%f"
00054 #endif
00055 
00056 
00057 typedef struct parm {
00058         char    title[85];
00059         char    version[85];
00060         int     IfBox, Nmxrs, IfCap,
00061                  Natom,  Ntypes,  Nbonds, Nbonh,  Mbona,  Ntheth,  Mtheta, 
00062                  Nphih,  Mphia,  Nhparm, Nparm, Nnb, Nres,Mptra,
00063                  Nbona,  Ntheta,  Nphia,  Numbnd,  Numang,  Nptra,Jparm,
00064                  Natyp,  Nphb, Nat3, Ntype2d, Nttyp, Nspm, Iptres, Nspsol,
00065                  Ipatm, Natcap,Ifpert,Nbper,Ngper,Ndper,Mbper,Mgper,Mdper,
00066                  Numextra;
00067         _REAL   Box[3], Cutcap, Xcap, Ycap, Zcap;
00068 } parmstruct;
00069 
00070 static int read_parm7_flag(FILE *file, const char *flag, const char *format) {
00071   char buf[1024];
00072     
00073   /* read the %FLAG text */
00074   fscanf(file, "%s\n", buf);
00075   if (strcmp("%FLAG", buf)) {
00076     printf("AMBER 7 parm read error, at flag section %s,\n", flag);
00077     printf("        expected %%FLAG but got %s\n", buf);
00078     return 0; /* read of flag data failed */
00079   }
00080 
00081   /* read field name specifier */
00082   fscanf(file, "%s\n", buf);
00083   if (flag != NULL) {
00084     if (strcmp(flag, buf)) {
00085       printf("AMBER 7 parm read error at flag section %s,\n", flag);
00086       printf("      expected flag field %s but got %s\n", flag, buf);
00087       return 0; /* read of flag data failed */
00088     }
00089   }
00090 
00091   /* read format string */
00092   fscanf(file, "%s\n", buf);
00093   if (format != NULL) {
00094     if (strcmp(format, buf)) {
00095       printf("AMBER 7 parm read error at flag section %s,\n", flag);
00096       printf("      expected format %s but got %s\n", format, buf);
00097       return 0; /* read of flag data failed */
00098     }
00099   }
00100 
00101   return 1; /* read of flag data succeeded */
00102 }
00103 
00104 /*
00105  *  open_parm7_file() - fopen regular or popen compressed file for reading
00106  *  Return FILE handle on success.
00107  *  set as_pipe to 1 if opened with popen, or 0 if opened with fopen.
00108  */
00109 
00110 static FILE *open_parm7_file(const char *name, int *as_pipe)
00111 {
00112         struct stat     buf;
00113         char            cbuf[120];
00114         int             length;
00115   int &compressed = *as_pipe;
00116         FILE            *fp;
00117 
00118         length = strlen(name);
00119         compressed = 0;  // Just to start
00120         strcpy(cbuf, name);
00121 
00122         /*
00123          *  if file doesn't exist, maybe it has been compressed/decompressed
00124          */
00125 
00126         if (stat(cbuf, &buf) == -1) {
00127                 switch (errno) {
00128                 case ENOENT:    {
00129                         if (!compressed) {
00130                                 strcat(cbuf, ".Z");
00131                                 if (stat(cbuf, &buf) == -1) {
00132                                         printf("%s, %s: does not exist\n", 
00133                                                 name, cbuf);
00134                                         return(NULL);
00135                                 }
00136                                 compressed++;
00137                                 // Don't modify the filename
00138                                 //strcat(name, ".Z"); /* TODO: add protection */
00139                         } else {
00140                                 cbuf[length-2] = '\0';
00141                                 if (stat(cbuf, &buf) == -1) {
00142                                         printf("%s, %s: does not exist\n", 
00143                                                         name, cbuf);
00144                                         return(NULL);
00145                                 }
00146                                 compressed = 0;
00147                         }
00148                         break;
00149                 }
00150                 default:
00151                         return(NULL);
00152                 }
00153         }
00154 
00155         /*
00156          *  open the file
00157          */
00158 #if defined(_MSC_VER)
00159         if (compressed) {
00160           /* NO "zcat" on Win32 */
00161           printf("Cannot load compressed PARM files on Windows.\n");
00162           return NULL;
00163         }
00164 #else
00165         if (compressed) {
00166                 char pcmd[120];
00167 
00168                 sprintf(pcmd, "zcat %s", cbuf);
00169                 if ((fp = popen(pcmd, "r")) == NULL) {
00170                         perror(pcmd);
00171                         return NULL;
00172                 }
00173         }
00174 #endif
00175         else {
00176                 if ((fp = fopen(cbuf, "r")) == NULL) {
00177                         perror(cbuf);
00178                         return NULL;
00179                 }
00180         }
00181         return(fp);
00182 
00183 }
00184 
00185 static int parse_parm7_atoms(const char *fmt, 
00186     int natoms, molfile_atom_t *atoms, FILE *file) {
00187   if (strcmp(fmt, "%FORMAT(20a4)")) return 0;
00188   char buf[85];
00189   int j=0;
00190   for (int i=0; i<natoms; i++) {
00191     molfile_atom_t *atom = atoms+i;
00192     if (!(i%20)) {
00193       j=0;
00194       fgets(buf, 85, file);
00195     }
00196     strncpy(atom->name, buf+4*j, 4);
00197     atom->name[4]='\0';
00198     j++;
00199   }
00200   return 1;
00201 }
00202 
00203 static int parse_parm7_charge(const char *fmt, 
00204     int natoms, molfile_atom_t *atoms, FILE *file) {
00205   if (strcmp(fmt, "%FORMAT(5E16.8)")) return 0;
00206   for (int i=0; i<natoms; i++) {
00207     double q=0;
00208     if (fscanf(file, " %lf", &q) != 1) {
00209       fprintf(stderr, "PARM7: error reading charge at index %d\n", i);
00210       return 0;
00211     }
00212     atoms[i].charge = (float)q;
00213   }
00214   return 1;
00215 }
00216 
00217 static int parse_parm7_mass(const char *fmt,
00218     int natoms, molfile_atom_t *atoms, FILE *file) {
00219   if (strcmp(fmt, "%FORMAT(5E16.8)")) return 0;
00220   for (int i=0; i<natoms; i++) {
00221     double m=0;
00222     if (fscanf(file, " %lf", &m) != 1) {
00223       fprintf(stderr, "PARM7: error reading mass at index %d\n", i);
00224       return 0;
00225     }
00226     atoms[i].mass = (float)m;
00227   }
00228   return 1;
00229 }
00230 
00231 static int parse_parm7_atype(const char *fmt,
00232     int natoms, molfile_atom_t *atoms, FILE *file) {
00233   if (strcmp(fmt, "%FORMAT(20a4)")) return 0;
00234   char buf[85];
00235   int j=0;
00236   for (int i=0; i<natoms; i++) {
00237     molfile_atom_t *atom = atoms+i;
00238     if (!(i%20)) {
00239       j=0;
00240       fgets(buf, 85, file);
00241     }
00242     strncpy(atom->type, buf+4*j, 4);
00243     atom->type[4]='\0';
00244     j++;
00245   }
00246   return 1;
00247 }
00248 
00249 static int parse_parm7_resnames(const char *fmt,
00250     int nres, char *resnames, FILE *file) {
00251   if (strcmp(fmt, "%FORMAT(20a4)")) return 0;
00252   char buf[85];
00253   int j=0;
00254   for (int i=0; i<nres; i++) {
00255     if (!(i%20)) {
00256       j=0;
00257       fgets(buf, 85, file);
00258     }
00259     strncpy(resnames, buf+4*j, 4);
00260     resnames += 4;
00261     j++;
00262   }
00263   return 1;
00264 }
00265 
00266 static int parse_parm7_respointers(const char *fmt, int natoms, 
00267     molfile_atom_t *atoms, int nres, const char *resnames, FILE *file) {
00268   if (strcmp(fmt, "%FORMAT(10I8)")) return 0;
00269   int cur, next;
00270   fscanf(file, " %d", &cur);
00271   for (int i=1; i<nres; i++) {
00272     if (fscanf(file, " %d", &next) != 1) {
00273       fprintf(stderr, "PARM7: error reading respointer records at residue %d\n",
00274           i);
00275       return 0;
00276     }
00277     while (cur < next) {
00278       if (cur > natoms) {
00279         fprintf(stderr, "invalid atom index: %d\n", cur);
00280         return 0;
00281       }
00282       strncpy(atoms[cur-1].resname, resnames, 4);
00283       atoms[cur-1].resname[4] = '\0';
00284       atoms[cur-1].resid = i;
00285       cur++;
00286     }
00287     resnames += 4;
00288   }
00289   // store the last residue name
00290   while (cur <= natoms) {
00291     strncpy(atoms[cur-1].resname, resnames, 4);
00292     atoms[cur-1].resname[4] = '\0';
00293     atoms[cur-1].resid = nres;
00294     cur++;
00295   }
00296   return 1;
00297 }
00298 
00299 static int parse_parm7_bonds(const char *fmt,
00300     int nbonds, int *from, int *to, FILE *file) {
00301   if (strcmp(fmt, "%FORMAT(10I8)")) 
00302     return 0;
00303 
00304   int a, b, tmp;
00305   for (int i=0; i<nbonds; i++) {
00306     if (fscanf(file, " %d %d %d", &a, &b, &tmp) != 3) {
00307       fprintf(stderr, "PARM7: error reading bond number %d\n", i);
00308       return 0;
00309     }
00310     from[i] = a/3 + 1;
00311     to[i]   = b/3 + 1;
00312   }
00313 
00314   return 1;
00315 }
00316 
00317 /***********************************************************************
00318                             close_parm7_file   
00319 ************************************************************************/
00320 
00321 /*
00322  *  close_parm7_file() - close fopened or popened file
00323  */
00324 
00325 static void close_parm7_file(FILE *fileptr, int popn)
00326 {
00327 #if defined(_MSC_VER)
00328         if (popn) {
00329            printf("pclose() no such function on win32!\n");
00330         } else {
00331                 if (fclose(fileptr) == -1)
00332                         perror("fclose");
00333         }
00334 #else
00335         if (popn) {
00336                 if (pclose(fileptr) == -1)
00337                         perror("pclose");
00338         } else {
00339                 if (fclose(fileptr) == -1)
00340                         perror("fclose");
00341         }
00342 #endif
00343 }
00344 
00345 static const char *parm7 = "%8d%8d%8d%8d%8d%8d%8d%8d%8d%8d\n";
00346 
00347 static parmstruct *read_parm7_header(FILE *file) {
00348   char sdum[512]; 
00349   parmstruct *prm;
00350   prm = new parmstruct;
00351 
00352         /* READ VERSION */
00353   fgets(sdum, 512, file);
00354 
00355         /* READ TITLE */
00356   if (!read_parm7_flag(file, "TITLE", "%FORMAT(20a4)")) {
00357     delete prm;
00358     return NULL;
00359   }
00360 
00361   // read the title string itself, and handle empty lines
00362 #if 1
00363   // XXX this code fails with some AMBER 9 test files
00364   fscanf(file,"%s\n", prm->title);
00365 #else
00366   // XXX this hack causes AMBER 9 prmtop files to load
00367   fgets(prm->title, sizeof(prm->title), file);
00368 #endif
00369 
00370   if(strstr(prm->title, "%FLAG") == NULL) {
00371     // Got a title string, use a special method to pick up next flag
00372     if (!read_parm7_flag(file, "POINTERS", "%FORMAT(10I8)")) {
00373       delete prm;
00374       return NULL;
00375     }
00376   } else {
00377     // NO title string, use a special method to pick up next flag
00378     fscanf(file,"%s\n", sdum);
00379     if (strcmp("POINTERS", sdum)) {
00380       printf("AMBER 7 parm read error at flag section POINTERS\n");
00381       printf("      expected flag field POINTERS but got %s\n", sdum);
00382       delete prm;
00383       return NULL;
00384     }
00385     fscanf(file,"%s\n", sdum);
00386     if (strcmp("%FORMAT(10I8)", sdum)) {
00387       printf("AMBER 7 parm read error at flag section POINTERS,\n");
00388       printf("      expected format %%FORMAT(10I8) but got %s\n", sdum);
00389       delete prm;
00390       return NULL;
00391     }
00392   }
00393 
00394         /* READ POINTERS (CONTROL INTEGERS) */
00395         fscanf(file,parm7,
00396                 &prm->Natom,  &prm->Ntypes, &prm->Nbonh, &prm->Nbona,
00397                 &prm->Ntheth, &prm->Ntheta, &prm->Nphih, &prm->Nphia,
00398                 &prm->Jparm,  &prm->Nparm);
00399         fscanf(file, parm7,  
00400                 &prm->Nnb,   &prm->Nres,   &prm->Mbona,  &prm->Mtheta,
00401                 &prm->Mphia, &prm->Numbnd, &prm->Numang, &prm->Mptra,
00402                 &prm->Natyp, &prm->Nphb);
00403         fscanf(file, parm7,  &prm->Ifpert, &prm->Nbper,  &prm->Ngper,
00404                 &prm->Ndper, &prm->Mbper,  &prm->Mgper, &prm->Mdper,
00405                 &prm->IfBox, &prm->Nmxrs,  &prm->IfCap);
00406         
00407         fscanf(file,"%8d",&prm->Numextra); //BB
00408         prm->Nptra=prm->Mptra; //BB new to amber 7 files...
00409 
00410         prm->Nat3 = 3 * prm->Natom;
00411         prm->Ntype2d = prm->Ntypes * prm->Ntypes;
00412         prm->Nttyp = prm->Ntypes*(prm->Ntypes+1)/2;
00413 
00414   return prm;
00415 }
00416 
00417 
00418 #endif

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