00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "largefiles.h"
00019
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include "molfile_plugin.h"
00024 #include "unit_conversion.h"
00025
00026 typedef struct {
00027 FILE *file;
00028 int numatoms;
00029 const char *file_name;
00030 } cpmddata;
00031
00032 static void *open_cpmd_read(const char *filename, const char *filetype,
00033 int *natoms) {
00034 FILE *fd;
00035 cpmddata *data;
00036 char linebuf[255];
00037 int i, nfi_first, nfi_current, atomcount;
00038
00039 printf("cpmd) trying to open file '%s'\n",filename);
00040
00041 fd = fopen(filename, "rb");
00042 if (!fd) return NULL;
00043
00044 data = (cpmddata *)malloc(sizeof(cpmddata));
00045 data->file = fd;
00046 data->file_name = filename;
00047
00048 nfi_first = 0;
00049 nfi_current = 0;
00050
00051
00052 fgets(linebuf, 255, fd);
00053 i = sscanf(linebuf, "%d", &nfi_first);
00054 if (i < 1) {
00055 fprintf(stderr, "read) cpmd trajectory file '%s' should have the timestep number "
00056 "in the first column\n", filename);
00057 return NULL;
00058 }
00059 atomcount = 0;
00060 nfi_current = nfi_first;
00061
00062
00063
00064 while ((nfi_first == nfi_current) && !ferror(fd) && !feof(fd)) {
00065 ++atomcount;
00066 fgets(linebuf, 255, fd);
00067 i = sscanf(linebuf, "%d", &nfi_current);
00068 if (i < 1) {
00069 fprintf(stderr, "read) cpmd trajectory file '%s' should have the "
00070 "timestep number in the first column\n", filename);
00071 return NULL;
00072 }
00073 }
00074 printf("cpmd) found %d atoms in first timestep\n",atomcount);
00075 *natoms = atomcount;
00076 data->numatoms=*natoms;
00077
00078
00079 rewind(fd);
00080
00081 return data;
00082 }
00083
00084 static int read_cpmd_structure(void *mydata, int *optflags,
00085 molfile_atom_t *atoms) {
00086 int i, j;
00087 char *k;
00088 float coord;
00089 molfile_atom_t *atom;
00090 cpmddata *data = (cpmddata *)mydata;
00091
00092 printf("cpmd) trying to read structure\n");
00093 *optflags = MOLFILE_NOOPTIONS;
00094
00095 for(i=0;i<data->numatoms;i++) {
00096 char buffer[1024];
00097 char fbuffer[1024];
00098 k = fgets(fbuffer, 1024, data->file);
00099 atom = atoms + i;
00100 j=sscanf(fbuffer, "%s %f %f %f", buffer, &coord, &coord, &coord);
00101 if (k == NULL) {
00102 fprintf(stderr, "cpmd structure) missing atom(s) in file '%s'\n",data->file_name);
00103 fprintf(stderr, "cpmd structure) expecting '%d' atoms, found only '%d'\n",data->numatoms,i+1);
00104 return MOLFILE_ERROR;
00105 } else if (j < 4) {
00106 fprintf(stderr, "cpmd structure) missing type or coordinate(s) in file '%s' for atom '%d'\n",data->file_name,i+1);
00107 return MOLFILE_ERROR;
00108 }
00109
00110
00111 strncpy(atom->name, buffer, sizeof(atom->name));
00112 strncpy(atom->type, buffer, sizeof(atom->type));
00113 atom->resname[0] = '\0';
00114 atom->resid = 1;
00115 atom->chain[0] = '\0';
00116 atom->segid[0] = '\0';
00117
00118 }
00119
00120 rewind(data->file);
00121 return MOLFILE_SUCCESS;
00122 }
00123
00124 static int read_cpmd_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
00125 int i, j, nfi_first, nfi_current;
00126 char fbuffer[1024];
00127 float x, y, z;
00128 const float bohr=BOHR_TO_ANGS;
00129 char *k;
00130
00131 cpmddata *data = (cpmddata *)mydata;
00132 nfi_first = nfi_current = -1;
00133
00134
00135 for (i=0; i<natoms; i++) {
00136
00137 k = fgets(fbuffer, 1024, data->file);
00138
00139
00140 if (strstr(fbuffer, "NEW DATA")) {
00141 k = fgets(fbuffer, 1024, data->file);
00142 }
00143 j = sscanf(fbuffer, "%d %f %f %f", &nfi_current, &x, &y, &z);
00144 if (nfi_first < 0) nfi_first = nfi_current;
00145
00146 if (k == NULL) {
00147 return MOLFILE_ERROR;
00148 } else if (j < 4) {
00149 fprintf(stderr, "cpmd timestep) missing or illegal data in file"
00150 " '%s' for atom '%d'\n",data->file_name,i+1);
00151 return MOLFILE_ERROR;
00152 } else if (nfi_first != nfi_current) {
00153 fprintf(stderr, "cpmd timestep) short record in timestep %d of file"
00154 " '%s' for atom '%d'\n",nfi_first, data->file_name,i+1);
00155 }
00156
00157 ts->coords[3*i ] = x*bohr;
00158 ts->coords[3*i+1] = y*bohr;
00159 ts->coords[3*i+2] = z*bohr;
00160 }
00161
00162 return MOLFILE_SUCCESS;
00163 }
00164
00165 static void close_cpmd_read(void *mydata) {
00166 cpmddata *data = (cpmddata *)mydata;
00167
00168 fclose(data->file);
00169 free(data);
00170 }
00171
00172
00173 static molfile_plugin_t plugin;
00174
00175 VMDPLUGIN_API int VMDPLUGIN_init() {
00176 memset(&plugin, 0, sizeof(molfile_plugin_t));
00177 plugin.abiversion = vmdplugin_ABIVERSION;
00178 plugin.type = MOLFILE_PLUGIN_TYPE;
00179 plugin.name = "cpmd";
00180 plugin.prettyname = "CPMD";
00181 plugin.author = "Axel Kohlmeyer, John Stone";
00182 plugin.majorv = 0;
00183 plugin.minorv = 4;
00184 plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00185 plugin.filename_extension = "cpmd";
00186 plugin.open_file_read = open_cpmd_read;
00187
00188 plugin.read_next_timestep = read_cpmd_timestep;
00189 plugin.close_file_read = close_cpmd_read;
00190 return VMDPLUGIN_SUCCESS;
00191 }
00192
00193 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00194 (*cb)(v, (vmdplugin_t *)&plugin);
00195 return VMDPLUGIN_SUCCESS;
00196 }
00197
00198 VMDPLUGIN_API int VMDPLUGIN_fini() {
00199 return VMDPLUGIN_SUCCESS;
00200 }
00201