package bgu.bio.algorithms.alignment.stems;
import gnu.trove.list.array.TCharArrayList;
import bgu.bio.algorithms.alignment.GlobalSequenceAlignment;
import bgu.bio.algorithms.alignment.SequenceAlignment;
import bgu.bio.ds.rna.InnerStructure;
import bgu.bio.ds.rna.StemStructure;
import bgu.bio.util.ScoringMatrix;
import bgu.bio.util.alphabet.StemStructureAlphabet;
public class GlobalStemSimilarity extends GlobalSequenceAlignment implements
StemSimilarity {
private SequenceAlignment sequenceSimilarity;
private StemStructureAlphabet structureAlphabet;
private SequenceAlignment danglingAligner;
private StemStructure stem1;
private StemStructure stem2;
private double danglingScore;
private TCharArrayList emptyListHelper;
private boolean shouldCountDangling;
public GlobalStemSimilarity(ScoringMatrix structureScoringMatrix,
SequenceAlignment sequenceAligner) {
this(structureScoringMatrix, sequenceAligner, null);
}
public GlobalStemSimilarity(ScoringMatrix structureScoringMatrix,
SequenceAlignment sequenceAligner, SequenceAlignment danglingAligner) {
super(100, 100, StemStructureAlphabet.getInstance(),
structureScoringMatrix);
this.sequenceSimilarity = sequenceAligner;
this.structureAlphabet = StemStructureAlphabet.getInstance();
if (danglingAligner != null) {
this.danglingAligner = danglingAligner;
} else {
this.danglingAligner = sequenceAligner;
}
emptyListHelper = new TCharArrayList();
shouldCountDangling = false;
}
@Override
public void setStem1(StemStructure stem) {
this.stem1 = stem;
}
@Override
public void setStem2(StemStructure stem) {
this.stem2 = stem;
}
@Override
public void run() {
super.setSequences(stem1.getBackbone(), stem2.getBackbone());
buildMatrix();
}
@Override
protected final double similarity(int i, int j) {
final char c1 = i == 0 ? structureAlphabet.emptyLetter() : str1
.get(i - 1);
final char c2 = j == 0 ? structureAlphabet.emptyLetter() : str2
.get(j - 1);
// empty letter and special character i.e. the deletion of a special
// character
if ((i == 0 && this.structureAlphabet.isSpecial(c2))
|| (j == 0 && this.structureAlphabet.isSpecial(c1))) {
InnerStructure in1 = this.structureAlphabet.isSpecial(c1) ? stem1
.getInnerStructure(i - 1) : null;
InnerStructure in2 = this.structureAlphabet.isSpecial(c2) ? stem2
.getInnerStructure(j - 1) : null;
double innerScore = 0;
if (in1 != null) {
// calculate the deletion of the left side and the right side
InnerStructure in = in1;
this.sequenceSimilarity.setSequences(in.getSequenceLeft(),
emptyListHelper);
this.sequenceSimilarity.buildMatrix();
innerScore += this.sequenceSimilarity.getAlignmentScore();
this.sequenceSimilarity.setSequences(in.getSequenceRight(),
emptyListHelper);
this.sequenceSimilarity.buildMatrix();
innerScore += this.sequenceSimilarity.getAlignmentScore();
}
if (in2 != null) {
InnerStructure in = in2;
this.sequenceSimilarity.setSequences(in.getSequenceLeft(),
emptyListHelper);
this.sequenceSimilarity.buildMatrix();
innerScore += this.sequenceSimilarity.getAlignmentScore();
this.sequenceSimilarity.setSequences(in.getSequenceRight(),
emptyListHelper);
this.sequenceSimilarity.buildMatrix();
innerScore += this.sequenceSimilarity.getAlignmentScore();
}
return scoringMatrix.score(c1, c2) + innerScore;
}
if (!this.structureAlphabet.isSpecial(c1)
&& !this.structureAlphabet.isSpecial(c2)) {
// not a special case
return super.similarity(i, j);
}
if ((c1 == StemStructureAlphabet.INNER_LOOP && this.structureAlphabet
.isSpecial(c2))
|| (c2 == StemStructureAlphabet.INNER_LOOP && this.structureAlphabet
.isSpecial(c1))) {
// inner loop to right or left
InnerStructure in1 = stem1.getInnerStructure(i - 1);
InnerStructure in2 = stem2.getInnerStructure(j - 1);
double score = 0;
this.sequenceSimilarity.setSequences(in1.getSequenceLeft(),
in2.getSequenceLeft());
this.sequenceSimilarity.buildMatrix();
score = this.sequenceSimilarity.getAlignmentScore();
this.sequenceSimilarity.setSequences(in1.getSequenceRight(),
in2.getSequenceRight());
this.sequenceSimilarity.buildMatrix();
score += this.sequenceSimilarity.getAlignmentScore();
return score;
} else if (c1 == StemStructureAlphabet.BULDGE_RIGHT
&& c2 == StemStructureAlphabet.BULDGE_RIGHT) {
// right to right
InnerStructure in1 = stem1.getInnerStructure(i - 1);
InnerStructure in2 = stem2.getInnerStructure(j - 1);
this.sequenceSimilarity.setSequences(in1.getSequenceRight(),
in2.getSequenceRight());
this.sequenceSimilarity.buildMatrix();
return this.sequenceSimilarity.getAlignmentScore();
} else if ((c1 == StemStructureAlphabet.BULDGE_LEFT && c2 == StemStructureAlphabet.BULDGE_LEFT)) {
// left to left
InnerStructure in1 = stem1.getInnerStructure(i - 1);
InnerStructure in2 = stem2.getInnerStructure(j - 1);
this.sequenceSimilarity.setSequences(in1.getSequenceLeft(),
in2.getSequenceLeft());
this.sequenceSimilarity.buildMatrix();
return this.sequenceSimilarity.getAlignmentScore();
}
return Double.NEGATIVE_INFINITY;
}
@Override
public void buildMatrix() {
danglingScore = 0;
if (shouldCountDangling) {
danglingAligner.setSequences(stem1.getDanglingLeft(),
stem2.getDanglingLeft());
danglingAligner.buildMatrix();
danglingScore += danglingAligner.getAlignmentScore();
danglingAligner.setSequences(stem1.getDanglingRight(),
stem2.getDanglingRight());
danglingAligner.buildMatrix();
danglingScore += danglingAligner.getAlignmentScore();
}
super.buildMatrix();
}
@Override
public double getAlignmentScore() {
return super.getAlignmentScore() + danglingScore;
}
/**
* Return
*
* @return
*/
@Override
public double getDanglingScore() {
return this.danglingScore;
}
@Override
public void setDanglingScoreConsideration(boolean value) {
this.shouldCountDangling = value;
}
@Override
public GlobalStemSimilarity cloneAligner() {
System.out.println("ssss");
GlobalStemSimilarity other = new GlobalStemSimilarity(
scoringMatrix.cloneMatrix(), sequenceSimilarity.cloneAligner(),
danglingAligner.cloneAligner());
return other;
}
}