package bgu.bio.algorithms.alignment.stems;
import bgu.bio.algorithms.alignment.AffineGapGlobalSequenceAlignment;
import bgu.bio.algorithms.alignment.SequenceAlignment;
import bgu.bio.ds.rna.InnerStructure;
import bgu.bio.ds.rna.StemStructure;
import bgu.bio.util.AffineGapScoringMatrix;
import bgu.bio.util.alphabet.StemStructureAlphabet;
public class AffineGapStemSimilarity extends AffineGapGlobalSequenceAlignment
implements StemSimilarity {
private SequenceAlignment sequenceSimilarity;
private StemStructureAlphabet structureAlphabet;
private SequenceAlignment danglingAligner;
private StemStructure stem1;
private StemStructure stem2;
private double danglingScore;
private boolean shouldCountDangling;
public AffineGapStemSimilarity(
AffineGapScoringMatrix structureScoringMatrix,
SequenceAlignment sequenceAligner) {
this(structureScoringMatrix, sequenceAligner, null);
}
public AffineGapStemSimilarity(
AffineGapScoringMatrix 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;
}
}
@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);
if (!this.structureAlphabet.isSpecial(c1)
&& !this.structureAlphabet.isSpecial(c2)) {
// not a special case
return super.similarity(i, j);
}
if ((this.structureAlphabet.isSpecial(c1) && this.structureAlphabet
.isSpecial(c2))) {
// 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;
}
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 AffineGapStemSimilarity cloneAligner() {
AffineGapStemSimilarity other = new AffineGapStemSimilarity(
scoringMatrix.cloneMatrix(), sequenceSimilarity.cloneAligner(),
danglingAligner.cloneAligner());
return other;
}
}