GLYLIB
0.3.0b
|
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 }