GLYLIB  0.3.0b
add_to_moiety_selection.c
Go to the documentation of this file.
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 }
 All Classes Files Functions Variables Typedefs Defines