00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "largefiles.h"
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
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');
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
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
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
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
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
00155 for (i=0; i<natoms; i++) {
00156
00157 if (i > 0 || !box_failed) k = fgets(fbuffer, 1024, data->file);
00158
00159
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
00169
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
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, ×tep)) {
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