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 #include "molfile_plugin.h"
00035
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038 #include <string.h>
00039
00040 #if defined(_AIX)
00041 #include <strings.h>
00042 #endif
00043
00044 #define LINESIZE 256
00045
00046 typedef struct {
00047 FILE *file;
00048 molfile_atom_t *atomlist;
00049 int natoms, nbonds, optflags, coords_read;
00050 int *from, *to;
00051 float *bondorder;
00052 } mol2data;
00053
00054
00055
00056 static void *open_mol2_read(const char *path, const char *filetype,
00057 int *natoms) {
00058 FILE *fd;
00059 mol2data *mol2;
00060 char line[LINESIZE];
00061 int match, nbonds, optflags;
00062
00063 fd = fopen(path, "r");
00064 if (!fd)
00065 return NULL;
00066
00067
00068 do {
00069 fgets(line, LINESIZE, fd);
00070 if ( ferror(fd) || feof(fd) ) {
00071 fprintf(stderr, "mol2plugin) No molecule record found in file.\n");
00072 return NULL;
00073 }
00074 } while ( strncmp(line, "@<TRIPOS>MOLECULE", 17) );
00075
00076 fgets(line, LINESIZE, fd);
00077 fgets(line, LINESIZE, fd);
00078 match = sscanf(line, " %d %d", natoms, &nbonds);
00079 if (match == 1) {
00080 nbonds = 0;
00081 }
00082 else if (match != 2) {
00083 fprintf(stderr, "mol2plugin) Cannot determine the number of atoms.\n");
00084 return NULL;
00085 }
00086 fgets(line, LINESIZE, fd);
00087 fgets(line, LINESIZE, fd);
00088 if ( strncmp(line, "NO_CHARGES", 10) == 0 ) {
00089 optflags = MOLFILE_NOOPTIONS;
00090 }
00091 else {
00092 optflags = MOLFILE_CHARGE;
00093 }
00094
00095
00096 mol2 = (mol2data *) malloc(sizeof(mol2data));
00097 memset(mol2, 0, sizeof(mol2data));
00098 mol2->file = fd;
00099 mol2->natoms = *natoms;
00100 mol2->nbonds = nbonds;
00101 mol2->optflags = optflags;
00102 mol2->coords_read = 0;
00103 mol2->from = NULL;
00104 mol2->to = NULL;
00105 mol2->bondorder = NULL;
00106
00107 return mol2;
00108 }
00109
00110
00111 static int read_mol2(void *v, int *optflags, molfile_atom_t *atoms) {
00112 mol2data *mol2 = (mol2data *)v;
00113 char line[LINESIZE];
00114 int i, match;
00115 molfile_atom_t *atom;
00116
00117 *optflags = mol2->optflags;
00118
00119
00120 rewind(mol2->file);
00121 do {
00122 fgets(line, LINESIZE, mol2->file);
00123 if ( ferror(mol2->file) || feof(mol2->file) ) {
00124 fprintf(stderr, "mol2plugin) No atom record found in file.\n");
00125 return MOLFILE_ERROR;
00126 }
00127 } while ( strncmp(line, "@<TRIPOS>ATOM", 13) );
00128
00129
00130 for (i = 0; i < mol2->natoms; i++) {
00131 atom = atoms+i;
00132
00133 fgets(line, LINESIZE, mol2->file);
00134 if ( ferror(mol2->file) || feof(mol2->file) ) {
00135 fprintf(stderr, "mol2plugin) Error occurred reading atom record.\n");
00136 return MOLFILE_ERROR;
00137 }
00138
00139 match = sscanf(line, " %*d %s %*f %*f %*f %s %d %s %f",
00140 atom->name, atom->type, &atom->resid, atom->resname, &atom->charge);
00141
00142
00143
00144 switch (match) {
00145 case 0:
00146 fprintf(stderr, "mol2plugin) Improperly formatted atom record.\n");
00147 return MOLFILE_ERROR;
00148
00149 case 1:
00150 atom->resid = 0;
00151
00152 case 2:
00153 sprintf(atom->resname, "%d", atom->resid);
00154
00155 case 3:
00156 atom->charge = 0.0;
00157
00158 default:
00159 break;
00160 }
00161
00162
00163 atom->chain[0] = '\0';
00164 atom->segid[0] = '\0';
00165 }
00166
00167 rewind(mol2->file);
00168
00169 return MOLFILE_SUCCESS;
00170 }
00171
00172
00173
00174
00175 static int read_mol2_bonds_aux(void *v, int *nbonds, int **fromptr, int **toptr,
00176 float **bondorderptr) {
00177 mol2data *mol2 = (mol2data *)v;
00178 char line[LINESIZE], bond_type[16];
00179 int i, match, bond_from, bond_to, bond_index, current_nbonds;
00180 float curr_order;
00181
00182 if (mol2->nbonds == 0) {
00183 *nbonds = 0;
00184 *fromptr = NULL;
00185 *toptr = NULL;
00186 return MOLFILE_SUCCESS;
00187 }
00188
00189 current_nbonds = mol2->nbonds;
00190
00191
00192 rewind(mol2->file);
00193 do {
00194 fgets(line, LINESIZE, mol2->file);
00195 if ( ferror(mol2->file) || feof(mol2->file) ) {
00196 fprintf(stderr, "mol2plugin) No bond record found in file.\n");
00197 return MOLFILE_ERROR;
00198 }
00199 } while ( strncmp(line, "@<TRIPOS>BOND", 13) );
00200
00201
00202 bond_index = 0;
00203 for (i = 0; i < mol2->nbonds; i++) {
00204 fgets(line, LINESIZE, mol2->file);
00205 if ( ferror(mol2->file) || feof(mol2->file) ) {
00206 fprintf(stderr, "mol2plugin) Error occurred reading bond record.\n");
00207 return MOLFILE_ERROR;
00208 }
00209
00210
00211 if (strncmp(line, "@", 1) == 0) {
00212
00213 break;
00214 }
00215
00216 match = sscanf(line, " %*d %d %d %s", &bond_from, &bond_to, bond_type);
00217 if (match < 3) {
00218 fprintf(stderr, "mol2plugin) Improperly formatted bond record.\n");
00219 continue;
00220 }
00221 if ( strncmp(bond_type, "nc", 2) == 0 ) {
00222
00223 current_nbonds--;
00224 } else if ( strncmp(bond_type, "ar", 2) == 0) {
00225
00226 curr_order = 1.5;
00227 mol2->from[bond_index] = bond_from;
00228 mol2->to[bond_index] = bond_to;
00229 mol2->bondorder[bond_index]=curr_order;
00230 bond_index++;
00231 } else {
00232
00233 curr_order=strtod(bond_type,NULL);
00234 if (curr_order<1.0 || curr_order>4.0) curr_order=1;
00235
00236 fflush(stdout);
00237 mol2->from[bond_index] = bond_from;
00238 mol2->to[bond_index] = bond_to;
00239 mol2->bondorder[bond_index]=curr_order;
00240 bond_index++;
00241 }
00242 }
00243 if (bond_index > 0) {
00244 *nbonds = current_nbonds;
00245 *fromptr = mol2->from;
00246 *toptr = mol2->to;
00247 *bondorderptr = mol2->bondorder;
00248 } else {
00249 printf("mol2plugin) WARNING: no bonds defined in mol2 file\n");
00250 *nbonds = 0;
00251 *fromptr = NULL;
00252 *toptr = NULL;
00253 *bondorderptr = NULL;
00254 }
00255
00256 rewind(mol2->file);
00257 return MOLFILE_SUCCESS;
00258 }
00259
00260
00261
00262 static int read_mol2_timestep(void *v, int natoms, molfile_timestep_t *ts) {
00263 mol2data *mol2 = (mol2data *)v;
00264 char line[LINESIZE];
00265 int i, match;
00266 float x, y, z;
00267
00268
00269 do {
00270 fgets(line, LINESIZE, mol2->file);
00271 if ( ferror(mol2->file) || feof(mol2->file) ) {
00272
00273
00274 if (mol2->coords_read == 0) {
00275 fprintf(stderr, "mol2plugin) No atom record found in file.\n");
00276 }
00277
00278 return MOLFILE_ERROR;
00279 }
00280 } while ( strncmp(line, "@<TRIPOS>ATOM", 13) );
00281
00282
00283 for (i = 0; i < mol2->natoms; i++) {
00284 fgets(line, LINESIZE, mol2->file);
00285 if ( ferror(mol2->file) || feof(mol2->file) ) {
00286 fprintf(stderr, "mol2plugin) Error occurred reading atom coordinates.\n");
00287 return MOLFILE_ERROR;
00288 }
00289
00290
00291 match = sscanf(line, " %*d %*s %f %f %f", &x, &y, &z);
00292 if (match < 3) {
00293 fprintf(stderr, "mol2plugin) Improperly formatted atom coordinates.\n");
00294 return MOLFILE_ERROR;
00295 }
00296
00297 if (ts) {
00298 ts->coords[3*i ] = x;
00299 ts->coords[3*i+1] = y;
00300 ts->coords[3*i+2] = z;
00301 }
00302 }
00303
00304 mol2->coords_read = 1;
00305 return MOLFILE_SUCCESS;
00306 }
00307
00308
00309 static void *open_mol2_write(const char *filename, const char *filetype,
00310 int natoms) {
00311 FILE *fd;
00312 mol2data *data;
00313
00314 fd = fopen(filename, "w");
00315 if (!fd) {
00316 fprintf(stderr, "mol2plugin) Error: unable to open mol2 file %s for writing\n",
00317 filename);
00318 return NULL;
00319 }
00320
00321 data = (mol2data *) malloc(sizeof(mol2data));
00322 memset(data, 0, sizeof(mol2data));
00323 data->natoms = natoms;
00324 data->file = fd;
00325 data->nbonds = 0;
00326
00327 return data;
00328 }
00329
00330
00331 static int write_mol2_structure(void *mydata, int optflags,
00332 const molfile_atom_t *atoms) {
00333 mol2data *data = (mol2data *)mydata;
00334 data->atomlist = (molfile_atom_t *)malloc(data->natoms*sizeof(molfile_atom_t));
00335 memcpy(data->atomlist, atoms, data->natoms*sizeof(molfile_atom_t));
00336 return MOLFILE_SUCCESS;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 static int write_mol2_timestep(void *mydata, const molfile_timestep_t *ts) {
00402 mol2data *data = (mol2data *)mydata;
00403 const molfile_atom_t *atom;
00404 const float *pos;
00405 float chrgsq;
00406 int i;
00407
00408
00409 chrgsq=0.0;
00410 atom = data->atomlist;
00411 for (i = 0; i < data->natoms; i++) {
00412 chrgsq += atom->charge*atom->charge;
00413 ++atom;
00414 }
00415
00416
00417 fprintf(data->file, "@<TRIPOS>MOLECULE\n");
00418 fprintf(data->file, "generated by VMD\n");
00419 fprintf(data->file, " %4d %4d 1 0 0\n", data->natoms, data->nbonds);
00420 fprintf(data->file, "SMALL\n");
00421
00422 if (chrgsq > 0.0001) {
00423 fprintf(data->file, "USER_CHARGES\n");
00424 } else {
00425 fprintf(data->file, "NO_CHARGES\n");
00426 }
00427 fprintf(data->file, "****\n");
00428 fprintf(data->file, "Energy = 0\n\n");
00429
00430
00431 fprintf(data->file, "@<TRIPOS>ATOM\n");
00432 atom = data->atomlist;
00433 pos = ts->coords;
00434
00435
00436 for (i = 0; i < data->natoms; i++) {
00437 #if 0
00438 getmol2ff(mol2fftype, atom->type);
00439 fprintf(data->file, "%7d %-4s %8.4f %8.4f %8.4f %4s %4d %3s %8.6f\n", i+1, atom->name, pos[0], pos[1], pos[2], mol2fftype, atom->resid, atom->resname, atom->charge);
00440 #else
00441 fprintf(data->file, "%7d %-4s %8.4f %8.4f %8.4f %4s %4d %3s %8.6f\n", i+1, atom->name, pos[0], pos[1], pos[2], atom->type, atom->resid, atom->resname, atom->charge);
00442 #endif
00443 ++atom;
00444 pos += 3;
00445 }
00446
00447
00448
00449 int l=1;
00450 printf("mol2plugin) numbonds: %d\n", data->nbonds);
00451 if (data->nbonds>0) fprintf(data->file, "@<TRIPOS>BOND\n");
00452 for (i=0; i<data->nbonds; i++) {
00453
00454
00455
00456 if (data->bondorder != NULL) {
00457 fprintf(data->file, "%5d %5d %5d %2d\n", l ,data->from[i], data->to[i],
00458 (int)data->bondorder[i]);
00459 } else {
00460 fprintf(data->file, "%5d %5d %5d %2d\n", l ,data->from[i], data->to[i], 1);
00461 }
00462
00463 l++;
00464 }
00465
00466
00467 fprintf(data->file,"\n@<TRIPOS>SUBSTRUCTURE\n");
00468 fprintf(data->file,"1 **** 1 TEMP ");
00469 fprintf(data->file,"0 **** **** 0 ROOT\n");
00470
00471 return MOLFILE_SUCCESS;
00472 }
00473
00474 static int write_mol2_bonds(void *v, int nbonds, int *fromptr, int *toptr,
00475 float *bondorderptr, int *bondtype,
00476 int nbondtypes, char **bondtypename) {
00477 printf("*** RUNNING WRITE_MOL2_BONDS\n");
00478 mol2data *data = (mol2data *)v;
00479 data->nbonds = nbonds;
00480 data->from = (int *) malloc(nbonds * sizeof(int));
00481 data->to = (int *) malloc(nbonds * sizeof(int));
00482
00483 for (int i=0;i<nbonds;i++) {
00484 data->from[i]=fromptr[i];
00485 data->to[i]=toptr[i];
00486 }
00487 printf("*** I THINK nbonds is %i\n", nbonds);
00488 data->nbonds = nbonds;
00489 if (bondorderptr != NULL) {
00490 data->bondorder = (float *) malloc(nbonds * sizeof(float));
00491 for (int i=0;i<nbonds;i++) {
00492 data->bondorder[i]=bondorderptr[i];
00493 }
00494 }
00495
00496 return MOLFILE_SUCCESS;
00497 }
00498
00499
00500 static void close_mol2_write(void *mydata) {
00501 mol2data *data = (mol2data *)mydata;
00502 if (data) {
00503 if (data->file) fclose(data->file);
00504 if (data->from != NULL) free(data->from);
00505 data->from = NULL;
00506 if (data->to != NULL) free(data->to);
00507 data->to = NULL;
00508 if (data->bondorder != NULL) free(data->bondorder);
00509 data->bondorder = NULL;
00510 if (data->atomlist != NULL) free(data->atomlist);
00511 data->atomlist = NULL;
00512 free(data);
00513 }
00514 }
00515
00516
00517
00518 static void close_mol2_read(void *v) {
00519 mol2data *mol2 = (mol2data *)v;
00520 if (mol2) {
00521 if (mol2->file) fclose(mol2->file);
00522 if (mol2->from != NULL) free(mol2->from);
00523 mol2->from = NULL;
00524 if (mol2->to != NULL) free(mol2->to);
00525 mol2->to = NULL;
00526 if (mol2->bondorder != NULL) free(mol2->bondorder);
00527 mol2->bondorder = NULL;
00528 free(mol2);
00529 }
00530 }
00531
00532
00533 static int read_mol2_bonds(void *v, int *nbonds, int **fromptr, int **toptr,
00534 float **bondorderptr, int **bondtype,
00535 int *nbondtypes, char ***bondtypename) {
00536 mol2data *mol2 = (mol2data *)v;
00537
00538
00539
00540
00541 if (mol2->nbonds > 0) {
00542 mol2->from = (int *) malloc(mol2->nbonds*sizeof(int));
00543 mol2->to = (int *) malloc(mol2->nbonds*sizeof(int));
00544 mol2->bondorder = (float *) malloc(mol2->nbonds*sizeof(float));
00545 if (mol2->from == NULL || mol2->to == NULL || mol2->bondorder == NULL) {
00546 fprintf(stderr, "mol2plugin) ERROR: Failed to allocate memory for bonds\n");
00547 fclose(mol2->file);
00548 mol2->file = NULL;
00549 return MOLFILE_ERROR;
00550 }
00551 if ((read_mol2_bonds_aux(mol2, nbonds, &(mol2->from), &(mol2->to), &(mol2->bondorder))) != MOLFILE_SUCCESS) {
00552 fclose(mol2->file);
00553 mol2->file = NULL;
00554 return MOLFILE_ERROR;
00555 }
00556 *fromptr = mol2->from;
00557 *toptr = mol2->to;
00558 *bondorderptr = mol2->bondorder;
00559 *bondtype = NULL;
00560 *nbondtypes = 0;
00561 *bondtypename = NULL;
00562 } else {
00563 printf("mol2plugin) WARNING: zero bonds defined in mol2 file.\n");
00564 *nbonds = 0;
00565 *fromptr=NULL;
00566 *toptr=NULL;
00567 *bondorderptr=NULL;
00568 *bondtype = NULL;
00569 *nbondtypes = 0;
00570 *bondtypename = NULL;
00571 }
00572 return MOLFILE_SUCCESS;
00573 }
00574
00575 static molfile_plugin_t plugin;
00576
00577 VMDPLUGIN_API int VMDPLUGIN_init() {
00578 memset(&plugin, 0, sizeof(molfile_plugin_t));
00579 plugin.abiversion = vmdplugin_ABIVERSION;
00580 plugin.type = MOLFILE_PLUGIN_TYPE;
00581 plugin.name = "mol2";
00582 plugin.prettyname = "MDL mol2";
00583 plugin.author = "Peter Freddolino, Eamon Caddigan";
00584 plugin.majorv = 0;
00585 plugin.minorv = 17;
00586 plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
00587 plugin.filename_extension = "mol2";
00588 plugin.open_file_read = open_mol2_read;
00589 plugin.read_structure = read_mol2;
00590 plugin.read_bonds = read_mol2_bonds;
00591 plugin.read_next_timestep = read_mol2_timestep;
00592 plugin.close_file_read = close_mol2_read;
00593 plugin.open_file_write = open_mol2_write;
00594 plugin.write_structure = write_mol2_structure;
00595 plugin.write_timestep = write_mol2_timestep;
00596 plugin.close_file_write = close_mol2_write;
00597 plugin.write_bonds = write_mol2_bonds;
00598 return VMDPLUGIN_SUCCESS;
00599 }
00600
00601 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00602 (*cb)(v, (vmdplugin_t *)&plugin);
00603 return VMDPLUGIN_SUCCESS;
00604 }
00605
00606 VMDPLUGIN_API int VMDPLUGIN_fini() {
00607 return VMDPLUGIN_SUCCESS;
00608 }
00609