MASA-Core
BestScoreList.cpp
Go to the documentation of this file.
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, &params);
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 */