GLYLIB
0.3.0b
|
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 */