GLYLIB  0.3.0b
bonding_utilities.c
Go to the documentation of this file.
00001 /** \file bonding_utilities.c  20101214 BLFoley
00002  * Purpose:  Provide utilities relevant to bonding within the various
00003  *      structures.  For example: build a connection tree from atom-
00004  *      level bonds; build atom-level bonds from a connection tree; 
00005  *      deduce bonding via distance. 
00006  *
00007  * Some useful definitions:
00008  *
00009  *      See also the molecule, residue and atom structures.  Most notation
00010  *              is very consistent and can be determined from context.
00011  *
00012  *      connection_tree:  non-redundant description of bonding
00013  *      m.aT:   atom-level connectiontree in a molecule structure
00014  *      m.rT:   residue-level connectiontree in a molecule structure
00015  *      r.aT:   atom-level connectiontree in a residue structure
00016  *
00017  * Some caveats/requirements:
00018  *
00019  *      * All functions here assume that the information contained in
00020  *              the data they depend on are correct.
00021  *      * All functions here should check for the presence of data and
00022  *              write an error to stdout if the data is not found.  This
00023  *              error is (hopefully) for the programmer, not end user.
00024  *      * In general, all molecule indices need to be set.
00025  *
00026  * Return values:
00027  *
00028  *      0       All is ok
00029  *      1       No data present to work with (procedure state unknown)
00030  *      2       Insufficient data to work with (procedure state unknown)
00031  *      3       No atoms found in molecule/residue
00032  *      4       No residues found in molecule
00033  * 
00034  */
00035 
00036 /***********   follow_molecule_atom_molbonds_for_contree() ************/
00037 /** The purpose of this function is to follow atoms recursively through
00038  * atom-level bonding until all are seen. 
00039  */
00040 void follow_molecule_atom_molbonds_for_contree(molecule *m, molindex mi){
00041 int t=m[0].r[mi.r].a[mi.a].mTi, /* the tree index */
00042         ii=0, /* local molbond index of incoming atom */
00043         rbi=0, /* convenience holder for local rbi */
00044         mbi=0; /* counter for molbonds */ 
00045 molindex fi; /* convenience molindex to follow */
00046 
00047 /* If this atom has been seen in the tree, just go back. */
00048 if(m[0].aT[t].rbi!=-1){return;};
00049 
00050 /* Mark this atom seen in tree */
00051 if(m[0].aT[t].ni>0){/* if there is an incoming bond */
00052         rbi=m[0].aT[t].rbi=m[0].aT[t].i[0].i; /* set the index to the first one */
00053         /* Identify the incoming bond */
00054         ii=-1;
00055         for(mbi=0;mbi<m[0].r[mi.r].a[mi.a].nmb;mbi+++){
00056                 fi=m[0].r[mi.r].a[mi.a].mb[mbi].t;
00057                 if(m[0].r[fi.r].a[fi.a].moli.m!=m[0].aT[t].ensi.m){
00058                         mywhine("molecule indices do not match in follow_molecule_atom_molbonds_for_contree");}
00059                 if((fi.r==m[0].aT[rbi].ensi.r)&&(fi.a==m[0].aT[rbi].ensi.a)){ii=mbi;}
00060                 }
00061         if(ii==-1){mywhine("did not find bond match in follow_molecule_atom_molbonds_for_contree.");}
00062         } 
00063 else{ /* if this is an origin atom */
00064         if(m[0].r[mi.r].a[mi.a].mb==NULL){mywhine("cannot access molbonds (mol/atom/contree)");}
00065         ii=0;
00066         fi=m[0].r[mi.r].a[mi.a].mb[0].t; /* find moli of first bond target */
00067         rbi=m[0].aT[t].rbi=m[0].r[fi.r].a[fi.a].mTi;
00068         }
00069 
00070 /*  Determine the proper bond order to maintain chirality. 
00071 
00072         Get each cross product vector for that with the incoming
00073         bond.  Save it.  Get all other cross-products.
00074         Get angles.  Sort angles.  Set outgoing in order.
00075 */
00076 
00077 /* Announce it to all the outgoing bonds */
00078 /* Call this function for all atoms with outgoing bonds */
00079 
00080 return;
00081 }
00082 
00083 /***********   set_connection_tree_molecule_atoms() ******************/
00084 /** The purpose of this function is to set the connection tree within a
00085  * molecule that is based on atom-level bonding.  
00086  *
00087  * The molecule can be alone or part of an assembly/ensemble.
00088  */
00089 
00090 int set_connection_tree_molecule_atoms(molecule *m){
00091 int     r=ri=0, /* residue index */
00092         a=ai=0, /* atom index */
00093         t=0, /* tree index */
00094         na=0, /* number of atoms in molecule */
00095         *new; /* na of these; atom has NOT been seen=0, has been seen=1;*/
00096 
00097 /* Do a little sanity check */
00098 if(m[0].nr==0){
00099         printf("No residues found in molecule in set_connection_tree_molecule_atoms\n");
00100         return 4;
00101         }
00102 if(m[0].r[0].na==0){
00103         printf("No atoms found in first residue in set_connection_tree_molecule_atoms\n");
00104         return 2;
00105         }
00106 if(m[0].r[0].a[0].nmb==0){
00107         printf("No bonding info found for first atom in set_connection_tree_molecule_atoms\n");
00108         return 1;
00109         }
00110 
00111 /* Count the number of atoms */
00112 for(r=0;r<m[0].nr;r++){ na+=m[0].r[r].na; }
00113 /* allocate spaces */
00114 new=(int*)calloc(na,sizeof(int));
00115 m[0].aT=(connection_tree*)calloc(na,sizeof(connection_tree));
00116 /* initialize the tree */
00117 t=0;
00118 ri=ai=-1;
00119 for(r=0;r<m[0].nr;r++){ 
00120         for(a=0;a<m[0].r[r].na;a++){ 
00121                 m[0].aT[t].rbi=-1; /* indicate not seen */
00122                 m[0],aT[t].isorigin='N'; /* indicate not origin */
00123                 m[0].aT[t].ensi.i=m[0].r[r].a[a].mTi=t; /* know thyself */
00124                 m[0].aT[t].ensi.E=-1;
00125                 m[0].aT[t].ensi.A=-1;
00126                 m[0].aT[t].ensi.m=m[0].r[r].a[a].moli.m;
00127                 m[0].aT[t].ensi.r=m[0].r[r].a[a].moli.r;
00128                 m[0].aT[t].ensi.a=m[0].r[r].a[a].moli.a;
00129                 /* while we're here, find the first atom that has only one bond.
00130                         We'll use that as the tree origin */
00131                 if(ai==-1) {
00132                         if(m[0].r[r].a[a].nmb==1){
00133                                 m[0],aT[t].isorigin='Y'; /* indicate is origin */
00134                                 ai=a;
00135                                 ri=r;
00136                                 }
00137                         }
00138                 t++;
00139                 }
00140         if(t>na){mywhine("tree count got larger than na in set_connection_tree_molecule_atoms");}
00141         }
00142 if(na==1){ /* just a single atom */
00143         m[0].aT[0].ni=m[0].aT[0].no=m[0].aT[0].rbi=0;
00144         return 0;
00145         }
00146 if(ai==-1){ /* if all atoms have more than one bond */ 
00147         m[0],aT[0].isorigin='Y'; /* indicate is origin */
00148         ai=0;
00149         ri=0;
00150         }
00151 /* Start at the origin atom */
00152 follow_molecule_atom_molbonds_for_contree(m,m[0].r[ri].a[ai].moli);
00153 /* That oughtta do it */
00154 
00155 return 0;
00156 }
00157 
00158 
00159 /***********   set_connection_tree_molecule_residues() ******************/
00160 /** The purpose of this function is to set the connection tree within a
00161  * molecule that is based on residue-level bonding.  
00162  */
00163 
00164 /***************   set_connection_tree_residues_atoms() ********************/
00165 /** The purpose of this function is to set the connection tree within a
00166  * residue that is based on atom-level bonding.  
00167  */
 All Classes Files Functions Variables Typedefs Defines