|
MASA-Core
|
00001 /******************************************************************************* 00002 * 00003 * Copyright (c) 2010-2015 Edans Sandes 00004 * 00005 * This file is part of MASA-Core. 00006 * 00007 * MASA-Core is free software: you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation, either version 3 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * MASA-Core is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with MASA-Core. If not, see <http://www.gnu.org/licenses/>. 00019 * 00020 ******************************************************************************/ 00021 00022 #include "BestScoreList.hpp" 00023 00024 #include <stdlib.h> 00025 #include <stdio.h> 00026 00027 #define DEBUG (0) 00028 00029 00030 /*#define MY_MUTEX_INIT 00031 #define MY_MUTEX_DESTROY 00032 #define MY_MUTEX_LOCK 00033 #define MY_MUTEX_UNLOCK 00034 */ 00035 00036 #define MY_MUTEX_INIT pthread_mutex_init(&mutex, NULL); 00037 #define MY_MUTEX_DESTROY pthread_mutex_destroy(&mutex); 00038 #define MY_MUTEX_LOCK pthread_mutex_lock(&mutex); 00039 #define MY_MUTEX_UNLOCK pthread_mutex_unlock(&mutex); 00040 00041 00042 00043 BestScoreList::BestScoreList(int limit, int min_score, int seq0_len, int seq1_len, const score_params_t* score_params) 00044 { 00045 this->limit = limit; 00046 this->min_score = min_score; 00047 this->seq0_len = seq0_len; 00048 this->seq1_len = seq1_len; 00049 this->score_params = score_params; 00050 00051 MY_MUTEX_INIT 00052 } 00053 00054 BestScoreList::~BestScoreList() { 00055 MY_MUTEX_DESTROY 00056 } 00057 00058 00059 score_t BestScoreList::getBestScore() const { 00060 set<score_t>::iterator it=begin(); 00061 if (it == end()) { 00062 score_t null_score; 00063 null_score.score = -INF; 00064 null_score.i = -1; 00065 null_score.j = -1; 00066 return null_score; 00067 } else { 00068 return *it; 00069 } 00070 } 00071 00072 bool BestScoreList::isDerived(const score_t best, const score_t score) { 00073 int diff_z = score.score - best.score; 00074 int diff_x = score.j - best.j; 00075 int diff_y = score.i - best.i; 00076 00077 if (diff_z >= 0) { 00078 return false; 00079 } 00080 00081 if (min_score >= 0 && best.score > (abs(diff_x) + abs(diff_y))/score_params->gap_ext) { 00082 return true; 00083 } 00084 if (min_score < 0) { 00085 int min_len = seq0_len < seq1_len ? seq0_len : seq1_len; 00086 if ((abs(diff_x) + abs(diff_y)) > min_len) { 00087 return true; 00088 } 00089 } 00090 00091 int gaps; 00092 int diagonal; 00093 if ((diff_x <= 0 && diff_y <= 0) || (diff_x >= 0 && diff_y >= 0)) { 00094 gaps = abs(abs(diff_x)-abs(diff_y)); 00095 diagonal = (abs(diff_x) < abs(diff_y)) ? abs(diff_x) : abs(diff_y); 00096 } else { 00097 gaps = abs(diff_x)+abs(diff_y); 00098 diagonal = (abs(diff_x) < abs(diff_y)) ? abs(diff_x) : abs(diff_y); 00099 } 00100 const float prob_match = 0.25f; 00101 const float prob_gap_adj = 2.0f; 00102 /*if (best.z > 0) { 00103 gap_extra_adj = best.z/DNA_GAP_EXT; 00104 }*/ 00105 00106 int z_min = (score_params->mismatch*(1-prob_match) + score_params->match*prob_match)*diagonal; 00107 int z_max = score_params->match*diagonal; 00108 int g_diff = score_params->gap_ext*gaps; 00109 00110 return (diff_z >= z_min - g_diff*prob_gap_adj) && (diff_z <= z_max - g_diff/prob_gap_adj); 00111 } 00112 00113 bool BestScoreList::isAllowed(const score_t best, const score_t score) { 00114 if (best.score > 0 && score.score < 0.25*best.score) { 00115 return false; 00116 } 00117 if (best.score < 0 && score.score < 1.10*best.score) { 00118 return false; 00119 } 00120 return true; 00121 } 00122 00123 void BestScoreList::add(int i, int j, int score) { 00124 MY_MUTEX_LOCK 00125 _add(i,j,score); 00126 MY_MUTEX_UNLOCK 00127 } 00128 00129 void BestScoreList::_add(int i, int j, int score) { 00130 if (score < min_score) return; 00131 score_t reg; 00132 reg.score = score; 00133 reg.i = i; 00134 reg.j = j; 00135 //int3 reg = make_int3(j, i, score); 00136 00137 if (size() == limit) { 00138 set<score_t>::iterator it=end(); 00139 it--; 00140 if (it->score > score) { 00141 return; 00142 } 00143 } 00144 00145 if (size() > 0) { 00146 set<score_t>::iterator best=begin(); 00147 if (!isAllowed(*best, reg)) return; 00148 } 00149 00150 if (find(reg) != end()) { 00151 return; 00152 } 00153 00154 bool derived = false; 00155 for (set<score_t>::iterator it=begin() ; it != end(); it++ ) { 00156 if (isDerived(*it, reg)) { 00157 derived = true; 00158 //printf("HEY NOT: (%d,%d,%d) -> (%d,%d,%d)\n", reg.y, reg.x, reg.z, it->y, it->x, it->z); 00159 break; 00160 } 00161 } 00162 00163 if (!derived) { 00164 set<score_t>::iterator it=begin(); 00165 while (it != end()) { 00166 if (isDerived(reg, *it) || !isAllowed(reg, *it)) { 00167 set<score_t>::iterator toErase = it; 00168 it++; 00169 erase(toErase); 00170 //printf("HEY ERASE: (%d,%d,%d) -> (%d,%d,%d)\n", reg.y, reg.x, reg.z, it->y, it->x, it->z); 00171 } else { 00172 it++; 00173 } 00174 } 00175 00176 00177 insert(reg); 00178 if (size() > limit) { 00179 set<score_t>::iterator it=end(); 00180 it--; 00181 erase(it); 00182 } 00183 if (DEBUG) { 00184 int c = 1; 00185 printf(" I: %d,%d,%d\n", reg.i, reg.j, reg.score); 00186 for (set<score_t>::iterator it=begin() ; it != end(); it++ ) { 00187 printf("%2d: %d,%d,%d\n", c++, it->i, it->j, it->score); 00188 } 00189 printf("----\n"); 00190 } 00191 } 00192 00193 00194 00195 } 00196 00197 /* 00198 g++ -pthread src/common/BestScoreList.cpp -o test && ./test 00199 void* testFunctionThread(void* args) { 00200 BestScoreList* list = (BestScoreList*)args; 00201 for (int k=0; k<100000; k++) { 00202 int i = (int)((float)rand()/RAND_MAX*1000000); 00203 int j = (int)(((float)rand()/RAND_MAX*1000)*((float)rand()/RAND_MAX*1000)); 00204 int s = (int)(((float)rand()/RAND_MAX*102)*((float)rand()/RAND_MAX*50)*((float)rand()/RAND_MAX*70)); 00205 if (k%1000==0) printf("%d: add[%d,%d,%d]\n", k, i, j, s); 00206 list->add(i, j, s); 00207 } 00208 } 00209 00210 int main() { 00211 pthread_t thread[400]; 00212 score_params_t params; 00213 params.match = 1; 00214 params.mismatch = -3; 00215 params.gap_open = 3; 00216 params.gap_ext = 2; 00217 BestScoreList* writer = new BestScoreList(1000, 0, 1000000, 1000000, ¶ms); 00218 for (int i=0; i<50; i++) { 00219 //sleep(1); 00220 int rc = pthread_create(&thread[i], NULL, testFunctionThread, (void *)writer); 00221 printf("pthread_create(thread[%d]): %d\n", i, rc); 00222 } 00223 for (int i=0; i<50; i++) { 00224 pthread_join(thread[i], NULL); 00225 } 00226 } 00227 */
1.7.6.1