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.16 $       $Date: 2021/08/26 02:25:36 $
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(data->file) != '\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, box_failed;
00076   char buffer[1024], fbuffer[1024], *k;
00077   float coord;
00078   molfile_atom_t *atom;
00079   tinkerdata *data = (tinkerdata *)mydata;
00080   
00081   *optflags = MOLFILE_NOOPTIONS;
00082 
00083   /* attempt to get box size */
00084   k = fgets(fbuffer, 1024, data->file);
00085   if (NULL == k) return MOLFILE_ERROR;
00086   j = sscanf(fbuffer, "%f %f %f %f %f %f", &coord, &coord, &coord, &coord, &coord, &coord);
00087   box_failed = (j < 3) ? 1 : 0;
00088 
00089   for (i=0; i<data->numatoms; i++) {
00090     int atomtypeindex=0;
00091 
00092     /* reuse line if box size failed, it's an atom line */
00093     if (i > 0 || !box_failed) 
00094       k = fgets(fbuffer, 1024, data->file);
00095 
00096     atom = atoms + i;
00097     j=sscanf(fbuffer, "%d %s %f %f %f %d", &atomid, buffer, &coord, &coord, &coord, &atomtypeindex);
00098     if (NULL == k) {
00099       fprintf(stderr, "tinker structure) missing atom(s) in file '%s'\n", data->file_name);
00100       fprintf(stderr, "tinker structure) expecting '%d' atoms, found only '%d'\n", data->numatoms, i+1);
00101       return MOLFILE_ERROR;
00102     } else if (j < 5) {
00103       fprintf(stderr, "tinker structure) missing type or coordinate(s) in file '%s' for atom '%d'\n", data->file_name, i+1);
00104       return MOLFILE_ERROR;
00105     }
00106 
00107     strncpy(atom->name, buffer, sizeof(atom->name));
00108 #if 0
00109     strncpy(atom->type, atom->name, sizeof(atom->type));
00110 #else
00111     sprintf(atom->type, "%d", atomtypeindex);
00112 #endif
00113     atom->resname[0] = '\0';
00114     atom->resid = 1;
00115     atom->chain[0] = '\0';
00116     atom->segid[0] = '\0';
00117   }
00118 
00119   rewind(data->file);
00120   return MOLFILE_SUCCESS;
00121 }
00122 
00123 static int read_tinker_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
00124   int i, j, atomid, box_failed;
00125   char atom_name[1024], fbuffer[1024], *k;
00126   float x, y, z, box[6];
00127   
00128   tinkerdata *data = (tinkerdata *)mydata;
00129   
00130   /* skip over the first line */
00131   if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00132   k = fgets(fbuffer, 1024, data->file);
00133   if (NULL == k) return MOLFILE_ERROR;
00134 
00135   /* attempt to get box size */
00136   j = sscanf(fbuffer, "%f %f %f %f %f %f", box, box+1, box+2, box+3, box+4, box+5);
00137   if (j > 2){
00138     box_failed = 0;
00139 
00140     if (ts != NULL){
00141       ts->A = box[0];
00142       ts->B = box[1];
00143       ts->C = box[2];
00144       if (j > 5){
00145         ts->alpha = box[3];
00146         ts->beta  = box[4];
00147         ts->gamma = box[5];
00148       }
00149     }
00150   } else {
00151     box_failed = 1;
00152   }
00153 
00154   /* read the coordinates */
00155   for (i=0; i<natoms; i++) {
00156     /* reuse line if box size failed, it's an atom line */
00157     if (i > 0 || !box_failed) k = fgets(fbuffer, 1024, data->file);
00158 
00159     /* Read in atom type, X, Y, Z, skipping any remaining data fields */
00160     j = sscanf(fbuffer, "%d %s %f %f %f", &atomid, atom_name, &x, &y, &z);
00161     if (NULL == k) {
00162       return MOLFILE_ERROR;
00163     } else if (j < 5) {
00164       fprintf(stderr, "tinker timestep) missing type or coordinate(s) in file '%s' for atom '%d'\n",data->file_name,i+1);
00165       return MOLFILE_ERROR;
00166     } else if (j >= 5) {
00167       if (ts != NULL) { 
00168         /* only save coords if we're given a timestep pointer, */
00169         /* otherwise assume that VMD wants us to skip past it. */
00170         ts->coords[3*i  ] = x;
00171         ts->coords[3*i+1] = y;
00172         ts->coords[3*i+2] = z;
00173       }
00174     } else {
00175       break;
00176     }
00177   }
00178   
00179   return MOLFILE_SUCCESS;
00180 }
00181     
00182 static void close_tinker_read(void *mydata) {
00183   tinkerdata *data = (tinkerdata *)mydata;
00184   fclose(data->file);
00185   free(data->file_name);
00186   free(data);
00187 }
00188 
00189 /* registration stuff */
00190 static molfile_plugin_t plugin;
00191 
00192 VMDPLUGIN_API int VMDPLUGIN_init() {
00193   memset(&plugin, 0, sizeof(molfile_plugin_t));
00194   plugin.abiversion = vmdplugin_ABIVERSION;
00195   plugin.type = MOLFILE_PLUGIN_TYPE;
00196   plugin.name = "tinker";
00197   plugin.prettyname = "Tinker";
00198   plugin.author = "John Stone";
00199   plugin.majorv = 0;
00200   plugin.minorv = 7;
00201   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00202   plugin.filename_extension = "arc,txyz";
00203   plugin.open_file_read = open_tinker_read;
00204   plugin.read_structure = read_tinker_structure;
00205   plugin.read_next_timestep = read_tinker_timestep;
00206   plugin.close_file_read = close_tinker_read;
00207   return VMDPLUGIN_SUCCESS;
00208 }
00209 
00210 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00211   (*cb)(v, (vmdplugin_t *)&plugin);
00212   return VMDPLUGIN_SUCCESS;
00213 }
00214 
00215 VMDPLUGIN_API int VMDPLUGIN_fini() {
00216   return VMDPLUGIN_SUCCESS;
00217 }
00218 
00219 
00220 #ifdef TEST_PLUGIN
00221 
00222 int main(int argc, char *argv[]) {
00223   molfile_timestep_t timestep;
00224   void *v;
00225   int natoms;
00226   int i, nsets, set;
00227 
00228   while (--argc) {
00229     ++argv;
00230     v = open_tinker_read(*argv, "tinker", &natoms);
00231     if (!v) {
00232       fprintf(stderr, "open_tinker_read failed for file %s\n", *argv);
00233       return 1;
00234     }
00235     fprintf(stderr, "open_tinker_read succeeded for file %s\n", *argv);
00236     fprintf(stderr, "number of atoms: %d\n", natoms);
00237 
00238     i = 0;
00239     timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
00240     while (!read_tinker_timestep(v, natoms, &timestep)) {
00241       i++;
00242     }
00243     fprintf(stderr, "ended read_next_timestep on frame %d\n", i);
00244 
00245     close_tinker_read(v);
00246   }
00247   return 0;
00248 }
00249 
00250 #endif
00251 

Generated on Fri Apr 19 03:09:32 2024 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002