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

tinkerplugin.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: tinkerplugin.c,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.15 $       $Date: 2017/02/03 06:13:03 $
00015  *
00016  ***************************************************************************/
00017 
00018  /*
00019   * The .arc file is the one coming straight out of tinker.
00020   * Many frames, looks like a regular tinker, except that in the last columns
00021   * after x, y and z it has :
00022   * 
00023   * atom type (not important for viz)
00024   * 
00025   * and then info in a Z-matrix form
00026   * 
00027   * atom to which you are bonded, atom to which you are 'angled' and atom to
00028   * which you are 'torsioned'.
00029   * 
00030   */
00031 
00032 #include "largefiles.h"   /* platform dependent 64-bit file I/O defines */
00033 
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <ctype.h>
00038 #include "molfile_plugin.h"
00039 
00040 typedef struct {
00041   FILE *file;
00042   int numatoms;
00043   char *file_name;
00044   molfile_atom_t *atomlist;
00045 } tinkerdata;
00046  
00047 static void *open_tinker_read(const char *filename, const char *filetype, 
00048                            int *natoms) {
00049   FILE *fd;
00050   tinkerdata *data;
00051   int i;
00052 
00053   fd = fopen(filename, "rb");
00054   if (!fd) return NULL;
00055   
00056   data = (tinkerdata *)malloc(sizeof(tinkerdata));
00057   data->file = fd;
00058   data->file_name = strdup(filename);
00059 
00060   /* First line is the number of atoms, followed by other stuff */
00061   i = fscanf(data->file, "%d", natoms);
00062   if (i < 1) {
00063     fprintf(stderr, "\n\nread) ERROR: tinker file '%s' should have the number of atoms in the first line.\n", filename);
00064     return NULL;
00065   }
00066   data->numatoms=*natoms;
00067 
00068   while (getc(fd) != '\n'); /* skip rest of this line */
00069  
00070   return data;
00071 }
00072 
00073 static int read_tinker_structure(void *mydata, int *optflags, 
00074                                  molfile_atom_t *atoms) {
00075   int i, j, atomid;
00076   char *k;
00077   float coord;
00078   molfile_atom_t *atom;
00079   tinkerdata *data = (tinkerdata *)mydata;
00080   
00081   *optflags = MOLFILE_NOOPTIONS;
00082 
00083   for (i=0; i<data->numatoms; i++) {
00084     char buffer[1024], fbuffer[1024];
00085     int atomtypeindex=0;
00086     k = fgets(fbuffer, 1024, data->file);
00087     atom = atoms + i;
00088     j=sscanf(fbuffer, "%d %s %f %f %f %d", &atomid, buffer, &coord, &coord, &coord, &atomtypeindex);
00089     if (k == NULL) {
00090       fprintf(stderr, "tinker structure) missing atom(s) in file '%s'\n", data->file_name);
00091       fprintf(stderr, "tinker structure) expecting '%d' atoms, found only '%d'\n", data->numatoms, i+1);
00092       return MOLFILE_ERROR;
00093     } else if (j < 5) {
00094       fprintf(stderr, "tinker structure) missing type or coordinate(s) in file '%s' for atom '%d'\n", data->file_name, i+1);
00095       return MOLFILE_ERROR;
00096     }
00097 
00098     strncpy(atom->name, buffer, sizeof(atom->name));
00099 #if 0
00100     strncpy(atom->type, atom->name, sizeof(atom->type));
00101 #else
00102     sprintf(atom->type, "%d", atomtypeindex);
00103 #endif
00104     atom->resname[0] = '\0';
00105     atom->resid = 1;
00106     atom->chain[0] = '\0';
00107     atom->segid[0] = '\0';
00108   }
00109 
00110   rewind(data->file);
00111   return MOLFILE_SUCCESS;
00112 }
00113 
00114 static int read_tinker_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
00115   int i, j, atomid, box_failed;
00116   char atom_name[1024], fbuffer[1024], *k;
00117   float x, y, z, box[6];
00118   
00119   tinkerdata *data = (tinkerdata *)mydata;
00120   
00121   /* skip over the first line */
00122   if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00123   k = fgets(fbuffer, 1024, data->file);
00124   if (NULL == k) return MOLFILE_ERROR;
00125 
00126   /* attempt to get box size */
00127   j = sscanf(fbuffer, "%f %f %f %f %f %f", box, box+1, box+2, box+3, box+4, box+5);
00128   if (j > 2){
00129     box_failed = 0;
00130 
00131     if (ts != NULL){
00132       ts->A = box[0];
00133       ts->B = box[1];
00134       ts->C = box[2];
00135       if (j > 5){
00136         ts->alpha = box[3];
00137         ts->beta  = box[4];
00138         ts->gamma = box[5];
00139       }
00140     }
00141   } else {
00142     box_failed = 1;
00143   }
00144 
00145   /* read the coordinates */
00146   for (i=0; i<natoms; i++) {
00147     /* reuse line if box size failed, it's an atom line */
00148     if (i > 0 || !box_failed) k = fgets(fbuffer, 1024, data->file);
00149 
00150     /* Read in atom type, X, Y, Z, skipping any remaining data fields */
00151     j = sscanf(fbuffer, "%d %s %f %f %f", &atomid, atom_name, &x, &y, &z);
00152     if (k == NULL) {
00153       return MOLFILE_ERROR;
00154     } else if (j < 5) {
00155       fprintf(stderr, "tinker timestep) missing type or coordinate(s) in file '%s' for atom '%d'\n",data->file_name,i+1);
00156       return MOLFILE_ERROR;
00157     } else if (j >= 5) {
00158       if (ts != NULL) { 
00159         /* only save coords if we're given a timestep pointer, */
00160         /* otherwise assume that VMD wants us to skip past it. */
00161         ts->coords[3*i  ] = x;
00162         ts->coords[3*i+1] = y;
00163         ts->coords[3*i+2] = z;
00164       }
00165     } else {
00166       break;
00167     }
00168   }
00169   
00170   return MOLFILE_SUCCESS;
00171 }
00172     
00173 static void close_tinker_read(void *mydata) {
00174   tinkerdata *data = (tinkerdata *)mydata;
00175   fclose(data->file);
00176   free(data->file_name);
00177   free(data);
00178 }
00179 
00180 /* registration stuff */
00181 static molfile_plugin_t plugin;
00182 
00183 VMDPLUGIN_API int VMDPLUGIN_init() {
00184   memset(&plugin, 0, sizeof(molfile_plugin_t));
00185   plugin.abiversion = vmdplugin_ABIVERSION;
00186   plugin.type = MOLFILE_PLUGIN_TYPE;
00187   plugin.name = "tinker";
00188   plugin.prettyname = "Tinker";
00189   plugin.author = "John Stone";
00190   plugin.majorv = 0;
00191   plugin.minorv = 6;
00192   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00193   plugin.filename_extension = "arc";
00194   plugin.open_file_read = open_tinker_read;
00195   plugin.read_structure = read_tinker_structure;
00196   plugin.read_next_timestep = read_tinker_timestep;
00197   plugin.close_file_read = close_tinker_read;
00198   return VMDPLUGIN_SUCCESS;
00199 }
00200 
00201 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00202   (*cb)(v, (vmdplugin_t *)&plugin);
00203   return VMDPLUGIN_SUCCESS;
00204 }
00205 
00206 VMDPLUGIN_API int VMDPLUGIN_fini() {
00207   return VMDPLUGIN_SUCCESS;
00208 }
00209 
00210 
00211 #ifdef TEST_PLUGIN
00212 
00213 int main(int argc, char *argv[]) {
00214   molfile_timestep_t timestep;
00215   void *v;
00216   int natoms;
00217   int i, nsets, set;
00218 
00219   while (--argc) {
00220     ++argv;
00221     v = open_tinker_read(*argv, "tinker", &natoms);
00222     if (!v) {
00223       fprintf(stderr, "open_tinker_read failed for file %s\n", *argv);
00224       return 1;
00225     }
00226     fprintf(stderr, "open_tinker_read succeeded for file %s\n", *argv);
00227     fprintf(stderr, "number of atoms: %d\n", natoms);
00228 
00229     i = 0;
00230     timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
00231     while (!read_tinker_timestep(v, natoms, &timestep)) {
00232       i++;
00233     }
00234     fprintf(stderr, "ended read_next_timestep on frame %d\n", i);
00235 
00236     close_tinker_read(v);
00237   }
00238   return 0;
00239 }
00240 
00241 #endif
00242 

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