MASA-Core
AbstractDiagonalAligner.hpp
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 #ifndef ABSTRACTDIAGONALALIGNER_HPP_
00023 #define ABSTRACTDIAGONALALIGNER_HPP_
00024 
00025 #include "../libmasa.hpp"
00026 
00027 #include "../pruning/BlockPruningDiagonal.hpp"
00028 
00029 /**
00030  * @brief Abstract class that processes diagonal of blocks.
00031  *
00032  * This class implements some common behavior to simplify the implementation
00033  * of diagonal aligners. Use the AbstractDiagonalAligner if you want to compute
00034  * all blocks inside the diagonal at once inside the architecture hardware/software.
00035  * Differently from the AbstractBlockAligner,
00036  * the AbstractDiagonalAligner does not use an AbstractBlockProcessor object,
00037  * what means that the Aligner must compute the blocks by themselves.
00038  *
00039  * In order to extend an AbstractDiagonalAligner, the class must implement
00040  * two group of methods.
00041  *
00042  * <ul>
00043  *  <li>Memory related methods: get/set methods that obtain the
00044  *      results from the specific architecture, such as block scores and
00045  *      special rows/columns.
00046  *  <li>Iteration methods: responsible to execute the diagonal iterations.
00047  *      The diagonals are numbered from 0. Generically speaking, diagonal
00048  *      with number $d$ is expected to compute all blocks $(bx,by)$ such that
00049  *      $bx+by=d$ is true.
00050  * </ul>
00051  *
00052  * The memory related methods are called considering the order of the executed
00053  * iteration, so we guarantee that a special row/column will only be issued
00054  * when it is already computed.
00055  */
00056 class AbstractDiagonalAligner : public AbstractAligner {
00057 public:
00058         /* Constructors */
00059 
00060         AbstractDiagonalAligner();
00061         virtual ~AbstractDiagonalAligner();
00062 
00063         /* Implementation of virtual methods from IAligner */
00064 
00065         virtual void alignPartition(Partition partition);
00066 
00067         virtual void clearStatistics();
00068         virtual void printInitialStatistics(FILE* file);
00069         virtual void printStageStatistics(FILE* file);
00070         virtual void printFinalStatistics(FILE* file);
00071         virtual void printStatistics(FILE* file);
00072         virtual long long getProcessedCells();
00073         virtual const char* getProgressString() const;
00074 
00075 protected:
00076 
00077         /* Virtual methods that must be implemented by subclasses */
00078 
00079         /**
00080          * Returns the number of horizontal blocks that the grid must have
00081          * for a given width partition.
00082          *
00083          * @param width the width of the partition to be aligned.
00084          * @return the recommended grid width for that partition.
00085          */
00086         virtual int getGridWidth(int width) = 0;
00087 
00088         /**
00089          * Returns the default height of each block. All the blocks will have
00090          * the same height except the bottom most rows, that may be truncated.
00091          *
00092          * @return the default height of each block.
00093          */
00094         virtual int getBlockHeight() = 0;
00095 
00096         /**
00097          * Returns the bottom-most cells of a block computed from the previous
00098          * computed diagonal. The block cells range is in the interval $[j,j+len)$.
00099          * Since we are processing in diagonals, only one block can reside in this
00100          * range. The cells will be saved in a special row by MASA-Core.
00101          *
00102          * @param j the start column of the cells to be returned.
00103          * @param len the number of cells to be returned.
00104          * @return the vector containing the special cells.
00105          */
00106         virtual const cell_t* getSpecialRow(int j, int len) = 0;
00107 
00108         /**
00109          * Returns the cells in the interval $[j,j+len)$ of the bottom-most row.
00110          *
00111          * @param l the start column of the cells to be returned.
00112          * @param len the number of cells to be returned.
00113          * @return the vector containing the special cells.
00114          */
00115         virtual const cell_t* getLastRow(int j, int len) = 0;
00116 
00117         /**
00118          * Returns the cells in the interval $[i,i+len)$ of the bottom-most row.
00119          *
00120          * @param i the start column of the cells to be returned.
00121          * @param len the number of cells to be returned.
00122          * @return the vector containing the special cells.
00123          */
00124         virtual const cell_t* getLastColumn(int i, int len) = 0;
00125 
00126         /**
00127          * Returns the best scores of the blocks from the last computed diagonal.
00128          * @return the best scores of each blocks (ordered from left to right).
00129          */
00130         virtual const score_t* getBlockScores() = 0;
00131 
00132         /**
00133          * Initializes the cells in the range $[j,j+len)$ of the first row.
00134          * @param cells the vector containing the cells.
00135          * @param j the start column of the cells to be initialized.
00136          * @param len the number of cells to be initialized.
00137          */
00138         virtual void setFirstRow(const cell_t* cells, int j, int len) = 0;
00139 
00140         /**
00141          * Initializes the cells in the range $[i,i+len)$ of the first column.
00142          * @param cells the vector containing the cells.
00143          * @param i the start column of the cells to be initialized.
00144          * @param len the number of cells to be initialized.
00145          */
00146         virtual void setFirstColumn(const cell_t* cells, int i, int len) = 0;
00147 
00148         /**
00149          * Clear the rows of the pruned blocks, in range $[b0,b1)$. The rows
00150          * must be cleared with very small numbers (-INF) in order to avoid
00151          * garbage data in the special rows or in future non-pruned blocks
00152          * that may use the same area in memory.
00153          *
00154          * @param b0 first block to be cleared (inclusive).
00155          * @param b1 last block to be cleared (exclusive)
00156          */
00157         virtual void clearPrunedBlocks(int b0, int b1) = 0;
00158 
00159         /**
00160          * Executes initialization procedures before the first diagonal be processed.
00161          */
00162         virtual void initializeDiagonals() = 0;
00163 
00164         /**
00165          * Executes one diagonal with the blocks from $[windowLeft, windowRight]$.
00166          * The diagonals are numbered from 0, but the first diagonal (0) is not
00167          * expected to compute any block. Diagonal 1 is expected to compute
00168          * block $(0,0)$, diagonal 2 is expected to compute blocks $(1,0)$ and
00169          * $(0,1)$, and so on. Generically speaking, diagonal $d$ is expected
00170          * to compute all blocks $(bx,by)$ that $bx+by=d$.
00171          *
00172          * @param diagonal the diagonal number to be processed.
00173          * @param windowLeft the first block to be processed (inclusive).
00174          * @param windowRight the last block to be processed (inclusive).
00175          */
00176         virtual void processDiagonal(int diagonal, int windowLeft, int windowRight) = 0;
00177 
00178         /**
00179          * Executes finalization procedures after the last diagonal is processed.
00180          */
00181         virtual void finalizeDiagonals() = 0;
00182 
00183 
00184         /* Other protected methods*/
00185 
00186         Partition getPartition() const;
00187 private:
00188         /**
00189          * Vector used to store the cells of the first column.
00190          * @see AbstractDiagonalAligner::loadFirstColumn() method.
00191          */
00192         cell_t*  h_loadColumn;
00193 
00194         /** number of columns of blocks */
00195         int gridWidth;
00196         /** number of rows of blocks */
00197         int gridHeight;
00198 
00199         /** Number of external diagonals to be processed in the current partition.*/
00200         int externalDiagonalCount;
00201         /** The id of the current external diagonal being processed. */
00202         int currentExternalDiagonal;
00203 
00204         /** The partition currently being processed */
00205         Partition partition;
00206         /** Block Pruner object */
00207         BlockPruningDiagonal* pruner;
00208 
00209         /** First block of non-pruned window */
00210         int windowStart;
00211         /** Last block of non-pruned window */
00212         int windowEnd;
00213 
00214         /*
00215          * The following attributes are used for statistics purpose only.
00216          */
00217         /** Total number of blocks containing in the grid */
00218         int statTotalBlocks;
00219         /** Number of pruned blocks in the left side of the grid */
00220         int statPrunedBlocksLeft;
00221         /** Number of pruned blocks in the left side of the grid */
00222         int statPrunedBlocksRight;
00223         /** Total number of cells in the grid */
00224         long long statTotalCells;
00225         /** Maintains the minimum gridWidth used. */
00226         int statMinGridWidth;
00227         /** Maintains the maximum gridWidth used. */
00228         int statMaxGridWidth;
00229 
00230         /* Iteration related methods */
00231 
00232         Grid* configureGrid(Partition partition);
00233         void prepareIterations();
00234         void processNextIteration();
00235         bool hasMoreIterations();
00236         void finalizeIterations();
00237 
00238         /* ``flushXXX'' methods dispatch data from the Aligner to MASA-Core. */
00239 
00240         void flushSpecialRows();
00241         void flushLastRow();
00242         void flushLastColumn();
00243         void flushLastCell();
00244         void flushBlockScores();
00245 
00246         /* ``loadXXX'' methods receives data from MASA-Core and send them to the Aligner. */
00247 
00248         void loadFirstRow();
00249         void loadFirstColumn();
00250 
00251         /* Other methods */
00252 
00253         bool isSpecialRow(int by);
00254         void pruneBlocks();
00255 };
00256 
00257 #endif /* ABSTRACTDIAGONALALIGNER_HPP_ */