package org.broadinstitute.sting.playground.indels; import org.broadinstitute.sting.playground.utils.Interval; /** This class represents an indel as an interval with respect to the original reference and, in addition, * stores the indel type ( (I)nsertion or (D)eletion ) and can return meaningful event size (see below). * Depending on the indel type, the positions on the reference are: *
start, or starts after stop, it does not overlap
* with the indel event (neither spans over deleted region or contains any of the inserted bases).
*
*/
public class Indel implements Interval {
public static enum IndelType { I, D };
private long mStart;
private long mLength;
private IndelType mType;
/** Creates nBases-long indel at specified start position; the object will be unusable
* until indel type is set.
* @param start start position on the reference
* @param nBases number of inserted or deleted bases
*/
//public Indel(long start, long nBases) {
// mType=null;
// mStart=start;
// mLength=nBases;
// }
/** Creates nBases-long indel of the specified type (insertion or deletion), at specified start position.
* @param start start position on the reference
* @param nBases number of inserted or deleted bases
* @param type Indel type: I or D.
*/
public Indel(long start, long nBases, IndelType type) {
mType=type;
mStart=start;
mLength=nBases;
}
/** Start coordinate on the reference; for deletions it is the position of the first deleted base,
* for insertions it is the first base after the insertion.
* This is the "left boundary" of the event on the original reference: every alignment that ends
* befor this position on the reference does not overlap with the indel.
* @return indel's left boundary
*/
public long getStart() { return mStart; }
/** Sets start position of the interval.
*
* @param s start coordinate
*/
public void setStart(long s) { mStart = s; }
/** Indel's stop coordinate on the reference; for deletions it is the position of the last deleted base,
* for insertions it is the last base before the insertion site (which makes it equal to getStart() - 1).
* This is the "right boundary" of the event: every alignment that starts after
* this position on the reference
* does not overlap with the indel.
* @return indel's right boundary
*/
public long getStop() {
if ( mType == IndelType.I ) return mStart - 1;
else return mStart + mLength - 1;
}
/** This method is not supported in IndelInterval and will throw an exception. Use setIndelLength() instead.
*
* @param s stop coordinate
*/
public void setStop(long s) {
throw new UnsupportedOperationException("Method setStop(long) is not supported in IndelInterval");
}
/** Returns type of this indel ( I or D).
*
* @return I or D enum element
*/
public IndelType getType() { return mType; }
/** Sets the number of bases in this indel (i.e. the actual number of inserted or
* deleted bases). Stop position will be always correctly computed based on the indel length and indel type.
* @param nBases length of the indel (not the length of the event on the original reference!)
*/
public void setIndelLength(long nBases) { mLength = nBases; }
/** Returns actual number of inserted or deleted bases in the indel.
*
* @return number of bases (not the event length on the original reference).
* @see #getLength()
*/
public long getIndelLength() { return mLength; }
/**
* Returns true if this interval overlaps with i as judjed by getStart() and getStop() positions of the
* two interval objects.
*
* @param i Another interval
* @return true iff intervals overlap
*/
public boolean overlapsP(Interval i) {
return ! disjointP(i); //To change body of implemented methods use File | Settings | File Templates.
}
/**
* Returns true if this interval does not overlap with i as judjed by getStart() and getStop() positions of the
* two interval objects.
*
* @param i Another interval
* @return true iff intervals do not overlap
*/
public boolean disjointP(Interval i) {
return i.getStop() < this.getStart() || i.getStart() > this.getStop();
}
/** Returns length of the region affected by the indel on the original reference. Note that an insertion
* has length of 0.
* @return length of the event on the original, unmodified reference
*/
public long getLength() {
if ( mType == IndelType.I ) return 0;
return mLength;
}
@Override
public boolean equals(Object o) {
if ( ! ( o instanceof Indel ) ) return false;
Indel i = (Indel)o;
return this.mType == i.mType && this.mStart == i.mStart && this.mLength == i.mLength ;
}
@Override
public int hashCode() {
return (int)( mStart << 6 + mStart + mLength );
}
}