package bgu.bio.algorithms.alignment;
import gnu.trove.list.array.TCharArrayList;
import java.util.Arrays;
import bgu.bio.util.ScoringMatrix;
import bgu.bio.util.alphabet.AlphabetUtils;
public abstract class AbsSequenceAlignmentNoMatrix implements SequenceAlignment {
/**
* The first input string
*/
protected TCharArrayList str1;
/**
* The second input String
*/
protected TCharArrayList str2;
/**
* The lengths of the input strings
*/
protected int length1, length2;
/**
* The score matrix. The true scores should be divided by the normalization
* factor.
*/
protected double[] dpRow1;
protected double[] dpRow2;
protected ScoringMatrix scoringMatrix;
/**
* The normalization factor. To get the true score, divide the integer score
* used in computation by the normalization factor.
*/
protected double normFactor = 1.0;
protected AlphabetUtils alphabet;
public AbsSequenceAlignmentNoMatrix(char[] str1, char[] str2,
AlphabetUtils alphabet, ScoringMatrix matrix) {
this.scoringMatrix = matrix;
this.alphabet = alphabet;
this.str1 = new TCharArrayList();
this.str2 = new TCharArrayList();
this.setSequences(str1, str2);
}
public AbsSequenceAlignmentNoMatrix(int size1, int size2,
AlphabetUtils alphabet, ScoringMatrix matrix) {
this.scoringMatrix = matrix;
this.alphabet = alphabet;
length1 = size1;
length2 = size2;
dpRow1 = new double[length2 + 1];
dpRow2 = new double[length2 + 1];
this.str1 = new TCharArrayList();
this.str2 = new TCharArrayList();
}
@Override
public void setSequences(String str1, String str2) {
this.setSequences(str1.toCharArray(), str2.toCharArray());
}
@Override
public void setSequences(char[] str1, char[] str2) {
setSequences(str1, str1.length, str2, str2.length);
}
@Override
public void setSequences(char[] str1, int size1, char[] str2, int size2) {
this.str1.resetQuick();
for (int i = 0; i < str1.length; i++) {
this.str1.add(str1[i]);
}
this.str2.resetQuick();
for (int i = 0; i < str2.length; i++) {
this.str2.add(str2[i]);
}
boolean init = ((dpRow1 == null) || (size2 >= dpRow1.length));
length1 = size1;
length2 = size2;
if (init) {
dpRow1 = new double[length2 + 1];
dpRow2 = new double[length2 + 1];
}
}
@Override
public void setSequences(TCharArrayList str1, TCharArrayList str2) {
this.str1.resetQuick();
for (int i = 0; i < str1.size(); i++) {
this.str1.add(str1.get(i));
}
this.str2.resetQuick();
for (int i = 0; i < str2.size(); i++) {
this.str2.add(str2.get(i));
}
boolean init = ((dpRow1 == null) || (str2.size() >= dpRow1.length));
length1 = str1.size();
length2 = str2.size();
if (init) {
dpRow1 = new double[length2 + 1];
dpRow2 = new double[length2 + 1];
}
}
/**
* Compute the similarity score of substitution: use a substitution matrix
* if the cost model The position of the first character is 1. A position of
* 0 represents a gap.
*
* @param i
* Position of the character in str1
* @param j
* Position of the character in str2
* @return Cost of substitution of the character in str1 by the one in str2
*/
protected double similarity(int i, int j) {
final char c1 = i == 0 ? this.alphabet.emptyLetter() : str1.get(i - 1);
final char c2 = j == 0 ? this.alphabet.emptyLetter() : str2.get(j - 1);
return this.scoringMatrix.score(c1, c2);
}
/**
* Build the score matrix using dynamic programming. Note: The indel scores
* must be negative. Otherwise, the part handling the first row and column
* has to be modified.
*/
@Override
public void buildMatrix() {
int i; // length of prefix substring of str1
int j; // length of prefix substring of str2
double[] temp = null;
// base case
dpRow1[0] = 0.0;
initTable();
// the rest of the matrix
for (i = 1; i <= length1; i++) {
// rest of the table
for (j = 1; j <= length2; j++) {
calculateCell(i, j);
}
temp = dpRow2;
dpRow2 = dpRow1;
dpRow1 = temp;
}
}
/**
* Compute the initialization of the matrix
*/
protected abstract void initTable();
/**
* Compute the value of the the given cell coordinates in the matrix
*
* @param i
* row
* @param j
* column
*/
protected abstract void calculateCell(int i, int j);
/**
* Get the maximum value in the score matrix.
*/
protected abstract double getMaxScore();
/**
* Get the alignment score between the two input strings.
*/
@Override
public double getAlignmentScore() {
return getMaxScore() / normFactor;
}
/**
* print the dynamic programming matrix
*/
public void printDPMatrix() {
System.out.println(Arrays.toString(dpRow2));
System.out.println(Arrays.toString(dpRow1));
}
@Override
public void setNormFactor(double p_Factor) {
normFactor = p_Factor;
}
}