Added functionality in pileups to not only determine whether there's an insertion or deletion following the current position, but to also get the indel length and involved bases - definitely needed for extended event removal, and needed for pool caller indel functionality.
This commit is contained in:
parent
2c1b14d35e
commit
6866a41914
|
|
@ -175,8 +175,8 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
return String.format("%s ro=%d go=%d co=%d cec=%d %s", read.getReadName(), readOffset, genomeOffset, cigarOffset, cigarElementCounter, curElement);
|
return String.format("%s ro=%d go=%d co=%d cec=%d %s", read.getReadName(), readOffset, genomeOffset, cigarOffset, cigarElementCounter, curElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CigarOperator peekForwardOnGenome() {
|
public CigarElement peekForwardOnGenome() {
|
||||||
return ( cigarElementCounter + 1 > curElement.getLength() && cigarOffset + 1 < nCigarElements ? cigar.getCigarElement(cigarOffset + 1) : curElement ).getOperator();
|
return ( cigarElementCounter + 1 > curElement.getLength() && cigarOffset + 1 < nCigarElements ? cigar.getCigarElement(cigarOffset + 1) : curElement );
|
||||||
}
|
}
|
||||||
|
|
||||||
public CigarOperator stepForwardOnGenome() {
|
public CigarOperator stepForwardOnGenome() {
|
||||||
|
|
@ -462,15 +462,19 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
final SAMRecordState state = iterator.next(); // state object with the read/offset information
|
final SAMRecordState state = iterator.next(); // state object with the read/offset information
|
||||||
final GATKSAMRecord read = (GATKSAMRecord) state.getRead(); // the actual read
|
final GATKSAMRecord read = (GATKSAMRecord) state.getRead(); // the actual read
|
||||||
final CigarOperator op = state.getCurrentCigarOperator(); // current cigar operator
|
final CigarOperator op = state.getCurrentCigarOperator(); // current cigar operator
|
||||||
final CigarOperator nextOp = state.peekForwardOnGenome(); // next cigar operator
|
final CigarElement nextElement = state.peekForwardOnGenome(); // next cigar element
|
||||||
|
final CigarOperator nextOp = nextElement.getOperator();
|
||||||
final int readOffset = state.getReadOffset(); // the base offset on this read
|
final int readOffset = state.getReadOffset(); // the base offset on this read
|
||||||
|
byte[] insertedBases = Arrays.copyOfRange(read.getReadBases(), readOffset + 1, readOffset + 1 + nextElement.getLength());
|
||||||
|
int nextElementLength = nextElement.getLength();
|
||||||
|
|
||||||
if (op == CigarOperator.N) // N's are never added to any pileup
|
if (op == CigarOperator.N) // N's are never added to any pileup
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (op == CigarOperator.D) {
|
if (op == CigarOperator.D) {
|
||||||
if (readInfo.includeReadsWithDeletionAtLoci()) { // only add deletions to the pileup if we are authorized to do so
|
if (readInfo.includeReadsWithDeletionAtLoci()) { // only add deletions to the pileup if we are authorized to do so
|
||||||
pile.add(new PileupElement(read, readOffset, true, nextOp == CigarOperator.D, nextOp == CigarOperator.I, nextOp == CigarOperator.S || (state.getGenomeOffset() == 0 && read.getSoftStart() != read.getAlignmentStart())));
|
pile.add(new PileupElement(read, readOffset, true, nextOp == CigarOperator.D, nextOp == CigarOperator.I, nextOp == CigarOperator.S || (state.getGenomeOffset() == 0 && read.getSoftStart() != read.getAlignmentStart()),
|
||||||
|
null,nextOp == CigarOperator.D? nextElementLength:-1));
|
||||||
size++;
|
size++;
|
||||||
nDeletions++;
|
nDeletions++;
|
||||||
if (read.getMappingQuality() == 0)
|
if (read.getMappingQuality() == 0)
|
||||||
|
|
@ -479,7 +483,8 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!filterBaseInRead(read, location.getStart())) {
|
if (!filterBaseInRead(read, location.getStart())) {
|
||||||
pile.add(new PileupElement(read, readOffset, false, nextOp == CigarOperator.D, nextOp == CigarOperator.I, nextOp == CigarOperator.S || (state.getGenomeOffset() == 0 && read.getSoftStart() != read.getAlignmentStart())));
|
pile.add(new PileupElement(read, readOffset, false, nextOp == CigarOperator.D, nextOp == CigarOperator.I, nextOp == CigarOperator.S || (state.getGenomeOffset() == 0 && read.getSoftStart() != read.getAlignmentStart()),
|
||||||
|
new String(insertedBases),nextElementLength));
|
||||||
size++;
|
size++;
|
||||||
if (read.getMappingQuality() == 0)
|
if (read.getMappingQuality() == 0)
|
||||||
nMQ0Reads++;
|
nMQ0Reads++;
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
protected abstract AbstractReadBackedPileup<RBP, PE> createNewPileup(GenomeLoc loc, PileupElementTracker<PE> pileupElementTracker);
|
protected abstract AbstractReadBackedPileup<RBP, PE> createNewPileup(GenomeLoc loc, PileupElementTracker<PE> pileupElementTracker);
|
||||||
|
|
||||||
protected abstract PE createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion, boolean isBeforeDeletion, boolean isBeforeInsertion, boolean isNextToSoftClip);
|
protected abstract PE createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion, boolean isBeforeDeletion, boolean isBeforeInsertion, boolean isNextToSoftClip);
|
||||||
|
protected abstract PE createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion, boolean isBeforeDeletion, boolean isBeforeInsertion, boolean isNextToSoftClip, String nextEventBases, int nextEventLength );
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ public class ExtendedEventPileupElement extends PileupElement {
|
||||||
|
|
||||||
|
|
||||||
public ExtendedEventPileupElement(GATKSAMRecord read, int offset, int eventLength, String eventBases, Type type) {
|
public ExtendedEventPileupElement(GATKSAMRecord read, int offset, int eventLength, String eventBases, Type type) {
|
||||||
super(read, offset, type == Type.DELETION, false, false, false); // extended events are slated for removal
|
super(read, offset, type == Type.DELETION, false, false, false,null,-1); // extended events are slated for removal
|
||||||
this.read = read;
|
this.read = read;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.eventLength = eventLength;
|
this.eventLength = eventLength;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,10 @@ public class PileupElement implements Comparable<PileupElement> {
|
||||||
protected final boolean isBeforeDeletion;
|
protected final boolean isBeforeDeletion;
|
||||||
protected final boolean isBeforeInsertion;
|
protected final boolean isBeforeInsertion;
|
||||||
protected final boolean isNextToSoftClip;
|
protected final boolean isNextToSoftClip;
|
||||||
|
protected final int eventLength;
|
||||||
|
protected final String eventBases; // if it is a deletion, we do not have information about the actual deleted bases
|
||||||
|
// in the read itself, so we fill the string with D's; for insertions we keep actual inserted bases
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new pileup element.
|
* Creates a new pileup element.
|
||||||
|
|
@ -37,12 +41,15 @@ public class PileupElement implements Comparable<PileupElement> {
|
||||||
* @param isBeforeDeletion whether or not this base is before a deletion
|
* @param isBeforeDeletion whether or not this base is before a deletion
|
||||||
* @param isBeforeInsertion whether or not this base is before an insertion
|
* @param isBeforeInsertion whether or not this base is before an insertion
|
||||||
* @param isNextToSoftClip whether or not this base is next to a soft clipped base
|
* @param isNextToSoftClip whether or not this base is next to a soft clipped base
|
||||||
|
* @param nextEventBases bases in event in case element comes before insertion or deletion
|
||||||
|
* @param nextEventLength length of next event in case it's insertion or deletion
|
||||||
*/
|
*/
|
||||||
@Requires({
|
@Requires({
|
||||||
"read != null",
|
"read != null",
|
||||||
"offset >= -1",
|
"offset >= -1",
|
||||||
"offset <= read.getReadLength()"})
|
"offset <= read.getReadLength()"})
|
||||||
public PileupElement(final GATKSAMRecord read, final int offset, final boolean isDeletion, final boolean isBeforeDeletion, final boolean isBeforeInsertion, final boolean isNextToSoftClip) {
|
public PileupElement(final GATKSAMRecord read, final int offset, final boolean isDeletion, final boolean isBeforeDeletion, final boolean isBeforeInsertion, final boolean isNextToSoftClip,
|
||||||
|
final String nextEventBases, final int nextEventLength) {
|
||||||
if (offset < 0 && isDeletion)
|
if (offset < 0 && isDeletion)
|
||||||
throw new ReviewedStingException("Pileup Element cannot create a deletion with a negative offset");
|
throw new ReviewedStingException("Pileup Element cannot create a deletion with a negative offset");
|
||||||
|
|
||||||
|
|
@ -52,6 +59,14 @@ public class PileupElement implements Comparable<PileupElement> {
|
||||||
this.isBeforeDeletion = isBeforeDeletion;
|
this.isBeforeDeletion = isBeforeDeletion;
|
||||||
this.isBeforeInsertion = isBeforeInsertion;
|
this.isBeforeInsertion = isBeforeInsertion;
|
||||||
this.isNextToSoftClip = isNextToSoftClip;
|
this.isNextToSoftClip = isNextToSoftClip;
|
||||||
|
if (isBeforeInsertion)
|
||||||
|
eventBases = nextEventBases;
|
||||||
|
else
|
||||||
|
eventBases = null; // ignore argument in any other case
|
||||||
|
if (isBeforeDeletion || isBeforeInsertion)
|
||||||
|
eventLength = nextEventLength;
|
||||||
|
else
|
||||||
|
eventLength = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDeletion() {
|
public boolean isDeletion() {
|
||||||
|
|
@ -104,6 +119,20 @@ public class PileupElement implements Comparable<PileupElement> {
|
||||||
return getBaseDeletionQual(offset);
|
return getBaseDeletionQual(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns length of the event (number of inserted or deleted bases
|
||||||
|
*/
|
||||||
|
public int getEventLength() {
|
||||||
|
return eventLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns actual sequence of inserted bases, or a null if the event is a deletion or if there is no event in the associated read.
|
||||||
|
*/
|
||||||
|
public String getEventBases() {
|
||||||
|
return eventBases;
|
||||||
|
}
|
||||||
|
|
||||||
public int getMappingQual() {
|
public int getMappingQual() {
|
||||||
return read.getMappingQuality();
|
return read.getMappingQuality();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,13 @@ public class ReadBackedPileupImpl extends AbstractReadBackedPileup<ReadBackedPil
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PileupElement createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion, boolean isBeforeDeletion, boolean isBeforeInsertion, boolean isNextToSoftClip) {
|
protected PileupElement createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion, boolean isBeforeDeletion, boolean isBeforeInsertion,
|
||||||
return new PileupElement(read, offset, isDeletion, isBeforeDeletion, isBeforeInsertion, isNextToSoftClip);
|
boolean isNextToSoftClip) {
|
||||||
|
return new PileupElement(read, offset, isDeletion, isBeforeDeletion, isBeforeInsertion, isNextToSoftClip, null,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PileupElement createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion, boolean isBeforeDeletion, boolean isBeforeInsertion,
|
||||||
|
boolean isNextToSoftClip,String nextEventBases, final int nextEventLength) {
|
||||||
|
return new PileupElement(read, offset, isDeletion, isBeforeDeletion, isBeforeInsertion, isNextToSoftClip, nextEventBases,nextEventLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue