GLYLIB  0.3.0b
bonding_utilities.c
Go to the documentation of this file.
00001 /** \file bonding_utilities.c
00002 * \addtogroup BONDING
00003 *   Purpose:  Functions associated with bonding. 
00004 *   Begin 20110417 BLFoley
00005 *
00006 *   Return values for follow functions:
00007 *        0 : Made it all the way to the end.  All ok.
00008 *       -1 : Made it to an appropriate end in the middle.  Don't continue.
00009 *       -2 : Something else happened, but probably is ok.
00010 * 
00011 */
00012 #include <mylib.h>
00013 #include <molecules.h>
00014 
00015 /*
00016     This function sets molbonds at the residue level (r.rb).
00017 */
00018 void set_molecule_residue_molbonds(molecule *m)
00019 {
00020 int ri,ai,bi,this_b;
00021 
00022 for(ri=0;ri<m[0].nr;ri++)
00023     {
00024     /*
00025     Count the number of interresidue bonds.
00026     */
00027     m[0].r[ri].nrb=0;
00028     for(ai=0;ai<m[0].r[ri].na;ai++)
00029         {
00030         for(bi=0;bi<m[0].r[ri].a[ai].nmb;bi++)
00031             {
00032             if(m[0].r[ri].a[ai].mb[bi].s.r!=m[0].r[ri].a[ai].mb[bi].t.r) m[0].r[ri].nrb++;
00033             }
00034         }
00035     m[0].r[ri].rb=(molbond*)calloc(m[0].r[ri].nrb,sizeof(molbond));
00036     this_b=0;
00037     for(ai=0;ai<m[0].r[ri].na;ai++)
00038         {
00039 /*printf("This atom is %s\n",m[0].r[ri].a[ai].N);*/
00040         for(bi=0;bi<m[0].r[ri].a[ai].nmb;bi++)
00041             {
00042 /*printf("\tm[0].r[%d].a[%d].mb[%d].s.r = %d\n",ri,ai,bi,m[0].r[ri].a[ai].mb[bi].s.r);*/
00043 /*printf("\tm[0].r[%d].a[%d].mb[%d].t.r = %d\n",ri,ai,bi,m[0].r[ri].a[ai].mb[bi].t.r);*/
00044             if(m[0].r[ri].a[ai].mb[bi].s.r!=m[0].r[ri].a[ai].mb[bi].t.r)
00045                 {
00046                 m[0].r[ri].rb[this_b]=m[0].r[ri].a[ai].mb[bi];
00047 /*printf("\t this_b is %d\n",this_b);*/
00048 /*printf("\tfound molbond for %s from %d-%d-%d-%d to %d-%d-%d-%d\n",m[0].r[ri].N,\
00049 m[0].r[ri].a[ai].mb[bi].s.i,m[0].r[ri].a[ai].mb[bi].s.m,m[0].r[ri].a[ai].mb[bi].s.r,m[0].r[ri].a[ai].mb[bi].s.a,\
00050 m[0].r[ri].a[ai].mb[bi].t.i,m[0].r[ri].a[ai].mb[bi].t.m,m[0].r[ri].a[ai].mb[bi].t.r,m[0].r[ri].a[ai].mb[bi].t.a);*/
00051 /*printf("\tsetting it to residue level as %d-%d-%d-%d to %d-%d-%d-%d\n",\
00052 m[0].r[ri].rb[this_b].s.i,m[0].r[ri].rb[this_b].s.m,m[0].r[ri].rb[this_b].s.r,m[0].r[ri].rb[this_b].s.a,\
00053 m[0].r[ri].rb[this_b].t.i,m[0].r[ri].rb[this_b].t.m,m[0].r[ri].rb[this_b].t.r,m[0].r[ri].rb[this_b].t.a);*/
00054                 this_b++;
00055 
00056                 }
00057             }
00058         if(this_b>m[0].r[ri].nrb){mywhine("this_b>m[0].r[ri].nrb in set_molecule_residue_molbonds.");}
00059         }
00060     }
00061 
00062 return;
00063 }
00064 
00065 /*
00066     The  next two functions set the connection tree (m.rT) at the
00067         residue level (sets bonding between residues).  It uses r.rb
00068         so see also set_molecule_residue_molbonds().
00069 */
00070 void set_molecule_residue_nodes_from_bonds(molecule *m)
00071 {
00072 int ri,finished;
00073 char ensisame='y';
00074 m[0].rT=(residue_node*)calloc(m[0].nr,sizeof(residue_node));
00075 for(ri=0;ri<m[0].nr;ri++) 
00076     { 
00077     m[0].r[ri].mTi=-ri-1;
00078     m[0].rT[ri].isorigin='N';
00079     m[0].rT[ri].ID=copy_moli_to_ensi(m[0].r[ri].moli);
00080     m[0].rT[ri].ID.i=ri;
00081     if(ri>0)
00082         {
00083         ensisame=is_consistent_ensi_ensi(m[0].rT[ri].ID,m[0].rT[ri-1].ID);
00084         if(ensisame!='n')
00085             {
00086             mywhine("The residue molindexes are not unique in set_molecule_residue_nodes_from_bonds.\n");
00087             }
00088         }
00089     }
00090 if(m[0].nr==1) 
00091     {
00092     m[0].r[0].mTi=0;
00093     return;
00094     }
00095 m[0].rT[0].isorigin='Y';
00096 finished = follow_molecule_residue_nodes_from_bonds(m, 0, &m[0].r[0]);
00097 return;
00098 }
00099 int follow_molecule_residue_nodes_from_bonds(molecule *m, int iTree, residue *r)
00100 {
00101 char is_incoming='n';
00102 int bi,ni,oi,finished=0;
00103 residue *rt;
00104 /* This function doesn't choose where to start.  It just follows. */
00105 
00106 /* And, the value of mTi should be negative */
00107 if(r[0].mTi>=0){mywhine("unexpected init of r[0].mTi in follow_molecule_residue_nodes_from_bonds.");}
00108 
00109 /* 
00110 0.  If this is not the end of a list, declare space for outgoing bonds 
00111 */
00112 if(m[0].rT[iTree].nmbi<0)
00113   {
00114   mywhine("Unexpected init of rT[].nmbi in follow_molecule_residue_nodes_from_bonds.");
00115   }
00116 m[0].rT[iTree].nmbo=r[0].nrb-m[0].rT[iTree].nmbi;
00117 /* 
00118     If this is the end of a list, go find any unseen or bail.
00119 */
00120 if(m[0].rT[iTree].nmbo<=0)
00121     {
00122     r[0].mTi=-(r[0].mTi+1);
00123     for(ni=0;ni<m[0].nr;ni++)
00124         {
00125         if(m[0].r[ni].mTi<0) 
00126            { 
00127            finished = follow_molecule_residue_nodes_from_bonds(m,ni,&m[0].r[ni]);
00128            }
00129         if(finished==-1) break;
00130         }
00131     if (finished == -1) { return -1;}
00132     if (ni==m[0].nr) { return -1;}
00133     else { return -2;}
00134     }
00135 
00136 m[0].rT[iTree].mbo=(molbond**)calloc(m[0].rT[iTree].nmbo,sizeof(molbond*));
00137 for(oi=0;oi<m[0].rT[iTree].nmbo;oi++)
00138     {
00139     m[0].rT[iTree].mbo[oi]=(molbond*)calloc(1,sizeof(molbond));
00140     }
00141 
00142 /*
00143 1.  Set each bond that is not an incoming bond as an outgoing bond 
00144 */
00145 oi=0;
00146 for(bi=0;bi<r[0].nrb;bi++)
00147     {
00148     /*
00149     If the two atoms are not part of the same molecule, complain, and don't bother.
00150     */
00151     if(r[0].rb[bi].s.m!=r[0].rb[bi].t.m) 
00152         {
00153         printf("Found bond between two molecules in follow_molecule_residue_nodes_from_bonds.\n");
00154         printf("Ignoring that bond.\n");
00155         m[0].rT[iTree].nmbo--;
00156         continue;
00157         }
00158     /*
00159     Check to see if the current bond is one of the incoming bonds.
00160     */
00161     is_incoming='n';
00162     for(ni=0;ni<m[0].rT[iTree].nmbi;ni++)
00163         { 
00164         if(is_consistent_molbond_molbond_inverse(m[0].rT[iTree].mbi[ni][0],r[0].rb[bi])!='n') is_incoming='y';
00165         }
00166     /*
00167     If not, then set this as outgoing.
00168     */
00169     if(is_incoming=='n') 
00170         {
00171         m[0].rT[iTree].mbo[oi][0]=r[0].rb[bi];
00172         oi++;
00173         }
00174     if(oi>m[0].rT[iTree].nmbo){mywhine("overstepped outgoing bonds in follow_molecule_residue_nodes_from_bonds.");}
00175     }
00176 
00177 /* 
00178 2.  Set the current atom's state as seen.  Assumes a.rTi is initialized negative. 
00179 */
00180 r[0].mTi = -(r[0].mTi + 1); /* make positive and add one*/
00181 
00182 /*
00183 3.  Identify the current atom as incoming to each outgoing atom. 
00184 */
00185 for(oi=0;oi<m[0].rT[iTree].nmbo;oi++)
00186     {
00187     /* 
00188     get target residue
00189     */
00190     rt=&m[0].r[m[0].rT[iTree].mbo[oi][0].t.r]; 
00191     /* 
00192     record location in contree 
00193     */
00194     if(rt[0].mTi>=0) 
00195         {
00196         printf("\nTarget residue mTi is nonnegative in follow_molecule_residue_nodes_from_bonds.\n");
00197         printf("This might be a problem.\n");
00198         bi=rt[0].mTi;
00199         } 
00200     else{bi=-(rt[0].mTi+1);}
00201     m[0].rT[iTree].mbo[oi][0].i=bi;
00202     /* 
00203     identify current residue as incoming to the target atom
00204     */
00205     m[0].rT[bi].nmbi++; 
00206     if(m[0].rT[bi].nmbi==1) { m[0].rT[bi].mbi=(molbond**)calloc(1,sizeof(molbond*)); }
00207     else { m[0].rT[bi].mbi=(molbond**)realloc(m[0].rT[bi].mbi,m[0].rT[bi].nmbi*sizeof(molbond*));}
00208     m[0].rT[bi].mbi[m[0].rT[bi].nmbi-1]=(molbond*)calloc(1,sizeof(molbond));
00209     m[0].rT[bi].mbi[m[0].rT[bi].nmbi-1][0]=m[0].rT[iTree].mbo[oi][0];
00210     }
00211 
00212 /* 
00213 4.  Call each outgoing atom, in order, with this function 
00214 */
00215 for(oi=0;oi<m[0].rT[iTree].nmbo;oi++)
00216     { 
00217     /* 
00218     get target residue
00219     */
00220     rt=&m[0].r[m[0].rT[iTree].mbo[oi][0].t.r]; 
00221     /* 
00222     record location in contree 
00223     */
00224     if(rt[0].mTi>=0) { continue; } 
00225     else{bi=-(rt[0].mTi+1);}
00226     finished = follow_molecule_residue_nodes_from_bonds(m, bi, rt);
00227     }
00228 
00229 return finished;
00230 }
00231 
00232 
00233 void set_residue_atom_nodes_from_bonds(residue *r)
00234 {
00235 int ai,finished=0;
00236 char ensisame='y';
00237 r[0].aT=(atom_node*)calloc(r[0].na,sizeof(atom_node));
00238 for(ai=0;ai<r[0].na;ai++) 
00239     { 
00240     r[0].a[ai].rTi=-ai-1;
00241     r[0].aT[ai].isorigin='N';
00242     r[0].aT[ai].ID=copy_moli_to_ensi(r[0].a[ai].moli);
00243     r[0].aT[ai].ID.i=ai;
00244     if(ai>0)
00245         {
00246         ensisame=is_consistent_ensi_ensi(r[0].aT[ai].ID,r[0].aT[ai-1].ID);
00247         if(ensisame!='n')
00248             {
00249             mywhine("The atom molindexes are not unique in set_residue_atom_nodes_from_bonds.\n");
00250             }
00251         }
00252     }
00253 if(r[0].na==1) 
00254     {
00255     r[0].a[0].rTi=0;
00256     return;
00257     }
00258 r[0].aT[0].isorigin='Y';
00259 finished = follow_residue_atom_nodes_from_bonds(r, 0, &r[0].a[0]);
00260 return;
00261 }
00262 int follow_residue_atom_nodes_from_bonds(residue *r, int iTree, atom *a)
00263 {
00264 char is_incoming='n';
00265 int bi,ni,oi,finished=0;
00266 atom *at;
00267 /* 
00268     This function doesn't choose where to start.  It just follows.
00269  
00270     At this point, the value of rTi should be negative or something is wrong.
00271 */
00272 if(a[0].rTi>=0){mywhine("Unexpected init of a[0].rTi in follow_residue_atom_nodes_from_bonds.");}
00273 
00274 /* 
00275 0.  Declare space for outgoing bonds 
00276 */
00277 if(r[0].aT[iTree].ni<0){mywhine("Unexpected init of aT[].ni in follow_residue_atom_nodes_from_bonds.");}
00278 r[0].aT[iTree].no=a[0].nmb-r[0].aT[iTree].ni;
00279 /* 
00280     If this is the end of a list, go find any unseen or bail.
00281 */
00282 if(r[0].aT[iTree].no<=0)
00283     {
00284     a[0].rTi=-(a[0].rTi+1);
00285     for(ni=0;ni<r[0].na;ni++)
00286         {
00287         if(r[0].a[ni].rTi<0) 
00288            { 
00289            finished = follow_residue_atom_nodes_from_bonds(r,ni,&r[0].a[ni]);
00290            }
00291         if(finished==-1) break;
00292         }
00293     if (finished == -1) { return -1;}
00294     if (ni==r[0].na) { return -1;}
00295     else { return -2;}
00296     } 
00297 
00298 r[0].aT[iTree].o=(ensindex**)calloc(r[0].aT[iTree].no,sizeof(ensindex*));
00299 for(oi=0;oi<r[0].aT[iTree].no;oi++)
00300     {
00301     r[0].aT[iTree].o[oi]=(ensindex*)calloc(1,sizeof(ensindex));
00302     }
00303 
00304 /* 
00305 1.  Set each bond that is not an incoming bond as an outgoing bond 
00306 */
00307 oi=0;
00308 for(bi=0;bi<a[0].nmb;bi++)
00309     {
00310     /*
00311     If the two atoms are not part of the same residue, don't bother.
00312     */
00313     if(a[0].mb[bi].s.r!=a[0].mb[bi].t.r)
00314         {
00315         r[0].aT[iTree].no--;
00316         continue;
00317         }
00318     /*
00319     Check to see if the current bond is one of the incoming bonds.
00320     */
00321     is_incoming='n';
00322     for(ni=0;ni<r[0].aT[iTree].ni;ni++)
00323         {
00324         if(is_consistent_ensi_moli(r[0].aT[iTree].i[ni][0],a[0].mb[bi].t)!='n') is_incoming='y';
00325         }
00326     /*
00327     If not, then set this as outgoing.
00328     */
00329     if(is_incoming=='n') 
00330         {
00331         r[0].aT[iTree].o[oi][0]=copy_moli_to_ensi(a[0].mb[bi].t);
00332         oi++;
00333         }
00334     if(oi>r[0].aT[iTree].no){mywhine("overstepped outgoing bonds in follow_residue_atom_nodes_from_bonds.");}
00335     }
00336 
00337 /* 
00338 2.  Set the current atom's state as seen.  Assumes a.rTi is initialized negative. 
00339 */
00340 a[0].rTi = -(a[0].rTi + 1); /* make positive and add one*/
00341 
00342 /*
00343 3.  Identify the current atom as incoming to each outgoing atom. 
00344 */
00345 for(oi=0;oi<r[0].aT[iTree].no;oi++)
00346     {
00347     /* 
00348     get target atom 
00349     */
00350     at=&r[0].a[r[0].aT[iTree].o[oi][0].a]; 
00351     /* 
00352     record location in contree 
00353     */
00354     if(at[0].rTi>=0) { continue; } 
00355     else{bi=-(at[0].rTi+1);}
00356     r[0].aT[iTree].o[oi][0].i=bi;
00357     /* 
00358     identify current atom as incoming to the target atom
00359     */
00360     r[0].aT[bi].ni++; 
00361     if(r[0].aT[bi].ni==1) { r[0].aT[bi].i=(ensindex**)calloc(1,sizeof(ensindex*)); }
00362     else { r[0].aT[bi].i=(ensindex**)realloc(r[0].aT[bi].i,r[0].aT[bi].ni*sizeof(ensindex*));}
00363     r[0].aT[bi].i[r[0].aT[bi].ni-1]=(ensindex*)calloc(1,sizeof(ensindex));
00364     r[0].aT[bi].i[r[0].aT[bi].ni-1][0]=r[0].aT[iTree].ID;
00365     }
00366 
00367 /* 
00368 4.  Call each outgoing atom, in order, with this function 
00369 */
00370 for(oi=0;oi<r[0].aT[iTree].no;oi++)
00371     { 
00372     /* 
00373     get target atom 
00374     */
00375     at=&r[0].a[r[0].aT[iTree].o[oi][0].a]; 
00376     /* 
00377     record location in contree 
00378     */
00379     if(at[0].rTi>=0) { continue; } 
00380     else{bi=-(at[0].rTi+1);}
00381     finished = follow_residue_atom_nodes_from_bonds(r, bi, at);
00382     }
00383 
00384 return finished;
00385 }
00386 
00387 void set_molecule_atom_nodes_from_bonds(molecule *m)
00388 {
00389 int ri,ai,na=0,aai,finished=0;
00390 char ensisame='y'; 
00391 
00392 for(ri=0;ri<m[0].nr;ri++)
00393     {
00394     na+=m[0].r[ri].na;
00395     }
00396 if((m[0].na>0)&&(m[0].na!=na))
00397     {
00398     printf("\nWarning:  m.na != sum of all r.na in set_molecule_atom_nodes_from_bonds\n");
00399     printf("            Setting those to be equal.  Hope that\'s ok.\n");
00400     }
00401 m[0].na=na;
00402 m[0].aT=(atom_node*)calloc(m[0].na,sizeof(atom_node));
00403 aai=0;
00404 for(ri=0;ri<m[0].nr;ri++) 
00405     { 
00406 for(ai=0;ai<m[0].r[ri].na;ai++) 
00407     { 
00408     m[0].r[ri].a[ai].mTi=-aai-1;
00409     m[0].aT[aai].isorigin='N';
00410     m[0].aT[aai].ID=copy_moli_to_ensi(m[0].r[ri].a[ai].moli);
00411     m[0].aT[aai].ID.i=aai;
00412     /*  The following isn't a comprehensive check.  Just a spot-check. */
00413     if(aai>0)
00414         {
00415         ensisame=is_consistent_ensi_ensi(m[0].aT[aai].ID,m[0].aT[aai-1].ID);
00416         if(ensisame!='n')
00417             {
00418             mywhine("The atom molindexes are not unique in set_molecule_atom_nodes_from_bonds.\n");
00419             }
00420         }
00421     aai++;
00422     }
00423     }
00424 if(m[0].na==1) 
00425     {
00426     m[0].r[0].a[0].mTi=0;
00427     return;
00428     }
00429 m[0].aT[0].isorigin='Y';
00430 finished = follow_molecule_atom_nodes_from_bonds(m, 0, &m[0].r[0].a[0]);
00431 return;
00432 }
00433 
00434 int  follow_molecule_atom_nodes_from_bonds(molecule *m, int iTree, atom *a)
00435 {
00436 char is_incoming='n';
00437 int bi,ni,oi,finished=0;
00438 atom *at;
00439 /* 
00440     This function doesn't choose where to start.  It just follows. 
00441 
00442     At this point, the value of rTi should be negative 
00443 */
00444 if(a[0].mTi>=0){mywhine("unexpected init of a[0].mTi in follow_molecule_atom_nodes_from_bonds.");}
00445 
00446 /* 
00447 0.  Declare space for outgoing bonds 
00448 */
00449 if(m[0].aT[iTree].ni<0){mywhine("Unexpected init of aT[].ni in follow_molecule_atom_nodes_from_bonds");}
00450 m[0].aT[iTree].no=a[0].nmb-m[0].aT[iTree].ni;
00451 /* 
00452     If this is the end of a list, go find any unseen or bail.
00453 */
00454 
00455 if(m[0].aT[iTree].no<=0)
00456     {
00457     a[0].mTi=-(a[0].mTi+1);
00458     for(ni=0;ni<m[0].na;ni++)
00459         {
00460         at=&m[0].r[m[0].aT[ni].ID.r].a[m[0].aT[ni].ID.a];
00461         if(at[0].mTi<0) 
00462            { 
00463            finished = follow_molecule_atom_nodes_from_bonds(m,ni,at);
00464            }
00465         if(finished==-1) break;
00466         }
00467     if (finished == -1) { return -1;}
00468     if (ni==m[0].na) { return -1;}
00469     else { return -2;}
00470     } 
00471 
00472 m[0].aT[iTree].o=(ensindex**)calloc(m[0].aT[iTree].no,sizeof(ensindex*));
00473 for(oi=0;oi<m[0].aT[iTree].no;oi++)
00474     {
00475     m[0].aT[iTree].o[oi]=(ensindex*)calloc(1,sizeof(ensindex));
00476     }
00477 
00478 /* 
00479 1.  Set each bond that is not an incoming bond as an outgoing bond 
00480 */
00481 
00482 oi=0;
00483 for(bi=0;bi<a[0].nmb;bi++)
00484     {
00485     /*
00486     If the two atoms are not part of the same molecule, complain, and don't bother.
00487     */
00488     if(a[0].mb[bi].s.m!=a[0].mb[bi].t.m) 
00489         {
00490         m[0].aT[iTree].no--;
00491         continue;
00492         }
00493     /*
00494     Check to see if the current bond is one of the incoming bonds.
00495     */
00496     is_incoming='n';
00497     for(ni=0;ni<m[0].aT[iTree].ni;ni++)
00498         {
00499         if(is_consistent_ensi_moli(m[0].aT[iTree].i[ni][0],a[0].mb[bi].t)!='n') is_incoming='y';
00500         }
00501     /*
00502     If not, then set this as outgoing.
00503     */
00504     if(is_incoming=='n') 
00505         {
00506         m[0].aT[iTree].o[oi][0]=copy_moli_to_ensi(a[0].mb[bi].t);
00507         oi++;
00508         }
00509     if(oi>m[0].aT[iTree].no){mywhine("overstepped outgoing bonds in follow_molecule_atom_nodes_from_bonds.");}
00510     }
00511 
00512 /* 
00513 2.  Set the current atom's state as seen.  Assumes a.rTi is initialized negative. 
00514 */
00515 a[0].mTi = -(a[0].mTi + 1); /* make positive and add one*/
00516 
00517 /*
00518 3.  Identify the current atom as incoming to each outgoing atom. 
00519 */
00520 for(oi=0;oi<m[0].aT[iTree].no;oi++)
00521     {
00522     /* 
00523     get target atom 
00524     */
00525     at=&m[0].r[m[0].aT[iTree].o[oi][0].r].a[m[0].aT[iTree].o[oi][0].a]; 
00526     /* 
00527     record location in contree 
00528     */
00529     if(at[0].mTi>=0) { continue; } 
00530     else{bi=-(at[0].mTi+1);}
00531     m[0].aT[iTree].o[oi][0].i=bi;
00532     /* 
00533     identify current atom as incoming to the target atom
00534     */
00535     m[0].aT[bi].ni++; 
00536     if(m[0].aT[bi].ni==1) { m[0].aT[bi].i=(ensindex**)calloc(1,sizeof(ensindex*)); }
00537     else { m[0].aT[bi].i=(ensindex**)realloc(m[0].aT[bi].i,m[0].aT[bi].ni*sizeof(ensindex*));}
00538     m[0].aT[bi].i[m[0].aT[bi].ni-1]=(ensindex*)calloc(1,sizeof(ensindex));
00539     m[0].aT[bi].i[m[0].aT[bi].ni-1][0]=m[0].aT[iTree].ID;
00540     }
00541 
00542 /* 
00543 4.  Call each outgoing atom, in order, with this function 
00544 */
00545 for(oi=0;oi<m[0].aT[iTree].no;oi++)
00546     { 
00547     /* 
00548     get target atom 
00549     */
00550     at=&m[0].r[m[0].aT[iTree].o[oi][0].r].a[m[0].aT[iTree].o[oi][0].a]; 
00551     /* 
00552     record location in contree 
00553     */ 
00554     if(at[0].mTi>=0) { continue; } 
00555     else{bi=-(at[0].mTi+1);}
00556     finished = follow_molecule_atom_nodes_from_bonds(m, bi, at);
00557     }
00558 
00559 return finished;
00560 }
 All Classes Files Functions Variables Typedefs Defines