Smith Waterman for C ++(Visual Studio 14.0)

时间:2017-08-03 12:54:10

标签: c++ alignment

我想一举两得,因为问题非常类似:

1
我在github Smith Waterman Alignment上遵循了这个代码,用C ++创建了smith-waterman。经过一些研究,我明白了实施     对于"较新的"而言,double H[N_a+1][N_b+1];是不可能的。 C ++版本。因此,要创建一个常量变量,我将此行更改为:

double **H = new double*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
    H[i] = new double[nSynth + 1];

也是int I_i[N_a+1][N_b+1], I_j[N_a+1][N_b+1];的同一方案,所以一个(好的,无处不在,存在二维数组)。现在我得到了例外:

Unhandled exception at 0x00007FFF7B413C58 in Smith-Waterman.exe: Microsoft C 
++ exception: std :: bad_alloc at location 0x0000008FF4F9FA50.

这里有什么问题?已经调试过,程序会抛出for (int i = 0; i < nReal + 1; i++)之上的异常。

2:
此代码使用std::strings作为参数。是否也可以为cv::Mat创建一个smith waterman algortihm?

为了进一步澄清,我的完整代码如下:

#include "BinaryAlignment.h"
#include "WallMapping.h"

//using declarations
using namespace cv;
using namespace std;

//global variables
std::string bin;
cv::Mat temp;
std::stringstream sstrMat;

const int maxMismatch = 2;
const float mu = 0.33f;
const float delta = 1.33;
int ind;


BinaryAlignment::BinaryAlignment() { }
BinaryAlignment::~BinaryAlignment() { }

/**
*** Convert matrix to binary sequence
**/
std::string BinaryAlignment::matToBin(cv::Mat src, std::experimental::filesystem::path path) {

    cv::Mat linesMat = WallMapping::wallMapping(src, path);

    for (int i = 0; i < linesMat.size().height; i++) {
        for (int j = 0; j < linesMat.size().width; j++) {
            if (linesMat.at<Vec3b>(i, j)[0] == 0
                && linesMat.at<Vec3b>(i, j)[1] == 0
                && linesMat.at<Vec3b>(i, j)[2] == 255) {
                src.at<int>(i, j) = 1;
            }
            else {
                src.at<int>(i, j) = 0;
            }
            sstrMat << src.at<int>(i, j);
        }
    }
    bin = sstrMat.str();

    return bin;
}


double BinaryAlignment::similarityScore(char a, char b) {
    double result;

    if (a == b)
        result = 1;
    else
        result = -mu;

    return result;
}

double BinaryAlignment::findArrayMax(double array[], int length) {
    double max = array[0];
    ind = 0;

    for (int i = 1; i < length; i++) {
        if (array[i] > max) {
            max = array[i];
            ind = i;
        }
    }
    return max;
}


