GLYLIB
0.3.0b
|
00001 /** \file add_to_moiety_selection.c Parses input string and adds selection to 00002 a "moiety_selection" structure. 00003 00004 This function might not be complete -- it is being written for a certain project, 00005 and should be expanded as needed. 00006 00007 NOTE!!! The moiety_selection *MUST* be allocated and initialized before calling 00008 this function. Initialization means that sub-arrays must have had an 00009 initial allocation (so that realloc won't choke). 00010 00011 It also must be initialized so that the "nX" variables start at zero. 00012 They need not be zero when they come to this function, but they need 00013 to be something real and not whatever garbage was left in memory. 00014 00015 00016 The current syntax is: 00017 00018 number moiety-size-class moiety-designation optional_NOT designation_list 00019 00020 Only one such 'sentence' is allowed per call. 00021 00022 Syntax Examples: 00023 00024 Add residues number 1, 2, 8 and 38 to the selection: 00025 00026 4 Residue Numbers 1 2 8 38 00027 00028 Add atoms not named O5 and O6 00029 00030 2 Atoms Names -NOT- O5 O6 00031 00032 NOTE: Regarding entries, the function inspects only the smallest number of characters 00033 necessary to differentiate keywords. So, for the moiety-size-class entry, the 00034 strings "Residue" "R" "Raisin" and "RESI" are all the same to the program. 00035 00036 Acceptable values for input. The star (*) indicates the part of the function that will 00037 be written now (starting 20080910-ish): 00038 00039 Number: integer 00040 Eventually, this could be written to also read "range", but not today. 00041 00042 moiety-size-class: Atom Residue(*) Molecule Assembly Ensemble Group 00043 First letter differentiates. 00044 00045 moiety-designation: Name Number Index 00046 First two letters differentiate (actually, using second 00047 character in the string presently). 00048 Number = the number in the input data set (e.g., pdb file). 00049 Index = the array index as stored internally to the program 00050 00051 optional_NOT: -NOT- 00052 Must include all five characters, case sensitive. 00053 A single moiety_selection must be all positive or all negative. 00054 The calling function should decide before adding info to it. 00055 If SEL doesn't match, an error will be produced. 00056 00057 designation_list: (varies) 00058 Space-separated list of names or numbers. Names must exactly 00059 match the string contained in "N". Currently, spaces are not 00060 permitted in the names. (someone could re-write to allow it...) 00061 00062 More about the selections: 00063 - Selections will be set only within the relevant class. For example, 00064 if the class is set to "residue", then only residues will be 00065 added to the structure; their associated atoms will not be 00066 explicitly included. Similarly, if the -NOT- option is chosen 00067 with class residue, all residues except those listed will be 00068 added to the selection, but not the associated atoms. 00069 - Only the first "number" designations will be scanned from the 00070 designation_list. Any trailing characters or words will be 00071 ignored after the first "number" words are found. 00072 - Empty selection strings will be ingored and no error returned. The 00073 moiety_selection structure will be unaltered. 00074 - Errors will be returned if: 00075 - The first word in SEL is not an integer 00076 - Fewer than "number" words are found in the designation list 00077 - No match is found for either class or designation 00078 - The existing moiety_selection is set to be a positive list 00079 but SEL is negative or vice-versa. 00080 - Note, of course, that this function merely parses a 00081 selection string. It has no knowledge whether the 00082 molecule, etc., actually contains the selected items. 00083 00084 */ 00085 00086 #include <mylib.h> 00087 #include <molecules.h> 00088 00089 void add_to_moiety_selection(moiety_selection *M, const char *SEL){ 00090 int aa=0, ///< counter 00091 ab=0, ///< counter 00092 ac=0, ///< counter 00093 posneg=0, ///< flag for negative selection 00094 number=0; ///< number of designations in the list 00095 char *tp, ///< Temporary pointer 00096 *ts, ///< Temporary string 00097 *S, ///< The trimmed selection 00098 *class, ///< The class 00099 *des, ///< The designation 00100 **d; ///< The designation_list 00101 00102 /// Make sure there is no leading or trailing whitespace in S to cause confusion 00103 S=strdup(prune_string_whitespace(SEL)); 00104 00105 /// grab three items, place into number, class and designation 00106 tp=S; // use a temporary pointer (tp) to move around in S. 00107 00108 // Get Integer 00109 aa=strcspn(tp," \t\n\v\r\f"); ///< Find length of first word -- this should be the integer 00110 if(aa==0){return;} ///< If the string S is empty, return without complaint 00111 ts=(char*)calloc(aa+1,sizeof(char)); 00112 strncpy(ts,tp,aa); 00113 ts[aa]='\0'; 00114 ab=sscanf(ts,"%d",&number); ///< Scan in the first integer 00115 if(ab==0){mywhine("add_to_moiety_selection: Initial item in SEL not an integer");} 00116 free(ts); 00117 00118 // Get Class 00119 tp+=aa; // move the pointer past the first item 00120 aa=strspn(tp," \t\n\v\r\f"); 00121 tp+=aa; // move past the whitespace 00122 aa=strcspn(tp," \t\n\v\r\f"); ///< Find length of second word -- this should be the class 00123 class=(char*)calloc((aa+1),sizeof(char)); 00124 strncpy(class,tp,aa); 00125 class[aa]='\0'; 00126 00127 00128 00129 // Get Designation 00130 tp+=aa; // move the pointer past the second item 00131 aa=strspn(tp," \t\n\v\r\f"); 00132 tp+=aa; // move past the whitespace 00133 aa=strcspn(tp," \t\n\v\r\f"); ///< Find length of third word -- this should be the designation 00134 des=(char*)calloc((aa+1),sizeof(char)); 00135 strncpy(des,tp,aa); 00136 des[aa]='\0'; 00137 00138 // See if there is an Optional -NOT- 00139 ts=strstr(tp,"-NOT-"); 00140 if(ts!=NULL){ // if a not entry was found 00141 posneg=-1; 00142 tp=ts+5; // move the tp pointer past the "-NOT-" 00143 } 00144 else{posneg=+1;} 00145 00146 if((M[0].posneg!=0)&&(M[0].posneg!=posneg)){mywhine("add_to_moiety_selection: positive/negative mismatch with SEL and M.");} 00147 M[0].posneg=posneg; // In case it was zero 00148 00149 // separate the designation_list by scanning for non-whitespace 00150 d=(char**)calloc(number,sizeof(char*)); 00151 for(ab=0;ab<number;ab++){ 00152 aa=strspn(tp," \t\n\v\r\f"); 00153 tp+=aa; // move past the whitespace 00154 aa=strcspn(tp," \t\n\v\r\f"); ///< Find length of the ab'th item in the designation_list 00155 d[ab]=(char*)calloc((aa+1),sizeof(char)); 00156 strncpy(d[ab],tp,aa); 00157 d[ab][aa]='\0'; 00158 } 00159 00160 // add the string entries to the appropriate parts of the moiety_selection 00161 switch(class[0]){ ///< First letter of class differentiates molecule, residue or atom 00162 case 'M': 00163 case 'm': 00164 switch(des[1]){ ///< Second letter of designation differentiates name, number or index 00165 case 'A': 00166 case 'a': 00167 ab=M[0].nmN; 00168 M[0].nmN+=number; 00169 M[0].mN=(char**)realloc(M[0].mN,M[0].nmN*sizeof(char*)); 00170 for(aa=0;aa<number;aa++){M[0].mN[aa+ab]=strdup(d[aa]);} 00171 break; 00172 case 'U': 00173 case 'u': 00174 ab=M[0].nmn; 00175 M[0].nmn+=number; 00176 M[0].mn=(int*)realloc(M[0].mn,M[0].nmn*sizeof(int)); 00177 for(aa=0;aa<number;aa++){ac=sscanf(d[aa],"%d",&M[0].mn[aa+ab]); 00178 if(ac!=1){mywhine("add_to_moiety_selection: expected integer for des-number, got something else");}} 00179 break; 00180 case 'N': 00181 case 'n': 00182 ab=M[0].nmi; 00183 M[0].nmi+=number; 00184 M[0].mi=(int*)realloc(M[0].mi,M[0].nmi*sizeof(int)); 00185 for(aa=0;aa<number;aa++){ac=sscanf(d[aa],"%d",&M[0].mi[aa+ab]); 00186 if(ac!=1){mywhine("add_to_moiety_selection: expected integer for index, got something else");}} 00187 break; 00188 default: 00189 mywhine("add_to_moiety_selection: unrecognized moiety-designation"); 00190 } 00191 break; 00192 case 'R': 00193 case 'r': 00194 switch(des[1]){ ///< Second letter of designation differentiates name, number or index 00195 case 'A': 00196 case 'a': 00197 ab=M[0].nrN; 00198 M[0].nrN+=number; 00199 M[0].rN=(char**)realloc(M[0].rN,M[0].nrN*sizeof(char*)); 00200 for(aa=0;aa<number;aa++){M[0].rN[aa+ab]=strdup(d[aa]);} 00201 break; 00202 case 'U': 00203 case 'u': 00204 ab=M[0].nrn; 00205 M[0].nrn+=number; 00206 M[0].rn=(int*)realloc(M[0].rn,M[0].nrn*sizeof(int)); 00207 for(aa=0;aa<number;aa++){ac=sscanf(d[aa],"%d",&M[0].rn[aa+ab]); 00208 if(ac!=1){mywhine("add_to_moiety_selection: expected integer for des-number, got something else");}} 00209 break; 00210 case 'N': 00211 case 'n': 00212 ab=M[0].nri; 00213 M[0].nri+=number; 00214 M[0].ri=(int*)realloc(M[0].ri,M[0].nri*sizeof(int)); 00215 for(aa=0;aa<number;aa++){ac=sscanf(d[aa],"%d",&M[0].ri[aa+ab]); 00216 if(ac!=1){mywhine("add_to_moiety_selection: expected integer for index, got something else");}} 00217 break; 00218 default: 00219 mywhine("add_to_moiety_selection: unrecognized moiety-designation"); 00220 } 00221 break; 00222 case 'A': 00223 case 'a': 00224 switch(des[1]){ ///< Second letter of designation differentiates name, number or index 00225 case 'A': 00226 case 'a': 00227 ab=M[0].naN; 00228 M[0].naN+=number; 00229 M[0].aN=(char**)realloc(M[0].aN,M[0].naN*sizeof(char*)); 00230 for(aa=0;aa<number;aa++){M[0].aN[aa+ab]=strdup(d[aa]);} 00231 break; 00232 case 'U': 00233 case 'u': 00234 ab=M[0].nan; 00235 M[0].nan+=number; 00236 M[0].an=(int*)realloc(M[0].an,M[0].nan*sizeof(int)); 00237 for(aa=0;aa<number;aa++){ac=sscanf(d[aa],"%d",&M[0].an[aa+ab]); 00238 if(ac!=1){mywhine("add_to_moiety_selection: expected integer for des-number, got something else");}} 00239 break; 00240 case 'N': 00241 case 'n': 00242 ab=M[0].nai; 00243 M[0].nai+=number; 00244 M[0].ai=(int*)realloc(M[0].ai,M[0].nai*sizeof(int)); 00245 for(aa=0;aa<number;aa++){ac=sscanf(d[aa],"%d",&M[0].ai[aa+ab]); 00246 if(ac!=1){mywhine("add_to_moiety_selection: expected integer for index, got something else");}} 00247 break; 00248 default: 00249 mywhine("add_to_moiety_selection: unrecognized moiety-designation"); 00250 } 00251 break; 00252 default: 00253 mywhine("add_to_moiety_selection: unrecognized moiety-size-class"); 00254 } 00255 00256 free(ts); 00257 free(class); 00258 free(des); 00259 for(aa=0;aa<number;aa++){free(d[aa]);} 00260 free(d); 00261 00262 return; 00263 }