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 <math.h>
00045 #include <float.h>
00046 #include "molfile_plugin.h"
00047
00048 #ifndef M_PI_2
00049 #define M_PI_2 1.57079632679489661922
00050 #endif
00051
00052 typedef struct {
00053 FILE *file;
00054 int numatoms;
00055 char *file_name;
00056 molfile_graphics_t *graphlist;
00057 } lammpsdata;
00058
00059 static char* find_next_item(FILE* fd, char* szItem) {
00060 char szLine[1024];
00061 char* pcolon;
00062 int nReturn;
00063
00064 while(fgets(szLine, 1024, fd)) {
00065 pcolon = strrchr(szLine, ':');
00066 if(pcolon) {
00067 *pcolon = 0;
00068 if(0 == strcmp(szLine, "ITEM")) {
00069 *pcolon = ':';
00070 pcolon+=2;
00071 strcpy(szItem, pcolon);
00072 nReturn = (int)strcspn(szItem, "\n\r");
00073 if(nReturn)
00074 szItem[nReturn] = 0;
00075 return szItem;
00076 }
00077 }
00078 }
00079
00080 return NULL;
00081 }
00082
00083
00084 static int find_item(FILE* fd, char* szItem) {
00085 char szBuffer[1024];
00086 while(find_next_item(fd, szBuffer)) {
00087 if(0 == strcmp(szBuffer, szItem))
00088 return 1;
00089 }
00090 return 0;
00091 }
00092
00093
00094 static void *open_lammps_read(const char *filename, const char *filetype, int *natoms) {
00095 FILE *fd;
00096 lammpsdata *data;
00097 char szBuffer[1024];
00098
00099 fd = fopen(filename, "rb");
00100 if (!fd) return NULL;
00101
00102 data = (lammpsdata *)malloc(sizeof(lammpsdata));
00103 data->file = fd;
00104 data->file_name = strdup(filename);
00105 data->graphlist = NULL;
00106 *natoms = 0;
00107
00108 if(!find_item(data->file, "NUMBER OF ATOMS")) {
00109 fprintf(stderr, "lammpsplugin) Unable to fine 'NUMBER OF ATOMS' item\n");
00110 return NULL;
00111 }
00112
00113 if(!fgets(szBuffer, 1024, data->file)) {
00114 fprintf(stderr, "lammpsplugin) dump file '%s' should have the number of atoms after line ITEM: NUMBER OF ATOMS.\n", filename);
00115 return NULL;
00116 }
00117 *natoms = atoi(szBuffer);
00118
00119 data->numatoms=*natoms;
00120 rewind(data->file);
00121
00122 return data;
00123 }
00124
00125
00126 static int read_lammps_structure(void *mydata, int *optflags, molfile_atom_t *atoms) {
00127 int i, j;
00128 char szBuffer[1024];
00129 molfile_atom_t *atom;
00130 lammpsdata *data = (lammpsdata *)mydata;
00131 int atomid;
00132 char atom_type[1025];
00133 float x, y, z;
00134 char *k;
00135
00136 *optflags = MOLFILE_NOOPTIONS;
00137
00138
00139 rewind(data->file);
00140
00141
00142 if(!find_item(data->file, "ATOMS")) {
00143 fprintf(stderr, "lammpsplugin) couldn't find atoms to read structure from file '%s'.\n", data->file_name);
00144 return MOLFILE_ERROR;
00145 }
00146
00147
00149
00150 k = fgets(szBuffer, 1024, data->file);
00151
00152
00153 j = sscanf(szBuffer, "%d %s %f %f %f", &atomid, atom_type, &x, &y, &z);
00154
00155 if (k == NULL) {
00156 fprintf(stderr, "lammpsplugin) Error while reading structure from lammps dump file '%s': atom missing in the first timestep\n",data->file_name);
00157 fprintf(stderr, "lammpsplugin) expecting '%d' atoms, found only '%d'\n",data->numatoms,i+1);
00158 return MOLFILE_ERROR;
00159 } else if (j < 5) {
00160 fprintf(stderr, "lammpsplugin) Error while reading structure from lammps dump file '%s': missing type or coordinate(s) for atom '%d'\n", data->file_name, i+1);
00161 return MOLFILE_ERROR;
00162 }
00163
00164 atom = atoms + i;
00165 sprintf(atom->name, "%02d", atomid);
00166 strncpy(atom->type, atom_type, sizeof(atom->type));
00167 strcpy(atom->resname, "");
00168 atom->resid = 1;
00169 strcpy(atom->chain, "");
00170 strcpy(atom->segid, "");
00171
00172 }
00173
00174 rewind(data->file);
00175 return MOLFILE_SUCCESS;
00176 }
00177
00178
00179 static int read_lammps_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
00180 int i, j;
00181 char atom_name[1025], szBuffer[1025];
00182 float x, y, z;
00183 int atomid;
00184 float lo[3],hi[3], l[3];
00185
00186 lammpsdata *data = (lammpsdata *)mydata;
00187
00188
00189 if(!find_item(data->file, "TIMESTEP")) return MOLFILE_ERROR;
00190
00191
00192 if(!ts) return MOLFILE_SUCCESS;
00193
00194
00195 if(!find_item(data->file, "NUMBER OF ATOMS")) {
00196 fprintf(stderr, "lammpsplugin) lammps dump file '%s', unable to find item: NUMBER OF ATOMS for current timestep.\n", data->file_name);
00197 return MOLFILE_ERROR;
00198 }
00199
00200 if(!fgets(szBuffer, 1024, data->file)) {
00201 fprintf(stderr, "lammpsplugin) lammps dump file '%s', should have the number of atoms after line ITEM: NUMBER OF ATOMS.\n", data->file_name);
00202 return MOLFILE_ERROR;
00203 }
00204
00205 if(natoms != atoi(szBuffer)) {
00206 fprintf(stderr, "lammpsplugin) lammps dump file '%s', wrong number of atoms in timestep.\n", data->file_name);
00207 return MOLFILE_ERROR;
00208 }
00209
00210
00211 if(!find_item(data->file, "BOX BOUNDS")) {
00212 fprintf(stderr, "lammpsplugin) lammps dump file '%s', could not find ITEM: BOX BOUNDS.\n", data->file_name);
00213 return MOLFILE_ERROR;
00214 }
00215
00216 if (NULL == fgets(szBuffer, 1024, data->file)) return MOLFILE_ERROR;
00217 sscanf(szBuffer,"%f %f", lo, hi);
00218 l[0] = hi[0] - lo[0];
00219
00220 if (NULL == fgets(szBuffer, 1024, data->file)) return MOLFILE_ERROR;
00221 sscanf(szBuffer,"%f %f", lo+1, hi+1);
00222 l[1] = hi[1] - lo[1];
00223
00224 if (NULL == fgets(szBuffer, 1024, data->file)) return MOLFILE_ERROR;
00225 sscanf(szBuffer,"%f %f", lo+2, hi+2);
00226 l[2] = hi[2] - lo[2];
00227
00228 ts->A = l[0];
00229 ts->B = l[1];
00230 ts->C = l[2];
00231 ts->alpha = 90.0;
00232 ts->beta = 90.0;
00233 ts->gamma = 90.0;
00234
00235
00236 if (!find_item(data->file, "ATOMS")) {
00237 fprintf(stderr, "lammpsplugin) lammps dump file '%s', could not find ITEM: ATOMS.\n", data->file_name);
00238 return MOLFILE_ERROR;
00239 }
00240
00241 for (i=0; i<natoms; i++) {
00242 if(!fgets(szBuffer, 1024, data->file)) {
00243
00244 fprintf(stderr, "lammpsplugin) lammps dump file '%s', unexpected end of file or error while reading coordinates for atom %d.\n", data->file_name, i);
00245 return MOLFILE_ERROR;
00246 }
00247
00248
00249 j = sscanf(szBuffer, "%d %s %f %f %f", &atomid, atom_name, &x, &y, &z);
00250 if (j != 5) {
00251 fprintf(stderr, "lammpsplugin) lammps dump file '%s', error while parsing coordinates for atom %d.\n", data->file_name, i);
00252 return MOLFILE_ERROR;
00253 }
00254
00255 if (atomid > 0 && atomid <= natoms) {
00256 int addr = 3 * (atomid - 1);
00257
00258
00259 ts->coords[addr ] = x * l[0];
00260 ts->coords[addr + 1] = y * l[1];
00261 ts->coords[addr + 2] = z * l[2];
00262 } else {
00263 fprintf(stderr, "lammpsplugin) ignoring illegal atom index %d\n", atomid);
00264 }
00265 }
00266
00267 return MOLFILE_SUCCESS;
00268 }
00269
00270
00271 static void close_lammps_read(void *mydata) {
00272 lammpsdata *data = (lammpsdata *)mydata;
00273 fclose(data->file);
00274 free(data->file_name);
00275 if(data->graphlist) free(data->graphlist);
00276 free(data);
00277 }
00278
00279
00280
00281 static molfile_plugin_t lammpsplugin = {
00282 vmdplugin_ABIVERSION,
00283 MOLFILE_PLUGIN_TYPE,
00284 "lammpstrj",
00285 "LAMMPS Trajectory",
00286 "John E. Stone",
00287 0,
00288 3,
00289 VMDPLUGIN_THREADSAFE,
00290 "lammpstrj",
00291 open_lammps_read,
00292 read_lammps_structure,
00293 0,
00294 read_lammps_timestep,
00295 close_lammps_read,
00296 0,
00297 0,
00298 0,
00299 0,
00300 0,
00301 0,
00302 0,
00303 };
00304
00305 VMDPLUGIN_API int VMDPLUGIN_init() {
00306 return VMDPLUGIN_SUCCESS;
00307 }
00308
00309 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00310 (*cb)(v, (vmdplugin_t *)&lammpsplugin);
00311 return VMDPLUGIN_SUCCESS;
00312 }
00313
00314 VMDPLUGIN_API int VMDPLUGIN_fini() {
00315 return VMDPLUGIN_SUCCESS;
00316 }
00317
00318
00319 #ifdef TEST_PLUGIN
00320
00321 int main(int argc, char *argv[]) {
00322 molfile_timestep_t timestep;
00323 void *v;
00324 int natoms;
00325 int i, nsets, set;
00326
00327 while (--argc) {
00328 ++argv;
00329 v = open_lammps_read(*argv, "lammps", &natoms);
00330 if (!v) {
00331 fprintf(stderr, "open_lammps_read failed for file %s\n", *argv);
00332 return 1;
00333 }
00334 fprintf(stderr, "open_lammps_read succeeded for file %s\n", *argv);
00335 fprintf(stderr, "number of atoms: %d\n", natoms);
00336
00337 i = 0;
00338 timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
00339 while (!read_lammps_timestep(v, natoms, ×tep)) {
00340 i++;
00341 }
00342 fprintf(stderr, "ended read_next_timestep on frame %d\n", i);
00343
00344 close_lammps_read(v);
00345 }
00346 return 0;
00347 }
00348
00349 #endif
00350