GLYLIB
0.3.0b
|
00001 /* Author: Michael Tessier 00002 Extended and updated by BLFoley */ 00003 #include <mylib.h> 00004 #include <PDB.h> 00005 #include <gly_codeutils.h> 00006 #define TRUE 1 00007 #define FALSE 0 00008 00009 fileslurp get_assembly_PDB_ATOM_lines(assembly *A,char isource,int savei,char raltname,int xs) 00010 { 00011 int mi,ri,ai,ainit,rinit,ntot,Li,nModels,Mi,this_x,nAlt,iFM; 00012 fileslurp FA,*FM; 00013 char *aptr,*rptr,*tmp; 00014 /* allocate savei space if not -1 and if not already allocated */ 00015 if(savei!=-1) 00016 { 00017 for(mi=0;mi<A[0].nm;mi++) 00018 { 00019 for(ri=0;ri<A[0].m[mi][0].nr;ri++) 00020 { 00021 if(A[0].m[mi][0].r[ri].ni==0) 00022 { 00023 A[0].m[mi][0].r[ri].ni=savei+1; 00024 A[0].m[mi][0].r[ri].i=(int*)calloc(savei+1,sizeof(int)); 00025 } 00026 else if (A[0].m[mi][0].r[ri].ni<savei+1) 00027 { 00028 A[0].m[mi][0].r[ri].ni=savei+1; 00029 A[0].m[mi][0].r[ri].i=\ 00030 (int*)realloc(A[0].m[mi][0].r[ri].i,(savei+1)*sizeof(int)); 00031 } 00032 for(ai=0;ai<A[0].m[mi][0].r[ri].na;ai++) 00033 { 00034 if(A[0].m[mi][0].r[ri].a[ai].ni==0) 00035 { 00036 A[0].m[mi][0].r[ri].a[ai].ni=savei+1; 00037 A[0].m[mi][0].r[ri].a[ai].i=(int*)calloc(savei+1,sizeof(int)); 00038 } 00039 else if (A[0].m[mi][0].r[ri].a[ai].ni<savei+1) 00040 { 00041 A[0].m[mi][0].r[ri].a[ai].ni=savei+1; 00042 A[0].m[mi][0].r[ri].a[ai].i=\ 00043 (int*)realloc(A[0].m[mi][0].r[ri].a[ai].i,(savei+1)*sizeof(int)); 00044 } 00045 } } } 00046 } 00047 00048 /* 00049 As a quick error check, see if the first residue's altname exists, if requested. 00050 */ 00051 if((tolower(raltname)=='y')&&(A[0].m[0][0].r[0].altname==NULL)) 00052 { 00053 printf("\nYou requested an assembly PDB print using alternate residue names.\n"); 00054 printf("But the first one has not been set. Not checking others.\n"); 00055 printf("This might cause trouble. (in get_assembly_ATOM_lines)\n"); 00056 } 00057 00058 /* 00059 Figure out how many slurps we will need based on the coords to be printed. 00060 */ 00061 if(xs==-3) /* print main plus all alternates */ 00062 { 00063 nAlt=A[0].m[0][0].r[0].a[0].nalt; /* for error-checking, grab number alts for first atom */ 00064 nModels=nAlt+1; 00065 this_x=-1; 00066 } 00067 else if (xs==-2) /* print only all alternates */ 00068 { 00069 nAlt=A[0].m[0][0].r[0].a[0].nalt; /* for error-checking, grab number alts for first atom */ 00070 nModels=nAlt; 00071 this_x=0; 00072 } 00073 else if (xs==-1) /* print only the main set of coordinates */ 00074 { 00075 nAlt=0; 00076 nModels=1; 00077 this_x=-1; 00078 } 00079 else /* print only one alternate set */ 00080 { 00081 nAlt=xs+1; 00082 nModels=1; 00083 this_x=xs; 00084 } 00085 00086 FM=(fileslurp*)calloc((nModels*A[0].nm),sizeof(fileslurp)); 00087 if(tolower(isource)=='n') ainit=rinit=-1; 00088 else ainit=rinit=1; 00089 00090 ntot=0; /* the total number of lines returned by get_molecule_PDB_ATOM_lines */ 00091 00092 for(Mi=0;Mi<nModels;Mi++) 00093 { 00094 iFM=Mi*A[0].nm; 00095 for(mi=0;mi<A[0].nm;mi++) 00096 { 00097 /* 00098 Make a little sanity check for presence of coordinates, if needed 00099 */ 00100 if(nAlt>0) 00101 { 00102 if(A[0].m[mi][0].r[0].a[0].nalt<nAlt) /* if the first atom doesn't have enough alt coords */ 00103 {mywhine("In get_assembly_PDB_ATOM_lines, requested coordinates do not appear to exist.");} 00104 } 00105 /* 00106 Grab the ATOM lines for each molecule 00107 */ 00108 FM[iFM]=get_molecule_PDB_ATOM_lines(A[0].m[mi],rinit,ainit,savei,savei,'n',raltname,this_x); 00109 if(FM[iFM].n==0){mywhine("no lines found in FM from get_assembly_PDB_ATOM_lines ");} 00110 ntot+=FM[iFM].n; 00111 /* 00112 get new values for rinit and ainit if not using 'n' 00113 must use L[n-2] because the last one is always "TER" 00114 */ 00115 if(ainit!=-1) 00116 { 00117 aptr=&FM[iFM].L[FM[iFM].n-2][6]; /* serial begins index 6 (column 7) */ 00118 tmp=strdup(aptr); /* 5 chars */ 00119 tmp[6]='\0'; 00120 sscanf(tmp,"%d",&ainit); 00121 tmp=NULL; 00122 ainit++; 00123 rptr=&FM[iFM].L[FM[iFM].n-2][22]; /* resSeq begins index 22 (column 23) */ 00124 tmp=strdup(rptr); 00125 tmp[5]='\0'; 00126 sscanf(tmp,"%d",&rinit); 00127 tmp=NULL; 00128 rinit++; 00129 } 00130 iFM++; 00131 } /* close loop over number of molecules */ 00132 if(ainit!=-1) { ainit=rinit=1; } 00133 this_x++; 00134 } /* close loop over number of models */ 00135 /* 00136 Set up the space for the whole assembly's collected lines 00137 */ 00138 if(nModels>1) {ntot += nModels*2;} /* for MODEL and ENDMDL lines */ 00139 FA.n=ntot; 00140 FA.L=(char**)calloc(FA.n,sizeof(char*)); 00141 Li=0; /* used here to be the total number of lines */ 00142 for(Mi=0;Mi<nModels;Mi++) 00143 { 00144 iFM=Mi*A[0].nm; 00145 if(nModels>1) 00146 { 00147 FA.L[Li]=(char*)calloc(16,sizeof(char)); 00148 sprintf(FA.L[Li],"MODEL %4d\n",Mi+1); 00149 Li++; 00150 } 00151 for(mi=0;mi<A[0].nm;mi++) 00152 { 00153 for(ai=0;ai<FM[iFM].n;ai++) 00154 { 00155 FA.L[Li]=strdup(FM[iFM].L[ai]); 00156 Li++; 00157 } 00158 deallocateFileslurp(&FM[iFM]); 00159 iFM++; 00160 } 00161 if(nModels>1) 00162 { 00163 FA.L[Li]=(char*)calloc(8,sizeof(char)); 00164 sprintf(FA.L[Li],"ENDMDL\n"); 00165 Li++; 00166 } 00167 } /* close loop over number of models */ 00168 free(FM); 00169 00170 return FA; 00171 } 00172 00173 fileslurp get_ensemble_PDB_ATOM_lines(ensemble *E,char isource,int savei,char raltname,int xs) 00174 { 00175 int mi,ri,ai,ainit,rinit,ntot,Li,nModels,Mi,this_x,nAlt,iFM; 00176 fileslurp FE,*FM; 00177 char *aptr,*rptr,*tmp; 00178 /* allocate savei space if not -1 and if not already allocated */ 00179 if(savei!=-1) 00180 { 00181 for(mi=0;mi<E[0].nm;mi++) 00182 { 00183 for(ri=0;ri<E[0].m[mi].nr;ri++) 00184 { 00185 if(E[0].m[mi].r[ri].ni==0) 00186 { 00187 E[0].m[mi].r[ri].ni=savei+1; 00188 E[0].m[mi].r[ri].i=(int*)calloc(savei+1,sizeof(int)); 00189 } 00190 else if (E[0].m[mi].r[ri].ni<savei+1) 00191 { 00192 E[0].m[mi].r[ri].ni=savei+1; 00193 E[0].m[mi].r[ri].i=\ 00194 (int*)realloc(E[0].m[mi].r[ri].i,(savei+1)*sizeof(int)); 00195 } 00196 for(ai=0;ai<E[0].m[mi].r[ri].na;ai++) 00197 { 00198 if(E[0].m[mi].r[ri].a[ai].ni==0) 00199 { 00200 E[0].m[mi].r[ri].a[ai].ni=savei+1; 00201 E[0].m[mi].r[ri].a[ai].i=(int*)calloc(savei+1,sizeof(int)); 00202 } 00203 else if (E[0].m[mi].r[ri].a[ai].ni<savei+1) 00204 { 00205 E[0].m[mi].r[ri].a[ai].ni=savei+1; 00206 E[0].m[mi].r[ri].a[ai].i=\ 00207 (int*)realloc(E[0].m[mi].r[ri].a[ai].i,(savei+1)*sizeof(int)); 00208 } 00209 } } } 00210 } 00211 /* 00212 As a quick error check, see if the first residue's altname exists, if requested. 00213 */ 00214 if((tolower(raltname)=='y')&&(E[0].m[0].r[0].altname==NULL)) 00215 { 00216 printf("\nYou requested an assembly PDB print using alternate residue names.\n"); 00217 printf("But the first one has not been set. Not checking others.\n"); 00218 printf("This might cause trouble. (in get_ensemble_ATOM_lines)\n"); 00219 } 00220 00221 /* 00222 Figure out how many slurps we will need based on the coords to be printed. 00223 */ 00224 if(xs==-3) /* print main plus all alternates */ 00225 { 00226 nAlt=E[0].m[0].r[0].a[0].nalt; /* for error-checking, grab number alts for first atom */ 00227 nModels=nAlt+1; 00228 this_x=-1; 00229 } 00230 else if (xs==-2) /* print only all alternates */ 00231 { 00232 nAlt=E[0].m[0].r[0].a[0].nalt; /* for error-checking, grab number alts for first atom */ 00233 nModels=nAlt; 00234 this_x=0; 00235 } 00236 else if (xs==-1) /* print only the main set of coordinates */ 00237 { 00238 nAlt=0; 00239 nModels=1; 00240 this_x=-1; 00241 } 00242 else /* print only one alternate set */ 00243 { 00244 nAlt=xs+1; 00245 nModels=1; 00246 this_x=xs; 00247 } 00248 00249 FM=(fileslurp*)calloc((nModels*E[0].nm),sizeof(fileslurp)); 00250 if(tolower(isource)=='n') ainit=rinit=-1; 00251 else ainit=rinit=1; 00252 00253 ntot=0; /* the total number of lines returned by get_molecule_PDB_ATOM_lines */ 00254 00255 for(Mi=0;Mi<nModels;Mi++) 00256 { 00257 iFM=Mi*E[0].nm; 00258 for(mi=0;mi<E[0].nm;mi++) 00259 { 00260 /* 00261 Make a little sanity check for presence of coordinates, if needed 00262 */ 00263 if(nAlt>0) 00264 { 00265 if(E[0].m[mi].r[0].a[0].nalt<nAlt) /* if the first atom doesn't have enough alt coords */ 00266 {mywhine("In get_assembly_PDB_ATOM_lines, requested coordinates do not appear to exist.");} 00267 } 00268 /* 00269 Grab the ATOM lines for each molecule 00270 */ 00271 FM[iFM]=get_molecule_PDB_ATOM_lines(&E[0].m[mi],rinit,ainit,savei,savei,'n',raltname,this_x); 00272 if(FM[iFM].n==0){mywhine("no lines found in FM from get_ensemble_PDB_ATOM_lines ");} 00273 ntot+=FM[iFM].n; 00274 /* 00275 get new values for rinit and ainit if not using 'n' 00276 must use L[n-2] because the last one is always "TER" 00277 */ 00278 if(ainit!=-1){ 00279 aptr=&FM[iFM].L[FM[iFM].n-2][6]; /* serial begins index 6 (column 7) */ 00280 tmp=strdup(aptr); 00281 tmp[6]='\0'; 00282 sscanf(tmp,"%d",&ainit); 00283 tmp=NULL; 00284 ainit++; 00285 } 00286 if(rinit!=-1){ 00287 rptr=&FM[iFM].L[FM[iFM].n-2][22]; /* resSeq begins index 22 (column 23) */ 00288 tmp=strdup(rptr); 00289 tmp[5]='\0'; 00290 sscanf(tmp,"%d",&rinit); 00291 tmp=NULL; 00292 rinit++; 00293 } 00294 iFM++; 00295 } /* close loop over number of molecules */ 00296 this_x++; 00297 } /* close loop over number of models */ 00298 /* 00299 Set up the space for the whole assembly's collected lines 00300 */ 00301 if(nModels>1) {ntot += nModels*2;} /* for MODEL and ENDMDL lines */ 00302 FE.n=ntot; 00303 /*printf("ntot is %d\n",ntot);*/ 00304 FE.L=(char**)calloc(FE.n,sizeof(char*)); 00305 Li=0; /* used here to be the total number of lines */ 00306 for(Mi=0;Mi<nModels;Mi++) 00307 { 00308 iFM=Mi*E[0].nm; 00309 if(nModels>1) 00310 { 00311 FE.L[Li]=(char*)calloc(16,sizeof(char)); 00312 sprintf(FE.L[Li],"MODEL %4d\n",Mi+1); 00313 Li++; 00314 } 00315 for(mi=0;mi<E[0].nm;mi++) 00316 { 00317 for(ai=0;ai<FM[iFM].n;ai++) 00318 { 00319 FE.L[Li]=strdup(FM[iFM].L[ai]); 00320 Li++; 00321 } 00322 deallocateFileslurp(&FM[iFM]); 00323 iFM++; 00324 } 00325 if(nModels>1) 00326 { 00327 FE.L[Li]=(char*)calloc(8,sizeof(char)); 00328 sprintf(FE.L[Li],"ENDMDL\n"); 00329 Li++; 00330 } 00331 } /* close loop over number of models */ 00332 free(FM); 00333 00334 return FE; 00335 } 00336 00337 00338 const char * 00339 get_PDB_line_for_ATOM(atom *a, residue *r, int ai, int ri, int asave, char raltname,int xs) 00340 { 00341 char *line, tmp[81]; 00342 int i,rhere=0,ahere=0; 00343 if((xs>=0)&&(a[0].xa==NULL)) 00344 {mywhine("In get_PDB_line_for_ATOM, set alternate coordinate, but a.xa is NULL.");} 00345 line=(char*)calloc(82,sizeof(char)); /* 80 cols plus newline and termination */ 00346 /* 00347 pdb_a[2].b[1].c[0] = 6; RECORD NAME (1-6) 00348 */ 00349 sprintf(line,"ATOM "); 00350 /* 00351 pdb_a[2].b[1].c[1] = 5; serial (7-11) 00352 00353 This gets saved to a[0].i[asave] as well for LINK and CONECT cards later 00354 a[0].i[asave] space must be preallocated. 00355 */ 00356 if(ai==-1) ahere=a[0].n; 00357 else ahere=ai; 00358 if(ahere>99999){mywhine("Can not have atom serial > 99999 in pdb write utils.\n");} 00359 sprintf(tmp,"%5d",ahere); 00360 strcat(line,tmp); 00361 if(asave>=0){a[0].i[asave]=ahere;} 00362 /* 00363 pdb_a[2].b[1].c[2] = 1; N/A (12) 00364 */ 00365 strcat(line," "); 00366 /* 00367 pdb_a[2].b[1].c[3] = 4; name (13-16) 00368 00369 If there is an element (a.E) defined, use that to justify 00370 else, pad initially with a space unless (a) the name starts with 00371 a number or (b) the name is already 4 chars. 00372 00373 Ideally, figure out what element we have and set the beginning 00374 of it's designator at space 2, but... code that later... 00375 00376 In the meantime, the calling function will have to set the name 00377 to a pdb-appropriate value if this function can't do it. 00378 */ 00379 tmp[0]='\0'; 00380 if((strlen(a[0].N)>=4)||(isdigit(a[0].N[0]!=0))){ strcpy(tmp,a[0].N); } 00381 else 00382 { 00383 if(a[0].N!=NULL){ 00384 for(i=0;i<strlen(a[0].N);i++){ 00385 if(a[0].N[i]==a[0].N[0]){break;} 00386 } 00387 if(i<strlen(a[0].N)){ /* we have an element name here */ 00388 if(i==0){sprintf(tmp," %s",a[0].N);} 00389 else{strcpy(tmp,a[0].N);} 00390 } 00391 } 00392 else {sprintf(tmp," %s",a[0].N);} 00393 } 00394 00395 strcat(line,get_char_string(tmp,'l',4)); 00396 /* 00397 pdb_a[2].b[1].c[4] = 1; altLoc (17) 00398 00399 This is currently not supported in the library (20110410) 00400 */ 00401 strcat(line," "); 00402 /* 00403 pdb_a[2].b[1].c[5] = 3; resName (18-20) 00404 */ 00405 if(tolower(raltname)=='y') 00406 { 00407 if(r[0].altname!=NULL) strcat(line,get_char_string(r[0].altname,'l',3)); 00408 else strcat(line,"???"); 00409 } 00410 else{strcat(line,get_char_string(r[0].N,'l',3));} 00411 /* 00412 pdb_a[2].b[1].c[6] = 1; N/A (21) 00413 */ 00414 strcat(line," "); 00415 /* 00416 pdb_a[2].b[1].c[7] = 1; chainID (22) 00417 */ 00418 if((a[0].cID!='\0')&&(a[0].cID!=NULL)){strncat(line,a[0].cID,1);} 00419 else if((r[0].cID!='\0')&&(a[0].cID!=NULL)){strncat(line,r[0].cID,1);} 00420 else{strcat(line," ");} 00421 /* 00422 pdb_a[2].b[1].c[8] = 4; resSeq (23-26) 00423 */ 00424 if(ri==-1) rhere=r[0].n; 00425 else rhere=ri; 00426 if(rhere>9999){mywhine("Can not have residue serial > 9999 in pdb write utils.\n");} 00427 sprintf(tmp,"%4d",rhere); 00428 strcat(line,tmp); 00429 /* 00430 pdb_a[2].b[1].c[9] = 1; iCode (27) 00431 */ 00432 if(r[0].IC=='\0'){strcat(line," ");} 00433 else{strncat(line,r[0].IC,1);} 00434 /* 00435 pdb_a[2].b[1].c[10] = 3; N/A (28-30) 00436 */ 00437 strcat(line," "); 00438 /* 00439 pdb_a[2].b[1].c[11] = 8; x (31-38) 00440 */ 00441 if(xs==-1) strcat(line,get_float_string((double)a[0].x.i, 'r', 8, 3)); 00442 else strcat(line,get_float_string((double)a[0].xa[xs].i, 'r', 8, 3)); 00443 /* 00444 pdb_a[2].b[1].c[12] = 8; y (39-46) 00445 */ 00446 if(xs==-1) strcat(line,get_float_string((double)a[0].x.j, 'r', 8, 3)); 00447 else strcat(line,get_float_string((double)a[0].xa[xs].j, 'r', 8, 3)); 00448 /* 00449 pdb_a[2].b[1].c[13] = 8; z (47-54) 00450 */ 00451 if(xs==-1) strcat(line,get_float_string((double)a[0].x.k, 'r', 8, 3)); 00452 else strcat(line,get_float_string((double)a[0].xa[xs].k, 'r', 8, 3)); 00453 /* 00454 pdb_a[2].b[1].c[14] = 6; occupancy (55-60) 00455 00456 This currently doesn't have a computational equivalent. 00457 Perhaps it could represent an rmsd at standard ambient 00458 conditions or something. But, for now, we just assign a 00459 value of 1.00 so that certain other programs will accept 00460 the file. 00461 00462 */ 00463 strcat(line," 1.00"); 00464 /* 00465 pdb_a[2].b[1].c[15] = 6; tempFactor (61-66) 00466 00467 This currently doesn't have a computational equivalent. 00468 We just set it to zero. 00469 */ 00470 strcat(line," 0.00"); 00471 /* 00472 pdb_a[2].b[1].c[16] = 10; N/A (67-76) 00473 */ 00474 strcat(line," "); 00475 /* 00476 pdb_a[2].b[1].c[17] = 2; element 00477 */ 00478 /*printf("a[0].E is >>>%s<<<\n",a[0].E);*/ 00479 if(a[0].E==NULL){strcat(line," ");} 00480 else 00481 { 00482 if(strlen(a[0].E)==1) 00483 { 00484 strcat(line," "); 00485 strcat(line,a[0].E); 00486 } 00487 else{strncat(line,a[0].E,2);} 00488 } 00489 00490 /* 00491 pdb_a[2].b[1].c[18] = 2; charge 00492 00493 This has little meaning unless writing a "pdbq" (e.g., autodock) 00494 file, which breaks standard format. We just leave blank. 00495 */ 00496 /*printf("the line (%d chars long) is >>>%s<<<\n",strlen(line),line);*/ 00497 strcat(line," \n"); 00498 00499 if(strlen(line)>81){mywhine("something went wrong in get_PDB_line_for_ATOM");} 00500 00501 00502 return (const char *)line; 00503 } 00504 00505 void make_ATOM_HETATM(char *pdbline){ 00506 if(strlen(pdbline)<6){mywhine("pdbline too short in make_ATOM_HETATM");} 00507 if((pdbline[0]=='A')&&(pdbline[1]=='T')&&(pdbline[2]=='O')&&(pdbline[3]=='M')){ 00508 pdbline[0]='H'; 00509 pdbline[1]='E'; 00510 pdbline[2]='T'; 00511 pdbline[3]='A'; 00512 pdbline[4]='T'; 00513 pdbline[5]='M'; 00514 } 00515 return; 00516 } 00517 00518 /* 00519 ri and ainit are the numbers to use for the atom serial and 00520 residue resSeq. If set to -1, they will use the "n" values 00521 stored in the structure. 00522 */ 00523 fileslurp 00524 get_residue_PDB_ATOM_lines(residue *r,int ri,int ainit,int rsave, int asave,char raltname, int xs) 00525 { 00526 int i,aihere,rihere; 00527 fileslurp FR; 00528 FR.n=r[0].na; 00529 FR.L=(char**)calloc(FR.n,sizeof(char*)); 00530 if(ri==-1){rihere=r[0].n;} 00531 else{rihere=ri;} 00532 if(ainit>=0){aihere=ainit;} 00533 /* 00534 r[0].i[rsave] and each a[i].i[asave] should be pre-allocated 00535 unless they are set to -1, and they won't be used 00536 */ 00537 if(rsave>=0){r[0].i[rsave]=rihere;} 00538 for(i=0;i<FR.n;i++){ 00539 if(ainit==-1){aihere=r[0].a[i].n;} 00540 /* call get_PDB_line_for_ATOM for each atom */ 00541 FR.L[i]=strdup(get_PDB_line_for_ATOM(&r[0].a[i], r, aihere, rihere, asave, raltname, xs)); 00542 if(ainit>=0){aihere++;} 00543 } 00544 return FR; 00545 } 00546 00547 fileslurp 00548 get_molecule_PDB_ATOM_lines(molecule *mol,int rinit,int ainit,int rsave,int asave, 00549 char oneres, char raltname, int xs) 00550 { 00551 int i,j,b,aihere,rihere,*resconnects,ntot=0; 00552 residue *this_r; 00553 atom *this_a; 00554 fileslurp *FR,FM; 00555 char bondinfocomplete='y'; 00556 00557 FR=(fileslurp*)calloc(mol[0].nr,sizeof(fileslurp)); 00558 resconnects=(int*)calloc(mol[0].nr,sizeof(int)); 00559 00560 if(ainit==-1){aihere=-1;} 00561 else{aihere=ainit;} 00562 if(rinit>=0){rihere=rinit;} 00563 if(tolower(oneres)=='y') 00564 { 00565 if(rinit==-1){rihere=mol[0].r[0].n;} 00566 else{rihere=rinit;} 00567 rinit=-2; 00568 } 00569 00570 for(i=0;i<mol[0].nr;i++){ 00571 this_r=&mol[0].r[i]; 00572 if(rinit==-1){rihere=this_r[0].n;} 00573 FR[i]=get_residue_PDB_ATOM_lines(this_r,rihere,aihere,rsave,asave,raltname,xs); 00574 ntot+=FR[i].n; 00575 if(ainit>=0){aihere+=this_r[0].na;} 00576 for(j=0;j<this_r[0].na;j++){ 00577 this_a=&this_r[0].a[j]; 00578 if((this_r[0].na>1)&&(this_a[0].nmb==0)){bondinfocomplete='n';} 00579 for(b=0;b<this_a[0].nmb;b++){ 00580 if(this_a[0].mb[b].s.r!=this_a[0].mb[b].t.r){ 00581 resconnects[i]++; 00582 } 00583 } 00584 } 00585 if(rinit>=0){rihere++;} 00586 } 00587 00588 /* 00589 Until the residue-level connection tree gets set, there is no foolproof 00590 or elegant way to do this next bit. In fact, until the PDB folks adopt 00591 an official "end of branch" card, there isn't even a legitimate way to 00592 do it. The following assumes the first residue is the connection tree 00593 start point -- that is, if there are two+ connections to other residues, 00594 then there is a branch. All other residues are branch points if they 00595 have three or more connections to other residues. 00596 */ 00597 if(bondinfocomplete=='n') 00598 { 00599 //printf("\nBonding info not complete or not present in write PDB utils.\n"); 00600 //printf("\tCannot set LINK and CONECT cards or TER cards within molecules:\n"); 00601 } 00602 /* find the number of TER cards */ 00603 b=0; /* the number of TER cards needed */ 00604 if(resconnects[0]!=1){b++;} 00605 for(i=1;i<mol[0].nr;i++) 00606 { if(resconnects[i]!=2){ b++; } } 00607 //b++; /* for the final TER card */ 00608 FM.n=ntot+b; 00609 FM.L=(char**)calloc(FM.n,sizeof(char*)); 00610 b=0; /* now, it's the total number of lines */ 00611 for(i=0;i<mol[0].nr;i++) 00612 { 00613 for(j=0;j<FR[i].n;j++) 00614 { 00615 FM.L[b]=strdup(FR[i].L[j]); 00616 b++; 00617 } 00618 if(i==0) 00619 { 00620 if(resconnects[0]!=1) 00621 { 00622 FM.L[b]=strdup("TER \n"); 00623 b++; 00624 } 00625 } 00626 else 00627 { 00628 if(resconnects[i]!=2) 00629 { 00630 FM.L[b]=strdup("TER \n"); 00631 b++; 00632 } 00633 } 00634 } 00635 if(b>(FM.n)){mywhine("something went wrong in get_molecule_PDB_ATOM_lines");} 00636 //FM.L[b]=strdup("TER \n"); 00637 00638 return FM; 00639 } 00640 00641 00642 00643 00644 void outputMolPDB(molecule* mol, char* filename) 00645 { 00646 int i; 00647 FILE *file; 00648 fileslurp FM; 00649 FM=get_molecule_PDB_ATOM_lines(mol,1,1,-1,-1,'n','n',-1); 00650 if(FM.n==0){mywhine("no lines found in FM from outputMolPDB");} 00651 file = myfopen(filename,"w"); 00652 for(i=0;i<FM.n;i++) 00653 { 00654 if(FM.L[i]==NULL){mywhine("found null line in FM from outputMolPDB");} 00655 if(strncmp("TER",FM.L[i],3)!=0) 00656 { 00657 fprintf(file,"%s",FM.L[i]); 00658 } 00659 } 00660 fclose(file); 00661 } 00662 00663 00664 void outputAsmblPDB(assembly* asmbl, char* filename) 00665 { 00666 int i,mi,rinit=0,ainit=0; 00667 FILE* file; 00668 char *tmp,*rptr,*aptr; 00669 fileslurp *FM; 00670 FM=(fileslurp*)calloc(asmbl[0].nm,sizeof(fileslurp)); 00671 rinit=ainit=1; 00672 for(mi=0;mi<asmbl[0].nm;mi++) 00673 { 00674 FM[mi]=get_molecule_PDB_ATOM_lines(asmbl[0].m[mi],rinit,ainit,-1,-1,'n','n',-1); 00675 if(FM[mi].n==0){mywhine("no lines found in FM from outputAsmblPDB");} 00676 /* 00677 get new values for rinit and ainit 00678 must use L[n-2] because the last one is always "TER" 00679 */ 00680 aptr=&FM[mi].L[FM[mi].n-2][6]; /* serial begins index 6 (column 7) */ 00681 tmp=strdup(aptr); 00682 tmp[6]='\0'; 00683 sscanf(tmp,"%d",&ainit); 00684 ainit++; 00685 free(tmp); 00686 rptr=&FM[mi].L[FM[mi].n-2][22]; /* resSeq begins index 22 (column 23) */ 00687 tmp=strdup(rptr); 00688 tmp[5]='\0'; 00689 sscanf(tmp,"%d",&rinit); 00690 rinit++; 00691 free(tmp); 00692 } 00693 file = myfopen(filename,"w"); 00694 for(mi=0;mi<asmbl[0].nm;mi++) 00695 { 00696 for(i=0;i<FM[mi].n;i++) 00697 { 00698 if(FM[mi].L[i]==NULL){mywhine("found null line in FM from outputAsmblPDB");} 00699 if(strncmp("TER ",FM[mi].L[i],6)!=0) 00700 { 00701 fprintf(file,"%s",FM[mi].L[i]); 00702 } 00703 } 00704 fprintf(file,"TER \n"); 00705 deallocateFileslurp(&FM[mi]); 00706 } 00707 free(FM); 00708 fclose(file); 00709 } 00710