00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "molfile_plugin.h"
00019
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <string.h>
00023
00024 #if defined(_AIX)
00025 #include <strings.h>
00026 #endif
00027
00028 #define LINESIZE 256
00029
00030 typedef struct {
00031 FILE *file;
00032 molfile_atom_t *atomlist;
00033 molfile_metadata_t *meta;
00034 int natoms, nbonds, optflags, coords_read;
00035 int *from, *to;
00036 float *bondorder;
00037 } xbgfdata;
00038
00039
00040
00041
00042 static void *open_bgf_read(const char *path, const char *filetype,
00043 int *natoms) {
00044 FILE *fd;
00045 xbgfdata *bgf;
00046 char line[LINESIZE];
00047 int nbonds, optflags;
00048 int numat=0;
00049 nbonds=0;
00050 int nbline;
00051
00052
00053 bgf = new xbgfdata;
00054
00055 bgf->meta = (molfile_metadata_t *) malloc(sizeof(molfile_metadata_t));
00056 memset(bgf->meta, 0, sizeof(molfile_metadata_t));
00057
00058 bgf->meta->remarklen = 0;
00059 bgf->meta->remarks = NULL;
00060
00061 if ((fd = fopen(path, "r")) == NULL)
00062 return NULL;
00063
00064 do {
00065 fgets(line, LINESIZE, fd);
00066 if ( ferror(fd) || feof(fd) ) {
00067 printf("xbgfplugin) Improperly terminated bgf file\n");
00068 return NULL;
00069 }
00070
00071 if ((strncmp(line, "ATOM", 4) == 0) || (strncmp(line, "HETATM", 6)==0))
00072 numat++;
00073
00074 if (strncmp(line,"CONECT",6)==0) {
00075 nbline=(strlen(line)-1)/6;
00076 nbline -= 2;
00077 nbonds += nbline;
00078 }
00079
00080
00081 if (strncmp(line, "REMARK", 4)==0 || strncmp(line, "LEWIS", 4)==0 ||
00082 strncmp(line, "VDW", 3)==0) {
00083 int len=strlen(line);
00084 int newlen = len + bgf->meta->remarklen;
00085 char *newstr=(char*) realloc(bgf->meta->remarks, newlen + 1);
00086 if (newstr != NULL) {
00087 bgf->meta->remarks = newstr;
00088 bgf->meta->remarks[bgf->meta->remarklen] = '\0';
00089 memcpy(bgf->meta->remarks + bgf->meta->remarklen, line, len);
00090 bgf->meta->remarks[newlen] = '\0';
00091 bgf->meta->remarklen = newlen;
00092 }
00093 }
00094
00095 optflags = MOLFILE_INSERTION | MOLFILE_CHARGE | MOLFILE_BFACTOR | MOLFILE_OCCUPANCY | MOLFILE_ATOMICNUMBER;
00096 } while ( strncmp(line, "END", 3) );
00097
00098 *natoms = numat;
00099 rewind(fd);
00100
00101 bgf->file = fd;
00102 bgf->natoms = *natoms;
00103 bgf->nbonds = nbonds;
00104
00105 bgf->optflags = optflags;
00106 bgf->coords_read = 0;
00107 bgf->from = NULL;
00108 bgf->to = NULL;
00109
00110 return bgf;
00111 }
00112
00113
00114 static void adjust_bgf_field_string(char *field) {
00115 int i, len;
00116
00117 len = strlen(field);
00118 while (len > 0 && field[len-1] == ' ') {
00119 field[len-1] = '\0';
00120 len--;
00121 }
00122
00123 while (len > 0 && field[0] == ' ') {
00124 for (i=0; i < len; i++)
00125 field[i] = field[i+1];
00126 len--;
00127 }
00128 }
00129
00130 static void get_bgf_coordinates(const char *record,
00131 float *x, float *y, float *z) {
00132 char numstr[50];
00133 memset(numstr, 0, sizeof(numstr));
00134 if (x != NULL) {
00135 strncpy(numstr, record + 32, 10);
00136 *x = (float) atof(numstr);
00137 }
00138
00139 if (y != NULL) {
00140 strncpy(numstr+10, record + 42, 10);
00141 *y = (float) atof(numstr+10);
00142 }
00143
00144 if (z != NULL) {
00145 strncpy(numstr+20, record + 52, 10);
00146 *z = (float) atof(numstr+20);
00147 }
00148 }
00149
00150
00151 static void get_bgf_fields(const char *record, char *name, char *resname,
00152 char *chain, char* segname, float *occupancy,
00153 float *bfactor, int *elementindex,
00154 int *resid, char *type, float *charge,
00155 float *x, float *y, float *z, char* insert) {
00156 char tempresid[6];
00157 char tempcharge[8];
00158 char tempbeta[7];
00159 char tempocc[7];
00160 char tempelem[4];
00161 strcpy(insert, " ");
00162
00163
00164 strncpy(name, record + 14, 5);
00165 name[5] = '\0';
00166 adjust_bgf_field_string(name);
00167
00168
00169 strncpy(resname, record + 20, 4);
00170 resname[4] = '\0';
00171 adjust_bgf_field_string(resname);
00172
00173
00174 strncpy(segname, record + 101, 4);
00175 segname[4]='\0';
00176 adjust_bgf_field_string(segname);
00177
00178
00179 chain[0] = record[25];
00180 chain[1] = '\0';
00181
00182
00183 strncpy(tempresid, record + 27, 5);
00184 tempresid[5] = '\0';
00185 adjust_bgf_field_string(tempresid);
00186 *resid=atoi(tempresid);
00187
00188
00189 strncpy(type, record+63, 5);
00190 type[5]='\0';
00191 adjust_bgf_field_string(type);
00192
00193
00194 strncpy(tempcharge, record + 74, 7);
00195 tempcharge[7] = '\0';
00196 adjust_bgf_field_string(tempcharge);
00197 *charge=atof(tempcharge);
00198
00199
00200 strncpy(tempbeta, record + 83, 6);
00201 tempbeta[6] = '\0';
00202 adjust_bgf_field_string(tempbeta);
00203 *bfactor=atof(tempbeta);
00204
00205 strncpy(tempocc, record + 90, 6);
00206 tempocc[6] = '\0';
00207 adjust_bgf_field_string(tempocc);
00208 *occupancy=atof(tempocc);
00209
00210 strncpy(tempelem, record + 97, 3);
00211 tempelem[3] = '\0';
00212 adjust_bgf_field_string(tempelem);
00213 *elementindex=atoi(tempelem);
00214
00215
00216 get_bgf_coordinates(record, x, y, z);
00217 }
00218
00219
00220
00221 static int read_bgf_structure(void *v, int *optflags, molfile_atom_t *atoms) {
00222 xbgfdata *bgf = (xbgfdata *)v;
00223 char line[LINESIZE];
00224 molfile_atom_t *atom;
00225 int natoms=0;
00226
00227
00228 *optflags = bgf->optflags;
00229
00230
00231 rewind(bgf->file);
00232 do {
00233 fgets(line, LINESIZE, bgf->file);
00234 if ( ferror(bgf->file) || feof(bgf->file) ) {
00235 printf("xbgfplugin) FORMAT ATOM record found in file.\n");
00236 return MOLFILE_ERROR;
00237 }
00238 } while ( strncmp(line, "FORMAT ATOM", 11) );
00239
00240
00241 do {
00242 fgets(line, LINESIZE, bgf->file);
00243 if ( ferror(bgf->file) || feof(bgf->file) ) {
00244 printf("xbgfplugin) Error occurred reading atom record.\n");
00245 return MOLFILE_ERROR;
00246 }
00247
00248 if (strncmp(line, "ATOM", 4) && strncmp(line, "HETATM", 6)) continue;
00249 atom=atoms+natoms;
00250 natoms++;
00251 get_bgf_fields(line, atom->name, atom->resname, atom->chain, atom->segid,
00252 &atom->occupancy, &atom->bfactor, &atom->atomicnumber,
00253 &atom->resid, atom->type, &atom->charge,
00254 NULL, NULL, NULL, atom->insertion);
00255 } while (strncmp(line, "END", 3));
00256
00257 bgf->natoms = natoms;
00258
00259 return MOLFILE_SUCCESS;
00260 }
00261
00262
00263
00264 static int read_bgf_timestep(void *v, int natoms, molfile_timestep_t *ts) {
00265 xbgfdata *bgf = (xbgfdata *)v;
00266 char line[LINESIZE];
00267 int i;
00268 float x, y, z;
00269
00270
00271
00272
00273 if (bgf->coords_read) {
00274 return MOLFILE_EOF;
00275 }
00276
00277
00278 rewind(bgf->file);
00279 do {
00280 fgets(line, LINESIZE, bgf->file);
00281 if ( ferror(bgf->file) || feof(bgf->file) ) {
00282 printf("xbgfplugin) No FORMAT ATOM record found in file.\n");
00283 return MOLFILE_ERROR;
00284 }
00285 } while ( strncmp(line, "FORMAT ATOM", 11) );
00286
00287
00288 for (i = 0; i < bgf->natoms; i++) {
00289 fgets(line, LINESIZE, bgf->file);
00290 if ( ferror(bgf->file) || feof(bgf->file) ) {
00291 printf("xbgfplugin) Error occurred reading atom coordinates.\n");
00292 return MOLFILE_ERROR;
00293 }
00294
00295
00296 if (strncmp(line,"ATOM",4)!=0 && strncmp(line,"HETATM",6)!=0) continue;
00297
00298 get_bgf_coordinates(line, &x, &y, &z);
00299
00300 if (ts) {
00301 ts->coords[3*i ] = x;
00302 ts->coords[3*i+1] = y;
00303 ts->coords[3*i+2] = z;
00304 }
00305 }
00306
00307 bgf->coords_read = 1;
00308 return MOLFILE_SUCCESS;
00309 }
00310
00311
00312 static void *open_bgf_write(const char *filename, const char *filetype,
00313 int natoms) {
00314 FILE *fd;
00315 xbgfdata *data;
00316
00317 if ((fd = fopen(filename, "w")) == NULL) {
00318 printf("xbgfplugin) Error, unable to open bgf file %s for writing\n",
00319 filename);
00320 return NULL;
00321 }
00322
00323 data = (xbgfdata *)malloc(sizeof(xbgfdata));
00324 data->natoms = natoms;
00325 data->file = fd;
00326 return data;
00327 }
00328
00329
00330 static int write_bgf_structure(void *mydata, int optflags,
00331 const molfile_atom_t *atoms) {
00332 xbgfdata *data = (xbgfdata *)mydata;
00333 data->atomlist = (molfile_atom_t *)malloc(data->natoms*sizeof(molfile_atom_t));
00334 memcpy(data->atomlist, atoms, data->natoms*sizeof(molfile_atom_t));
00335 return MOLFILE_SUCCESS;
00336 }
00337
00338
00339 static int read_bgf_bonds(void *v, int *nbonds, int **fromptr, int **toptr, float **bondorderptr) {
00340 xbgfdata *bgf = (xbgfdata *)v;
00341 char line[LINESIZE];
00342 char nextline[LINESIZE];
00343 if (bgf->nbonds == 0) {
00344 *nbonds = 0;
00345 *fromptr = NULL;
00346 *toptr = NULL;
00347 *bondorderptr = NULL;
00348 return MOLFILE_SUCCESS;
00349 }
00350
00351
00352 bgf->from = new int[bgf->nbonds];
00353 bgf->to = new int[bgf->nbonds];
00354 bgf->bondorder = new float[bgf->nbonds];
00355
00356
00357 rewind(bgf->file);
00358 do {
00359 fgets(line, LINESIZE, bgf->file);
00360 if ( ferror(bgf->file) || feof(bgf->file) ) {
00361 printf("xbgfplugin) No bond record found in file.\n");
00362 return MOLFILE_ERROR;
00363 }
00364 } while ( strncmp(line, "FORMAT CONECT", 13) != 0 );
00365
00366
00367 int j;
00368 int k;
00369 bool conline=false;
00370 char currbond[7]="xxxxxx";
00371 char currcon[7]="xxxxxx";
00372 char* bondptr;
00373 char* conptr;
00374 int bonds[8];
00375 float orders[8];
00376 int numbonds;
00377 int numords;
00378 float bo;
00379 int i=0;
00380 int numfields=0;
00381 fgets(line, LINESIZE, bgf->file);
00382 while (1) {
00383
00384
00385 conline=false;
00386 if (strncmp(line,"END",3)==0)
00387 break;
00388
00389 fgets(nextline, LINESIZE, bgf->file);
00390 if ( ferror(bgf->file) || feof(bgf->file) ) {
00391 printf("xbgfplugin) Error occurred reading bond record.\n");
00392 return MOLFILE_ERROR;
00393 }
00394
00395 if (strncmp(nextline,"ORDER",5)==0)
00396 conline=true;
00397
00398 if (strncmp(line,"CONECT",6)==0) {
00399 numfields=(strlen(line)-1)/6;
00400 bondptr=&line[0];
00401 numfields--;
00402 bondptr += 6;
00403 numbonds=0;
00404 numords=0;
00405 strncpy(currbond,bondptr,6);
00406 j=atoi(currbond);
00407 numfields--;
00408 bondptr += 6;
00409
00410 while ((numfields > 0) && (numbonds < 8)) {
00411 strncpy(currbond,bondptr,6);
00412 numfields--;
00413 bondptr += 6;
00414 bonds[numbonds]=atoi(currbond);
00415 numbonds++;
00416 }
00417
00418 if (conline) {
00419 numfields=(strlen(line)-1)/6;
00420 conptr=&nextline[0];
00421 numfields -= 2;
00422 conptr += 12;
00423 numords=0;
00424 while ((numfields > 0) && (numords < numbonds)) {
00425 strncpy(currcon,conptr,6);
00426 numfields--;
00427 conptr+=6;
00428 bo=atof(currcon);
00429 orders[numords]=bo;
00430 numords++;
00431 }
00432 }
00433
00434 for (int l=0;l<numbonds;l++) {
00435 k=bonds[l];
00436 if (j<k) {
00437 bgf->from[i]=j;
00438 bgf->to[i]=k;
00439 if (conline) {
00440 bgf->bondorder[i]=orders[l];
00441 } else {
00442 bgf->bondorder[i]=1.0;
00443 }
00444 i++;
00445 }
00446 }
00447
00448 if (conline) {
00449 fgets(line, LINESIZE, bgf->file);
00450 } else {
00451 strncpy(line,nextline,LINESIZE);
00452 }
00453 } else {
00454 strncpy(line,nextline,LINESIZE);
00455 }
00456 }
00457
00458 *nbonds = i;
00459 *fromptr = bgf->from;
00460 *toptr = bgf->to;
00461 *bondorderptr = bgf->bondorder;
00462
00463 return MOLFILE_SUCCESS;
00464 }
00465
00466
00467 static int read_bonds(void *v, int *nbonds, int **fromptr, int **toptr, float **bondorderptr) {
00468 xbgfdata *bgf = (xbgfdata *)v;
00469
00470
00471 *nbonds=bgf->nbonds;
00472 if (bgf->nbonds > 0) {
00473 bgf->from = (int *) malloc(*nbonds*sizeof(int));
00474 bgf->to = (int *) malloc(*nbonds*sizeof(int));
00475 bgf->bondorder = (float *) malloc(*nbonds*sizeof(float));
00476
00477 if ((read_bgf_bonds(bgf, nbonds, &(bgf->from), &(bgf->to), &(bgf->bondorder))) != MOLFILE_SUCCESS) {
00478 fclose(bgf->file);
00479 bgf->file = NULL;
00480 return MOLFILE_ERROR;
00481 }
00482 *fromptr = bgf->from;
00483 *toptr = bgf->to;
00484 *bondorderptr = bgf->bondorder;
00485 } else {
00486 printf("xbgfplugin) WARNING: no bonds defined in xbgf file.\n");
00487 *fromptr = NULL;
00488 *toptr = NULL;
00489 *bondorderptr = NULL;
00490 }
00491 return MOLFILE_SUCCESS;
00492 }
00493
00494
00495 static int write_bgf_timestep(void *mydata, const molfile_timestep_t *ts) {
00496 xbgfdata *data = (xbgfdata *)mydata;
00497 const molfile_atom_t *atom;
00498 const float *pos;
00499 int i;
00500
00501
00502 fprintf(data->file, "BIOGRF 332\n");
00503 fprintf(data->file, "REMARK NATOM %4i\n", data->natoms);
00504 fprintf(data->file, "FORCEFIELD DREIDING\n");
00505 fprintf(data->file, "FORMAT ATOM (a6,1x,i6,1x,a5,1x,a4,1x,a1,1x,i5,3f10.5,1x,a5,i3,i2,1x,f8.5,1x,f6.3,1x,f6.3,1x,i3,1x,a4)\n");
00506
00507
00508 atom = data->atomlist;
00509 pos = ts->coords;
00510 int numbonds=0;
00511 int lp=0;
00512 for (i = 0; i < data->natoms; i++) {
00513 fprintf(data->file, "%-6s %6i %5s %4s %1s %5i%10.5f%10.5f%10.5f %-5s%3i%2i %8.5f %6.3f %6.3f %3i %4s\n", "ATOM", i+1, atom->name, atom->resname, atom->chain, atom->resid, pos[0], pos[1], pos[2], atom->type, numbonds, lp, atom->charge, atom->bfactor, atom->occupancy, atom->atomicnumber, atom->segid);
00514 ++atom;
00515 pos += 3;
00516 }
00517
00518
00519 fprintf(data->file,"FORMAT CONECT (a6,14i6) \nFORMAT ORDER (a6,i6,13f6.3)\n");
00520
00521
00522 int* bonds=(int *)malloc((data->natoms+1) * sizeof(int) * 6);
00523 float* orders=(float *)malloc((data->natoms+1)*sizeof(float) * 6);
00524 int* numcons=(int *)malloc((data->natoms+1)*sizeof(int));
00525 for (i=0;i<data->natoms+1;i++) {
00526 numcons[i]=0;
00527 }
00528
00529 int j,k;
00530 float o;
00531 for (i=0;i<data->nbonds;i++) {
00532 j=data->from[i];
00533 k=data->to[i];
00534 o=data->bondorder[i];
00535 numcons[j]++;
00536 numcons[k]++;
00537 if (numcons[j]>6) {
00538 printf("xbgfplugin) Warning: Bond overflow. Not all bonds were written\n");
00539 numcons[j]--;
00540 numcons[k]--;
00541 continue;
00542 }
00543
00544 if (numcons[k]>6) {
00545 printf("xbgfplugin) Warning: Bond overflow. Not all bonds were written\n");
00546 numcons[k]--;
00547 numcons[j]--;
00548 continue;
00549 }
00550 bonds[6*j+numcons[j]-1]=k;
00551 bonds[6*k+numcons[k]-1]=j;
00552 orders[6*j+numcons[j]-1]=o;
00553 orders[6*k+numcons[k]-1]=o;
00554 }
00555
00556 for (i=1;i<=data->natoms;i++) {
00557 fprintf(data->file,"CONECT%6i",i);
00558 for (j=0;j<numcons[i];j++) {
00559 fprintf(data->file,"%6i",bonds[6*i+j]);
00560 }
00561 fprintf(data->file,"\nORDER %6i",i);
00562 for (j=0;j<numcons[i];j++) {
00563 fprintf(data->file,"%6.3f",orders[6*i+j]);
00564 }
00565 fprintf(data->file,"\n");
00566 }
00567
00568 free(bonds);
00569 free(orders);
00570 free(numcons);
00571
00572 fprintf(data->file,"END\n");
00573 return MOLFILE_SUCCESS;
00574 }
00575
00576 static int write_bonds(void *v, int nbonds, int *fromptr, int *toptr, float *bondorderptr) {
00577 xbgfdata *data = (xbgfdata *)v;
00578 data->from = new int[nbonds];
00579 data->to = new int[nbonds];
00580 data->bondorder = new float[nbonds];
00581
00582
00583 for (int i=0;i<nbonds;i++) {
00584 data->from[i]=fromptr[i];
00585 data->to[i]=toptr[i];
00586 data->bondorder[i]=bondorderptr[i];
00587 }
00588
00589 data->nbonds = nbonds;
00590
00591 return MOLFILE_SUCCESS;
00592 }
00593
00594 static void close_bgf_write(void *mydata) {
00595 xbgfdata *data = (xbgfdata *)mydata;
00596 fclose(data->file);
00597
00598 if (data->atomlist != NULL) free(data->atomlist);
00599 if (data->from != NULL) free(data->from);
00600 if (data->to != NULL) free(data->to);
00601 if (data->bondorder != NULL) free(data->bondorder);
00602 free(data);
00603 }
00604
00605
00606
00607 static void close_bgf_read(void *v) {
00608 xbgfdata *bgf = (xbgfdata *)v;
00609 if (bgf) {
00610 if (bgf->file) fclose(bgf->file);
00611 if (bgf->from != NULL) free(bgf->from);
00612 if (bgf->to != NULL) free(bgf->to);
00613 if (bgf->bondorder != NULL) free(bgf->bondorder);
00614
00615
00616 if (bgf->meta->remarks != NULL)
00617 free(bgf->meta->remarks);
00618 if (bgf->meta != NULL)
00619 free(bgf->meta);
00620 delete bgf;
00621 }
00622 }
00623
00624
00625 static int read_molecule_metadata(void *v, molfile_metadata_t **metadata) {
00626 xbgfdata *bgf = (xbgfdata *)v;
00627 *metadata = bgf->meta;
00628 return MOLFILE_SUCCESS;
00629 }
00630
00631
00632 static molfile_plugin_t bgfplugin = {
00633 vmdplugin_ABIVERSION,
00634 MOLFILE_PLUGIN_TYPE,
00635 "xbgf",
00636 "Internal Paratool Format",
00637 "Peter Freddolino ",
00638 0,
00639 6,
00640 VMDPLUGIN_THREADSAFE,
00641 "xbgf",
00642 open_bgf_read,
00643 read_bgf_structure,
00644 read_bonds,
00645 read_bgf_timestep,
00646 close_bgf_read,
00647 open_bgf_write,
00648 write_bgf_structure,
00649 write_bgf_timestep,
00650 close_bgf_write,
00651 0,
00652 0,
00653 0,
00654 read_molecule_metadata,
00655 write_bonds
00656 };
00657
00658 VMDPLUGIN_API int VMDPLUGIN_init() {
00659 return VMDPLUGIN_SUCCESS;
00660 }
00661
00662 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00663 (*cb)(v, (vmdplugin_t *)&bgfplugin);
00664 return VMDPLUGIN_SUCCESS;
00665 }
00666
00667 VMDPLUGIN_API int VMDPLUGIN_fini() {
00668 return VMDPLUGIN_SUCCESS;
00669 }
00670
00671