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