From a3edf549cf4353fd52f72b0b3ceffe977a32f1ce Mon Sep 17 00:00:00 2001 From: valasatava Date: Wed, 12 Apr 2017 20:06:16 -0700 Subject: [PATCH 1/2] Cherry-pick the c5fa135 commit --- .../core/alignment/SimpleAlignedSequence.java | 126 +++++++++++++----- .../alignment/template/AlignedSequence.java | 12 ++ 2 files changed, 107 insertions(+), 31 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/alignment/SimpleAlignedSequence.java b/biojava-core/src/main/java/org/biojava/nbio/core/alignment/SimpleAlignedSequence.java index ede117fc88..b369c50fa9 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/alignment/SimpleAlignedSequence.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/alignment/SimpleAlignedSequence.java @@ -31,6 +31,7 @@ import org.biojava.nbio.core.sequence.location.template.Location; import org.biojava.nbio.core.sequence.location.template.Point; import org.biojava.nbio.core.sequence.template.*; +import org.biojava.nbio.core.util.Equals; import java.io.Serializable; import java.util.ArrayList; @@ -59,7 +60,10 @@ public class SimpleAlignedSequence, C extends Compound> im // cached (lazily initialized) private int numGaps = -1; - private int[] alignmentFromSequence, sequenceFromAlignment; + private int numGapPositions = -1; + + private int[] alignmentFromSequence; + private int[] sequenceFromAlignment; /** * Creates an {@link AlignedSequence} for the given {@link Sequence} in a global alignment. @@ -131,25 +135,35 @@ public void clearCache() { sequenceFromAlignment = null; } - @Override - public int getAlignmentIndexAt(int sequenceIndex) { - if (alignmentFromSequence == null) { - alignmentFromSequence = new int[original.getLength()]; - int s = 1, a = 1; - for (int i = 0; i < numBefore; i++, s++) { - alignmentFromSequence[s - 1] = a; - } - for (; s <= alignmentFromSequence.length && a <= length; s++, a++) { - while (a <= length && isGap(a)) { - a++; - } - alignmentFromSequence[s - 1] = a; - } - a--; - for (int i = 0; i < numAfter; i++, s++) { - alignmentFromSequence[s - 1] = a; + private void setAlignmentFromSequence() { + alignmentFromSequence = new int[original.getLength()]; + int s = 1, a = 1; + for (int i = 0; i < numBefore; i++, s++) { + alignmentFromSequence[s - 1] = a; + } + for (; s <= alignmentFromSequence.length && a <= length; s++, a++) { + while (a <= length && isGap(a)) { + a++; } + alignmentFromSequence[s - 1] = a; + } + a--; + for (int i = 0; i < numAfter; i++, s++) { + alignmentFromSequence[s - 1] = a; } + } + + @Override + public int[] getAlignmentFromSequence() { + if (alignmentFromSequence == null) + setAlignmentFromSequence(); + return alignmentFromSequence; + } + + @Override + public int getAlignmentIndexAt(int sequenceIndex) { + if (alignmentFromSequence == null) + setAlignmentFromSequence(); return alignmentFromSequence[sequenceIndex - 1]; } @@ -167,6 +181,7 @@ public Location getLocationInAlignment() { public int getNumGaps() { if (numGaps == -1) { numGaps = 0; + numGapPositions = 0; C cGap = getCompoundSet().getCompoundForString(gap); boolean inGap = false; for (C compound : getAsList()) { @@ -175,6 +190,7 @@ public int getNumGaps() { numGaps++; inGap = true; } + numGapPositions++; } else { inGap = false; } @@ -194,21 +210,31 @@ public int getOverlapCount() { return 1; } - @Override - public int getSequenceIndexAt(int alignmentIndex) { - if (sequenceFromAlignment == null) { - sequenceFromAlignment = new int[length]; - int a = 1, s = numBefore + 1; - for (int i = 0; i < getStart().getPosition(); i++, a++) { - sequenceFromAlignment[a - 1] = s; - } - for (; a <= length; a++) { - if (!isGap(a)) { - s++; - } - sequenceFromAlignment[a - 1] = s; + private void setSequenceFromAlignment() { + sequenceFromAlignment = new int[length]; + int a = 1, s = numBefore + 1; + for (int i = 0; i < getStart().getPosition(); i++, a++) { + sequenceFromAlignment[a - 1] = s; + } + for (; a <= length; a++) { + if (!isGap(a)) { + s++; } + sequenceFromAlignment[a - 1] = s; } + } + + @Override + public int[] getSequenceFromAlignment() { + if (sequenceFromAlignment == null) + setSequenceFromAlignment(); + return sequenceFromAlignment; + } + + @Override + public int getSequenceIndexAt(int alignmentIndex) { + if (sequenceFromAlignment == null) + setSequenceFromAlignment(); return sequenceFromAlignment[alignmentIndex - 1]; } @@ -266,6 +292,30 @@ public List getAsList() { return compounds; } + @Override + public boolean equals(Object o){ + + if(! Equals.classEqual(this, o)) { + return false; + } + + Sequence other = (Sequence)o; + if ( original.getAsList().size() != other.getAsList().size()) + return false; + + for ( int i = 0 ; i< original.getAsList().size() ; i++){ + if ( ! original.getAsList().get(i).equalsIgnoreCase(other.getAsList().get(i))) + return false; + } + return true; + } + + @Override + public int hashCode(){ + String s = getSequenceAsString(); + return s.hashCode(); + } + @Override public C getCompoundAt(int alignmentIndex) { return alignmentIndex >= 1 && alignmentIndex <= length && isGap(alignmentIndex) ? @@ -382,4 +432,18 @@ private void setLocation(List steps) { public SequenceView getInverse() { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public int getNumGapPositions() { + if (numGapPositions == -1) + getNumGaps(); + return numGapPositions; + } + + @Override + public double getCoverage() { + + double coverage = getLength() - getNumGapPositions(); + return coverage / getOriginalSequence().getLength(); + } } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/alignment/template/AlignedSequence.java b/biojava-core/src/main/java/org/biojava/nbio/core/alignment/template/AlignedSequence.java index 5ddcde13a1..98ec5c9794 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/alignment/template/AlignedSequence.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/alignment/template/AlignedSequence.java @@ -47,6 +47,18 @@ enum Step { COMPOUND, GAP } */ void clearCache(); + /** Returns the alignment. + * + * @return the alignment + */ + int[] getAlignmentFromSequence(); + + /** Returns the sequence positions at each alignment index + * + * @return array of the sequence positions + */ + int[] getSequenceFromAlignment(); + /** * Returns the column index within an alignment corresponding to the given index in the original {@link Sequence}. * Both indices are 1-indexed and inclusive. From 450b43c7ce0fc3e31da1485583aaf90d00e1c35e Mon Sep 17 00:00:00 2001 From: valasatava Date: Wed, 5 Jul 2017 15:06:49 -0700 Subject: [PATCH 2/2] Adding missing methods to the interface --- .../core/alignment/template/AlignedSequence.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/alignment/template/AlignedSequence.java b/biojava-core/src/main/java/org/biojava/nbio/core/alignment/template/AlignedSequence.java index 98ec5c9794..76a1fe1c8b 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/alignment/template/AlignedSequence.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/alignment/template/AlignedSequence.java @@ -142,4 +142,20 @@ enum Step { COMPOUND, GAP } */ boolean isGap(int alignmentIndex); + /** + * Returns number of gap positions (gap openings and extensions) in the sequence. This could be determined from the {@link Location} + * information or from gap {@link Compound}s, which may not necessarily result in the same number. + * + * @return number of gap positions in the sequence + */ + int getNumGapPositions(); + + /** + * Returns the coverage, as a fraction between 0 and 1, of this {@link AlignedSequence} with respect to the original sequence. + * This is equivalent to ({@link #getLength()} - {@link #getNumGapPositions()}) / getOriginalSequence().getLength(). + * + * @return coverage of the original sequence by the aligned sequence + */ + double getCoverage(); + }