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
00033
00034
00035
00036
00037
00038 #include "largefiles.h"
00039
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <ctype.h>
00044 #include "molfile_plugin.h"
00045
00046 #include "periodic_table.h"
00047
00048 typedef struct {
00049 FILE *file;
00050 int numatoms;
00051 char *file_name;
00052 molfile_atom_t *atomlist;
00053 } xyzdata;
00054
00055 static void *open_xyz_read(const char *filename, const char *filetype,
00056 int *natoms) {
00057 FILE *fd;
00058 xyzdata *data;
00059 int i;
00060
00061 fd = fopen(filename, "rb");
00062 if (!fd) return NULL;
00063
00064 data = (xyzdata *)malloc(sizeof(xyzdata));
00065 data->file = fd;
00066 data->file_name = strdup(filename);
00067
00068
00069 i = fscanf(data->file, "%d", natoms);
00070 if (i < 1) {
00071 fprintf(stderr, "\n\nread) ERROR: xyz file '%s' should have the number of atoms in the first line.\n", filename);
00072 return NULL;
00073 }
00074 data->numatoms=*natoms;
00075
00076 while (getc(fd) != '\n');
00077
00078 while (getc(fd) != '\n');
00079
00080 return data;
00081 }
00082
00083 static int read_xyz_structure(void *mydata, int *optflags,
00084 molfile_atom_t *atoms) {
00085 int i, j;
00086 char *k;
00087 float coord;
00088 molfile_atom_t *atom;
00089 xyzdata *data = (xyzdata *)mydata;
00090
00091
00092 *optflags = MOLFILE_ATOMICNUMBER | MOLFILE_MASS | MOLFILE_RADIUS;
00093
00094 for(i=0; i<data->numatoms; i++) {
00095 char buffer[1024], fbuffer[1024];
00096 k = fgets(fbuffer, 1024, data->file);
00097 atom = atoms + i;
00098 j=sscanf(fbuffer, "%s %f %f %f", buffer, &coord, &coord, &coord);
00099 if (k == NULL) {
00100 fprintf(stderr, "xyz structure) missing atom(s) in file '%s'\n", data->file_name);
00101 fprintf(stderr, "xyz structure) expecting '%d' atoms, found only '%d'\n", data->numatoms, i);
00102 return MOLFILE_ERROR;
00103 } else if (j < 4) {
00104 fprintf(stderr, "xyz structure) missing type or coordinate(s) in file '%s' for atom '%d'\n",
00105 data->file_name, i+1);
00106 return MOLFILE_ERROR;
00107 }
00108
00109
00110
00111 if (isdigit(buffer[0])) {
00112 int idx;
00113 idx = atoi(buffer);
00114 strncpy(atom->name, get_pte_label(idx), sizeof(atom->name));
00115 atom->atomicnumber = idx;
00116 atom->mass = get_pte_mass(idx);
00117 atom->radius = get_pte_vdw_radius(idx);
00118 } else {
00119 int idx;
00120 strncpy(atom->name, buffer, sizeof(atom->name));
00121 idx = get_pte_idx(buffer);
00122 atom->atomicnumber = idx;
00123 atom->mass = get_pte_mass(idx);
00124 atom->radius = get_pte_vdw_radius(idx);
00125 }
00126 strncpy(atom->type, atom->name, sizeof(atom->type));
00127 atom->resname[0] = '\0';
00128 atom->resid = 1;
00129 atom->chain[0] = '\0';
00130 atom->segid[0] = '\0';
00131
00132 }
00133
00134 rewind(data->file);
00135 return MOLFILE_SUCCESS;
00136 }
00137
00138 static int read_xyz_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
00139 int i, j;
00140 char atom_name[1024], fbuffer[1024], *k;
00141 float x, y, z;
00142
00143 xyzdata *data = (xyzdata *)mydata;
00144
00145
00146 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00147 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00148
00149
00150 for (i=0; i<natoms; i++) {
00151 k = fgets(fbuffer, 1024, data->file);
00152
00153
00154 j = sscanf(fbuffer, "%s %f %f %f", atom_name, &x, &y, &z);
00155 if (k == NULL) {
00156 return MOLFILE_ERROR;
00157 } else if (j < 4) {
00158 fprintf(stderr, "xyz timestep) missing type or coordinate(s) in file '%s' for atom '%d'\n",data->file_name,i+1);
00159 return MOLFILE_ERROR;
00160 } else if (j >= 4) {
00161 if (ts != NULL) {
00162
00163
00164 ts->coords[3*i ] = x;
00165 ts->coords[3*i+1] = y;
00166 ts->coords[3*i+2] = z;
00167 }
00168 } else {
00169 break;
00170 }
00171 }
00172
00173 return MOLFILE_SUCCESS;
00174 }
00175
00176 static void close_xyz_read(void *mydata) {
00177 xyzdata *data = (xyzdata *)mydata;
00178 fclose(data->file);
00179 free(data->file_name);
00180 free(data);
00181 }
00182
00183
00184 static void *open_xyz_write(const char *filename, const char *filetype,
00185 int natoms) {
00186 FILE *fd;
00187 xyzdata *data;
00188
00189 fd = fopen(filename, "w");
00190 if (!fd) {
00191 fprintf(stderr, "Error) Unable to open xyz file %s for writing\n",
00192 filename);
00193 return NULL;
00194 }
00195
00196 data = (xyzdata *)malloc(sizeof(xyzdata));
00197 data->numatoms = natoms;
00198 data->file = fd;
00199 data->file_name = strdup(filename);
00200 return data;
00201 }
00202
00203 static int write_xyz_structure(void *mydata, int optflags,
00204 const molfile_atom_t *atoms) {
00205 xyzdata *data = (xyzdata *)mydata;
00206 data->atomlist = (molfile_atom_t *)malloc(data->numatoms*sizeof(molfile_atom_t));
00207 memcpy(data->atomlist, atoms, data->numatoms*sizeof(molfile_atom_t));
00208 return MOLFILE_SUCCESS;
00209 }
00210
00211 static int write_xyz_timestep(void *mydata, const molfile_timestep_t *ts) {
00212 xyzdata *data = (xyzdata *)mydata;
00213 const molfile_atom_t *atom;
00214 const float *pos;
00215 int i;
00216
00217 fprintf(data->file, "%d\n", data->numatoms);
00218 fprintf(data->file, " generated by VMD\n");
00219
00220 atom = data->atomlist;
00221 pos = ts->coords;
00222 for (i = 0; i < data->numatoms; ++i) {
00223 fprintf(data->file, " %-2s %15.6f %15.6f %15.6f\n",
00224 atom->type, pos[0], pos[1], pos[2]);
00225 ++atom;
00226 pos += 3;
00227 }
00228 return MOLFILE_SUCCESS;
00229 }
00230
00231
00232 static void close_xyz_write(void *mydata) {
00233 xyzdata *data = (xyzdata *)mydata;
00234 fclose(data->file);
00235 free(data->atomlist);
00236 free(data->file_name);
00237 free(data);
00238 }
00239
00240
00241 static molfile_plugin_t xyzplugin = {
00242 vmdplugin_ABIVERSION,
00243 MOLFILE_PLUGIN_TYPE,
00244 "xyz",
00245 "XYZ",
00246 "Mauricio Carrillo Tripp, John E. Stone, Axel Kohlmeyer",
00247 0,
00248 9,
00249 VMDPLUGIN_THREADSAFE,
00250 "xyz",
00251 open_xyz_read,
00252 read_xyz_structure,
00253 0,
00254 read_xyz_timestep,
00255 close_xyz_read,
00256 open_xyz_write,
00257 write_xyz_structure,
00258 write_xyz_timestep,
00259 close_xyz_write,
00260 0,
00261 0,
00262 0
00263 };
00264
00265 VMDPLUGIN_API int VMDPLUGIN_init() {
00266 return VMDPLUGIN_SUCCESS;
00267 }
00268
00269 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00270 (*cb)(v, (vmdplugin_t *)&xyzplugin);
00271 return VMDPLUGIN_SUCCESS;
00272 }
00273
00274 VMDPLUGIN_API int VMDPLUGIN_fini() {
00275 return VMDPLUGIN_SUCCESS;
00276 }
00277
00278
00279 #ifdef TEST_PLUGIN
00280
00281 int main(int argc, char *argv[]) {
00282 molfile_timestep_t timestep;
00283 void *v;
00284 int natoms;
00285 int i, nsets, set;
00286
00287 while (--argc) {
00288 ++argv;
00289 v = open_xyz_read(*argv, "xyz", &natoms);
00290 if (!v) {
00291 fprintf(stderr, "open_xyz_read failed for file %s\n", *argv);
00292 return 1;
00293 }
00294 fprintf(stderr, "open_xyz_read succeeded for file %s\n", *argv);
00295 fprintf(stderr, "number of atoms: %d\n", natoms);
00296
00297 i = 0;
00298 timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
00299 while (!read_xyz_timestep(v, natoms, ×tep)) {
00300 i++;
00301 }
00302 fprintf(stderr, "ended read_next_timestep on frame %d\n", i);
00303
00304 close_xyz_read(v);
00305 }
00306 return 0;
00307 }
00308
00309 #endif
00310