/**
*** Smith-Waterman alignment for given sequences
**/
int BinaryAlignment::watermanAlign(std::string seqSynth, std::string seqReal, bool viableAlignment) {   
    const int nSynth = seqSynth.length();                                               //length of sequences
    const int nReal = seqReal.length();

    //H[nSynth + 1][nReal + 1]
    double **H = new double*[nReal + 1];
    for (int i = 0; i < nReal + 1; i++)
        H[i] = new double[nSynth + 1];

    cout << "passt";

    for (int m = 0; m <= nSynth; m++)
        for (int n = 0; n <= nReal; n++)
            H[m][n] = 0;

    double temp[4];
    int **Ii = new int*[nReal + 1];
    for (int i = 0; i < nReal + 1; i++)
        Ii[i] = new int[nSynth + 1];

    int **Ij = new int*[nReal + 1];
    for (int i = 0; i < nReal + 1; i++)
        Ij[i] = new int[nSynth + 1];

    for (int i = 1; i <= nSynth; i++) {
        for (int j = 1; j <= nReal; j++) {
            temp[0] = H[i - 1][j - 1] + similarityScore(seqSynth[i - 1], seqReal[j - 1]);
            temp[1] = H[i - 1][j] - delta;
            temp[2] = H[i][j - 1] - delta;
            temp[3] = 0;
            H[i][j] = findArrayMax(temp, 4);

            switch (ind) {
            case 0:                                  // score in (i,j) stems from a match/mismatch
                Ii[i][j] = i - 1;
                Ij[i][j] = j - 1;
                break;
            case 1:                                  // score in (i,j) stems from a deletion in sequence A
                Ii[i][j] = i - 1;
                Ij[i][j] = j;
                break;
            case 2:                                  // score in (i,j) stems from a deletion in sequence B
                Ii[i][j] = i;
                Ij[i][j] = j - 1;
                break;
            case 3:                                  // (i,j) is the beginning of a subsequence
                Ii[i][j] = i;
                Ij[i][j] = j;
                break;
            }
        }
    }

    //Print matrix H to console 
    std::cout << "**********************************************" << std::endl;
    std::cout << "The scoring matrix is given by  " << std::endl << std::endl;
    for (int i = 1; i <= nSynth; i++) {
        for (int j = 1; j <= nReal; j++) {
            std::cout << H[i][j] << " ";
        }
        std::cout << std::endl;
    }

    //search H for the moaximal score
    double Hmax = 0;
    int imax = 0, jmax = 0;

    for (int i = 1; i <= nSynth; i++) {
        for (int j = 1; j <= nReal; j++) {
            if (H[i][j] > Hmax) {
                Hmax = H[i][j];
                imax = i;
                jmax = j;
            }
        }
    }

    std::cout << Hmax << endl;
    std::cout << nSynth << ", " << nReal << ", " << imax << ", " << jmax << std::endl;
    std::cout << "max score: " << Hmax << std::endl;
    std::cout << "alignment index: " << (imax - jmax) << std::endl;

    //Backtracing from Hmax
    int icurrent = imax, jcurrent = jmax;
    int inext = Ii[icurrent][jcurrent];
    int jnext = Ij[icurrent][jcurrent];
    int tick = 0;
    char *consensusSynth = new char[nSynth + nReal + 2];
    char *consensusReal = new char[nSynth + nReal + 2];

    while (((icurrent != inext) || (jcurrent != jnext)) && (jnext >= 0) && (inext >= 0)) {

        if (inext == icurrent)
            consensusSynth[tick] = '-';                         //deletion in A
        else
            consensusSynth[tick] = seqSynth[icurrent - 1];      //match / mismatch in A

        if (jnext == jcurrent)
            consensusReal[tick] = '-';                          //deletion in B
        else
            consensusReal[tick] = seqReal[jcurrent - 1];        //match/mismatch in B

        //fix for adding first character of the alignment.
        if (inext == 0)
            inext = -1;
        else if (jnext == 0)
            jnext = -1;
        else
            icurrent = inext;
        jcurrent = jnext;
        inext = Ii[icurrent][jcurrent];
        jnext = Ij[icurrent][jcurrent];

        tick++;
    }


    // Output of the consensus motif to the console
    std::cout << std::endl << "***********************************************" << std::endl;
    std::cout << "The alignment of the sequences" << std::endl << std::endl;
    for (int i = 0; i < nSynth; i++) {
        std::cout << seqSynth[i];
    };
    std::cout << "  and" << std::endl;
    for (int i = 0; i < nReal; i++) {
        std::cout << seqReal[i];
    };
    std::cout << std::endl << std::endl;
    std::cout << "is for the parameters  mu = " << mu << " and delta = " << delta << " given by" << std::endl << std::endl;
    for (int i = tick - 1; i >= 0; i--)
        std::cout << consensusSynth[i];
    std::cout << std::endl;
    for (int j = tick - 1; j >= 0; j--)
        std::cout << consensusReal[j];
    std::cout << std::endl;


    int numMismatches = 0;
    for (int i = tick - 1; i >= 0; i--) {
        if (consensusSynth[i] != consensusReal[i]) {
            numMismatches++;
        }
    }

    viableAlignment = numMismatches <= maxMismatch;
    return imax - jmax;
}

谢谢!

0 个答案:

没有答案