GLYLIB  0.3.0b
get_moiety_selection_assembly.c
Go to the documentation of this file.
00001 /** \file get_moiety_selection_assembly.c Returns an assembly pointing to the selections 
00002         indicated by the entries in a set of moiety_selections.
00003         
00004         If two different moiety_selections overlap (select some of the same items),
00005         the assembly will not contain redundant entries.  For example, if residue A
00006         is selected twice in one moiety selection or if it is selected in more than
00007         one moiety, the assembly returned will contain one pointer to residue A.  If
00008         choosing by name, and multiple residues are named "A", there will only be one
00009         pointer to each residue of that name no matter how many times "A" is specified
00010         as a selection.
00011 
00012         Note that a negative moiety_selection does not unselect -- it merely specifies
00013         a selection by saying "select all except".  Use the function (not written yet)
00014         called remove_moiety_selection_from_assembly to unselect items.
00015 
00016         The assembly will consist only of pointers to any members any classes represented 
00017         in the moiety selection.  For example, if a moiety selection contains residues
00018         A, B and C, there will be pointers to A, B and C, but not to any of the atoms
00019         contained within those residues.  However, if the moiety selections also contain
00020         explicit mention of atoms from any of those residues, the assembly will also
00021         contain pointers to those atoms explicitly mentioned.  It is up to some other
00022         function to prune or clean up or expand, etc.
00023 
00024         NOTES:
00025         - This function will set all the moli's for the residues and atoms and the mi
00026                 member in the molecule structure.  It will not check to see if you had
00027                 something else there first.  If you need to keep some information other 
00028                 than the standard indices, find somewhere else to put it.
00029         - The entries in the assembly will be ordered as the order in the original
00030                 ensemble.  For example, if the moiety_selection chooses residues number
00031                 5, 250, 48, 2 and 143, the assembly will contain pointers to residues
00032                 number 2, 5, 48, 143 and 250, in that order.  
00033         - If residues spanning different molecules are selected, the assembly will
00034                 not group them by molecule.  They will be in one long list of 
00035                 residue pointers.  You can use the moli entries to determine membership
00036                 in a particular molecule, if needed.
00037         - Of course, name, number or index entries in MS must exactly match names,
00038                 numbers and/or indices of entries in E.  If not, however, the function
00039                 will not complain.  It simply will not add selections to the assembly
00040                 where it does not find a match.
00041         - Of course, the moiety_selection should not contain any uninitialized or
00042                 members.  
00043 */
00044 
00045 #include "mylib.h"
00046 #include "molecules.h"
00047 
00048 
00049 //START HERE -- change name to get_moiety_selection_assembly_from_ensemble
00050 // Make similar called get_moiety_selection_assembly_from_assembly
00051 assembly get_moiety_selection_assembly(ensemble *E, int nMS, moiety_selection *MS){
00052 int     am=0,ar=0,aa=0,ai=0,ams=0, ///< counters
00053         aflag=0, ///< Flag used for setting negative selections
00054         numM=0, ///< Number of molecule pointers needed for assembly
00055         numR=0, ///< Number of residue pointers needed for assembly
00056         numA=0; ///< Number of atom pointers needed for assembly
00057 assembly A; ///< the assembly to return
00058 ensemble_tree_index IA; ///< the indices for holding selections
00059 
00060 // Set up the tree of indices (IA) analogous to the m,r,a structure in E
00061 //      initialize them all to be 0
00062 IA.nm=E[0].nm;
00063 IA.mi=(int*)calloc(IA.nm,sizeof(int));
00064 IA.m=(molecule_tree_index*)calloc(IA.nm,sizeof(molecule_tree_index));
00065 for(am=0;am<IA.nm;am++){ // for each molecule
00066         IA.m[am].nr=E[0].m[am].nr;
00067         IA.m[am].ri=(int*)calloc(IA.m[am].nr,sizeof(int));
00068         IA.m[am].r=(residue_tree_index*)calloc(IA.m[am].nr,sizeof(residue_tree_index));
00069         for(ar=0;ar<IA.m[am].nr;ar++){ // for each residue 
00070                 IA.m[am].r[ar].na=E[0].m[am].r[ar].na;
00071                 IA.m[am].r[ar].ai=(int*)calloc(IA.m[am].r[ar].na,sizeof(int));
00072                 }
00073         }
00074 
00075 
00076 /** Walk through each m, r, a of the ensemble.  Look for matches.  
00077 *
00078 * If there is a match, change the corresponding index in IA to equal one.  
00079 * Don't check to see whether it is already one -- that doesn't matter. */
00080 
00081 for(ams=0;ams<nMS;ams++){
00082 
00083 /// For each positive moiety_selection passed to the function
00084 if(MS[ams].posneg==1){ 
00085         // Molecules
00086         // For each molecule index specified
00087         for(ai=0;ai<MS[ams].nmi;ai++){ IA.mi[MS[ams].mi[ai]]=1; }
00088         // Check each molecule for names and numbers
00089         for(am=0;am<IA.nm;am++){ 
00090                 // For each name specified
00091                 for(ai=0;ai<MS[ams].nmN;ai++){ if((E[0].m[am].N!=NULL)&&(strcmp(E[0].m[am].N,MS[ams].mN[ai])==0)){IA.mi[am]=1;} }
00092                 // For each number specified
00093                 for(ai=0;ai<MS[ams].nmn;ai++){ if(E[0].m[am].n==MS[ams].mn[ai]){IA.mi[am]=1;} } 
00094         
00095                 // Residues
00096                 // For each index specified
00097                 for(ai=0;ai<MS[ams].nri;ai++){ IA.m[am].ri[MS[ams].ri[ai]]=1; }
00098                 // Now, check each residue for names and numbers 
00099                 for(ar=0;ar<IA.m[am].nr;ar++){ 
00100                         // For each name specified
00101                         for(ai=0;ai<MS[ams].nrN;ai++){ if((E[0].m[am].r[ar].N!=NULL)&&(strcmp(E[0].m[am].r[ar].N,MS[ams].rN[ai])==0)){IA.m[am].ri[ar]=1;} }
00102                         // For each number specified
00103                         for(ai=0;ai<MS[ams].nrn;ai++){ if(E[0].m[am].r[ar].n==MS[ams].rn[ai]){IA.m[am].ri[ar]=1;} }     
00104 
00105                         // Atoms
00106                         // For each index specified
00107                         for(ai=0;ai<MS[ams].nai;ai++){ IA.m[am].r[ar].ai[MS[ams].ai[ai]]=1; }
00108                         // Now, check each residue for names and numbers 
00109                         for(aa=0;aa<IA.m[am].r[ar].na;aa++){ 
00110 // For each atom name specified
00111 for(ai=0;ai<MS[ams].naN;ai++){ if((E[0].m[am].r[ar].a[aa].N!=NULL)&&(strcmp(E[0].m[am].r[ar].a[aa].N,MS[ams].aN[ai])==0)){IA.m[am].r[ar].ai[aa]=1;} }
00112 // For each atom number specified
00113 for(ai=0;ai<MS[ams].nan;ai++){ if(E[0].m[am].r[ar].a[aa].n==MS[ams].an[ai]){IA.m[am].r[ar].ai[aa]=1;} } 
00114                                 } // close aa loop
00115                         } // close ar loop
00116                 } // close am loop
00117         } // close if positive MS condition
00118 
00119 /// For each negative moiety_selection passed to the function
00120 if(MS[ams].posneg==1){ 
00121         // Molecules
00122         // Check each molecule for names and numbers
00123         for(am=0;am<IA.nm;am++){ 
00124                 // For each molecule index specified
00125                 aflag=1;
00126                 for(ai=0;ai<MS[ams].nmi;ai++){ if(am==MS[ams].mi[ai]) aflag=0; }
00127                 if(aflag==1) { IA.mi[am]=1; }
00128                 // For each name specified
00129                 aflag=1;
00130                 for(ai=0;ai<MS[ams].nmN;ai++){ if((E[0].m[am].N!=NULL)&&(strcmp(E[0].m[am].N,MS[ams].mN[ai])==0)){aflag=0;} }
00131                 if(aflag==1) { IA.mi[am]=1; }
00132                 // For each number specified
00133                 aflag=1;
00134                 for(ai=0;ai<MS[ams].nmn;ai++){ if(E[0].m[am].n==MS[ams].mn[ai]){aflag=0;} }     
00135                 if(aflag==1) { IA.mi[am]=1; }
00136         
00137                 // Residues
00138                 // Now, check each residue for names and numbers 
00139                 for(ar=0;ar<IA.m[am].nr;ar++){ 
00140                         // For each index specified
00141                         aflag=1;
00142                         for(ai=0;ai<MS[ams].nri;ai++){ if(ar==MS[ams].ri[ai]) aflag=0; }
00143                         if(aflag==1) { IA.m[am].ri[ar]=1; }
00144                         // For each name specified
00145                         aflag=1;
00146                         for(ai=0;ai<MS[ams].nrN;ai++){ if((E[0].m[am].r[ar].N!=NULL)&&(strcmp(E[0].m[am].r[ar].N,MS[ams].rN[ai])==0)){aflag=0;} }
00147                         if(aflag==1) { IA.m[am].ri[ar]=1; }
00148                         // For each number specified
00149                         aflag=1;
00150                         for(ai=0;ai<MS[ams].nrn;ai++){ if(E[0].m[am].r[ar].n==MS[ams].rn[ai]){aflag=0;} }       
00151                         if(aflag==1) { IA.m[am].ri[ar]=1; }
00152 
00153                         // Atoms
00154                         // Now, check each residue for names and numbers 
00155                         for(aa=0;aa<IA.m[am].r[ar].na;aa++){ 
00156 // For each index specified
00157 aflag=1;
00158 for(ai=0;ai<MS[ams].nai;ai++){ if(aa==MS[ams].ai[ai]) aflag=0; }
00159 if(aflag==1) { IA.m[am].r[ar].ai[aa]=1; } 
00160 // For each atom name specified
00161 aflag=1;
00162 for(ai=0;ai<MS[ams].naN;ai++){ if((E[0].m[am].r[ar].a[aa].N!=NULL)&&(strcmp(E[0].m[am].r[ar].a[aa].N,MS[ams].aN[ai])==0)){aflag=0;} }
00163 if(aflag==1) { IA.m[am].r[ar].ai[aa]=1; } 
00164 // For each atom number specified
00165 aflag=1;
00166 for(ai=0;ai<MS[ams].nan;ai++){ if(E[0].m[am].r[ar].a[aa].n==MS[ams].an[ai]){aflag=0;} } 
00167 if(aflag==1) { IA.m[am].r[ar].ai[aa]=1; } 
00168                                 } // close aa loop
00169                         } // close ar loop
00170                 } // close am loop
00171         } // close if negative MS condition
00172 
00173         } // close ams loop
00174 
00175 // after all the indices are set for selection, count, in IA, the number of
00176 //      m, r and a pointers the assembly will need and allocate them.
00177 numM=numR=numA=0;
00178 for(am=0;am<IA.nm;am++){ if(IA.mi[am]>0) numM++;
00179         for(ar=0;ar<IA.m[am].nr;ar++){ if(IA.m[am].ri[ar]>0) numR++;
00180                 for(aa=0;aa<IA.m[am].r[ar].na;am++){ if(IA.m[am].r[ar].ai[aa]==1) numA++;
00181                         }
00182                 }
00183         }
00184 A.nm=numM;
00185 A.m=(molecule**)calloc(A.nm,sizeof(molecule*));
00186 A.nr=numR;
00187 A.r=(residue**)calloc(A.nr,sizeof(residue*)); 
00188 A.na=numA;
00189 A.a=(atom**)calloc(A.na,sizeof(atom*)); 
00190 
00191 // Walk through IA and set an appropriate pointer whenever a "1" is encountered
00192 numM=numR=numA=0;
00193 for(am=0;am<IA.nm;am++){ 
00194         if(IA.mi[am]>0){
00195                 A.m[numM]=&E[0].m[am];
00196                 numM++;
00197                 if(numM>A.nm){mywhine("get_moiety_selection_assembly: memory allocation issue in A.nm/numM");}
00198                 }
00199         for(ar=0;ar<IA.m[am].nr;ar++){ 
00200                 if(IA.m[am].ri[ar]>0){
00201                         A.r[numR]=&E[0].m[am].r[ar];
00202                         numR++;
00203                         if(numR>A.nr){mywhine("get_moiety_selection_assembly: memory allocation issue in A.nr/numR");}
00204                         }
00205                 for(aa=0;aa<IA.m[am].r[ar].na;am++){ 
00206                         if(IA.m[am].r[ar].ai[aa]==1){
00207                                 A.a[numA]=&E[0].m[am].r[ar].a[aa];
00208                                 numA++;
00209                                 if(numA>A.na){mywhine("get_moiety_selection_assembly: memory allocation issue in A.na/numA");}
00210                                 }
00211                         }
00212                 }
00213         }
00214 
00215 return A;
00216 }
 All Classes Files Functions Variables Typedefs Defines