|
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 "CPUBlockProcessor.hpp" 00023 00024 #include <stdio.h> 00025 00026 /* 00027 * Some macros 00028 */ 00029 #define MAX2(A,B) (((A)>(B))?(A):(B)) 00030 #define MAX3(A,B,C) (MAX2(MAX2((A),(B)),(C))) 00031 #define MAX4(A,B,C,D) (MAX2(MAX2((A),(B)),MAX2((C),(D)))) 00032 00033 #define DEBUG (0) 00034 00035 CPUBlockProcessor::CPUBlockProcessor() { 00036 this->seq0 = NULL; 00037 this->seq1 = NULL; 00038 } 00039 00040 CPUBlockProcessor::~CPUBlockProcessor() { 00041 // TODO Auto-generated destructor stub 00042 } 00043 00044 void CPUBlockProcessor::setSequences(const char* seq0, const char* seq1, int seq0_len, int seq1_len) { 00045 this->seq0 = seq0; 00046 this->seq1 = seq1; 00047 } 00048 00049 void CPUBlockProcessor::unsetSequences() { 00050 00051 } 00052 00053 00054 /** 00055 * Implements the smith waterman recurrence function. 00056 * 00057 * @param c0 char of sequence s0 00058 * @param c1 char of sequence s1 00059 * @param[in,out] e00 Input E[i][j-1]; Output E[i][j] 00060 * @param[in,out] f00 Input F[i-1][j]; Output F[i][j] 00061 * @param[in] h01 Input H[i][j-1] 00062 * @param[in] h11 Input H[i-1][j-1] 00063 * @param[in] h10 Input H[i-1][j] 00064 * @param[out] h00 Ouput H[i][j] 00065 */ 00066 static void sw(const unsigned char c0, const unsigned char c1, 00067 int *e00, int *f00, const int h01, const int h11, const int h10, int *h00) { 00068 *e00 = MAX2(h01-DNA_GAP_OPEN, *e00)-DNA_GAP_EXT; // Horizontal propagation 00069 *f00 = MAX2(h10-DNA_GAP_OPEN, *f00)-DNA_GAP_EXT; // Vertical propagation 00070 int v1 = h11+((c1!=c0)?DNA_MISMATCH:DNA_MATCH); 00071 *h00 = MAX4(0, v1, *e00, *f00); 00072 } 00073 00074 /** 00075 * Implements the Needleman Wunsch recurrence function. 00076 * 00077 * @param c0 char of sequence s0 00078 * @param c1 char of sequence s1 00079 * @param[in,out] e00 Input E[i][j-1]; Output E[i][j] 00080 * @param[in,out] f00 Input F[i-1][j]; Output F[i][j] 00081 * @param[in] h01 Input H[i][j-1] 00082 * @param[in] h11 Input H[i-1][j-1] 00083 * @param[in] h10 Input H[i-1][j] 00084 * @param[out] h00 Ouput H[i][j] 00085 */ 00086 static void nw(const unsigned char c0, const unsigned char c1, 00087 int *e00, int *f00, const int h01, const int h11, const int h10, int *h00) { 00088 00089 *e00 = MAX2(h01-DNA_GAP_OPEN, *e00)-DNA_GAP_EXT; // Horizontal propagation 00090 *f00 = MAX2(h10-DNA_GAP_OPEN, *f00)-DNA_GAP_EXT; // Vertical propagation 00091 int v1 = h11+((c1!=c0)?DNA_MISMATCH:DNA_MATCH); 00092 *h00 = MAX3(v1, *e00, *f00); 00093 } 00094 00095 /** 00096 * Executes the SW/NW recurrence function for the given block. 00097 * @param[in,out] row Input: cells from the first row of the block, where 00098 * row[k] represents cell (i0-1,j0+k); 00099 * Output: the same range is used for write, but the output represents the 00100 * last row of the block; 00101 * @param[in,out] col Input: cells from the first column of the partition, where 00102 * col[k] represents cell (i0-1+k,j0-1). Note that 00103 * the col vector contains the diag cell (i0-1,j0-1). 00104 * Output: the same idea, but representing the last column of the partition. 00105 * Note that col[0] represents the diag cell (i0-1,j0-1). 00106 * 00107 * @param[in] i0 start row 00108 * @param[in] j0 start column 00109 * @param[in] i1 end row 00110 * @param[in] j1 end column 00111 * @return 00112 */ 00113 score_t CPUBlockProcessor::processBlock(cell_t *row, cell_t *col, 00114 const int i0, const int j0, const int i1, const int j1, 00115 const int recurrenceType) { 00116 /* Initializing the best score of this block */ 00117 score_t block_best; 00118 block_best.i = -1; 00119 block_best.j = -1; 00120 block_best.score = -INF; 00121 00122 /* sequence strings starting from the position i0 and j0. */ 00123 const char* seq0 = this->seq0 + i0; 00124 const char* seq1 = this->seq1 + j0; 00125 00126 int h11 = col[0].h; // diagonal cell H[i-1][j-1] 00127 //printf("[%d..%d][%d..%d] %d\n", i0, i1, j0, j1, h11); 00128 00129 for (int i=0; i<i1-i0; i++) { 00130 /* Reads cells from the previous left-block */ 00131 int h01 = col[i+1].h; // H[i][j-1] 00132 int e00 = col[i+1].e; // E[i][j-1] 00133 00134 const unsigned char c = seq0[i]; 00135 for (int j=0; j<j1-j0; j++) { 00136 int h10 = row[j].h; // H[i-1][j] 00137 int f10 = row[j].f; // F[i-1][j] 00138 00139 /* Calculates H[i][j] */ 00140 int h00; 00141 if (recurrenceType == SMITH_WATERMAN) { 00142 sw(c, seq1[j], &e00, &f10, h01, h11, h10, &h00); 00143 } else { 00144 nw(c, seq1[j], &e00, &f10, h01, h11, h10, &h00); 00145 } 00146 00147 /* Store the cells to be used in the next iteration */ 00148 h11 = h10; 00149 h01 = h00; 00150 row[j].h = h00; 00151 row[j].f = f10; 00152 00153 /* Updates best score if necessary */ 00154 if (block_best.score < h00) { 00155 block_best.score = h00; 00156 block_best.i = i0+i; 00157 block_best.j = j0+j; 00158 } 00159 } 00160 00161 /* Store cells to the next right block */ 00162 if (i==0) { 00163 col[0].h = h11; // Last diagonal cell H[i-1][j-1] 00164 } 00165 h11 = col[i+1].h; 00166 col[i+1].h = h01; 00167 col[i+1].e = e00; 00168 } 00169 //printf("[%d..%d][%d..%d] %d\n", i0, i1, j0, j1, h11); 00170 00171 if (DEBUG) printf("ProcessBlock (%d,%d)-(%d,%d) - best:(%d,%d,%d)\n", i0, j0, i1, j1, block_best.score, block_best.i, block_best.j); 00172 00173 return block_best; 00174 } 00175
1.7.6.1