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