MASA-Core
AlignerManager.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 "AlignerManager.hpp"
00023 #include <stdlib.h>
00024 #include "io/InitialCellsReader.hpp"
00025 
00026 #define DEBUG (0)
00027 
00028 /** Maximum number of cells computed per iteration in the matching procedure */
00029 #define BUS_BASE_SIZE   (1*1024) // 1K cells
00030 
00031 AlignerManager::AlignerManager(IAligner* aligner) {
00032         this->aligner = aligner;
00033         this->score_params = aligner->getScoreParameters();
00034 
00035         /* Clear the values of all structures */
00036 
00037         this->lastColumnWriter = NULL;
00038         this->lastRowWriter = NULL;
00039         this->firstColumnReader = NULL;
00040         this->firstRowFile = NULL;
00041 
00042         this->specialRowsPartition = NULL;
00043         this->bestScoreList = NULL;
00044         this->bestScoreLocation = AT_NOWHERE;
00045         this->goalScore = -INF;
00046         this->foundCrosspoint = false;
00047         this->nextCrosspoint.score = -INF;
00048         this->nextCrosspoint.i = -1;
00049         this->nextCrosspoint.j = -1;
00050 
00051         this->blocksFile = NULL;
00052 
00053         unsetSuperPartition();
00054 
00055         /*this->processLastCellFunction = NULL;
00056         this->processLastColumnFunction = NULL;
00057         this->processLastRowFunction = NULL;
00058         this->processScoreFunction = NULL;*/
00059 
00060         this->recurrenceType = SMITH_WATERMAN;
00061         this->blockPruning = false;
00062         //this->firstColumnGapped = false;
00063         //this->firstRowGapped = false;
00064 
00065         this->baseColumn = (cell_t*)malloc(BUS_BASE_SIZE*sizeof(cell_t));
00066         this->baseRow = (cell_t*)malloc(BUS_BASE_SIZE*sizeof(cell_t));
00067 
00068         this->lastColumnReader = NULL;
00069         this->lastRowReader = NULL;
00070 
00071         aligner->setManager(this);
00072 }
00073 
00074 AlignerManager::~AlignerManager() {
00075         /* Deallocate and close every previously allocated resource */
00076 
00077         if (firstRowFile != NULL) {
00078                 fclose(firstRowFile);
00079                 firstRowFile = NULL;
00080         }
00081 
00082         if (this->baseColumn != NULL) {
00083                 free(this->baseColumn);
00084                 this->baseColumn = NULL;
00085         }
00086 }
00087 
00088 /*
00089  * @see definition on header file
00090  */
00091 void AlignerManager::alignPartition(Partition partition, int start_type) {
00092         this->partition = partition;
00093         this->startType = start_type;
00094         this->foundCrosspoint = false;
00095 
00096         if (partition.getWidth() == 0 || partition.getHeight() == 0) {
00097                 fprintf(stderr, "Zero-area partition. Skipping.\n");
00098                 return;
00099         }
00100 
00101         lastColumnPos = 0; // TODO uniformizar sem +1
00102         lastRowPos = 0;
00103 
00104         bestScoreLastColumn.score = -INF;
00105         bestScoreLastColumn.i = -1;
00106         bestScoreLastColumn.j = -1;
00107         bestScoreLastRow.score = -INF;
00108         bestScoreLastRow.i = -1;
00109         bestScoreLastRow.j = -1;
00110 
00111         //this->firstColumnPos = 1;
00112         //this->firstRowPos = 0;
00113 
00114         this->active = true;
00115 
00116         if (specialRowsPartition != NULL) {
00117                 setFirstRowSource(specialRowsPartition->getFirstRowReader());
00118                 setFirstColumnSource(specialRowsPartition->getFirstColumnReader());
00119                 setLastColumnDestination(specialRowsPartition->getLastColumnWriter());
00120                 setLastRowDestination(specialRowsPartition->getLastRowWriter());
00121         }
00122 
00123         // TODO desalocar o firstColumn reader quando alocado internamente
00124         // verificar se existe algum cenĂ¡rio onde firstColumnReader == NULL
00125 //      if (firstColumnReader != NULL) {
00126 //              cell_t tmp;
00127 //              firstColumnReader->read(&tmp, 1);
00128 //      }
00129 
00130 //      if (mustDispatchLastColumn()) {
00131 //              cell_t first_cell;
00132 //              first_cell.h = partition.getWidth() *-score_params->gap_ext - (start_type==TYPE_GAP_1 ? 0 : score_params->gap_open);
00133 //              first_cell.f = first_cell.h;
00134 //          dispatchColumn(partition.getJ1(), &first_cell, 1);
00135 //      }
00136 
00137         if (goalScoreLocation == AT_SEQUENCE_2 || goalScoreLocation == AT_SEQUENCE_1_OR_2) {
00138                 match_result_t result = findFullGap(partition.getWidth(), start_type!=TYPE_GAP_1, lastColumnReader);
00139                 if (result.found) {
00140                         nextCrosspoint.j = partition.getJ1();
00141                         nextCrosspoint.i = partition.getI0();
00142                         nextCrosspoint.score = result.score;
00143                         nextCrosspoint.type = TYPE_GAP_1;
00144                         if (DEBUG) printf ( "-- Crosspoint found on last column: (%d,%d) - %d [%d] FULL GAP!\n",
00145                                         nextCrosspoint.i, nextCrosspoint.j, nextCrosspoint.score, nextCrosspoint.type);
00146                         this->active = false;
00147                 }
00148         }
00149 
00150         if (goalScoreLocation == AT_SEQUENCE_1 || goalScoreLocation == AT_SEQUENCE_1_OR_2) {
00151                 match_result_t result = findFullGap(partition.getHeight(), start_type!=TYPE_GAP_2, lastRowReader);
00152                 if (result.found) {
00153                         nextCrosspoint.j = partition.getJ0();
00154                         nextCrosspoint.i = partition.getI1();
00155                         nextCrosspoint.score = result.score;
00156                         nextCrosspoint.type = TYPE_GAP_2;
00157                         if (DEBUG) printf ( "-- Crosspoint found on last row: (%d,%d) - %d [%d] FULL GAP!\n",
00158                                         nextCrosspoint.i, nextCrosspoint.j, nextCrosspoint.score, nextCrosspoint.type);
00159                         this->active = false;
00160                 }
00161         }
00162 
00163 
00164         if (this->active) {
00165                 Partition partition_adj = Partition(partition, -seq0_offset, -seq1_offset);
00166                 aligner->alignPartition(partition_adj);
00167         }
00168 }
00169 
00170 /*
00171  * @see definition on header file
00172  */
00173 void AlignerManager::setSequences(Sequence* seq0, Sequence* seq1, int i0, int j0, int i1, int j1, FILE* stats) {
00174         if (DEBUG) printf("AlignerManager::setSequences(%p, %p, %d, %d, %d, %d, %p)\n", seq0, seq1, i0, j0, i1, j1, stats);
00175         seq0_offset = i0;
00176         seq1_offset = j0;
00177         aligner->setSequences(seq0->getData()+seq0_offset, seq1->getData()+seq1_offset, i1-i0, j1-j0);
00178         if (stats != NULL) {
00179                 aligner->printStageStatistics(stats);
00180         }
00181 }
00182 
00183 /*
00184  * @see definition on header file
00185  */
00186 void AlignerManager::unsetSequences() {
00187         aligner->unsetSequences();
00188 }
00189 
00190 
00191 
00192 /**
00193  *
00194  */
00195 void AlignerManager::setBlockPruning(bool blockPruning) {
00196         this->blockPruning = blockPruning;
00197 }
00198 
00199 /*
00200  * @see definition on header file
00201  */
00202 //void AlignerManager::setFirstColumnSource(int firstColumnInitType) {
00203 //      this->firstColumnInitType = firstColumnInitType;
00204 //      if (firstColumnInitType == INIT_WITH_GAPS_OPENED) {
00205 //              this->firstColumnReader = new InitialCellsReader(0, score_params->gap_ext);
00206 //      } else if (firstColumnInitType == INIT_WITH_GAPS) {
00207 //              this->firstColumnReader = new InitialCellsReader(score_params->gap_open, score_params->gap_ext);
00208 //      } else if (firstColumnInitType == INIT_WITH_ZEROES) {
00209 //              this->firstColumnReader = new InitialCellsReader();
00210 //      }
00211 //}
00212 
00213 /*
00214  * @see definition on header file
00215  */
00216 void AlignerManager::setFirstColumnSource(SeekableCellsReader* firstColumnReader) {
00217         firstColumnInitType = firstColumnReader->getType();
00218         this->firstColumnReader = firstColumnReader;
00219 
00220 //      if (this->firstColumnReader->getType() != INIT_WITH_CUSTOM_DATA) {
00221 //              this->firstColumnReader->seek(0);
00222 //      }
00223 
00224 //      if (specialRowsPartition != NULL) {
00225 //              specialRowsPartition->setFirstColumnReader(firstColumnReader);
00226 //      }
00227 
00228 }
00229 
00230 /*
00231  * @see definition on header file
00232  */
00233 //void AlignerManager::setFirstRowSource(int firstRowInitType) {
00234 //      this->firstRowInitType = firstRowInitType;
00235 //      if (firstRowInitType == INIT_WITH_GAPS_OPENED) {
00236 //              this->firstRowReader = new InitialCellsReader(0, score_params->gap_ext);
00237 //      } else if (firstRowInitType == INIT_WITH_GAPS) {
00238 //              this->firstRowReader = new InitialCellsReader(score_params->gap_open, score_params->gap_ext);
00239 //      } else if (firstRowInitType == INIT_WITH_ZEROES) {
00240 //              this->firstRowReader = new InitialCellsReader();
00241 //      }
00242 //}
00243 
00244 /*
00245  * @see definition on header file
00246  */
00247 void AlignerManager::setFirstRowSource(SeekableCellsReader* firstRowReader) {
00248         this->firstRowInitType = firstRowReader->getType();
00249         this->firstRowReader = firstRowReader;
00250 
00251 //      if (this->firstRowReader->getType() != INIT_WITH_CUSTOM_DATA) {
00252 //              this->firstRowReader->seek(0);
00253 //      }
00254 
00255 //      if (specialRowsPartition != NULL) {
00256 //              specialRowsPartition->setFirstRowReader(firstRowReader);
00257 //      }
00258 }
00259 
00260 /*
00261  * @see definition on header file
00262  */
00263 void AlignerManager::setLastColumnDestination(CellsWriter* lastColumnWriter) {
00264         this->lastColumnWriter = lastColumnWriter;
00265 }
00266 
00267 
00268 Partition AlignerManager::getSuperPartition() {
00269         if (superPartition.getJ0() == -1) {
00270                 return Partition(partition, -seq0_offset, -seq1_offset);
00271         } else {
00272                 return Partition(superPartition, -seq0_offset, -seq1_offset);
00273         }
00274 }
00275 
00276 void AlignerManager::setSuperPartition(Partition superPartition) {
00277         this->superPartition = superPartition;
00278 }
00279 
00280 void AlignerManager::unsetSuperPartition() {
00281         this->superPartition = Partition(-1,-1,-1,-1);
00282 }
00283 
00284 void AlignerManager::setLastRowDestination(CellsWriter* lastRowWriter) {
00285         this->lastRowWriter = lastRowWriter;
00286 }
00287 
00288 void AlignerManager::setLastColumnReader(SeekableCellsReader* lastColumnReader) {
00289         this->lastColumnReader = lastColumnReader;
00290 }
00291 
00292 void AlignerManager::setLastRowReader(SeekableCellsReader* lastRowReader) {
00293         this->lastRowReader = lastRowReader;
00294 }
00295 
00296 /*
00297  * @see definition on header file
00298  */
00299 void AlignerManager::setRecurrenceType(int recurrenceType) {
00300         this->recurrenceType = recurrenceType;
00301 }
00302 
00303 /*
00304  * @see definition on header file
00305  */
00306 void AlignerManager::setSpecialRowsPartition(SpecialRowsPartition* specialRowsPartition) {
00307         this->specialRowsPartition = specialRowsPartition;
00308 }
00309 
00310 /*
00311  * @see definition on header file
00312  */
00313 void AlignerManager::setSpecialRowInterval(const int specialRowInterval) {
00314         this->specialRowInterval = specialRowInterval;
00315 }
00316 
00317 
00318 void AlignerManager::receiveFirstColumn(cell_t* buffer, int len) {
00319         if (DEBUG) printf ( "AlignerManager::receiveFirstColumn(..,%d)\n", len);
00320         firstColumnReader->read(buffer, len);
00321 }
00322 
00323 /*
00324  * @see definition on header file
00325  */
00326 void AlignerManager::receiveFirstRow(cell_t* buffer, int len) {
00327         if (DEBUG) printf ( "AlignerManager::receiveFirstRow(..,%d)\n", len);
00328         firstRowReader->read(buffer, len);
00329 }
00330 
00331 /*
00332  * @see definition on header file
00333  */
00334 void AlignerManager::dispatchColumn(int j, const cell_t* buffer, int len) {
00335         j += seq1_offset;
00336         if (DEBUG) printf ( "AlignerManager::dispatchColumn (%d,..,%d) %d %s\n", j, len, partition.getJ1(), j==partition.getJ1()?"LAST COL":"");
00337 
00338         //printf("%d != %d \n", j0+j, j1);
00339         if (j == partition.getJ1()) {
00340                 int best_id = findBestCell(buffer, len);
00341                 score_t score_adj;
00342                 score_adj.score = buffer[best_id].h;
00343                 score_adj.j = partition.getJ1();
00344                 score_adj.i = partition.getI0()+lastColumnPos+best_id;
00345                 if (bestScoreLastColumn.score <= score_adj.score) {
00346                         bestScoreLastColumn = score_adj;
00347                 }
00348 
00349                 if (lastColumnWriter != NULL) {
00350                         lastColumnWriter->write(buffer, len);
00351                 }
00352                 if (bestScoreLocation == AT_SEQUENCE_2 || bestScoreLocation == AT_SEQUENCE_1_OR_2) {
00353                         bestScoreList->add(score_adj.i, score_adj.j, score_adj.score);
00354                 }
00355                 if (goalScoreLocation == AT_ANYWHERE || goalScoreLocation == AT_SEQUENCE_2 || goalScoreLocation == AT_SEQUENCE_1_OR_2) {
00356                         match_result_t result = findGoalCell(buffer, baseColumn, len, lastColumnReader);
00357                         if (result.found) {
00358                                 nextCrosspoint.j = partition.getJ1();
00359                                 nextCrosspoint.i = partition.getI0()+lastColumnPos+result.k;
00360                                 nextCrosspoint.score = result.score;
00361                                 nextCrosspoint.type = result.type==MATCH_ALIGNED ? TYPE_MATCH : TYPE_GAP_1;
00362                                 if (DEBUG) printf ( "-- Crosspoint found on last column: (%d,%d) - %d [%d]!\n",
00363                                                 nextCrosspoint.i, nextCrosspoint.j, nextCrosspoint.score, nextCrosspoint.type);
00364                                 stopAligner();
00365                         }
00366                 }
00367                 lastColumnPos += len;
00368         }
00369 }
00370 
00371 /*
00372  * @see definition on header file
00373  */
00374 void AlignerManager::dispatchRow(int i, const cell_t* buffer, int len) {
00375         i += seq0_offset;
00376         if (DEBUG) printf ( "AlignerManager::dispatchRow (%d,..,%d) %d %s\n", i, len, partition.getI1(), i==partition.getI1()?"LAST ROW":"");
00377         if (mustDispatchSpecialRows()) {
00378                 specialRowsPartition->write(i, buffer, len);
00379         }
00380         if (i == partition.getI1()) {
00381                 if (lastRowWriter != NULL) {
00382                         lastRowWriter->write(buffer, len);
00383                 }
00384                 if (bestScoreLocation == AT_SEQUENCE_1 || bestScoreLocation == AT_SEQUENCE_1_OR_2) {
00385                         int best_id = findBestCell(buffer, len);
00386                         score_t score_adj;
00387                         score_adj.score = buffer[best_id].h;
00388                         score_adj.j = partition.getJ0()+lastRowPos+best_id;
00389                         score_adj.i = partition.getI1();
00390                         bestScoreList->add(score_adj.i, score_adj.j, score_adj.score);
00391                 }
00392                 if (goalScoreLocation == AT_ANYWHERE || goalScoreLocation == AT_SEQUENCE_1 || goalScoreLocation == AT_SEQUENCE_1_OR_2) {
00393                         match_result_t result = findGoalCell(buffer, baseRow, len, lastRowReader);
00394                         if (result.found) {
00395                                 nextCrosspoint.i = partition.getI1();
00396                                 nextCrosspoint.j = partition.getJ0()+lastRowPos+result.k;
00397                                 nextCrosspoint.score = result.score;
00398                                 nextCrosspoint.type = result.type==MATCH_ALIGNED ? TYPE_MATCH : TYPE_GAP_2;
00399                                 if (DEBUG) printf ( "-- Crosspoint found on last row: (%d,%d) - %d [%d]!\n",
00400                                                 nextCrosspoint.i, nextCrosspoint.j, nextCrosspoint.score, nextCrosspoint.type);
00401                                 stopAligner();
00402                         }
00403                 }
00404                 lastRowPos += len;
00405         }
00406 }
00407 
00408 /*
00409  * @see definition on header file
00410  */
00411 void AlignerManager::dispatchScore(score_t score, int bx, int by) {
00412         score_t score_adj;
00413         score_adj.i = score.i + seq0_offset + 1;
00414         score_adj.j = score.j + seq1_offset + 1;
00415         score_adj.score = score.score;
00416         if (DEBUG) printf ( "AlignerManager::dispatchScore (%d,%d,%d) - block [%d,%d]\n", score_adj.i, score_adj.j, score_adj.score, bx, by);
00417 
00418         if (blocksFile != NULL && bx != -1 && by != -1) {
00419                 if (!blocksFile->isInitialized()) {
00420                         blocksFile->initialize(aligner->getGrid());
00421                 }
00422                 blocksFile->setScore(bx, by, score_adj.score);
00423         }
00424         if (score_adj.score > -INF) {
00425                 if (bestScoreLocation == AT_ANYWHERE) {
00426                         bestScoreList->add(score_adj.i, score_adj.j, score_adj.score);
00427                 } else if (bestScoreLocation == AT_SEQUENCE_1_AND_2) {
00428                         if (score_adj.i == partition.getI1() && score_adj.j == partition.getJ1()) {
00429                                 bestScoreList->add(score_adj.i, score_adj.j, score_adj.score);
00430                         }
00431                 }
00432                 if (goalScoreLocation == AT_ANYWHERE) {
00433                         if (score_adj.score == goalScore) {
00434                                 nextCrosspoint.i = score_adj.i;
00435                                 nextCrosspoint.j = score_adj.j;
00436                                 nextCrosspoint.score = 0;
00437                                 nextCrosspoint.type = 0;
00438                                 foundCrosspoint = true;
00439                                 stopAligner();
00440                                 if (DEBUG) printf ( ":GOAL END (%d,%d) - %d\n", nextCrosspoint.i, nextCrosspoint.j, nextCrosspoint.score);
00441                         }
00442                 }
00443         }
00444         /*if (processScoreFunction != NULL) {
00445                 processScoreFunction(score_adj, bx, by);
00446         }
00447         if (processLastCellFunction != NULL && score_adj.i == partition.getI1()-1 && score_adj.j == partition.getJ1()-1) {
00448                 processLastCellFunction(score_adj, bx, by);
00449         }*/
00450 }
00451 
00452 /*
00453  * @see definition on header file
00454  */
00455 bool AlignerManager::mustDispatchLastCell() {
00456         return /*processLastCellFunction != NULL
00457                         ||*/ (bestScoreLocation == AT_SEQUENCE_1_AND_2);
00458 }
00459 
00460 /*
00461  * @see definition on header file
00462  */
00463 bool AlignerManager::mustDispatchLastRow() {
00464         return /*processLastRowFunction != NULL
00465                         ||*/
00466                         (lastRowWriter != NULL)
00467                         || (bestScoreLocation == AT_SEQUENCE_1 || bestScoreLocation == AT_SEQUENCE_1_OR_2)
00468                         || ((goalScoreLocation == AT_ANYWHERE || goalScoreLocation == AT_SEQUENCE_1 || goalScoreLocation == AT_SEQUENCE_1_OR_2) && lastRowReader != NULL)
00469                         ;
00470 }
00471 
00472 /*
00473  * @see definition on header file
00474  */
00475 bool AlignerManager::mustDispatchLastColumn() {
00476         return /*(processLastColumnFunction != NULL)
00477                         ||*/
00478                         (lastColumnWriter != NULL)
00479                         || (bestScoreLocation == AT_SEQUENCE_2 || bestScoreLocation == AT_SEQUENCE_1_OR_2)
00480                         || ((goalScoreLocation == AT_ANYWHERE || goalScoreLocation == AT_SEQUENCE_2 || goalScoreLocation == AT_SEQUENCE_1_OR_2) && lastColumnReader != NULL)
00481                         ;
00482 }
00483 
00484 /*
00485  * @see definition on header file
00486  */
00487 bool AlignerManager::mustDispatchSpecialRows() {
00488         return specialRowsPartition != NULL && specialRowsPartition->isPersistent();
00489 }
00490 
00491 /*
00492  * @see definition on header file
00493  */
00494 bool AlignerManager::mustDispatchSpecialColumns() {
00495         return false;
00496 }
00497 
00498 /*
00499  * @see definition on header file
00500  */
00501 bool AlignerManager::mustDispatchScores() {
00502         return (/*processScoreFunction != NULL ||*/ bestScoreLocation == AT_ANYWHERE || goalScoreLocation == AT_ANYWHERE || blocksFile != NULL);
00503 }
00504 
00505 /*
00506  * @see definition on header file
00507  */
00508 int AlignerManager::getRecurrenceType() const {
00509         return recurrenceType;
00510 }
00511 
00512 /*
00513  * @see definition on header file
00514  */
00515 int AlignerManager::getSpecialRowInterval() const {
00516         return specialRowInterval;
00517 }
00518 
00519 int AlignerManager::getSpecialColumnInterval() const {
00520         return 0;
00521 }
00522 
00523 void AlignerManager::stopAligner() {
00524         active = false;
00525 }
00526 
00527 bool AlignerManager::mustContinue() {
00528         return active;
00529 }
00530 
00531 
00532 /*
00533  * @see definition on header file
00534  */
00535 bool AlignerManager::mustPruneBlocks() {
00536         return blockPruning;
00537 }
00538 
00539 /*
00540  * @see definition on header file
00541  */
00542 int AlignerManager::getFirstColumnInitType() {
00543         return firstColumnInitType;
00544 }
00545 
00546 /*
00547  * @see definition on header file
00548  */
00549 void AlignerManager::setPenalties(const int match, const int mismatch,
00550                 const int gapOpen, const int gapExtension) {
00551         // TODO Not supported yet.
00552         this->match = match;
00553         this->mismatch = mismatch;
00554         this->gapOpen = gapOpen;
00555         this->gapExtension = gapExtension;
00556 }
00557 
00558 /*
00559  * @see definition on header file
00560  */
00561 int AlignerManager::getFirstRowInitType() {
00562         return firstRowInitType;
00563 }
00564 
00565 void AlignerManager::setBestScoreList(BestScoreList* bestScoreList, const int bestScoreLocation) {
00566         if (bestScoreList == NULL || bestScoreList == NULL) {
00567                 this->bestScoreLocation = AT_NOWHERE;
00568                 this->bestScoreList = NULL;
00569         } else {
00570                 this->bestScoreLocation = bestScoreLocation;
00571                 this->bestScoreList = bestScoreList;
00572         }
00573 }
00574 
00575 void AlignerManager::setBlocksFile(BlocksFile* blocksFile) {
00576         this->blocksFile = blocksFile;
00577 }
00578 
00579 void AlignerManager::setGoalScore(int goalScore, const int goalScoreLocation) {
00580         if (goalScore == -INF || goalScoreLocation == AT_NOWHERE) {
00581                 unsetGoalScore();
00582         } else {
00583                 this->goalScore = goalScore;
00584                 this->goalScoreLocation = goalScoreLocation;
00585         }
00586 }
00587 
00588 void AlignerManager::unsetGoalScore() {
00589         this->goalScore = -INF;
00590         this->goalScoreLocation = AT_NOWHERE;
00591 }
00592 
00593 const crosspoint_t AlignerManager::getNextCrosspoint() const {
00594         if (foundCrosspoint) {
00595                 return nextCrosspoint;
00596         } else {
00597                 crosspoint_t null;
00598                 null.i = -1;
00599                 null.j = -1;
00600                 null.score = -INF;
00601                 null.type = TYPE_MATCH;
00602                 return null;
00603         }
00604 }
00605 
00606 
00607 bool AlignerManager::isFoundCrosspoint() const {
00608         return foundCrosspoint;
00609 }
00610 
00611 int AlignerManager::findBestCell(const cell_t* buffer, int len) {
00612         int best_score = -INF;
00613         int best_id = 0;
00614         for (int k = 0; k < len; k++) {
00615                 if (best_score < buffer[k].h) {
00616                         best_score = buffer[k].h;
00617                         best_id = k;
00618                 }
00619                 if (DEBUG) printf("bestCell: [%d]:%d/%d\n", k, buffer[k].h, best_score);
00620         }
00621         return best_id;
00622 }
00623 
00624 
00625 match_result_t AlignerManager::findGoalCell(const cell_t* buffer, cell_t* base, int len, CellsReader* cellsReader) {
00626         match_result_t result;
00627         result.found = false;
00628         if (!foundCrosspoint) {
00629                 if (cellsReader == NULL) {
00630                         /*if (goalScoreLocation != AT_ANYWHERE) {
00631                                 for (int k = 0; k < len; k++) {
00632                                         if (buffer[k].h == goalScore) {
00633                                                 result.found = true;
00634                                                 result.score = 0;
00635                                                 result.type = MATCH_ALIGNED;
00636                                                 result.k = k;
00637                                                 foundCrosspoint = true;
00638                                                 break;
00639                                         }
00640                                 }
00641                         }*/
00642                 } else {
00643                         for (int k=0; k<len; k+=BUS_BASE_SIZE) {
00644                                 int local_len = len-k > BUS_BASE_SIZE?BUS_BASE_SIZE:len-k;
00645                                 cellsReader->read(base, local_len);
00646                                 result = aligner->matchLastColumn ( buffer+k, base, local_len, goalScore );
00647                                 if ( result.found ) {
00648                                         result.k += k;
00649                                         foundCrosspoint = true;
00650                                         break;
00651                                 }
00652                         }
00653                 }
00654         }
00655         return result;
00656 }
00657 
00658 match_result_t AlignerManager::findFullGap(int len, bool openGap, SeekableCellsReader* cellsReader) {
00659         match_result_t result;
00660         result.found = false;
00661 
00662         if (!foundCrosspoint && cellsReader != NULL) {
00663                 cell_t first_cell;
00664                 first_cell.f = len*-score_params->gap_ext - (openGap ? score_params->gap_open : 0);
00665                 first_cell.h = -INF;
00666                 cell_t base_cell;
00667                 int offset = cellsReader->getOffset();
00668                 cellsReader->read(&base_cell, 1);
00669                 cellsReader->seek(offset);
00670                 if (base_cell.f + first_cell.f + score_params->gap_open == goalScore) {
00671                         result.found = true;
00672                         result.k = len;
00673                         result.score = base_cell.f;
00674                         result.type = MATCH_GAPPED;
00675                         foundCrosspoint = true;
00676                 }
00677 
00678 //              int first = -1;
00679 //              int last = -1;
00680 //              for (int k=0; k<len; k++) {
00681 //                      cellsReader->read(&base_cell, 1);
00682 //                      int gaps = len-k;
00683 //                      int min_penalty = (gaps==0) ? 0 : score_params->gap_open+gaps*score_params->gap_ext;
00684 //                      //int max_penalty = (gaps==0) ? 0 : (len+k)*score_params->gap_ext;
00685 //                      int min_range = k*score_params->mismatch - min_penalty;
00686 //                      int max_range = k*score_params->match - min_penalty;
00687 //                      int diff = goalScore-base_cell.h;
00688 //                      if (diff <= max_range && diff >= min_range) {
00689 ////                            printf(">>>>>> %d/%d, base: %d   diff: %d   range: %d/%d  %s\n", k, len,
00690 ////                                    base_cell.h, diff, min_range, max_range,
00691 ////                                    (diff <= max_range && diff >= min_range) ? "POSSIBLE!" : "");
00692 //                              if (first == -1) first = k;
00693 //                              last = k;
00694 //                      }
00695 //              }
00696 //              for (int k=len; k<len*2; k++) {
00697 //                      cellsReader->read(&base_cell, 1);
00698 //                      int gaps = k-len;
00699 //                      int min_penalty = (gaps==0) ? 0 : score_params->gap_open+gaps*score_params->gap_ext;
00700 //                      //int max_penalty = (gaps==0) ? 0 : (len+k)*score_params->gap_ext;
00701 //                      int min_range = len*score_params->mismatch - min_penalty;
00702 //                      int max_range = len*score_params->match - min_penalty;
00703 //                      int diff = goalScore-base_cell.h;
00704 //                      if (diff <= max_range && diff >= min_range) {
00705 ////                            printf(">>>>>$ %d/%d, base: %d   diff: %d   range: %d/%d  %s\n", k, len,
00706 ////                                    base_cell.h, diff, min_range, max_range,
00707 ////                                    (diff <= max_range && diff >= min_range) ? "POSSIBLE!" : "");
00708 //                              if (first == -1) first = k;
00709 //                              last = k;
00710 //                      }
00711 //              }
00712 //              cellsReader->seek(offset);
00713 //              printf(">>>>>>> RANGE: %d/%d\n", first+offset, last+offset);
00714 
00715         }
00716 
00717         return result;
00718 }
00719 
00720 score_t AlignerManager::getBestScoreLastColumn() const {
00721         return bestScoreLastColumn;
00722 }
00723 
00724 score_t AlignerManager::getBestScoreLastRow() const {
00725         return bestScoreLastRow;
00726 }
00727