00001 00002 #include "../headers/psorting.h" 00003 00004 /* 00005 00006 ## GENERAL INFORMATION 00007 ## 00008 ## FILE psorting.c 00009 ## AUTHORS P. Schmidtke and V. Le Guilloux 00010 ## LAST MODIFIED 28-11-08 00011 ## 00012 ## SPECIFICATIONS 00013 ## 00014 ## This file contains all function needed to sort pocket according to a given 00015 ## criteria. 00016 ## 00017 ## MODIFICATIONS HISTORY 00018 ## 00019 ## 28-11-08 (v) Corresp renamed to ovlp 00020 ## 28-11-08 (v) Created + Comments UTD 00021 ## 00022 ## TODO or SUGGESTIONS 00023 ## 00024 ## 00025 00026 */ 00027 00028 /* 00029 COPYRIGHT DISCLAIMER 00030 00031 Vincent Le Guilloux, Peter Schmidtke and Pierre Tuffery, hereby 00032 disclaim all copyright interest in the program “fpocket” (which 00033 performs protein cavity detection) written by Vincent Le Guilloux and Peter 00034 Schmidtke. 00035 00036 Vincent Le Guilloux 28 November 2008 00037 Peter Schmidtke 28 November 2008 00038 Pierre Tuffery 28 November 2008 00039 00040 GNU GPL 00041 00042 This file is part of the fpocket package. 00043 00044 fpocket is free software: you can redistribute it and/or modify 00045 it under the terms of the GNU General Public License as published by 00046 the Free Software Foundation, either version 3 of the License, or 00047 (at your option) any later version. 00048 00049 fpocket is distributed in the hope that it will be useful, 00050 but WITHOUT ANY WARRANTY; without even the implied warranty of 00051 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00052 GNU General Public License for more details. 00053 00054 You should have received a copy of the GNU General Public License 00055 along with fpocket. If not, see <http://www.gnu.org/licenses/>. 00056 00057 **/ 00058 00059 static void pock_qsort_rec(c_lst_pockets *pockets, node_pocket **pocks, 00060 int start, int end, 00061 int (*fcmp)(const node_pocket*, const node_pocket*) ) ; 00062 00063 static int pock_partition(c_lst_pockets *pockets, node_pocket **pocks, 00064 int start, int end, 00065 int (*fcmp)(const node_pocket*, const node_pocket*)); 00066 00067 /** 00068 ## FUNCTION: 00069 sort_pockets 00070 00071 ## SPECIFICATION: 00072 Top function used to sort pockets. First we copy the chained list of 00073 pockets in a tab to make use of indices (for the quick sort algorithm), 00074 and then we will sort this tab, and update in the same time the chained list. 00075 00076 00077 Finally, the given chained list will be modified and sorted using the 00078 function given in argument. 00079 00080 ## PARAMETRES: 00081 @ c_lst_pockets *pockets: The list of pockets that will be updated 00082 @ int (*fcmp)(const node_pocket*, const node_pocket*): Comparison function 00083 00084 ## RETURN: 00085 00086 */ 00087 void sort_pockets(c_lst_pockets *pockets, 00088 int (*fcmp)(const node_pocket*, const node_pocket*)) 00089 { 00090 size_t npock = 0 ; 00091 node_pocket **pocks = (node_pocket **)my_calloc(pockets->n_pockets, sizeof(node_pocket*)) ; 00092 node_pocket *cur = pockets->first ; 00093 00094 while(cur && npock < pockets->n_pockets) { 00095 pocks[npock] = cur ; 00096 cur = cur->next ; 00097 npock++ ; 00098 } 00099 pock_qsort_rec(pockets, pocks, 0, npock-1, fcmp) ; 00100 00101 my_free(pocks) ; 00102 } 00103 00104 /** 00105 ## FUNCTION: 00106 static pock_qsort_rec 00107 00108 ## SPECIFICATION: 00109 This function will perform a recursive quick sort on the given tab, updating 00110 the corresponding chained list. 00111 00112 ## PARAMETRES: 00113 @ c_lst_pockets *pockets : The list of pockets that will be updated 00114 @ node_pocket **pocks : Tab that will be sorted 00115 @ int start : start index of the sort 00116 @ int end : end index of the sort 00117 @ int (*fcmp)(const node_pocket*, const node_pocket*): Comparison function 00118 00119 ## RETURN: 00120 00121 */ 00122 static void pock_qsort_rec(c_lst_pockets *pockets, node_pocket **pocks, 00123 int start, int end, 00124 int (*fcmp)(const node_pocket*, const node_pocket*) ) 00125 { 00126 if(start < end) { 00127 int piv = 0 ; 00128 piv = pock_partition(pockets, pocks, start, end, fcmp) ; 00129 00130 pock_qsort_rec(pockets, pocks, start, piv-1, fcmp) ; 00131 pock_qsort_rec(pockets, pocks, piv+1, end, fcmp) ; 00132 } 00133 } 00134 00135 /** 00136 ## FUNCTION: 00137 static pock_partition 00138 00139 ## SPECIFICATION: 00140 Partition fuction used for the quicksort. The comparison between two pockets 00141 is done with the function given in last argument. The pivot is chosen as the 00142 first element of the tab. A possible amelioration is to chose it randomly, 00143 to avoid low performance on already sorted tab... 00144 00145 The function is sorting a tab of pointer to the pockets, and will update the 00146 corresponding chained list. 00147 00148 ## PARAMETRES: 00149 @ c_lst_pockets *pockets : The list of pockets that will be updated 00150 @ node_pocket **pocks : Tab that will be sorted 00151 @ int start : start index of the sort 00152 @ int end : end index of the sort 00153 @ int (*fcmp)(const node_pocket*, const node_pocket*): Comparison function 00154 00155 ## RETURN: 00156 00157 */ 00158 static int pock_partition(c_lst_pockets *pockets, node_pocket **pocks, int start, int end, 00159 int (*fcmp)(const node_pocket*, const node_pocket*)) 00160 { 00161 node_pocket *cpock = NULL, 00162 *tmp = NULL, 00163 *piv = NULL ; 00164 00165 int c = start, 00166 i = 0 ; 00167 00168 piv = pocks[start] ; // TODO: chose randomly the pivot. 00169 for(i = start+1 ; i <= end ; i++) { 00170 cpock = pocks[i] ; 00171 if( fcmp(cpock, piv) == -1) { 00172 c++ ; 00173 if(c != i) { 00174 swap_pockets(pockets, pocks[c], pocks[i]) ; 00175 tmp = pocks[c] ; 00176 pocks[c] = pocks[i] ; pocks[i] = tmp ; 00177 } 00178 } 00179 } 00180 00181 if(c != start) { 00182 swap_pockets(pockets, pocks[c], piv) ; 00183 tmp = pocks[c] ; 00184 pocks[c] = pocks[start] ; pocks[start] = tmp ; 00185 00186 } 00187 00188 return(c) ; 00189 } 00190 00191 /** 00192 ## FUNCTION: 00193 compare_pockets_nasph 00194 00195 ## SPECIFICATION: 00196 Function comparing two pocket on there number of alpha spheres. 00197 Uses this for quicksort, or whatever you want... 00198 00199 ## PARAMETRES: 00200 @ const node_pocket *p1: Pocket 1 00201 @ const node_pocket *p2: Pocket 2 00202 00203 ## RETURN:. 00204 00205 */ 00206 int compare_pockets_nasph(const node_pocket *p1, const node_pocket *p2) 00207 { 00208 if(p1->pocket->pdesc->nb_asph < p2->pocket->pdesc->nb_asph) return 1 ; 00209 else return -1 ; 00210 } 00211 00212 00213 /** 00214 ## FUNCTION: 00215 compare_pockets_volume 00216 00217 ## SPECIFICATION: 00218 Function comparing two pocket on there volume. Uses this for quicksort, or 00219 whatever you want... 00220 00221 ## PARAMETRES: 00222 @ const node_pocket *p1: Pocket 1 00223 @ const node_pocket *p2: Pocket 2 00224 00225 ## RETURN: 00226 1 if the volume of p2 is greater than the volume of p1, -1 else. 00227 00228 */ 00229 int compare_pockets_volume(const node_pocket *p1, const node_pocket *p2) 00230 { 00231 if(p1->pocket->pdesc->volume < p2->pocket->pdesc->volume) return 1 ; 00232 else return -1 ; 00233 } 00234 00235 /** 00236 ## FUNCTION: 00237 compare_pockets_score 00238 00239 ## SPECIFICATION: 00240 Function comparing two pocket on there score. Uses this for quicksort, or 00241 whatever you want... 00242 00243 ## PARAMETRES: 00244 @ const node_pocket *p1: Pocket 1 00245 @ const node_pocket *p2: Pocket 2 00246 00247 ## RETURN: 00248 1 if the score of p2 is greater than the score of p1, -1 else. 00249 00250 */ 00251 int compare_pockets_score(const node_pocket *p1, const node_pocket *p2) 00252 { 00253 if(p1->pocket->score < p2->pocket->score) return 1 ; 00254 else return -1 ; 00255 } 00256 00257 /** 00258 ## FUNCTION: 00259 compare_pockets_corresp 00260 00261 ## SPECIFICATION: 00262 Function comparing two pocket on there correspondance with the ligan (for the 00263 test programm). Uses this for quicksort, orwhatever you want... 00264 00265 ## PARAMETRES: 00266 @ const node_pocket *p1: Pocket 1 00267 @ const node_pocket *p2: Pocket 2 00268 00269 ## RETURN: 00270 1 if the correspondance of p2 is greater than the correspondance of p1, -1 else. 00271 00272 */ 00273 int compare_pockets_corresp(const node_pocket *p1, const node_pocket *p2) 00274 { 00275 if(p1->pocket->ovlp < p2->pocket->ovlp) return 1 ; 00276 else return -1 ; 00277 } 00278 00279 /** 00280 ## FUNCTION: 00281 compare_pockets_vol_corresp 00282 00283 ## SPECIFICATION: 00284 Function comparing two pocket on there volume correspondance with the ligan 00285 (for the test programm). Uses this for quicksort, orwhatever you want... 00286 00287 ## PARAMETRES: 00288 @ const node_pocket *p1: Pocket 1 00289 @ const node_pocket *p2: Pocket 2 00290 00291 ## RETURN: 00292 1 if the volume correspondance of p2 is greater than the volume 00293 correspondance of p1, -1 else. 00294 00295 */ 00296 int compare_pockets_vol_corresp(const node_pocket *p1, const node_pocket *p2) 00297 { 00298 if(p1->pocket->vol_corresp < p2->pocket->vol_corresp) return 1 ; 00299 else return -1 ; 00300 } 00301