00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef READ_PDB_H
00019 #define READ_PDB_H
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024
00025 #define PDB_RECORD_LENGTH 80
00026 #define PDB_BUFFER_LENGTH 83
00027
00028 #define VMDUSECONECTRECORDS 1
00029
00030
00031 enum {
00032 PDB_HEADER, PDB_REMARK, PDB_ATOM, PDB_CONECT, PDB_UNKNOWN, PDB_END, PDB_EOF, PDB_CRYST1
00033 };
00034
00035
00036
00037
00038
00039 static int read_pdb_record(FILE *f, char *retStr) {
00040 int ch;
00041 char inbuf[PDB_BUFFER_LENGTH];
00042 int recType = PDB_UNKNOWN;
00043
00044
00045
00046
00047
00048
00049
00050
00051 if (inbuf != fgets(inbuf, PDB_RECORD_LENGTH + 2, f)) {
00052 retStr[0] = '\0';
00053 recType = PDB_EOF;
00054 } else {
00055 #if 0
00056
00057
00058
00059
00060 if (inbuf[strlen(inbuf)-1] == '\n')
00061 inbuf[strlen(inbuf)-1] = '\0';
00062 #endif
00063
00064
00065 if (!strncmp(inbuf, "ATOM ", 5) || !strncmp(inbuf, "HETATM", 6)) {
00066
00067
00068
00069
00070 recType = PDB_ATOM;
00071 } else if (!strncmp(inbuf, "CONECT", 6)) {
00072 recType = PDB_CONECT;
00073 } else if (!strncmp(inbuf, "REMARK", 6)) {
00074 recType = PDB_REMARK;
00075 } else if (!strncmp(inbuf, "CRYST1", 6)) {
00076 recType = PDB_CRYST1;
00077 } else if (!strncmp(inbuf, "HEADER", 6)) {
00078 recType = PDB_HEADER;
00079 } else if (!strncmp(inbuf, "END", 3)) {
00080
00081
00082
00083
00084 recType = PDB_END;
00085 }
00086
00087 #if 0
00088
00089 if (recType == PDB_ATOM ||
00090 recType == PDB_CONECT ||
00091 recType == PDB_REMARK ||
00092 recType == PDB_HEADER ||
00093 recType == PDB_CRYST1) {
00094 strcpy(retStr, inbuf);
00095 } else {
00096 retStr[0] = '\0';
00097 }
00098 #else
00099 strcpy(retStr, inbuf);
00100 #endif
00101 }
00102
00103
00104 ch = fgetc(f);
00105 if (ch != '\r')
00106 ungetc(ch, f);
00107
00108 return recType;
00109 }
00110
00111
00112
00113 static void get_pdb_cryst1(const char *record,
00114 float *alpha, float *beta, float *gamma,
00115 float *a, float *b, float *c) {
00116 char tmp[PDB_RECORD_LENGTH+3];
00117 char ch, *s;
00118 memset(tmp, 0, sizeof(tmp));
00119 strncpy(tmp, record, PDB_RECORD_LENGTH);
00120
00121 s = tmp+6 ; ch = tmp[15]; tmp[15] = 0;
00122 *a = (float) atof(s);
00123 s = tmp+15; *s = ch; ch = tmp[24]; tmp[24] = 0;
00124 *b = (float) atof(s);
00125 s = tmp+24; *s = ch; ch = tmp[33]; tmp[33] = 0;
00126 *c = (float) atof(s);
00127 s = tmp+33; *s = ch; ch = tmp[40]; tmp[40] = 0;
00128 *alpha = (float) atof(s);
00129 s = tmp+40; *s = ch; ch = tmp[47]; tmp[47] = 0;
00130 *beta = (float) atof(s);
00131 s = tmp+47; *s = ch; ch = tmp[54]; tmp[54] = 0;
00132 *gamma = (float) atof(s);
00133 }
00134
00135
00136
00137 static void get_pdb_coordinates(const char *record,
00138 float *x, float *y, float *z,
00139 float *occup, float *beta) {
00140 char numstr[50];
00141 memset(numstr, 0, sizeof(numstr));
00142
00143 if (x != NULL) {
00144 strncpy(numstr, record + 30, 8);
00145 *x = (float) atof(numstr);
00146 }
00147
00148 if (y != NULL) {
00149 strncpy(numstr+10, record + 38, 8);
00150 *y = (float) atof(numstr+10);
00151 }
00152
00153 if (z != NULL) {
00154 strncpy(numstr+20, record + 46, 8);
00155 *z = (float) atof(numstr+20);
00156 }
00157
00158 if (occup != NULL) {
00159 strncpy(numstr+30, record + 54, 6);
00160 *occup = (float) atof(numstr+30);
00161 }
00162
00163 if (beta != NULL) {
00164 strncpy(numstr+40, record + 60, 6);
00165 *beta = (float) atof(numstr+40);
00166 }
00167 }
00168
00169
00170
00171 static void adjust_pdb_field_string(char *field) {
00172 int i, len;
00173
00174 len = strlen(field);
00175 while (len > 0 && field[len-1] == ' ') {
00176 field[len-1] = '\0';
00177 len--;
00178 }
00179
00180 while (len > 0 && field[0] == ' ') {
00181 for (i=0; i < len; i++)
00182 field[i] = field[i+1];
00183 len--;
00184 }
00185 }
00186
00187 static void get_pdb_header(const char *record, char *pdbcode, char *date,
00188 char *classification) {
00189 if (date != NULL) {
00190 strncpy(date, record + 50, 9);
00191 date[9] = '\0';
00192 }
00193
00194 if (classification != NULL) {
00195 strncpy(classification, record + 10, 40);
00196 classification[40] = '\0';
00197 }
00198
00199 if (pdbcode != NULL) {
00200 strncpy(pdbcode, record + 62, 4);
00201 pdbcode[4] = '\0';
00202 adjust_pdb_field_string(pdbcode);
00203 }
00204 }
00205
00206
00207 static void get_pdb_conect(const char *record, int natoms, int *idxmap,
00208 int *maxbnum, int *nbonds, int **from, int **to) {
00209 int bondto[11], numbonds, i;
00210
00211 int reclen = strlen(record);
00212 for (numbonds=0, i=0; i<11; i++) {
00213 char bondstr[6];
00214 const int fieldwidth = 5;
00215 int start = 6 + i*fieldwidth;
00216 int end = start + fieldwidth;
00217
00218 if (end >= reclen)
00219 break;
00220
00221 memcpy(bondstr, record + start, fieldwidth);
00222 bondstr[5] = '\0';
00223 if (sscanf(bondstr, "%d", &bondto[numbonds]) < 0)
00224 break;
00225 numbonds++;
00226 }
00227
00228 for (i=0; i<numbonds; i++) {
00229
00230 if (bondto[i] > bondto[0]) {
00231 int newnbonds = *nbonds + 1;
00232
00233
00234 if (newnbonds >= *maxbnum) {
00235 int newmax;
00236 int *newfromlist, *newtolist;
00237 newmax = (newnbonds + 11) * 1.25;
00238
00239 newfromlist = (int *) realloc(*from, newmax * sizeof(int));
00240 newtolist = (int *) realloc(*to, newmax * sizeof(int));
00241
00242 if (newfromlist != NULL || newtolist != NULL) {
00243 *maxbnum = newmax;
00244 *from = newfromlist;
00245 *to = newtolist;
00246 } else {
00247 printf("readpdb) failed to allocate memory for bondlists\n");
00248 return;
00249 }
00250 }
00251
00252 *nbonds = newnbonds;
00253 (*from)[newnbonds-1] = idxmap[bondto[0]] + 1;
00254 (*to)[newnbonds-1] = idxmap[bondto[i]] + 1;
00255 }
00256 }
00257 }
00258
00259
00260
00261
00262
00263
00264 static void get_pdb_fields(const char *record, int reclength, int *serial,
00265 char *name, char *resname, char *chain,
00266 char *segname, char *resid, char *insertion,
00267 char *altloc, char *elementsymbol,
00268 float *x, float *y, float *z,
00269 float *occup, float *beta) {
00270 char serialbuf[6];
00271
00272
00273 strncpy(serialbuf, record + 6, 5);
00274 serialbuf[5] = '\0';
00275 *serial = 0;
00276 sscanf(serialbuf, "%5d", serial);
00277
00278
00279 strncpy(name, record + 12, 4);
00280 name[4] = '\0';
00281 adjust_pdb_field_string(name);
00282
00283
00284 strncpy(altloc, record + 16, 1);
00285 altloc[1] = '\0';
00286
00287
00288 strncpy(resname, record + 17, 4);
00289 resname[4] = '\0';
00290 adjust_pdb_field_string(resname);
00291
00292
00293 chain[0] = record[21];
00294 chain[1] = '\0';
00295
00296
00297 strncpy(resid, record + 22, 4);
00298 resid[4] = '\0';
00299 adjust_pdb_field_string(resid);
00300
00301
00302 insertion[0] = record[26];
00303 insertion[1] = '\0';
00304
00305
00306 strncpy(elementsymbol, record + 76, 2);
00307 elementsymbol[2] = '\0';
00308
00309
00310 get_pdb_coordinates(record, x, y, z, occup, beta);
00311
00312
00313 if (reclength >= 73) {
00314 strncpy(segname, record + 72, 4);
00315 segname[4] = '\0';
00316 adjust_pdb_field_string(segname);
00317 } else {
00318 segname[0] = '\0';
00319 }
00320 }
00321
00322
00323
00324 static int write_raw_pdb_record(FILE *fd, const char *recordname,
00325 int index,const char *atomname, const char *resname,int resid,
00326 const char *insertion, const char *altloc, const char *elementsymbol,
00327 float x, float y, float z, float occ, float beta,
00328 const char *chain, const char *segname) {
00329 int rc;
00330 char indexbuf[32];
00331 char residbuf[32];
00332 char altlocchar;
00333
00334
00335
00336
00337
00338
00339
00340
00341 if (index < 100000) {
00342 sprintf(indexbuf, "%5d", index);
00343 } else if (index < 1048576) {
00344 sprintf(indexbuf, "%05x", index);
00345 } else {
00346 sprintf(indexbuf, "*****");
00347 }
00348
00349 if (resid < 10000) {
00350 sprintf(residbuf, "%4d", resid);
00351 } else if (resid < 65536) {
00352 sprintf(residbuf, "%04x", resid);
00353 } else {
00354 sprintf(residbuf, "****");
00355 }
00356
00357 altlocchar = altloc[0];
00358 if (altlocchar == '\0') {
00359 altlocchar = ' ';
00360 }
00361
00362 rc = fprintf(fd,
00363 "%s%5s %4s%c%-4s%c%4s%c %8.3f%8.3f%8.3f%6.2f%6.2f %-4s%2s\n",
00364 recordname, indexbuf, atomname, altlocchar, resname, chain[0],
00365 residbuf, insertion[0], x, y, z, occ, beta, segname, elementsymbol);
00366
00367 return (rc > 0);
00368 }
00369
00370 #endif