GLYLIB  0.3.0b
writePDB.c
Go to the documentation of this file.
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 
 All Classes Files Functions Variables Typedefs Defines