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 #include "molfile_plugin.h"
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #define PQR_RECORD_LENGTH 80
00032
00033
00034 enum {PQR_REMARK, PQR_ATOM, PQR_UNKNOWN, PQR_EOF, PQR_ERROR};
00035
00036
00037
00038
00039
00040
00041 static int read_pqr_record(FILE *f, char *retStr) {
00042
00043 char inbuf[PQR_RECORD_LENGTH+2];
00044 int recType = PQR_UNKNOWN;
00045
00046
00047
00048
00049
00050
00051
00052
00053 if(inbuf != fgets(inbuf, PQR_RECORD_LENGTH+1, f)) {
00054 retStr[0] = '\0';
00055 if (feof(f)) {
00056 recType = PQR_EOF;
00057 }
00058 else {
00059 recType = PQR_ERROR;
00060 }
00061 }
00062 else {
00063
00064 if(inbuf[strlen(inbuf)-1] == '\n')
00065 inbuf[strlen(inbuf)-1] = '\0';
00066
00067 if (!strncmp(inbuf, "ATOM ", 6)) {
00068 strcpy(retStr,inbuf);
00069 recType = PQR_ATOM;
00070 }
00071 else {
00072 retStr[0] = '\0';
00073 recType = PQR_UNKNOWN;
00074 }
00075 }
00076
00077
00078 {
00079 int ch = fgetc(f);
00080 if (ch != '\r') {
00081 ungetc(ch, f);
00082 }
00083 }
00084
00085 return recType;
00086 }
00087
00088
00089
00090
00091 static int get_pqr_fields(char *record, char *name, char *resname, char *chain,
00092 char *segname, char *resid,
00093 float *x, float *y, float *z, float *charge, float *radius) {
00094
00095
00096
00097
00098
00099
00100 strncpy(name, record+12, 4); name[4] = 0;
00101 strncpy(resname, record+17, 4); resname[4] = 0;
00102 strncpy(chain, record+21, 1); chain[1] = 0;
00103 strncpy(resid, record+22, 4); resid[4] = 0;
00104
00105 segname[0] = 0;
00106
00107 if (sscanf(record+30, "%f%f%f%f%f", x, y, z, charge, radius) != 5) {
00108 return 1;
00109 }
00110
00111 return 0;
00112 }
00113
00114
00115
00116
00117 static int get_pqr_coordinates(char *record, float *x, float *y, float *z) {
00118
00119 if (sscanf(record, "ATOM%*7d %*4s%*4s%*5s %f%f%f%*f%*f",
00120 x, y, z) == 3) {
00121 return 0;
00122 }
00123
00124
00125 else {
00126 return 1;
00127 }
00128 }
00129
00130
00131
00132
00133 static float get_atom_radius(molfile_atom_t *atom) {
00134 char *name, *type;
00135 name = atom->name;
00136 type = atom->type;
00137
00138
00139 return 1.0;
00140 }
00141
00142
00143
00144
00145 static int write_pqr_atom(FILE *fd, int index, const molfile_atom_t *atom,
00146 float x, float y, float z) {
00147 int rc;
00148
00149 rc = fprintf(fd, "ATOM %5d %-4s %s %5d %8.3f%8.3f%8.3f %.3f %.3f\n",
00150 index, atom->name, atom->resname, atom->resid,
00151 x, y, z, atom->charge, atom->radius);
00152
00153 return (rc > 0);
00154 }
00155
00156
00157
00158
00159
00160
00161 typedef struct {
00162 FILE *fd;
00163 int natoms;
00164 molfile_atom_t *atomlist;
00165 } pqrdata;
00166
00167 static void *open_pqr_read(const char *filepath, const char *filetype,
00168 int *natoms) {
00169 FILE *fd;
00170 pqrdata *pqr;
00171 char pqr_record[PQR_RECORD_LENGTH+2];
00172 int record_type;
00173
00174 fd = fopen(filepath, "r");
00175 if (!fd)
00176 return NULL;
00177 pqr = (pqrdata *)malloc(sizeof(pqrdata));
00178 pqr->fd = fd;
00179
00180 *natoms=0;
00181 do {
00182 record_type = read_pqr_record(pqr->fd, pqr_record);
00183 if (record_type == PQR_ATOM)
00184 *natoms += 1;
00185 else if (record_type == PQR_ERROR) {
00186 fprintf(stderr, "Error reading PQR file after opening.\n");
00187 free(pqr);
00188 return NULL;
00189 }
00190
00191 } while (record_type != PQR_EOF);
00192
00193
00194 if (!*natoms) {
00195 fprintf(stderr, "PQR file '%s' contains no atoms.\n", filepath);
00196 free(pqr);
00197 return NULL;
00198 }
00199
00200 rewind(pqr->fd);
00201 pqr->natoms = *natoms;
00202 return pqr;
00203 }
00204
00205
00206
00207
00208 static int read_pqr_structure(void *mydata, int *optflags,
00209 molfile_atom_t *atoms) {
00210 pqrdata *pqr = (pqrdata *)mydata;
00211 molfile_atom_t *atom;
00212 char pqr_record[PQR_RECORD_LENGTH + 1];
00213 int i, record_type;
00214 char ridstr[8];
00215 float newpos;
00216 long fpos = ftell(pqr->fd);
00217
00218 *optflags = MOLFILE_CHARGE | MOLFILE_RADIUS;
00219
00220 i = 0;
00221 do {
00222 record_type = read_pqr_record(pqr->fd, pqr_record);
00223 if ( (record_type == PQR_EOF) && (i < pqr->natoms) ) {
00224 fprintf(stderr, "Unexpected end-of-file.\n");
00225 return MOLFILE_ERROR;
00226 }
00227 else if (record_type == PQR_ERROR) {
00228 fprintf(stderr, "Error reading atom coordinates.\n");
00229 return MOLFILE_ERROR;
00230 }
00231 else if (record_type == PQR_ATOM) {
00232 if (i >= pqr->natoms) {
00233 fprintf(stderr, "Too many atoms.\n");
00234 return MOLFILE_ERROR;
00235 }
00236 atom = atoms+i;
00237 get_pqr_fields(pqr_record, atom->name, atom->resname, atom->chain,
00238 atom->segid, ridstr,
00239 &newpos, &newpos, &newpos, &atom->charge, &atom->radius);
00240 atom->resid = atoi(ridstr);
00241 strcpy(atom->type, atom->name);
00242 i++;
00243 }
00244 else {
00245
00246 }
00247 } while(record_type != PQR_EOF);
00248
00249 fseek(pqr->fd, fpos, SEEK_SET);
00250
00251 return MOLFILE_SUCCESS;
00252 }
00253
00254
00255
00256
00257 static int read_pqr_timestep(void *v, int natoms, molfile_timestep_t *ts) {
00258 pqrdata *pqr = (pqrdata *)v;
00259 char pqr_record[PQR_RECORD_LENGTH+2];
00260 int record_type, i;
00261 float *x, *y, *z;
00262
00263 if (pqr->natoms == 0)
00264 return MOLFILE_ERROR;
00265 if (ts) {
00266 x = ts->coords;
00267 y = x+1;
00268 z = x+2;
00269 } else {
00270 x = y = z = 0;
00271 }
00272
00273 i = 0;
00274 do {
00275 record_type = read_pqr_record(pqr->fd, pqr_record);
00276 if ( (record_type == PQR_EOF) && (i < pqr->natoms) ) {
00277 fprintf(stderr, "Unexpected end-of-file.\n");
00278 return MOLFILE_ERROR;
00279 }
00280 else if (record_type == PQR_ERROR) {
00281 fprintf(stderr, "Error reading atom coordinates.\n");
00282 return MOLFILE_ERROR;
00283 }
00284 else if (record_type == PQR_ATOM) {
00285
00286 if (ts) {
00287 get_pqr_coordinates(pqr_record, x, y, z);
00288 x += 3;
00289 y += 3;
00290 z += 3;
00291 i++;
00292 }
00293 }
00294 else {
00295
00296 }
00297 } while(i < pqr->natoms);
00298
00299 return MOLFILE_SUCCESS;
00300 }
00301
00302 static void close_pqr_read(void *v) {
00303 pqrdata *pqr = (pqrdata *)v;
00304 if (pqr->fd) {
00305 fclose(pqr->fd);
00306 pqr->fd = 0;
00307 }
00308 free(pqr);
00309 }
00310
00311 static void *open_pqr_write(const char *path, const char *filetype,
00312 int natoms) {
00313 FILE *fd;
00314 pqrdata *pqr;
00315 fd = fopen(path, "w");
00316 if (!fd) {
00317 fprintf(stderr, "Unable to open file %s for writing\n", path);
00318 return NULL;
00319 }
00320
00321 pqr = (pqrdata *)malloc(sizeof(pqrdata));
00322 pqr->fd = fd;
00323 pqr->natoms = natoms;
00324 pqr->atomlist = NULL;
00325 return pqr;
00326 }
00327
00328 static int write_pqr_structure(void *v, int optflags,
00329 const molfile_atom_t *atoms) {
00330 int i;
00331 pqrdata *pqr = (pqrdata *)v;
00332 int natoms = pqr->natoms;
00333 pqr->atomlist = (molfile_atom_t *)malloc(natoms*sizeof(molfile_atom_t));
00334
00335 memcpy(pqr->atomlist, atoms, natoms*sizeof(molfile_atom_t));
00336
00337
00338 if (!(optflags & MOLFILE_CHARGE)) {
00339 for (i=0; i<natoms; i++) pqr->atomlist[i].charge = 0.0f;
00340 }
00341 if (!(optflags & MOLFILE_RADIUS)) {
00342 for (i=0; i<natoms; i++) pqr->atomlist[i].radius =
00343 get_atom_radius(&(pqr->atomlist[i]));
00344 }
00345
00346 return MOLFILE_SUCCESS;
00347 }
00348
00349 static int write_pqr_timestep(void *v, const molfile_timestep_t *ts) {
00350 pqrdata *pqr = (pqrdata *)v;
00351 const molfile_atom_t *atom;
00352 const float *pos;
00353 int i;
00354
00355 if (pqr->natoms == 0)
00356 return MOLFILE_SUCCESS;
00357
00358 atom = pqr->atomlist;
00359 pos = ts->coords;
00360 for (i=0; i<pqr->natoms; i++) {
00361 if (!write_pqr_atom(pqr->fd, i+1, atom, pos[0], pos[1], pos[2])) {
00362 fprintf(stderr,
00363 "PQR: Error encoutered writing atom %d; file may be incomplete.\n",
00364 i+1);
00365 return MOLFILE_ERROR;
00366 }
00367 atom++;
00368 pos += 3;
00369 }
00370
00371 return MOLFILE_SUCCESS;
00372 }
00373
00374 static void close_pqr_write(void *v) {
00375 pqrdata *pqr = (pqrdata *)v;
00376 fclose(pqr->fd);
00377 free(pqr->atomlist);
00378 free(pqr);
00379 }
00380
00381
00382
00383
00384
00385 static molfile_plugin_t plugin = {
00386 vmdplugin_ABIVERSION,
00387 MOLFILE_PLUGIN_TYPE,
00388 "pqr",
00389 "PQR",
00390 "Eamon Caddigan",
00391 0,
00392 1,
00393 VMDPLUGIN_THREADSAFE,
00394 "pqr",
00395 open_pqr_read,
00396 read_pqr_structure,
00397 0,
00398 read_pqr_timestep,
00399 close_pqr_read,
00400 open_pqr_write,
00401 write_pqr_structure,
00402 write_pqr_timestep,
00403 close_pqr_write
00404 };
00405
00406 VMDPLUGIN_API int VMDPLUGIN_init() {
00407 return VMDPLUGIN_SUCCESS;
00408 }
00409
00410 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00411 (*cb)(v, (vmdplugin_t *)&plugin);
00412 return VMDPLUGIN_SUCCESS;
00413 }
00414
00415 VMDPLUGIN_API int VMDPLUGIN_fini() {
00416 return VMDPLUGIN_SUCCESS;
00417 }
00418