MASA-Core
Grid.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 "Grid.hpp"
00023 
00024 #include <stdio.h>
00025 #include "utils/AlignerUtils.hpp"
00026 
00027 Grid::Grid(Partition partition) {
00028         this->partition = partition;
00029         this->blockSplitHorizontal = NULL;
00030         this->blockSplitVertical = NULL;
00031 
00032         this->blockCountHorizontal = 0;
00033         this->blockCountVertical = 0;
00034 
00035         this->blockHeight = 0;
00036         this->blockWidth = 0;
00037 
00038         this->width = partition.getWidth();
00039         this->height = partition.getHeight();
00040 
00041         this->adjustment = 0;
00042 
00043         setMinBlockSize(1, 1);
00044 }
00045 
00046 Grid::~Grid() {
00047         delete blockSplitHorizontal;
00048         delete blockSplitVertical;
00049 }
00050 
00051 
00052 void Grid::setBlockHeight(int blockHeight) {
00053         if (blockHeight <= minBlockHeight) {
00054                 blockHeight = minBlockHeight;
00055         }
00056         this->blockHeight = blockHeight;
00057         this->blockCountVertical = (height+blockHeight-1)/blockHeight;
00058         this->blockSplitVertical = NULL;
00059 }
00060 
00061 void Grid::setBlockWidth(int blockWidth) {
00062         if (blockWidth <= minBlockWidth) {
00063                 blockWidth = minBlockWidth;
00064         }
00065         this->blockWidth = blockWidth;
00066         this->blockCountHorizontal = (width+blockWidth-1)/blockWidth;
00067         this->blockSplitHorizontal = NULL;
00068 }
00069 
00070 
00071 void Grid::splitGridVertically(int count, int* splits) {
00072         if (blockSplitHorizontal != NULL) {
00073                 delete blockSplitHorizontal;
00074         }
00075         this->blockHeight = -1;
00076         this->blockCountVertical = count;
00077         this->blockSplitVertical = splits;
00078 
00079 }
00080 
00081 void Grid::splitGridHorizontally(int count, int* splits) {
00082         if (blockSplitVertical != NULL) {
00083                 delete blockSplitVertical;
00084         }
00085         this->blockWidth = -1;
00086         this->blockCountHorizontal = count;
00087         this->blockSplitHorizontal = splits;
00088 }
00089 
00090 /**
00091  * Splits the grid in $count$ positions (vertically). If $count$ is greater
00092  * than the sequence size, then each partition has the almost the same height,
00093  * with a maximum difference of $1$.
00094  *
00095  * @param count number of parts to split the grid.
00096  */
00097 void Grid::splitGridVertically(int count) {
00098         if (blockSplitVertical != NULL) {
00099                 delete blockSplitVertical;
00100         }
00101         if (count > height/minBlockHeight) {
00102                 count = height/minBlockHeight;
00103         }
00104         if (count < 1) {
00105                 count = 1;
00106         }
00107         this->blockHeight = -1;
00108         this->blockCountVertical = count;
00109         this->blockSplitVertical = new int[count+1];
00110 
00111         // Splits the grid into blocks with almost equal size.
00112         AlignerUtils::splitBlocksEvenly(blockSplitVertical, partition.getI0(), partition.getI1(), count);
00113 }
00114 
00115 /**
00116  * Splits the grid in $count$ positions (horizontal). If $count$ is greater
00117  * than the sequence size, then each partition has the almost the same width,
00118  * with a maximum difference of $1$.
00119  *
00120  * @param count number of parts to split the grid.
00121  */
00122 void Grid::splitGridHorizontally(int count) {
00123         if (blockSplitHorizontal != NULL) {
00124                 delete blockSplitHorizontal;
00125         }
00126         if (count > width/minBlockWidth) {
00127                 count = width/minBlockWidth;
00128         }
00129         if (count < 1) {
00130                 count = 1;
00131         }
00132         this->blockWidth = -1;
00133         this->blockCountHorizontal = count;
00134         this->blockSplitHorizontal = new int[count+1];
00135 
00136         // Splits the grid into blocks with almost equal size.
00137         AlignerUtils::splitBlocksEvenly(blockSplitHorizontal, partition.getJ0(), partition.getJ1(), count);
00138 }
00139 
00140 
00141 void Grid::getBlockPositionV(int bx, int by, int* i0, int* i1) const {
00142         if (bx < 0 || by < 0 || bx >= blockCountHorizontal || by >= blockCountVertical) {
00143                 if (i0 != NULL) *i0 = -1;
00144                 if (i1 != NULL) *i1 = -1;
00145         } else {
00146                 if (blockSplitVertical != NULL) {
00147                         if (i0 != NULL) *i0 = blockSplitVertical[by];
00148                         if (i1 != NULL) *i1 = blockSplitVertical[by+1];
00149                 } else {
00150                         if (i0 != NULL) *i0 = partition.getI0() + by*blockHeight;
00151                         if (i1 != NULL) {
00152                                 *i1 = partition.getI0() + (by+1)*blockHeight;
00153                                 if (*i1 > partition.getI1()) {
00154                                         *i1 = partition.getI1();
00155                                 }
00156                         }
00157                 }
00158         }
00159 }
00160 
00161 void Grid::getBlockPositionH(int bx, int by, int* j0, int* j1) const {
00162         if (bx < 0 || by < 0 || bx >= blockCountHorizontal || by >= blockCountVertical) {
00163                 if (j0 != NULL) *j0 = -1;
00164                 if (j1 != NULL) *j1 = -1;
00165         } else {
00166                 if (blockSplitHorizontal != NULL) {
00167                         if (j0 != NULL) *j0 = blockSplitHorizontal[bx];
00168                         if (j1 != NULL) *j1 = blockSplitHorizontal[bx+1];
00169                 } else {
00170                         if (j0 != NULL) *j0 = partition.getJ0() + bx*blockWidth;
00171                         if (j1 != NULL) {
00172                                 *j1 = partition.getJ0() + (bx+1)*blockWidth;
00173                                 if (*j1 > partition.getJ1()) {
00174                                         *j1 = partition.getJ1();
00175                                 }
00176                         }
00177                 }
00178         }
00179 }
00180 
00181 void Grid::getBlockPosition(int bx, int by, int* i0, int* j0, int* i1, int* j1) const {
00182         getBlockPositionH(bx, by, j0, j1);
00183         getBlockPositionV(bx, by, i0, i1);
00184 }
00185 
00186 const int* Grid::getBlockSplitHorizontal() const {
00187         return blockSplitHorizontal;
00188 }
00189 
00190 const int* Grid::getBlockSplitVertical() const {
00191         return blockSplitVertical;
00192 }
00193 
00194 void Grid::setMinBlockSize(int minBlockWidth, int minBlockHeight) {
00195         this->minBlockWidth = minBlockWidth;
00196         this->minBlockHeight = minBlockHeight;
00197 }
00198 
00199 void Grid::setAdjustment(int adjustment) {
00200         this->adjustment = adjustment;
00201 }
00202 
00203 int Grid::getBlockAdjustment(int bx, int by) const {
00204         return adjustment;
00205 }
00206 
00207 int Grid::getGridWidth() const {
00208         return blockCountHorizontal;
00209 }
00210 
00211 int Grid::getGridHeight() const {
00212         return blockCountVertical;
00213 }
00214 
00215 int Grid::getBlockWidth(int bx, int by) const {
00216         int j0;
00217         int j1;
00218         getBlockPositionH(bx, by, &j0, &j1);
00219         return j1-j0;
00220 }
00221 
00222 int Grid::getBlockHeight(int bx, int by) const {
00223         int i0;
00224         int i1;
00225         getBlockPositionV(bx, by, &i0, &i1);
00226         return i1-i0;
00227 }
00228 
00229 int Grid::getHeight() const {
00230         return height;
00231 }
00232 
00233 int Grid::getWidth() const {
00234         return width;
00235 }