package bgu.bio.algorithms.alignment.constrained.re;
import bgu.bio.adt.matrix.FloatMatrix3D;
import bgu.bio.adt.matrix.IntMatrix4D;
import bgu.bio.ds.automata.TransitionTable;
import bgu.bio.util.ScoringMatrix;
import bgu.bio.util.alphabet.constrain.ConstrainedAlphabet;
public abstract class ConstrainedAlignmentEngine {
protected final boolean trace;
protected TransitionTable tr;
protected int additionalStatesCount;
protected ScoringMatrix score;
protected ConstrainedAlphabet constAlphabet;
protected FloatMatrix3D dpTable;
protected int startingStateId;
// Trace tables
/**
* The dynamic programming trace table will keep for each cell one of the
* optimal transitions which they came from.
*/
protected IntMatrix4D dpTrace; // a trace table in the size of [n][m][t][3]
protected char[] s1;
protected char[] s2;
protected int s1Length;
protected int s2Length;
public ConstrainedAlignmentEngine(ScoringMatrix score, TransitionTable tr,
ConstrainedAlphabet constAlphabet, boolean trace) {
this.tr = tr;
this.score = score;
this.constAlphabet = constAlphabet;
this.startingStateId = tr.getStartingState();
this.trace = trace;
}
public ConstrainedAlignmentEngine(ScoringMatrix score, TransitionTable tr,
ConstrainedAlphabet constAlphabet) {
this(score, tr, constAlphabet, false);
}
public void align(String s1, String s2){
this.align(s1.toCharArray(), s2.toCharArray());
}
public abstract void align(char[] s1, char[] s2);
public void printDPTable() {
System.out.print("|");
for (int i = 0; i < this.dpTable.getDimensionSize(1); i++) {
System.out.print(i + "|");
}
System.out.println();
for (int i = 0; i < this.dpTable.getDimensionSize(0); i++) {
System.out.print(i + "|");
for (int j = 0; j < this.dpTable.getDimensionSize(1); j++) {
for (int x = 0; x < this.dpTable.getDimensionSize(2); x++) {
System.out.print(this.dpTable.get(i, j, x) + ",");
}
System.out.print("|");
}
System.out.println();
}
}
public void setString1(String s1) {
this.s1 = s1.toCharArray();
}
public void setString2(String s2) {
this.s2 = s2.toCharArray();
}
public abstract double getOptimalScore();
public abstract String optimalAlignmentToHTML();
public abstract String[] getAlignment();
public abstract int countSubOptimalScores(double delta, double optimal);
public int countSubOptimalScores(int delta) {
return countSubOptimalScores(delta, getOptimalScore());
}
protected abstract void init();
/**
* Calculate single cell.
*
* @param i
* the row of the desired cell
* @param j
* the column of the desired cell
*
*/
public abstract void calculateSingleCell(int i, int j);
public void clear() {
dpTable.init(Float.NEGATIVE_INFINITY);
}
/**
* Rebuild the tables for the engine.
*
* @param newDim1
* the new first dimension size
* @param newDim2
* the new second dimension size
*
* @return true, if the tables are rebuilt and false otherwise
*/
protected boolean rebuildTheTables(int newDim1, int newDim2) {
if (this.dpTable == null || newDim1 > this.dpTable.getDimensionSize(0)
|| newDim2 > this.dpTable.getDimensionSize(1)) {
// System.out.print("Building new tables ... ");
this.dpTable = new FloatMatrix3D(newDim1, newDim2,
tr.getNumOfStates() + additionalStatesCount);
if (this.trace) {
this.dpTrace = new IntMatrix4D(newDim1, newDim2,
tr.getNumOfStates() + additionalStatesCount, 3);
}
return true;
}
return false;
}
/**
* @param absoluteScore
* @param stringLength
* @return the maximal possible score of an alignment of two strings, one of which has the given length
*/
public double relativeScore(double absoluteScore, int stringLength){
double a = stringLength*score.getMinValue();
double b = stringLength*score.getMaxValue();
return ((absoluteScore-a)/(b-a));
}
}